UniApp 全局通知功能实现

UniApp 全局通知功能实现:从 Vue 3 兼容性问题到完整解决方案

本文记录了一个 UniApp 项目中全局通知功能的完整实现过程,重点解决了 Vue 3 API 在旧版本 HBuilderX 中的兼容性问题,并提供了完整的代码示例和实现思路。

问题背景

在开发 UniApp 应用时,我尝试实现一个全局通知功能,但在运行时遇到了白屏问题。经过排查,发现这是因为项目使用了 Vue 3 的 API,而当前使用的 HBuilderX 版本对 Vue 3 支持不完善导致的兼容性问题。

解决方案

1. 降级到 Vue 2 写法

首先需要将项目从 Vue 3 的写法改为 Vue 2 的兼容性写法。

main.js - 修复版

javascript 复制代码
// 使用Vue 2的写法
import App from './App.vue'
import Vue from 'vue'
import './common/uni.promisify.adaptor'

Vue.config.productionTip = false
App.mpType = 'app'

const app = new Vue({
  ...App
})
app.$mount()

2. 应用入口文件调整

App.vue - 修复版

vue 复制代码
<script>
export default {
  onLaunch() {
    console.log('App启动')
    // 设置一个简单的token模拟登录
    uni.setStorageSync('token', 'test_token')
  },
  
  onShow() {
    console.log('App Show')
  },
  
  onHide() {
    console.log('App Hide')
  }
}
</script>

<style>
/* 全局样式 */
page {
  background-color: #f8f8f8;
  font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', Helvetica, sans-serif;
}

.container {
  padding: 20rpx;
}
</style>

核心功能实现

通知功能页面

创建一个功能完善的测试页面,包含多种通知类型和操作日志功能。

pages/index/index.vue - 核心代码结构

vue 复制代码
<template>
  <view class="container">
    <!-- 页面头部 -->
    <view class="header">
      <text class="title">推送通知测试</text>
      <text class="subtitle">点击按钮测试通知功能</text>
    </view>

    <!-- 功能按钮组 -->
    <view class="button-group">
      <button class="btn btn-primary" @tap="sendSimpleNotification">
        发送简单通知
      </button>
      
      <button class="btn btn-success" @tap="sendDelayedNotification">
        发送5秒延迟通知
      </button>
      
      <button class="btn btn-warning" @tap="sendCustomNotification">
        发送自定义通知
      </button>
      
      <button class="btn btn-error" @tap="clearNotifications">
        清空所有通知
      </button>
    </view>

    <!-- 操作日志显示 -->
    <view class="log-card">
      <text class="log-title">操作日志:</text>
      <scroll-view class="log-content" scroll-y>
        <text class="log-item" v-for="(log, index) in logs" :key="index">{{ log }}</text>
      </scroll-view>
    </view>
  </view>
</template>

通知功能方法实现

javascript 复制代码
<script>
export default {
  data() {
    return {
      messageCount: 1,
      logs: []
    }
  },
  
  methods: {
    // 初始化推送功能
    initPush() {
      if (typeof plus === 'undefined') {
        this.addLog('错误: plus对象未定义,请在真机上运行')
        return
      }
      
      // 监听通知点击事件
      plus.push.addEventListener('click', (msg) => {
        this.addLog('通知被点击: ' + msg.content)
        uni.showToast({
          title: '点击了通知',
          icon: 'success'
        })
      })
    },
    
    // 发送简单通知
    sendSimpleNotification() {
      const content = `这是第${this.messageCount}条测试消息`
      
      plus.push.createMessage(
        content,
        JSON.stringify({ type: 'test', id: this.messageCount }),
        {
          title: '测试通知',
          cover: false,
          sound: 'system'
        }
      )
      
      this.addLog('发送通知: ' + content)
      this.messageCount++
    },
    
    // 发送延迟通知
    sendDelayedNotification() {
      plus.push.createMessage(
        '这是5秒后显示的延迟通知',
        JSON.stringify({ type: 'delayed', time: new Date() }),
        {
          title: '延迟通知',
          delay: 5, // 5秒延迟
          cover: false
        }
      )
    },
    
    // 清空所有通知
    clearNotifications() {
      plus.push.clear()
      this.messageCount = 1
      this.addLog('清空所有通知')
    }
  }
}
</script>

兼容性处理

Promise 兼容性适配

创建 common/uni.promisify.adaptor.js 文件处理 Promise 兼容性问题:

javascript 复制代码
// common/uni.promisify.adaptor.js
if (!Promise.prototype.finally) {
  Promise.prototype.finally = function(callback) {
    let P = this.constructor;
    return this.then(
      value => P.resolve(callback()).then(() => value),
      reason => P.resolve(callback()).then(() => { throw reason })
    );
  };
}

配置文件

manifest.json - 配置 Android 通知权限:

json 复制代码
{
  "app-plus": {
    "distribute": {
      "android": {
        "permissions": [
          "<uses-permission android:name=\"android.permission.VIBRATE\"/>",
          "<uses-permission android:name=\"android.permission.POST_NOTIFICATIONS\"/>"
        ]
      }
    }
  }
}

样式设计

采用渐变背景和卡片式设计,提供良好的用户体验:

css 复制代码
.container {
  padding: 40rpx;
  min-height: 100vh;
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
}

.btn {
  width: 100%;
  padding: 28rpx;
  border-radius: 16rpx;
  font-size: 32rpx;
  text-align: center;
  border: none;
  color: white;
  font-weight: bold;
}

技术要点总结

  1. 环境检测 :通过检查 plus 对象是否存在来判断运行环境
  2. 错误处理:完整的 try-catch 机制确保应用稳定性
  3. 用户体验:实时操作日志和 Toast 提示
  4. 功能完善:支持多种通知类型(即时、延迟、自定义)
  5. 权限配置:正确配置 Android 通知权限

运行效果

实现后的应用具备以下功能:

  • 发送即时系统通知
  • 发送延迟通知(5秒后显示)
  • 发送随机内容的自定义通知
  • 一键清空所有通知
  • 实时操作日志记录
  • 通知点击事件处理

注意事项

  1. 此功能需要在真机环境中测试,模拟器可能无法正常使用推送功能
  2. 不同 Android 版本对通知权限的要求可能不同
  3. iOS 设备的通知机制与 Android 有所不同,需要额外配置

通过以上实现,我们成功解决了 Vue 3 兼容性问题,并实现了一个功能完整的 UniApp 全局通知系统。这个方案既保证了兼容性,又提供了良好的用户体验和可扩展性。

相关推荐
passerby606123 分钟前
完成前端时间处理的另一块版图
前端·github·web components
掘了30 分钟前
「2025 年终总结」在所有失去的人中,我最怀念我自己
前端·后端·年终总结
崔庆才丨静觅33 分钟前
实用免费的 Short URL 短链接 API 对接说明
前端
崔庆才丨静觅1 小时前
5分钟快速搭建 AI 平台并用它赚钱!
前端
崔庆才丨静觅1 小时前
比官方便宜一半以上!Midjourney API 申请及使用
前端
Moment1 小时前
富文本编辑器在 AI 时代为什么这么受欢迎
前端·javascript·后端
崔庆才丨静觅2 小时前
刷屏全网的“nano-banana”API接入指南!0.1元/张量产高清创意图,开发者必藏
前端
剪刀石头布啊2 小时前
jwt介绍
前端
爱敲代码的小鱼2 小时前
AJAX(异步交互的技术来实现从服务端中获取数据):
前端·javascript·ajax
万物得其道者成2 小时前
UniApp 多端滑块验证码插件 zxj-slide-verify 实用指南
uni-app