路由缓存问题 | vue-router的导航守卫

路由缓存问题

带参路由,当参数发生变化时,相同的组件实例将被复用 ,组件的生命周期钩子不会被调用,导致数据无法更新

两种解决方法:

1. 给 RouterView绑定key值,即

javascript 复制代码
<RouterView :key="$route.fullPath" />

特点:不复用,破坏组件缓存,强制执行,存在一定的浪费,即 会重复请求数据。如,

2. 使用 onBeforeRouteUpdate 导航钩子(导航守卫),会在每次路由更新之前执行,在回调中执行数据更新的业务逻辑即可。

javascript 复制代码
// 1. 导入钩子
import { onBeforeRouteUpdate } from 'vue-router'

// 2. 使用钩子,路由参数变化时,把数据接口重新发送
//     to 目标路由 
onBeforeRouteUpdate((to)=>{
    // 更新接口业务逻辑
})

特点:精细化控制,性能较好。如,

导航解析流程

  1. 导航被触发。
  2. 在失活的组件里调用离开守卫。
  3. 调用全局的 beforeEach 守卫。
  4. 在重用的组件里调用 beforeRouteUpdate 守卫 (2.2+)。
  5. 在路由配置里调用 beforeEnter。
  6. 解析异步路由组件。
  7. 在被激活的组件里调用 beforeRouteEnter。
  8. 调用全局的 beforeResolve 守卫 (2.5+)。
  9. 导航被确认。
  10. 调用全局的 afterEach 钩子。
  11. 触发 DOM 更新。
  12. 用创建好的实例调用 beforeRouteEnter 守卫中传给 next 的回调函数。

导航守卫

vue-router 提供的,用于通过 跳转/取消 守卫导航。

参数/查询的改变 并不会触发进入/离开的导航守卫。 可以通过观察 $route对象 来应对变化,或使用 BeforeRouteUpdate 的组件内守卫。

参数:

  • to 目标路由

  • from 离开的路由

  • next 函数,用于调用来resolve这个钩子

路由导航种类:

- 全局前置守卫 router.beforeEach

导航 触发时,守卫 按照创建顺序调用。守卫是异步解析执行,此时 导航在所有守卫resolve完之前按一直是处于等待中。--》执行顺序:守卫->导航

javascript 复制代码
const router = new VueRouter({ ... })

router.beforeEach((to, from, next) => {
  // ...
})

- 全局解析守卫 router.beforeResolve(2.5.0新增)

导航被确认之前 ,同时在所有组件内 守卫和 异步路由组件被解析之后,解析守卫就被调用

- 全局后置钩子 route.afterEach

不接受 next函数,且不改变导航本身。

javascript 复制代码
router.afterEach((to, from) => {
  // ...
})

- 单个路由独享 beforeEnter

在路由配置中 定义 beforeEnter 守卫。

javascript 复制代码
const router = new VueRouter({
  routes: [
    {
      path: '/foo',
      component: Foo,
      beforeEnter: (to, from, next) => {
        // ...
      }
    }
  ]
})

- 组件级 beforeRouteEnter、beforeRouteUpdate(2.2新增)、beforeRouteLeave

组件内 定义路由导航守卫。

  • 确认守卫 beforeRouteEnter ,守卫在导航确认前被调用,新组件尚未创建,即无法访问 this,只有它支持给next传递回调。
  • 更新守卫beforeRouteUpdate ,守卫在当前路由改变,但组件被复用时,用于更新(新路由重调接口)
  • 离开守卫 beforeRouteLeave ,用于禁止在还未保存修改前突然离开。可通过 next(false) 来取消。
javascript 复制代码
beforeRouteLeave (to, from , next) {
  const answer = window.confirm('Do you really want to leave? you have unsaved changes!')
  if (answer) {
    next()
  } else {
    next(false)
  }
}
javascript 复制代码
const Foo = {
  template: `...`,
  beforeRouteEnter (to, from, next) {
    next(vm => {})
    // 在渲染该组件的对应路由被 confirm 前调用
    // 不!能!获取组件实例 `this`
    // 因为当守卫执行前,组件实例还没被创建
  },
  beforeRouteUpdate (to, from, next) {
    // 在当前路由改变,但是该组件被复用时调用
    // 举例来说,对于一个带有动态参数的路径 /foo/:id,在 /foo/1 和 /foo/2 之间跳转的时候,
    // 由于会渲染同样的 Foo 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用。
    // 可以访问组件实例 `this`
  },
  beforeRouteLeave (to, from, next) {
    // 导航离开该组件的对应路由时调用
    // 可以访问组件实例 `this`
  }
}

参考:导航守卫 | Vue Router

相关推荐
喵个咪10 小时前
一套Schema,生成全部代码|Kratos高效开发新范式
前端·后端·架构
Dewyze同学10 小时前
我用 Cursor 三天从零到可上线:uni-app + Fastify 全栈小程序复盘
前端
qq_3813385010 小时前
前端虚拟列表与无限滚动性能优化实战:从万级数据到丝滑体验
前端·javascript·html·优化
hexu_blog10 小时前
前端vue后端springboot如何实现图片格式转换
前端·javascript·vue.js
代码煮茶10 小时前
Vue3 项目规范实战 | ESLint+Prettier+Git Hooks 搭建前端代码规范体系
前端·javascript·vue.js
米丘10 小时前
新一代代码格式化工具 Oxfmt/Oxlint
前端·rust·前端工程化
_Evan_Yao10 小时前
缓存与数据库的“双写悖论”:一致性的常见陷阱与破局之道
java·后端·缓存
韭菜炒大葱10 小时前
讲讲 浏览器的缓存机制
前端·面试·浏览器
AI砖家10 小时前
DeepSeek TUI 保姆级安装配置全指南 -Windows||macOS双平台全覆盖
服务器·前端·人工智能·windows·macos·ai编程·策略模式
Apache01210 小时前
chrome调试打开,让AI来操作浏览器
前端·chrome