清除keep-alive缓存,动态缓存

这个题目有点误导人,但是方向大致是这么个方向,其实不叫清除,而叫动态添加缓存。那么现在说下项目背景,用了vue2.0的后台系统,elementui再加之前没有删干净的乱七八糟的elment-admin的东西。需求嘛就是router外面套了keep-alive,就是从左边的侧边栏点击添加到窗口的很多tab页,切换时候要有缓存,关闭时候应该清掉缓存,现在就是关闭时候也有缓存导致再次打开时候上次的信息还在。看了网上很多强制清缓存的东西,大致意思就是从搞不清楚什么层级的对象里面找cache这个对象再清除掉,然后还有个什么key,我找了一天没找明白,我就换了个思路,特此记录下,给后面也有相同需求的人。

一,找到你写keep-alive的文件。改造成大致这样:

<template>
	<section class="app-main">
		<transition name="fade-transform" mode="out-in" v-if="$route.meta.keepAlive">
			<keep-alive>
				<router-view :key="key" />
			</keep-alive>
		</transition>
		<transition name="fade-transform" mode="out-in" v-else>
			<router-view :key="key" />
		</transition>
	</section>
</template>

意思嘛就是说你的路由中的meta的keepAlive是true的用缓存,是false的不用。

二,然后你就需要到你的router的文件里面去吧这个叫keepaAlive的全部false。我们是动态添加嘛,这里相当于一个init

就像这样:

{
	path:'/franchisee',
	component: Layout,
	redirect: 'noredirect',
	children:[{
		path: 'franchisee-view',
		name: 'franchisee-view',
		component: () =>import('@/views/franchisee/franchisee-view'),
		meta: {
			title: '加盟商管理',
			icon: 'dashboard',
			keepAlive: false
		},
	},{
		path: 'franchisee-detail',
		name: 'franchisee-detail',
		component: () =>import('@/views/franchisee/franchisee-detail'),
		meta: {
			title: '加盟商详情',
			icon: 'dashboard',
			keepAlive: false
		},
	},{
		path: 'franchisee-add',
		name: 'franchisee-add',
		component: () =>import('@/views/franchisee/franchisee-add'),
		meta: {
			title: '新增加盟商',
			icon: 'dashboard',
			keepAlive: false
		},
	},{

全部写false

三,然后去你TagView.vue文件(没有的话意思就是说你点击你页面的那个tag标签的那个页面上的方法的文件)找到以下两个方法,一个是添加,一个是关闭,没有的话自己写一个。

	addViewTags() {
			const {
				name
			} = this.$route;
			if (name) {
				this.$store.dispatch("addView", this.$route);
				this.$store.dispatch("addCachedView", this.$route);

			}
			this.$route.meta.keepAlive = true
			return false;
		},

起作用的主要就是这个this.$route.meta.keepAlive=true这个方法,意思就是你点开一个页面tag就动态置为true,只要你不关闭,切换时候它还是true。这样缓存就实现啦。

四,关的时候清除

还是在刚刚的文件上,关闭的时候把刚刚那个属性设置为false就行啦

		closeSelectedTag(view) {
			if (this.isActive(view)) { view.meta.keepAlive = false }

			this.$store.dispatch("delCachedViewThis", this)
			console.log(this)
			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("/");
					}
				}
			});
		},

下面的那些你们都可以不用看 主要是if (this.isActive(view)) { view.meta.keepAlive = false }这句话。哦。调用了方法是吧?我一起贴上来。

	isActive(route) {
			return route.path === this.$route.path;
		},

再附上结构的代码

	<div class="tags-view-container">
		<scroll-pane ref="scrollPane" class="tags-view-wrapper">
			<div class="a-flex-rfsfe">
				<router-link v-for="tag in visitedViews" ref="tag" :class="isActive(tag) ? 'active' : ''"
					:to="{ path: tag.path, query: tag.query, fullPath: tag.fullPath }" :key="tag.path"
					class="tags-view-item " style="margin-left: 4px;" @click.middle.native="closeSelectedTag(tag)"
					@contextmenu.prevent.native="openMenu(tag, $event)">
					<span>{{ tag.title }}</span>
					<!-- <span v-show="visitedViews.length > 1" -->
					<span class="el-icon-close a-ml-08" style="width: 9px; height: 9px; padding-bottom: 3px"
						@click.prevent.stop="closeSelectedTag(tag)" />
				</router-link>
			</div>
		</scroll-pane>

