`keep-alive`支持自定义缓存key和删除缓存方法
What problem does this feature solve?
Make it easier to control keep-alive caches..
What does the proposed API look like?
KeepAliveInstance.getKeys() => string[]
to get all the cached keys.KeepAliveInstance.removeCache( key: string ) => void
to remove a cache.KeepAliveInstance.clearCaches() => void
to remove whole caches.KeepAliveInstance.switchKey( oldKey: string, newKey: string ) => void
to switch the key of a cache to anthor one.
<template>
<router-view v-slot="{ Component, route }">
<transition>
<keep-alive ref="ka">
<!-- route.fullPath as the Root VNode Key -->
<component :is="Component" :key="route.fullPath" />
</keep-alive>
</transition>
</router>
</template>
<script>
export default {
methods: {
removeCache() {
const keys = this.$refs.ka.getKeys();
const key = this.$route.fullPath;
if(keys.includes(key)) {
this.$refs.ka.removeCache(key);
}
},
clearCaches() {
this.$refs.ka.clearCaches();
}
}
}
</script>
有官方大佬回复个吗?这个确实是有很大用处的提议。
keep-alive 可选地把 slots.default() 的 key 用作 root VNode 的 cache key
<keep-alive ref="ka">
<component :is="Component" :key="route.fullPath" />
</keep-alive>
keep-alive 的内部有 pruneCacheEntry( key: CacheKey ) => void 方法,这个方法可以expose出来,我们用这个方法可以可控地移除缓存。
include
其实就可以实现了,把组件包裹一层自定义一下的 name 就可以了。
参考: https://github.com/hminghe/md-admin-element-plus/blob/main/src/components/multi-window/components/MultiWindowKeepAlive.vue
不过还有一点点BUG, 等这个合并了就完美了。https://github.com/vuejs/core/pull/6235
include
其实就可以实现了,把组件包裹一层自定义一下的 name 就可以了。 参考: https://github.com/hminghe/md-admin-element-plus/blob/main/src/components/multi-window/components/MultiWindowKeepAlive.vue不过还有一点点BUG, 等这个合并了就完美了。#6235
给个赞,你的这个方式能解决我的问题!!!感谢大佬的思路!
// 代码大概会是这样子
import { h } from 'vue'
export function wrapperComponent(fullPath: String, comp: VNode) {
const wraper = {
name: fullPath,
render() {
return this.$slots.defaunt();
}
}
return h(wraper, null, comp)
}
不行啊 调用parentComp.ctx.deacti 报错
我上传了一个示例代码,你可以看一下, 给 keep-alive 下的 component 接收的组件包上一层自定义 name 的壳
不行啊 调用parentComp.ctx.deacti 报错
我上传了一个示例代码,你可以看一下, 给 keep-alive 下的 component 接收的组件包上一层自定义 name 的壳
deactive的时候 还是有问题的 vue-router
hminghe commented 9 days ago 不过还有一点点BUG, 等这个合并了就完美了。https://github.com/vuejs/core/pull/6235
等这个合并
#7702
My idea can solve this problem, and it has been used in production. But the harm is great. Welcome to discuss and propose better solutions
const wraper = { name: fullPath, render() { return this.$slots.defaunt(); } }
这种自定义组件名称的用法哪里有介绍?没见过这种语法
我这么做会有什么不好的地方吗?
<!-- 路由匹配到的组件将渲染在这里 -->
<router-view v-slot="{ Component }">
<keep-alive :include="includeTest">
<component :is="wrap(Component, $route.fullPath)" />
</keep-alive>
</router-view>
const includeTest = ref(['/test/page1'])
onMounted(() => {
console.log('layout/index onMounted')
})
onActivated(() => {
console.log('layout/index onActivated')
})
onDeactivated(() => {
})
const cache = new Map()
/**
* 组件复用缓存处理
* @param cmp 组件
* @param fullPath 全路径
*/
const wrap = (cmp: any, fullPath: string) => {
// console.log('cmp.type:', cmp.type, Object.keys(cmp.type))
// if (!chchedRoute.value.includes(fullPath)) return cmp
if (cache.has(fullPath)) {
cmp.type = cache.get(fullPath)
}
else {
const t: Record<string, any> = {}
for (const key of Object.keys(cmp.type))
t[key] = cmp.type[key]
cmp.type = t
cmp.type.__name = fullPath
cache.set(fullPath, cmp.type)
}
return cmp
}
@msojocs 抱歉这个我不是很清楚,我只是用vue有提供的api来包个壳,没有使用过这种方式。 你用的这个方式,如果vue组件内部的构成变更了,可能就不能正常使用了。
感谢,确实发生发一些问题。(scoped css 出现了问题。。)
编辑:
用 Object.keys(component)
暂时解决了
include
其实就可以实现了,把组件包裹一层自定义一下的 name 就可以了。 参考: https://github.com/hminghe/md-admin-element-plus/blob/main/src/components/multi-window/components/MultiWindowKeepAlive.vue 不过还有一点点BUG, 等这个合并了就完美了。#6235给个赞,你的这个方式能解决我的问题!!!感谢大佬的思路!
// 代码大概会是这样子 import { h } from 'vue' export function wrapperComponent(fullPath: String, comp: VNode) { const wraper = { name: fullPath, render() { return this.$slots.defaunt(); } } return h(wraper, null, comp) }
这个实践有个问题,包裹进来的组件变成了路由本身,导致层级很深,切换很慢,不知道是哪里的问题
include
其实就可以实现了,把组件包裹一层自定义一下的 name 就可以了。 参考: https://github.com/hminghe/md-admin-element-plus/blob/main/src/components/multi-window/components/MultiWindowKeepAlive.vue 不过还有一点点BUG, 等这个合并了就完美了。#6235给个赞,你的这个方式能解决我的问题!!!感谢大佬的思路!
// 代码大概会是这样子 import { h } from 'vue' export function wrapperComponent(fullPath: String, comp: VNode) { const wraper = { name: fullPath, render() { return this.$slots.defaunt(); } } return h(wraper, null, comp) }
这个实践有个问题,包裹进来的组件变成了路由本身,导致层级很深,切换很慢,不知道是哪里的问题
devtools 比较卡,关了 devtoools 或者生产环境是不会慢的。