vue组件缓存之动态设置keep-alive缓存

本文介绍了如何在Vue应用中实现按需缓存功能,通过在路由配置中添加deepth字段和使用keep-alive组件,结合监听路由变化,只在用户从详情页返回列表页时缓存列表页,其他情况下避免不必要的数据渲染。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

场景需求

从首页的点击导航进入列表页,

列表页点击列表进入 该 数据详情页

从详情页返回,希望列表页缓存,不重新渲染数据。

一、正常增加页面缓存

1、按需缓存组件

在路由信息中再加一个字段,这里是deepth字段,代表进入路由的层级,比如首页路由deepth是0.5,列表页是1,详情页是2

new Router({
    routes: [
        {
            path: '/',
            name: 'index',
            component: () => import('./views/keep-alive/index.vue'),
            meta: {
                deepth: 0.5 // 定义路由的层级
            }
        },
        {
            path: '/list',
            name: 'list',
            component: () => import('./views/keep-alive/list.vue'),
            meta: {
                deepth: 1
                keepAlive: true //需要被缓存
            }
        },
        {
            path: '/detail',
            name: 'detail',
            component: () => import('./views/keep-alive/detail.vue'),
            meta: {
                deepth: 2
           }
        }
    ]
})
 2、增加监听器

然后在 app.vue中增加监听器,监听 我们进入路由的 方向

<template>
    <keep-alive :include="include">
    <!-- 需要缓存的视图组件 -->
      <router-view v-if="$route.meta.keepAlive">
      </router-view>
    </keep-alive>
​
    <!-- 不需要缓存的视图组件 -->
    <router-view v-if="!$route.meta.keepAlive">
    </router-view>
</template>
<script>
    export default {
      name: "app",
      data: () => ({
        include: []
      }),
      watch: {
        $route(to, from) {
          //如果 要 to(进入) 的页面是需要 keepAlive 缓存的,把 name push 进 include数组
          if (to.meta.keepAlive) {
            !this.include.includes(to.name) && this.include.push(to.name);
          }
          //如果 要 form(离开) 的页面是 keepAlive缓存的,
          //再根据 deepth 来判断是前进还是后退
          //如果是后退
          if (from.meta.keepAlive && to.meta.deepth < from.meta.deepth) {
            var index = this.include.indexOf(from.name);
            index !== -1 && this.include.splice(index, 1);
          }
        }
      }
    };
</script>

 借鉴博主:进入博主链接

二、页面已增加缓存,但需要刷新页面

1、给需要缓存的页面增加时间戳key 
new Router({
    routes: [
        {
            path: '/',
            name: 'index',
            component: () => import('./views/keep-alive/index.vue'),
            meta: {
                deepth: 0.5 // 定义路由的层级
            }
        },
        {
            path: '/list',
            name: 'list',
            component: () => import('./views/keep-alive/list.vue'),
            meta: {
                deepth: 1,
                keepAlive: true, //需要被缓存
                keys:Date.now(),//增加时间戳 key值
            }
        },
        {
            path: '/detail',
            name: 'detail',
            component: () => import('./views/keep-alive/detail.vue'),
            meta: {
                deepth: 2
           }
        }
    ]
})
 2、组件渲染 key值处理
<template>
  <!-- <RouterView /> -->
  <router-view v-slot="{ Component, route }">
    <keep-alive :include="include">
      <component
        :is="Component"
        v-if="route.meta.keepAlive"
        :key="route.meta.keys ? route.meta.keys : route.fullPath"
      />
    </keep-alive>
    <component
      :is="Component"
      v-if="!route.meta.keepAlive"
      :key="route.fullPath"
    />
  </router-view>
</template>
 3、页面中路由跳转增加路由信息的key值处理,达到刷新页面效果

vue3代码为例

/**在 Vue Router 中,使用  router.beforeEach  方法添加的全局守卫是累加的,
 * 而不是替换的。因此,如果你在调用  removeGuard  时再次调用
 * router.beforeEach ,它不会覆盖之前的守卫,而是会将新的守卫添加到守卫链中。
 **/

// 控制守卫是否激活
const isGuardActive = ref(false)

// 添加全局守卫
router.beforeEach(guard)
function guard(to, from, next) {
  if (isGuardActive.value) {
    to.meta.keys = Date.now()
  }
  next()
}
// 在某个条件下移除全局守卫
function removeGuard() {
  console.log('在某个条件下移除全局守卫')
  isGuardActive.value = false // 设置为 false,表示不再执行守卫逻辑
}
//点击跳转按钮
function onSubmit() {
  isGuardActive.value = true
  router.push({
    path: '/carEmpower'
  }).then(() => {
    
    /**在 Vue Router 中,使用  router.beforeEach  方法添加的全局守卫是累加的,
     * 函数在  onSubmit()  方法中被调用,这会立即将  isGuardActive.value  设置为  false 。
     * 因此,当路由切换到  /carEmpower  时, guard  函数会检查  isGuardActive.value  的值,
     * 这时它已经是  false  了。 
     **/
     
    // 在路由切换完成后再调用 removeGuard
    removeGuard();
  });
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值