vue填坑记录:刷新浏览器,router导航守卫不响应

时间:2022-06-13
本文章向大家介绍vue填坑记录:刷新浏览器,router导航守卫不响应,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

先来说下背景,,,最近在看Vue SSR相关知识。参考 vue-ssr 官方 例子,vue-hackernews-2.0,https://github.com/vuejs/vue-hackernews-2.0

都搞定了后,遇到一个刷新页面的问题(我指的是手动刷新浏览器,不是用router程序刷新),因为程序里router有设置 导航守卫 beforeResolve 用于数据预加载使页面呈现效果。但是,刷新页面后,一直没有响应这个导航守卫。

路由配置如下:

export default {
  '/': {
    viewpath: 'views/homepage',
    name:'default',
    title:'首页',
  },
  '/hero': {
    viewpath: 'views/hero',
    name:'hero',
    title:'英雄',
  },
  '/tool': {
    viewpath: 'views/tool',
    name:'tool',
    title:'装备',
  },
}

分别对应三个页面,如下:

(tool页面,手动切换时正常显示的。有图是强刷浏览器,没有响应数据)

咱们先不说在页面create或者mounted做处理。 因为应用程序是打算同时支持vue SSR 和 普通 VUE 程序的,兼容代码写法,不像在vue-cli上客户端加一套逻辑。而且,有守卫导航这个好东西,就是解决这个需求的。

为甚 beforeResolve 没有生效呢???

我们来看一下 官方例子的写法,entry-client.js文件,

Vue.mixin({
  beforeRouteUpdate (to, from, next) {
    console.log('beforeupdate',to);
    const { asyncData } = this.$options
    if (asyncData) {
      asyncData({
        store: this.$store,
        route: to
      }).then(next).catch(next)
    } else {
      next()
    }
  }
})

const { app, router, store } = createApp()

if (window.__INITIAL_STATE__) { 
  store.replaceState(window.__INITIAL_STATE__)
}

router.onReady(() => {
  // Add router hook for handling asyncData.
  // Doing it after initial route is resolved so that we don't double-fetch
  // the data that we already have. Using router.beforeResolve() so that all
  // async components are resolved.

  router.beforeResolve((to, from, next) => {
      ...//这里就是我们想要,预取数据的。

注意到,这个beforeResolve守卫,是在route好了之后才设置的,目的是为了防止服务器已经获取的数据,客户端不用二次获取。 然而,在非ssr应用里,,,我们应该是在router.resolve()之前就应该设置这个导航,不能等页面router解析好了才设置。这就是为什么一刷新页面,没有响应,切换页面时正常的原因所在。

解决办法:把resovle移动到ready函数外面。当然,为了ssr的no double-fetch,,,加一个判断即可。简单的,根据 这个变量 window.__INITIAL_STATE__ 存在来判断即可。因为这个变量就是标志是服务器渲染的页面。