vue中tab标签页keep-alive二级路由+删除指定缓存页面

1.实现效果

在这里插入图片描述

2.keep-alive

2.1是什么:

keep-alive 是 Vue 的内置组件,keep-alive 包裹动态组件时,会缓存不活动的组件实例,而不是销毁它们。和 transition 相似,keep-alive是一个抽象组件:它自身不会渲染一个 DOM 元素,也不会出现在组件的父组件链中。

2.2做什么:

在组件切换过程中将状态保留在内存中,防止重复渲染DOM,减少加载时间及性能消耗,提高用户体验性。主要用于保留组件状态或避免重新渲染。比如:列表进详情页面,面包屑跳转页面等。

2.3怎么用:

1.基本用法
<!-- 基本 -->
<keep-alive>
  <component :is="view"></component>
</keep-alive>

<!-- 多个条件判断的子组件 -->
<keep-alive>
  <comp-a v-if="a > 1"></comp-a>
  <comp-b v-else></comp-b>
</keep-alive>

<!-- 和 `<transition>` 一起使用 -->
<transition>
  <keep-alive>
    <component :is="view"></component>
  </keep-alive>
</transition>

2.当组件在 keep-alive 内被切换,它的 activated 和 deactivated 这两个生命周期钩子函数将会被对应执行。
  • activated:在 keep-alive 组件激活时调用,服务器端渲染期间不被调用。在被缓存页面可以替代created更新数据。
  • deactivated:在 keep-alive 组件停用时调用,服务器端渲染期间不被调用。
3.Props:
include - 字符串或正则表达式。只有名称匹配的组件会被缓存。
exclude - 字符串或正则表达式。任何名称匹配的组件都不会被缓存。
max - 数字。最多可以缓存多少组件实例。

include 和 exclude prop 允许组件有条件地缓存。二者都可以用逗号分隔字符串、正则表达式或一个数组来表示:

<!-- 逗号分隔字符串 -->
<keep-alive include="a,b">
  <component :is="view"></component>
</keep-alive>

<!-- 正则表达式 (使用 `v-bind`) -->
<keep-alive :include="/a|b/">
  <component :is="view"></component>
</keep-alive>

<!-- 数组 (使用 `v-bind`) -->
<keep-alive :include="['a', 'b']">
  <component :is="view"></component>
</keep-alive>

匹配首先检查组件自身的 name 选项,如果 name 选项不可用,则匹配它的局部注册名称 (父组件 components 选项的键值)。匿名组件不能被匹配。

4.项目中的一些用法
  • 路由元信息中的keepAlive判断是否缓存
<!-- 结合路由一起使用 -->
<keep-alive>
  <router-view v-if="$route.meta.keepAlive"></router-view>
 </keep-alive>
 <router-view v-if="!$route.meta.keepAlive"></router-view>
  • 路由钩子中动态设置keepAlive
beforeRouteLeave (to, from, next) {
  if (to.path === 'xxx') {
    from.meta.keepAlive = true
  } else {
    from.meta.keepAlive = false
  }
  next()
},
  • vuex+include动态缓存组件

3.实现步骤

方法一.vuex+include

为每个页面设置不重复的name字段,当点击菜单栏的时候,将点击的组件的name值存入catch_components中,当关闭按钮时候,删除该项。

<keep-alive :include="catch_components" :max="10">
 <router-view></router-view>
</keep-alive>
index.vue:
computed:{
 ...mapState({
    catch_components: (state) => state.catch_components, // keepalive缓存
  }),
}
//点击选中某菜单
selectMenu(item, i, subName) {
   // 方法一:利用include
   this.$store.commit("addKeepAliveCache", item.name);
   var submenu = {
     path: item.path,
     name: item.name,
     label: item.title,
     index: i,
     subName: subName,
   };
   this.$store.commit("selectMenu", submenu);
   this.$router.push({ path: item.path });
 },
 
//关闭某个菜单
  handleClose(tab, index) {
    // 删除keepAlive缓存
    // 方法一:利用include
    this.$store.commit("removeKeepAliveCache", tab.name);
  },
vuex:
// 添加keepalive缓存
addKeepAliveCache(state, val) {
     if (val === '/homepage') {
         return;
     }
     if (state.catch_components.indexOf(val) === -1) {
         state.catch_components.push(val);
     }
 },
 // 删除keepalive缓存
removeKeepAliveCache(state, val) {
    let cache = state.catch_components;
    for (let i = 0; i < cache.length; i++) {
        if (cache[i] === val) {
            cache.splice(i, 1);
        }
    }
    state.catch_components = cache;
},

方法2.vuex+暴力删除cache和keys

无需设置页面的name字段,当点击菜单栏的时候,将点击的组件的路径值存入catch_components中,当关闭按钮时候,删除该路径,并找到当前已缓存的cache和keys,暴力删除该缓存页面。

<keep-alive :max="10">
 <router-view
    :key="$route.path"
    v-if="catch_components.includes(this.$route.path)"
  ></router-view>
</keep-alive>
<router-view
  :key="$route.path"
  v-if="!catch_components.includes(this.$route.path)"
></router-view>

如何拿到当前已缓存的cache和keys

  • 路由钩子函数中获取(此方法只能是关闭当前路由页面才能获取到)
beforeRouteLeave(to, from, next) {
  let cache = this.$vnode.parent.componentInstance.cache; //缓存的组件路径
   let keys = this.$vnode.parent.componentInstance.keys; // 缓存的组件key值
   next()
 },
  • computed中获取(这个方法可以监听到当前页面离开或点击关闭标签离开)
cache: {
   get() {
     if (!this.$route.matched[1]) return;
     const instances = this.$route.matched[1].instances;
     return instances && instances.default && instances.default.$vnode
       ? instances.default.$vnode.parent.componentInstance.cache
       : {};
   },
   set(val) {
     this.$route.matched[1].instances.default.$vnode.parent.componentInstance.cache =
       val;
   },
 },
 cache_key: {
   get() {
     if (!this.$route.matched[1]) return;
     const instances = this.$route.matched[1].instances;
     return instances && instances.default && instances.default.$vnode
       ? instances.default.$vnode.parent.componentInstance.keys
       : [];
   },
   set(val) {
     this.$route.matched[1].instances.default.$vnode.parent.componentInstance.keys =
       val;
   },
 },
   
index.vue
//当关闭tab标签时候,删除指定缓存
 handleClose(tab, index) {
  	// console.log("缓存-------------------------------", this.cache);
   	// console.log("keys---------------------------------", this.cache_key);
   	let cache = this.cache,
     	keys = this.cache_key;
   	if (cache[tab.path] != null) {
     	delete cache[tab.path];
     	keys.splice(keys.indexOf(tab.path), 1);
   	}
   	// 删除keepAlive缓存
   	// 方法二:利用path
   	this.$store.commit("removeKeepAliveCache", tab.path);
 },

4.完整代码,更新在苏苏的码云如果对你有帮助,欢迎你的star+订阅!

  • 2
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值