vue3 keep alive怎么定向销毁正在打开中的路由组件,重置所有操作?

描述

有个公共组件,需要定向删除keepAlive的缓存,已找到缓存,并删掉缓存里的那条数据,问题:

  1. vue2看见很多人在用类似obj.$destroy()操作,生命周期不一样,vue3 找到cache.$.appContext.app.unmount();但这个是干掉整个app的,vue3应该用什么
  2. 目前现象是

    1. 如果要清除缓存路由没有被打开,直接操作map数据就可以成功
    2. 如果要清除缓存路由正好是当前路由,直接操作map数据,这个路由的操作仍然会被缓存 ,如何正确定向清理vue3 keep alive

下面是捞到的keep alive map数据
image.png

更新

定向删除keepAlive某个key值的缓存

vue2可以操作下,vue3不可行,源码如下,生产环境无法操纵

    if (__DEV__ || __FEATURE_PROD_DEVTOOLS__) {
      ;(instance as any).__v_cache = cache
    }

所以

  1. 放弃这个功能(仔细读的三个项目都遗留放弃了精细操作,实际不同操作和预期可能会有差别)
  2. vue改进下(有翻到issue,没接受)
  3. 复制源码出来魔改下,vue2有很多项目这样做,vue3暂时没找到现成的,还没着手改了试试

重置操作(重置组件重新渲染)

直接方式不可行,找了github上有类似功能的项目,发现基本都是做空路由跳转。跳转到某个指定空路由,再跳转回本来要跳转的路由。

阅读 6.9k
2 个回答

想要实现前进更新后退销毁,核心在操作keep-alive的include。
具体做法就是当进入新页面时将页面name保存,再次进入就将它之后的name删除。

具体实现思路:
正常情况下页面是线性前进的:

A->B->C->D

include数组数据[A,B,C,D]

当再次进入C,就认为是D返回C

include数组数据[A,B,C]

D页面就被销毁了,从而实现了后退销毁

使用vuex保存include数组
const keep = {

 namespaced: true,
 state: () => {
     return {
         include: [],
     }
 },
 getters: {
     include(state) {
         return state.include
     },
 },
 mutations: {
     add(state, name) {
         let b = false
         let i = 0
         for (; i < state.include.length; ++i) {
             let e = state.include[i]
             if (e == name) {
                 b = true
                 break
             }
         }
         if (!b) {
             state.include.push(name)
         } else {
             state.include.splice(i + 1)
         }
     }
 },
 actions: {
 }

}
export default keep
在beforeEach中添加name
import store from "../store"
router.beforeEach((to, from,next) => {
// 页面name要和route 的name一样

 store.commit("keep/add", to.name)
 next()

})
include使用
<template>

 <router-view v-slot="{ Component }">
 <keep-alive :include="includeList">
     <component :is="Component" />
 </keep-alive>
 </router-view>

</template>
<script>
export default {

 computed: {
 includeList() {
     return this.$store.getters["keep/include"].join(",");
 },
 },

};
</script>
当然还有页面循环跳转的情况,一般是详情页

A->A->A->A 或A->B->C->A->B->C

这种情况如果不需要保存页面,就用wacth监控$route变化 重新请求接口

如果需要保存页面,就用动态路由addRoute添加新的路由

A1->A2->A3->A4

import time from "../views/time"
function copyObj(obj) {

 if (typeof obj == "object") {
     if (Array.isArray(obj)) {
         let arr = [];
         for (let item of obj) {
             arr.push(Object.assign(copyObj(item)));
         }
         return arr;
     } else if (obj == null) {
         return null;
     } else {
         let obj1 = {};
         for (let index in obj) {
             obj1[index] = copyObj((obj[index]));
         }
         return obj1;
     }
 } else if (typeof obj == "function") {
     return Object.assign(obj);
 } else if (typeof obj == undefined) {
     return undefined;
 } else {
     return obj;
 }

}
window.pushTime = function () {

 let t = new Date().getTime();
 let path = `/time/${t}`;
 // 深复制component
 time = copyObj(time)
 // component name要和route 的name一样
 time.name = path
 this.$router.addRoute({
     path,
     name: path,
     component: time,
 });
 this.$router.push({
     path,
 });

}

引入地址: http://www.cppcns.com/wangluo...

可以使用activated生命周期重置缓存组件的状态啊,为什么一定要销毁呢?

推荐问题