vue动态缓存:动态应用keep-alive


在实现动态缓存之前,先了解以下技术点:

1.假设A组件用了缓存,则A组件首次加载的钩子执行顺序:created—> activated —> mounted,而再次返回A组件时只会执行activated,如果你想每次进入A组件都做一些事情的话,你可以放在activated里面

2.使用include和exclude的时候,必须给所有路由管理起来的vue组件都设置name属性,后果不赘述。

3.当同时使用include和exclude的时候,exclude的优先级会更高,例
include里面有nameA,exclude里面也有nameA,则此时nameA代表的组件就不会被缓存(实现原理就在这了!!!!!)

对keep-alive不熟的童鞋戳 这里

应用场景:

逻辑思路:

要实现A(pre页)跳转B不缓存,即在跳转B页面之前exclude中要含有B,
反观C(next页)跳转B,B若想有缓存,则在B跳转C(next页)之前保证exclude里面没有B

对!!!思路就是这样,精简一点来说,每当B跳转页面之前,B—>A(B跳转pre页),exclude里面添加B的name属性,B—>C(B跳转next页)则把B的name属性在exclude中删除即可(这块逻辑对于脑瓜子好使的小伙伴一看就懂,而卤煮属于比较笨的一类,想的略久)

代码实现:
好了,就差怎么实现了,接下来直接上代码!!!

假设我就只有A、B、C三个页面,且B会用到缓存,我们只需要把B的name属性放到include,且同时控制explude中添加和删除B的name就可以实现动态缓存B组件,也就是上面的技术点3提到的优先级问题

此时B用到缓存,所以B的name属性一直在includeList放着,我们只是利用include和exclude的优先级来控制B是否缓存
我的页面入口代码如下:

<template>
	<div id="app">
		<keep-alive :include="includeList" :exclude="excludeList">
			<router-view />
		</keep-alive>
	</div>
<template>

<script>
	import { mapState } from 'vuex';
	export default {
		data() {
		    includeList: [ "nameB" ],
		},
		computed: {
			...mapState({
				excludeList: state => state.store.excludeList
			}),
		}
	}
</script>

上面思路说了,每当缓存页面B跳转之前进行逻辑操作,那么全局的导航守卫beforeEach登场!!!

import Vue from ‘'vue';
import Router from ‘'vue-router';
impport store from '../storeIndex'; // 根据自己的路径来

Vue.use(Router);

let router = new Router({
	routes: [
		{
			path: '/a',
			name: 'nameA',
			component: 组件A,
			meta: { keepAlive: false },
		},
		{
			path: '/b',
			name: 'nameB',
			component: 组件B
			meta: { keepAlive: true }, // 区分走缓存的组件
		},
		{
			path: '/c',
			name: 'nameC',
			component: 组件C
			meta: { keepAlive: false },
		},
	],
});

router.beforeEach((to, from, next) => {
	// 加keepAlive就是为了区分,不走缓存的页无需进入此逻辑,这部分单拉出去封装,这里卤煮为了方便大家理解
	if (from.meta && from.meta.keepAlive) {
		//  nameB-nameA表示B页面跳转A页面,因为我们上面思路中提到,只需要在缓存组件跳转其他页面时操作exclude里面的值即可
		const pointToRelation = [ 'nameB-nameA' ]; // 路由指向关系
		let excludeArr = store.state.store.excludeList.slice(); // 复制一份excludeList的数据
		const pointStr = `${from.name}-${to.name}`;
		if (pointToRelation .indexOf(pointStr ) > -1) { // 说明是缓存组件B跳转pre页,此时应该将nameB放到excludeList里面
			excludeArr.indexOf(from.name) === -1 && excludeArr.push(from.name); // 这里&&写法等同于if else 写法,可自行百度
		} else { // 说明是缓存组件B跳转next页,此时应该将nameB从excludeList里面删除
			excludeArr.indexOf(from.name) > -1 && excludeArr.splice(excludeArr.indexOf(from.name), 1);
		}
		store.commit('store/setExcludeList', excludeArr); // 最后利用vuex设置excludeList的值即可
	}
});

以上就是本次的分享了,之所以封装这种方法,是因为在网上看到很多动态缓存组件的方法,思路如下(供参考):
meta标签里添加isBack参数,然后在单组件中beforeRouterEnter(to, from, next)中根据to, from的name值来判断是不是next页返回,
若是返回则isBack置为true,然后在的activated中根据isBack来做一些逻辑处理(因为组件走了缓存,逻辑放到activated中处理最为稳妥,比如请求数据),
这样会导致另一个问题,那就是当你跳转下一页,在下一页滚动后再返回,缓存页的滚动高度会受影响,不知道你们有没有这样的问题,这个bug放到下一篇来说吧。

Logo

前往低代码交流专区

更多推荐