vue实现浏览器通知

// 建议将这类工具函数放在单独的文件中,例如 src/utils/notification.js
export function notifyMe(title, options = {}) {
  // 1. 环境检查:首先检查是否在浏览器环境中,避免在 SSR (Server-Side Rendering) 时出错
  if (typeof window === 'undefined') {
    console.warn('Notification is not available in a non-browser environment.');
    return Promise.reject(new Error('非浏览器环境,不支持 Notification'));
  }

  // 2. 特性检测:检查浏览器是否支持 Notification API
  if (!('Notification' in window)) {
    console.warn('This browser does not support desktop notification.');
    // 返回一个被拒绝的 Promise,让调用方可以优雅地处理
    return Promise.reject(new Error('此浏览器不支持桌面通知'));
  }

  // 3. 权限处理与通知创建
  // 如果权限已经被授予,直接创建通知
  if (Notification.permission === 'granted') {
    return createNotification(title, options);
  } 
  // 如果权限尚未被设置(即 'default'),则请求权限
  else if (Notification.permission !== 'denied') {
    return Notification.requestPermission().then(permission => {
      if (permission === 'granted') {
        console.log('Notification permission granted.');
        return createNotification(title, options);
      } else {
        // 如果用户拒绝或关闭了权限请求,打印警告并返回拒绝的 Promise
        console.warn(`Notification permission ${permission}.`);
        return Promise.reject(new Error(`通知权限被${permission === 'denied' ? '拒绝' : '忽略'}`));
      }
    });
  } 
  // 4. 如果权限已被拒绝,直接返回拒绝的 Promise
  else {
    console.warn('Notification permission has been denied.');
    return Promise.reject(new Error('通知权限已被拒绝,请在浏览器设置中更改'));
  }
}

/**
 * 内部辅助函数:创建并返回一个 Notification 实例
 * @param {string} title - 通知的标题
 * @param {object} options - 通知的选项,如 body, icon 等
 * @returns {Promise<Notification>} - 返回一个 resolved 的 Promise,其值为 Notification 实例
 */
function createNotification(title, options) {
  // 为通知添加默认图标(如果未提供),提升用户体验
  const defaultOptions = {
    icon: '/favicon.ico' // 假设你的项目根目录下有一个 favicon.ico
  };

  const notification = new Notification(title, { ...defaultOptions, ...options });
  
  // 将 Notification 实例包装在 Promise 中返回,方便调用方监听其事件
  return Promise.resolve(notification);
}

在vue页面使用

<template>
  <div>
    <button @click="requestNotification">请求并发送通知</button>
    <button @click="sendNotification" :disabled="!hasPermission">发送通知</button>
  </div>
</template>

<script>
import { notifyMe } from '@/utils/notification';

export default {
  data() {
    return {
      hasPermission: Notification.permission === 'granted'
    };
  },
  methods: {
    requestNotification() {
      notifyMe('你好,世界!', { body: '这是一条来自 Vue 的桌面通知。' })
        .then(notification => {
          console.log('通知已显示:', notification);
          // 你可以在这里监听通知的点击事件
          notification.onclick = () => {
            console.log('用户点击了通知');
            window.focus(); // 点击通知后聚焦到浏览器窗口
            notification.close(); // 关闭通知
          };
          this.hasPermission = true;
        })
        .catch(error => {
          console.error('发送通知失败:', error.message);
          // 在这里可以向用户显示一个友好的错误提示,例如一个 Toast
          alert(`通知失败: ${error.message}`);
        });
    },
    sendNotification() {
      if (Notification.permission !== 'granted') {
        alert('请先授予通知权限');
        return;
      }
      notifyMe('新消息', {
        body: '你收到了一条新的系统消息。',
        icon: '/path/to/your/icon.png', // 自定义图标
        // 其他可用选项:tag, data, vibrate, sound, timestamp 等
      });
    }
  }
}
</script>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值