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

Vue3+Vite+Vuex 页面重载时subscribe无法监听mutation问题

问题根因

核心是监听器注册时机晚于重载场景下的mutation执行时机:

  1. 你当前main.js的执行逻辑是:先触发store.dispatch('auth/attempt', localStorage.getItem('token')),这个action执行过程中会同步/异步触发SET_TOKEN、SET_USER等mutation。
  2. 等上述dispatch的Promise状态变为完成后,你才执行app.use(store)完成store注入、挂载应用,而你的store.subscribe监听器一般写在组件逻辑、路由守卫或依赖应用挂载的插件中,此时才会完成注册。
  3. 等监听器注册完成时,页面重载阶段触发的所有mutation早就执行完毕,自然无法被监听到。

登录场景下应用早已完成挂载、监听器提前注册完成,所以触发mutation时可以被正常捕获。
另外你的代码存在Vue3兼容问题:ADD_USER_DATA mutation中使用的Vue.set是Vue2专属API,Vue3中直接赋值即可实现响应式,保留该写法会抛出运行时异常。

修复方案

二选一即可,推荐优先用方案2,逻辑更稳妥:

  • 方案1:调整main.js执行顺序,先完成应用挂载、监听器注册,再执行初始化的用户身份校验逻辑
    调整后核心代码参考:
    // 先完成全局配置、插件、全局组件注册
    app.config.globalProperties.emitter = mitt();
    app.component('font-awesome-icon', FontAwesomeIcon)
    app.use(router)
      .use(store)
      .use(VueToast)
      .use(i18n)
    
    // 挂载应用,触发组件内部的监听器注册逻辑
    app.mount('#app')
    
    // 所有监听器就位后,再执行初始化token校验
    store.dispatch('auth/attempt', localStorage.getItem('token'))
    
  • 方案2:将subscribe监听器注册逻辑提前到store实例创建完成后立即执行,不依赖应用挂载流程
    在store的入口定义文件中,创建完store实例就直接注册监听:
    // store/index.js
    import { createStore } from 'vuex'
    const store = createStore({
      // 原有store配置:modules、state、mutations等
    })
    
    // store创建完成立刻注册监听,全局生效
    store.subscribe((mutation, state) => {
      // 自定义mutation监听逻辑
    })
    
    export default store
    

额外兼容修复:修改ADD_USER_DATA mutation的Vue2旧写法,适配Vue3响应式逻辑:

ADD_USER_DATA: (state, data) => {
  Object.keys(data).forEach( key => {
    state.user[key] = data[key]
  })
}

内容的提问来源于stack exchange,提问作者Bryan van der Starre

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 04:12:14