其实这里看具体的代码没有意义。毕竟大家的项目都不同,不可能照抄。掌握到思想的精髓就行了。意思就是初始时候全部置为false没有缓存,然后添加tag的时候动态改为true,关闭时候再改为false。这样就比你强制去清除那个什么cache简单多啦。
就这,希望能帮到大家。

后续。后来,发现这个方法也是不可行的,这样的话,需要缓存和不需要缓存的就无法区分开来了。记录下此问题的解决办法。就是搞个白名单,需要缓存的放入到白名单里面,然后在需要缓存的路由的meta里添加一个新属性,如果是关闭的话就把这个属性添加上,就不需要缓存了,如果没有这个属性又在白名单中的话就需要缓存。新开一个窗口先判断有没有,有并在白名单中,就添加上缓存属性,切换的之前删掉,切换的时候就是又没有了。白名单加动态删除添加属性来双重控制。上代码。
layout/components/TagsView.vue

export default {
	components: {
		ScrollPane,
	},
	data() {
		return {
			visible: false,
			top: 0,
			left: 0,
			selectedTag: {},
			whiteList: ['project-add', 'station-add', 'customer-add', 'franchisee-add', 'station-apply', 'station-construction', 'price-edit', 'project-confirmed', 'device-add', 'device-edit', 'device-type-edit', 'bank-card-add', 'staff-add', 'staff-exit', 'franchisee-change']
		};
	},
	computed: {
		visitedViews() {
			return this.$store.state.tagsView.visitedViews;
		},
	},
	watch: {
		$route() {
			this.addViewTags();
			this.moveToCurrentTag();
		},
		visible(value) {
			if (value) {
				document.body.addEventListener("click", this.closeMenu);
			} else {
				document.body.removeEventListener("click", this.closeMenu);
			}
		},
	},
	mounted() {
		this.addViewTags();
	},
	methods: {
		// generateTitle, // generateTitle by vue-i18n
		isActive(route) {

			return route.path === this.$route.path;
		},
		addViewTags() {
			const {
				name
			} = this.$route;
			this.$route.meta.keepAlive = false;
			let isKeep = this.whiteList.filter((item, index) => { return item == name });
			if (isKeep.length == 1 && !this.$route.meta.hasOwnProperty('hash')) {
				this.$route.meta.keepAlive = true;
			}
			if (name) {
				this.$store.dispatch("addView", this.$route);
				this.$store.dispatch("addCachedView", this.$route);

			}
			if (this.$route.meta.hasOwnProperty('hash')) {
				delete this.$route.meta.hash;
			}
			return false;
		},
		moveToCurrentTag() {
			const tags = this.$refs.tag;


			this.$nextTick(() => {
				for (const tag of tags) {
					if (tag.to.path === this.$route.path) {
						this.$refs.scrollPane.moveToTarget(tag);
						//	this.$route.meta.keepAlive = true

						// when query is different then update

						if (tag.to.fullPath !== this.$route.fullPath) {
							this.$store.dispatch("updateVisitedView", this.$route);
						}
						break;
					}
				}
			});
		},
		refreshSelectedTag(view) {
			console.log("view123", view);

			this.$store.dispatch("delCachedViewThis", this).then(() => {
				const {
					fullPath
				} = view;
				console.log("fullPath", fullPath);
				this.$nextTick(() => {
					this.$router.replace({
						path: fullPath,
					});

				});
			});
		},
		closeSelectedTag(view) {
			if (this.isActive(view)) {
				view.meta.keepAlive = false;
				view.meta.hash = "del";
			}

			this.$store.dispatch("delCachedViewThis", this)
			console.log(this)
			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("/");
					}
				}
			});
		},
		closeOthersTags() {
			this.$router.push(this.selectedTag);
			this.$store.dispatch("delOthersViews", this.selectedTag).then(() => {
				this.moveToCurrentTag();
			});
		},

		closeAllTags() {
			this.$store.dispatch("delAllViews");
			this.$router.push("/");
		},

		openMenu(tag, e) {
			const menuMinWidth = 105;
			const offsetLeft = this.$el.getBoundingClientRect().left; // container margin left
			const offsetWidth = this.$el.offsetWidth; // container width
			const maxLeft = offsetWidth - menuMinWidth; // left boundary
			const left = e.clientX - offsetLeft + 15; // 15: margin right

			if (left > maxLeft) {
				this.left = maxLeft;
			} else {
				this.left = left;
			}
			this.top = e.clientY;

			this.visible = true;
			this.selectedTag = tag;
		},
		closeMenu() {
			this.visible = false;
		},
	},
};
  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值