【Vite+vue3】vue3当中keep-alive的使用

所有内容首发微信公众号【WEB前端李志杰】,未经允许禁止转载!

是Vue本身提供的一个抽象组件,它自身并不会渲染一个 DOM 元素,主要用于保留组件状态或避免重新渲染。

Vue2.X版本

在Vue2.X中可直接使用组件包裹,使用v-if 配合$route.meta实现组件状态有条件的保留。

<template>
    <div id="app">
        <keep-alive v-if="includedComponents">
            <router-view ></router-view>
        </keep-alive>
        <router-view v-else></router-view>
    </div>
</template>
<script>
export default {
     computed:{
         includedComponents(){
             return this.$route.meta.keepAlive
         }
     }
}
</script>

组件状态保留是通过将组件实例以对象的形式存储在componentInstance中的cache对象内。因此可以利用组件提供的deactivated生命周期钩子手动删除保留的组件状态数据。

1、为每一个组件声明name属性,且name属性值应该具有唯一性,方便准确删除组件保留的数据;

2、为不需要保留状态的组件添加一个removeKeepAliveCache:true标识该组件不需要保留组件状态;

3、使用mixin全局注入如下组件生命周期钩子函数。

deactivated() {
    const removeTabItem = sessionStorage.getItem("removeTabItem");
    if (removeTabItem && this.$vnode && this.$vnode.parent) {
        if (this.$options.removeKeepAliveCache && this.$vnode.parent.componentInstance.cache) {
            let componentInstance = this.$vnode.parent.componentInstance;
            for (const key in componentInstance.cache) {
                if (Object.hasOwnProperty.call(componentInstance.cache, key)) {
                    const item = componentInstance.cache[key];
                    if (item.name === this.$options.name) {
                        delete componentInstance.cache[key];
                       }
                  }
            }
            sessionStorage.removeItem("removeTabItem");
        }
    }
},

Vue3.X版本

在Vue3.X中不能像Vue2.X那样直接使用组件包裹,否则会有如下警告:图片

接下来看看在Vue3.X中如何使用





至于为什么要变为这样,请查看vue-router官网对于router-view 的介绍:
https://next.router.vuejs.org/zh/api/#router-view-%E7%9A%84-v-slot
【Vite+vue3】vue3当中keep-alive的使用_第1张图片

至此,我们在vue3.X中也实现了对组件状态的保留。同样的,我们在Vue3.X中也可以使用v-if 配合$route.meta实现组件状态有条件的保留,请参照Vue2.X版本的示例,以下内容主要介绍通过组件提供的onDeactivated生命周期钩子函数在激活时如何删除保留的组件状态数据。
1、通过Vue提供的getCurrentInstance获取组件实例;
2、为不需要保留状态的组件添加一个removeKeepAliveCache:true标识该组件不需要保留组件状态;
3、通过onDeactivated生命周期钩子函数删除保留的数据。

// about/index.jsx
import { defineComponent, onDeactivated, getCurrentInstance } from "vue";
export default defineComponent({
name: "About",
removeKeepAliveCache: true,
setup() {
  const instance = getCurrentInstance();
  onDeactivated(() => {
    const cache = instance.parent.__v_cache;
    cache.forEach((value, key) => {
      if (key.removeKeepAliveCache) {
        cache.delete(key);
        }
      });
    });
    return () => (
       <>
         <h1>欢迎关注公众号~WEB前端李志杰~</h1>
       </>
    );
  },
});

Vue3.X进阶版

我们可以利用vue3.0的hooks开发思想进一步优化基于onDeactivated命周期钩子函数实现删除组件保留数据的这一部分逻辑。
1、新建一个hooks文件夹,并在hooks文件夹中新建一个useDeleteCache.js的文件,用来实现useDeleteCache函数。
图片
2、实现useDeleteCache.js,并且将获取到的组件实例return返回。

// useDeleteCache.js
import { onDeactivated, getCurrentInstance } from "vue"
export const useDeleteCache = () => {
   const instance = getCurrentInstance();
   onDeactivated(() => {
     const cache = instance.parent.__v_cache;
     cache.forEach((value, key) => {
       if (key.removeKeepAliveCache) {
         cache.delete(key);
       }
     });
   });
   return instance
}

3、改造about/index.jsx文件

// about/index.jsx
import { defineComponent, getCurrentInstance } from "vue";
import { useDeleteCache } from "../../hooks/useDeleteCache";
export default defineComponent({
name: "About",
removeKeepAliveCache: true,
setup() {
    const instance = useDeleteCache();
    return () => (
       <>
         <h1>欢迎关注公众号~WEB前端李志杰~</h1>
       </>
     );
   },
 });

至此,就实现了由About页面切换至其他页面时自动删除保留的About组件状态的全部功能。

最后附上一张Vue3.X关于组件实现的源码:

【Vite+vue3】vue3当中keep-alive的使用_第2张图片

往期精彩内容:
【Vue】在Vite+Vue3.0中使用jsx语法开发。

【Vite+vue3】vue3当中keep-alive的使用_第3张图片

你可能感兴趣的:(Vue,vue.js,前端,javascript,keep-alive,vite)