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放到下一篇来说吧。