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

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

作者: 苏苏哇哈哈 | 来源:发表于2022-05-22 21:14 被阅读0次

    1.实现效果

    keep-alive.gif

    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+订阅!

    相关文章

      网友评论

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

          本文链接:https://www.haomeiwen.com/subject/deklprtx.html