vue中,由于刷新页面,导致 vuex 数据丢失,如何判断是否刷新了,如果刷新了,需要重新请求数据放在 vuex 中

刷新页面 → Vuex 数据丢失 → 需要判断“是否刷新” → 如果是,重新请求数据并填充到 Vuex


✅ 最佳解决方案(一步到位)

我们分三步走:

  1. 监听页面是否刷新
  2. 如果是刷新,触发重新请求数据的 Action
  3. 在合适的生命周期(如 App.vue 或 store 初始化)执行

🧩 步骤 1:创建判断页面是否刷新的工具函数

// utils/pageReload.js
export function isPageReloaded() {
  // ✅ 优先使用标准 Performance API(现代浏览器)
  if (performance.getEntriesByType) {
    const [navEntry] = performance.getEntriesByType('navigation')
    if (navEntry) {
      return navEntry.type === 'reload'
    }
  }

  // 降级使用旧 API
  if (performance.navigation) {
    return performance.navigation.type === 1
  }

  // ⚠️ 降级方案:sessionStorage 标记法(100% 兼容)
  const reloaded = sessionStorage.getItem('__PAGE_RELOADED__') === 'true'
  if (!reloaded) {
    sessionStorage.setItem('__PAGE_RELOADED__', 'true')
  }
  return reloaded
}

✅ 这个函数能准确判断“页面是否被刷新”,兼容所有浏览器。


🧩 步骤 2:在 Vuex Store 中定义“恢复数据”的 Action

// store/modules/user.js (示例模块)
import api from '@/api'

export default {
  namespaced: true,
  state: {
    profile: null,
    token: '',
    permissions: [],
  },
  mutations: {
    SET_PROFILE(state, profile) {
      state.profile = profile
    },
    SET_TOKEN(state, token) {
      state.token = token
    },
    SET_PERMISSIONS(state, permissions) {
      state.permissions = permissions
    },
  },
  actions: {
    // ✅ 关键:重新拉取用户数据并填充 Vuex
    async restoreUserData({ commit, state }) {
      try {
        // 如果已有 token(比如存在 localStorage),才请求
        const token = localStorage.getItem('token')
        if (!token) return

        // 1. 设置 token
        commit('SET_TOKEN', token)

        // 2. 请求用户信息
        const profile = await api.getUserProfile()
        commit('SET_PROFILE', profile)

        // 3. 请求权限
        const permissions = await api.getUserPermissions()
        commit('SET_PERMISSIONS', permissions)

        console.log('✅ 刷新页面后,已重新加载用户数据到 Vuex')
      } catch (error) {
        console.error('❌ 恢复用户数据失败', error)
        // 可选:跳转到登录页
        // router.push('/login')
      }
    }
  }
}

💡 你也可以在根 store 或其他模块中定义类似 restoreAppData 的 Action。


🧩 步骤 3:在 App.vue 或 store 初始化时触发恢复

✅ 推荐方式:在 App.vuemounted 中判断并恢复

<!-- App.vue -->
<script>
import { mapActions } from 'vuex'
import { isPageReloaded } from '@/utils/pageReload'

export default {
  async mounted() {
    // 👇 判断是否是刷新页面
    if (isPageReloaded()) {
      console.log('监听页面刷新,正在恢复 Vuex 数据...')

      // 👇 调用 Vuex Action 重新请求数据
      await this.restoreUserData()
      // 如果有其他模块数据,也可以在这里恢复
      // await this.restoreCartData()
      // await this.restoreSettings()
    }
  },
  methods: {
    ...mapActions('user', ['restoreUserData']),
    // ...mapActions('cart', ['restoreCartData']),
  }
}
</script>

✅ 为什么在 App.vue?因为它是应用根组件,确保在任何页面渲染前执行。


🧩 步骤 4(可选):在路由守卫中恢复(适合权限控制场景)

如果你用 Vue Router,也可以在全局前置守卫中恢复:

// router/index.js
import { isPageReloaded } from '@/utils/pageReload'
import store from '@/store'

router.beforeEach(async (to, from, next) => {
  if (isPageReloaded() && !store.state.user.profile) {
    await store.dispatch('user/restoreUserData')
  }
  next()
})

⚠️ 注意避免重复触发:可以加个标记,比如 store.state.app.restored = true


✅ 完整流程总结

步骤 做什么
1 isPageReloaded() 判断是否刷新
2 App.vuemounted 中调用
3 触发 Vuex Action:restoreUserData()
4 Action 内部从 API 重新请求数据并 commit 到 state
5 页面组件从 Vuex 读取数据 → 数据已恢复 ✅

✅ 优化建议

1. 避免重复恢复

// store/modules/app.js
state: {
  restoredAfterReload: false
},
mutations: {
  SET_RESTORED(state) {
    state.restoredAfterReload = true
  }
},
actions: {
  async restoreAfterReload({ state, commit, dispatch }) {
    if (state.restoredAfterReload) return // 👈 避免重复执行
    await dispatch('user/restoreUserData')
    commit('SET_RESTORED')
  }
}

2. 显示加载状态(用户体验)

<!-- App.vue -->
<template>
  <div id="app">
    <div v-if="isLoading" class="loading">正在恢复数据...</div>
    <router-view v-else />
  </div>
</template>

<script>
export default {
  data() {
    return {
      isLoading: false
    }
  },
  async mounted() {
    if (isPageReloaded()) {
      this.isLoading = true
      await this.restoreAfterReload()
      this.isLoading = false
    }
  },
  methods: {
    ...mapActions('app', ['restoreAfterReload'])
  }
}
</script>

3. 结合 localStorage 缓存 token / 用户ID,避免无意义请求

// 在 restoreUserData 中:
const token = localStorage.getItem('token')
if (!token) {
  // 没有 token,跳转登录
  this.$router.push('/login')
  return
}

✅ 最终效果

  • 用户刷新页面 → Vuex 数据丢失 ❌
  • 系统自动检测到“刷新” → 自动调用 restoreUserData()
  • 重新请求 API → 填充 Vuex → 页面组件正常渲染 ✅
  • 用户无感知,体验无缝!

🚀 Bonus:如果你用 Pinia(Vue 3 新推荐状态管理)

逻辑完全一样:

// stores/user.ts
import { ref } from 'pinia'
import { defineStore } from 'pinia'
import { isPageReloaded } from '@/utils/pageReload'

export const useUserStore = defineStore('user', () => {
  const profile = ref(null)
  const token = ref('')

  async function restoreUserData() {
    const t = localStorage.getItem('token')
    if (!t) return
    token.value = t
    profile.value = await api.getUserProfile()
  }

  // 自动恢复
  if (isPageReloaded()) {
    restoreUserData()
  }

  return { profile, token, restoreUserData }
})

你现在就可以:

  1. 创建 utils/pageReload.js
  2. 在 Vuex 模块中添加 restoreUserData Action
  3. App.vuemounted 中调用
  4. 刷新页面 → 数据自动恢复!

需要我帮你根据你的具体 Vuex 模块结构定制代码吗?贴出来,我来帮你写 👍

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容