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 全局通知系统。这个方案既保证了兼容性,又提供了良好的用户体验和可扩展性。

相关推荐
sTone873753 小时前
Android核心概念(一)minSdkVersion targetSdkVersion compileSdkVersion
android·前端
林太白3 小时前
八大数据结构
前端·后端·算法
一 乐3 小时前
流浪动物救助|流浪猫狗救助|基于Springboot+vue的流浪猫狗救助平台设计与实现(源码+数据库+文档)
java·前端·数据库·vue.js·spring boot·毕设
火星数据-Tina3 小时前
Python + WebSocket 实现实时体育比分系统(含数据库设计与前端演示)
开发语言·前端
国思RDIF框架3 小时前
国思RDIF低代码快速开发框架 v6.2.2版本发布
前端·vue.js·后端
oil欧哟3 小时前
Agent 设计与上下文工程- 02 Workflow 设计模式(上)
前端·网络·人工智能
StarkCoder3 小时前
GetX 状态管理优化:从 GetBuilder 到 Obx 的性能提升实践
前端
小高0073 小时前
深入理解 package.json:前端项目的 "身份证"
前端·javascript·vue.js
StarkCoder3 小时前
Flutter ListView 数据变动导致的卡顿与跳动问题:Key 的妙用
前端