keep-alive路由缓存

keep-alive可以干什么

  • 可以缓存组件的内容,避免重复加载,影响效率

何时使用

  • 只要我们希望一个组件的内容,不要重复加载时使用

如何缓存页面

  • 在router.js或者router/index.js中
  • 在需要缓存的路由上添加meta:{keepAlive:true}
import Vue from 'vue'
import VueRouter from 'vue-router'
import Home from '../views/Home.vue'

Vue.use(VueRouter)

const routes = [
  {
    path: '/',
    name: 'home',
    component: Home,
    meta:{
      keepAlive:true//缓存
    }
  },
  {
    path:"/products/:kw",
    name:"products",
    component: ()=>import(/* webpackChunkName: "products" */ '../views/Products.vue'),
    props:true,
    meta:{
      keepAlive:false
    }
  }
]

const router = new VueRouter({
  mode:"history",
  routes
})

export default router

注意

meta不能改名!因为meta是路由对象专门定义,用来保存自定义的属性值的配置项
但是keepAlive是自定义的属性,可以改名

在App.vue中

  • 如果当前路由需要缓存($router.meta.keepAlive==true),就放在keep-alive包裹的一个router-view中
  • 如果当前路由不需要缓存($route.meta.leepAlive==false),就放在keep-alive外的一个router-view上
<template>
  <div id="app">
    <div id="nav">
      <router-link to="/">Home</router-link> |
      <router-link to="/about">About</router-link>
    </div>
    /*需要缓存的写法*/
    <keep-alive>
      <router-view v-if="$route.meta.keepAlive"/>
    </keep-alive>
    /*不需要缓存的写法*/
    <router-view v-if="!$route.meta.keepAlive"></router-view>
  </div>
</template>

结果

带有keepAlive:true的路由对应的页面,只在首次请求时,渲染一次内容,之后后退,跳转回来,都不再重新渲染内容

问题

虽然是同一个页面,但是有时数据需要缓存,有时数据不需要缓存

比如

假如有一个是商品列表,可以根据关键词,查询商品列表
如果从首页跳转过来,说明用户输入了查询条件,需要更新查询结果
如果从详情页跳转过来,说明用户从商品列表页面调和粗去的,现在又返回商品列表页面,那么应该保留之前的搜索结果

### Vue Keep-Alive 路由缓存失效的原因及解决方案 #### 一、原因分析 1. **路由配置错误** 如果 `meta` 字段未正确配置,或者缺少必要的字段(如 `keepAlive`),可能导致条件判断失败,从而影响缓存逻辑[^2]。 2. **嵌套路由问题** 对于多级嵌套的路由结构,父级组件如果没有正确应用 `keep-alive` 或者其 `meta` 配置不符合预期,则子路由可能不会被正常缓存[^3]。 3. **生命周期钩子冲突** 使用 `beforeRouteLeave` 和其他导航守卫时,可能会因为某些操作干扰到 `keep-alive` 的行为。例如,在离开页面前清除了状态数据或触发了强制更新的行为[^4]。 4. **动态排除机制不当** 当使用 `exclude` 属性来控制特定页面不被缓存时,如果逻辑设计不合理,容易导致意外情况发生,比如忘记重置 `exclude` 列表[^5]。 --- #### 二、解决方案 ##### 方法一:优化 Meta 配置与模板结构调整 通过合理设置 `$route.meta.keepAlive` 来区分需要缓存和不需要缓存的内容: ```html <template> <!-- 缓存 --> <keep-alive> <router-view v-if="$route.meta && $route.meta.keepAlive"/> </keep-alive> <!--缓存 --> <router-view v-if="!($route.meta && $route.meta.keepAlive)"/> </template> ``` 上述代码利用布尔值判断确保只有设置了 `keepAlive=true` 的路由才会进入缓存区域[^1]。 --- ##### 方法二:采用 Include/Exclude 动态管理缓存策略 可以借助 `include/exclude` 参数更灵活地指定哪些组件参与缓存。以下是具体实现: ###### 设置 Route Name 并启用 include 方式 在路由定义中为每个目标组件赋予唯一的 `name` 属性: ```javascript const routes = [ { path: '/example', name: 'ExamplePage', // 组件名作为标识符 component: Example, meta: { keepAlive: true } }, ]; ``` 随后修改 `<keep-alive>` 定义如下: ```html <keep-alive :include="['ExamplePage']"> <router-view /> </keep-alive> ``` 此方法允许开发者精确筛选符合条件的目标组件进行缓存--- ##### 方法三:引入 Refresh Mechanism (刷新机制) 针对 Tab 页面场景下频繁切换的需求,可以通过增加额外的状态变量(如 `refreshing` 和 `exclude`)完成手动清理缓存的功能: ```html <keep-alive :exclude="exclude"> <router-view v-if="!refreshing" /> </keep-alive> ``` 配合 JavaScript 控制逻辑: ```javascript export default { data() { return { refreshing: false, // 是否正在刷新标志位 exclude: [] // 排除列表,默认为空数组 }; }, methods: { refreshCurrentView(routeName) { this.refreshing = true; this.exclude.push(routeName); this.$nextTick(() => { setTimeout(() => { this.refreshing = false; this.exclude = []; }, 0); }); } } }; ``` 当调用 `refreshCurrentView('ExamplePage')` 后,当前视图会被短暂移出 DOM 结构并重新渲染,达到模拟刷新的效果。 --- ##### 方法四:排查常见报错 遇到诸如 `[vite] Internal Server Error <KeepAlive> expects exactly one child component.` 这样的提示时,请确认 `<keep-alive>` 内部仅存在单一顶层节点;而如果是 `parentComponent.ctx.deactivate is not a function` 类型异常,则可能是框架版本兼容性引发的问题,建议升级至最新稳定版 VUE/VITE。 --- ### 总结 通过对以上几种典型问题及其对应的修复手段介绍可以看出,解决 `keep-alive` 路由缓存失效的关键在于细致调整路由元信息以及科学运用相关参数选项。同时也要留意实际开发环境中的潜在隐患因素,及时验证效果直至满足业务需求为止。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值