You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Vue.js中如何监听当前时间变化实现token过期自动登出功能

问题根源

Date.now()不属于Vue的响应式依赖项,你通过computed定义的currentTime没有可检测的响应式依赖变化,会一直返回缓存的计算结果,值不会自动更新,对应的watcher自然无法触发。

解决方案

1. 将currentTime改为响应式状态变量并定时更新

不要用computed定义currentTime,改为在响应式状态中声明,通过定时器定期更新它的值,你需求的最小提醒粒度为1分钟,设置30秒的更新间隔足够覆盖所有场景,不会产生多余性能开销。

Vue3 组合式API示例

import { ref, onMounted, onUnmounted, watch } from 'vue'
import { useStore } from 'vuex' // 用Pinia同理导入对应store即可

const store = useStore()
const currentTime = ref(Date.now())
let timeUpdateTimer = null
// 标记已弹出过的提醒,避免重复触发
const notifiedIntervals = ref([])

onMounted(() => {
  // 每30秒更新一次当前时间
  timeUpdateTimer = setInterval(() => {
    currentTime.value = Date.now()
  }, 30 * 1000)
})

onUnmounted(() => {
  // 组件卸载时清除定时器,避免内存泄漏
  if (timeUpdateTimer) clearInterval(timeUpdateTimer)
})

Vue2/选项式API示例

export default {
  data() {
    return {
      currentTime: Date.now(),
      timeUpdateTimer: null,
      notifiedIntervals: []
    }
  },
  mounted() {
    this.timeUpdateTimer = setInterval(() => {
      this.currentTime = Date.now()
    }, 30 * 1000)
  },
  beforeDestroy() {
    if (this.timeUpdateTimer) clearInterval(this.timeUpdateTimer)
  }
}

2. 调整watcher逻辑避免重复提醒

原有watcher逻辑可以正常复用,建议增加提醒标记逻辑,避免同一提醒被重复触发:

// 以Vue3为例,选项式写法逻辑完全一致
watch(currentTime, (newVal) => {
  const expiryTime = localStorage.getItem('scatTokenExpiryTime')
  if (!expiryTime) return
  const expiryTimestamp = Number(expiryTime)
  const remainSeconds = (expiryTimestamp - newVal) / 1000

  // 过期直接登出
  if (remainSeconds <= 0) {
    store.dispatch('logoutUser')
    // 登出后清除定时器和提醒标记
    if (timeUpdateTimer) clearInterval(timeUpdateTimer)
    notifiedIntervals.value = []
    return
  }

  // 对应分钟数转秒数判断,避免重复弹窗
  const checkIntervals = [30*60, 5*60, 1*60]
  checkIntervals.forEach(interval => {
    if (remainSeconds <= interval && remainSeconds > interval - 30 && !notifiedIntervals.value.includes(interval)) {
      handleDialog(`${interval/60}分钟后登录状态将过期,请及时操作`)
      notifiedIntervals.value.push(interval)
    }
  })
})
额外注意

如果该token校验逻辑需要全局生效,建议把上述代码放在根组件App.vue中实现,避免页面切换时组件销毁导致定时器被清除,逻辑失效。

内容的提问来源于stack exchange,提问作者rhythmo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.05 10:18:00