1200字范文,内容丰富有趣,写作的好帮手!
1200字范文 > vue-element-admin项目采用keep-alive全缓存 删除标签移除指定的缓存

vue-element-admin项目采用keep-alive全缓存 删除标签移除指定的缓存

时间:2022-04-20 06:08:28

相关推荐

vue-element-admin项目采用keep-alive全缓存 删除标签移除指定的缓存

旧方案存在的问题

之前在/weixin_35958891/article/details/102685382博客中解决了三级菜单无法缓存的问题,但是那个方案是有bug 的就是缓存只在超过20个后才会删除第一个旧的,也就是会同时存在20个页面缓存的情况,除非f5刷新要不然缓存一直都存在。

解决思路

看了大佬的博客得到启发https://juejin.im/post/6844903649517240328,删除标签的时候将缓存删掉。TagsView.vue中删除单个、删除其他、删除全部标签分别触发方法,到AppMain.vue中去实现具体的删除逻辑。下面是vue的keep-alive.js的源码,感兴趣的可以把vue的源码拉下来看一下,

function pruneCacheEntry (cache,key,keys,current) {const cached = cache[key]if (cached && (!current || cached.tag !== current.tag)) {ponentInstance.$destroy()}cache[key] = nullremove(keys, key)}

可以看到删除缓存一共分三步

1、调用destory()2、清空cache3、移除kes里对应的key值

代码

layout/components/AppMain.vue中

<template><section class="app-main"><transition name="fade-transform" mode="out-in"><keep-alive :max="20"><router-view :key="key" /></keep-alive></transition></section></template><script>import Bus from '../bus.js'export default {name: 'AppMain',computed: {cachedViews() {return this.$store.state.tagsView.cachedViews;},key() {return this.$route.fullPath;}},mounted() {// 关闭标签触发Bus.$on('removeCache', (name, view) => {this.removeCache(name, view);});},methods: {// 获取有keep-alive子节点的VnodegetVnode() {// 判断子集非空if (this.$children.length == 0) return false;let vnode;for (let item of this.$children) {// 如果data中有key则代表找到了keep-alive下面的子集,这个key就是router-view上的keyif (item.$vnode.data.key) {vnode = item.$vnode;break;}}return vnode ? vnode : false;},// 移除keep-alive缓存removeCache(name, view = {}) {let vnode = this.getVnode();if (!vnode) return false;let componentInstance = ponentInstance;// 这个key是用来获取前缀用来后面正则匹配用的let keyStart = vnode.key.split('/')[0];let thisKey = `${keyStart}${view.fullPath}`;let regKey = `${keyStart}${view.path}`;this[name]({componentInstance, thisKey, regKey });},// 移除其他closeOthersTags({componentInstance, thisKey }) {Object.keys(componentInstance.cache).forEach((key, index) => {if (key != thisKey) {// 1 销毁实例(这里存在多个key指向一个缓存的情况可能前面一个已经清除掉了所有要加判断)if (componentInstance.cache[key]) {componentInstance.cache[key].componentInstance.$destroy();}// 2 删除缓存delete componentInstance.cache[key];// 3 移除key中对应的keycomponentInstance.keys.splice(index, 1);}});},// 移除所有缓存closeAllTags({componentInstance }) {// 1 销毁实例Object.keys(componentInstance.cache).forEach(key => {if (componentInstance.cache[key]) {componentInstance.cache[key].componentInstance.$destroy();}});// 2 删除缓存componentInstance.cache = {};// 3 移除key中对应的keycomponentInstance.keys = [];},// 移除单个缓存closeSelectedTag({componentInstance, regKey }) {let reg = new RegExp(`^${regKey}`);Object.keys(componentInstance.cache).forEach((key, i) => {if (reg.test(key)) {// 1 销毁实例if (componentInstance.cache[key]) {componentInstance.cache[key].componentInstance.$destroy();}// 2 删除缓存delete componentInstance.cache[key];// 3 移除key中对应的keycomponentInstance.keys.splice(i, 1);}});}}};</script>

layout/components/TagsView.vue中,这里主要就是用bus触发一下方法,就不贴完整代码了,免得干扰主逻辑,不要忘了引入bus,在beforeDestory生命周期里把bus关一下

closeSelectedTag(view) {this.$store.dispatch("delView", view).then(({visitedViews }) => {if (this.isActive(view)) {const latestView = visitedViews.slice(-1)[0];if (latestView) {this.$router.push(latestView);} else {this.$router.push("/");}}//关闭单个Bus.$emit('removeCache','closeSelectedTag',view)});},closeOthersTags() {this.$router.push(this.selectedTag);//关闭其他Bus.$emit('removeCache','closeOthersTags',this.selectedTag);this.$store.dispatch("delOthersViews", this.selectedTag).then(() => {this.moveToCurrentTag();});},closeAllTags(view) {this.$store.dispatch("delAllViews").then(({visitedViews }) => {this.toLastView(visitedViews, view);//关闭所有Bus.$emit('removeCache','closeAllTags')});},

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。