You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何实现无需刷新页面的实时提醒通知功能

如何实现无需刷新页面的实时提醒通知功能

嘿,我来帮你搞定这个实时提醒的问题!你已经搭好了后端的提醒数据接口,也能在Vue里拿到3小时内的待提醒列表,接下来只需要在前端做定时检查,就能实现无需刷新的弹窗提醒啦。我给你分步骤拆解:

第一步:在Vue组件里添加定时检查逻辑

首先,我们需要一个定时器,每隔一段时间就去检查当前时间和提醒时间是否匹配。同时要避免重复提醒同一个事项,所以得记录已经触发过的提醒ID。

先在组件的data里加两个变量:

data() {
  return {
    reminders: [],
    triggeredReminders: [], // 用来存已经触发过的提醒ID,避免重复弹窗
    checkInterval: null // 存定时器实例,方便销毁时清除
  }
}

然后在mounted钩子启动定时器,比如每隔30秒检查一次(你可以根据需求调整间隔):

mounted() {
  this.getReminders(); // 先获取一次初始数据
  // 启动定时检查,同时每隔一段时间拉取最新提醒数据
  this.checkInterval = setInterval(() => {
    this.getReminders();
    this.checkReminders();
  }, 30000); // 30000毫秒 = 30秒
}

接下来写核心的checkReminders方法,用来对比时间并触发弹窗:

methods: {
  getReminders() {
    axios.get('/reminders/get-reminders')
      .then(response => {
        this.reminders = response.data.data;
      })
  },
  checkReminders() {
    const now = new Date();
    this.reminders.forEach(reminder => {
      // 把后端返回的remindTime转成Date对象,注意时区要和后端一致
      const remindTime = new Date(reminder.remindTime);
      // 检查当前时间是否已到提醒时间,且该提醒还没触发过
      if (now >= remindTime && !this.triggeredReminders.includes(reminder.id)) {
        // 弹出提醒,你也可以换成UI库的通知组件替代原生alert
        alert(`提醒:${reminder.title}\n${reminder.description}`);
        // 把该提醒ID加入已触发列表,避免重复弹窗
        this.triggeredReminders.push(reminder.id);
      }
    });
  }
}

最后,别忘了在组件销毁时清除定时器,防止内存泄漏:

beforeUnmount() {
  if (this.checkInterval) {
    clearInterval(this.checkInterval);
  }
}

第二步:优化建议(可选)

如果想让提醒更精准或者减少前端压力,可以做这些优化:

  • 数据库加状态字段:给reminders表加一个status字段(比如untriggered/triggered),后端返回数据时只返回untriggered的提醒,触发后后端把状态改成triggered,这样前端不用自己记录已触发的ID,更可靠。
    迁移代码可以加:
    $table->enum('status', ['untriggered', 'triggered'])->default('untriggered');
    
    后端查询时加:
    $latestReminder = Reminder::where('remindTime', '<=', Carbon::now()->addHours(3)->toDateTimeString())
      ->where('remindTime', '>=', Carbon::now()->toDateTimeString())
      ->where('status', 'untriggered') // 只查未触发的
      ->latest()
      ->take(3)
      ->get();
    
  • 用WebSocket实现实时推送:如果需要毫秒级的实时提醒,可以用Laravel Echo配合Pusher或者Socket.io,后端在提醒时间到的时候主动推送给前端,这样不用前端轮询,效率更高。不过这个方案配置稍微复杂一点,适合对实时性要求高的场景。

注意事项

  • 时区问题:确保后端返回的remindTime和前端的时间时区一致,最好统一用UTC时间存储和传输,前端转成本地时间处理,避免因为时区差导致提醒不准。
  • 弹窗样式:默认的alert比较简陋,你可以换成Element UI、Ant Design Vue等UI库的通知组件,视觉体验会更好。

备注:内容来源于stack exchange,提问作者Maison012

火山引擎 最新活动