需求:
页面顺序,从A到B到C,对于B 页面,进入C页面时,需要缓存,进入A页面时,不需要缓存,A进入B的时候是要刷新的。所以,问题就是,如何让keep-alive 缓存动态进行?
思路就是:
动态改变keep-alive的include数组。
- 首先创建A,B,C页面
-----a.vue
<template>
<div>
<div @click="handleGo">a页面</div>
<input />
</div>
</template>
<script>
export default {
name: "aaa", //跟router.js的name一致,因为keep-alive根据这个来知道这是哪个页面
methods: {
handleGo() {
this.$router.push({ path: "/b" });
},
},
};
</script>
-----b.vue
<template>
<div>
<div @click="handleGo">b页面</div>
<input />
</div>
</template>
<script>
export default {
name: "bbb",//跟router.js的name一致,因为keep-alive根据这个来知道这是哪个页面
methods: {
handleGo() {
this.$router.push({ path: "/c" });
},
},
};
</script>
-----c.vue
<template>
<div>
<div @click="handleGo">c页面,返回</div>
<input />
</div>
</template>
<script>
export default {
name: "ccc",//跟router.js的name一致,因为keep-alive根据这个来知道这是哪个页面
methods: {
handleGo() {
this.$router.go(-1);
},
},
};
</script>
- router.js文件(路由)配置当前页面的路由
import Vue from 'vue'
import VueRouter from 'vue-router'
import A from '../views/a.vue';
import B from '../views/b.vue';
import C from '../views/c.vue';
import store from '../store';
Vue.use(VueRouter)
const routes = [
{
path: '/',
name: 'aaa',//跟a.vue页面的name一致,因为keep-alive根据这个来知道这是哪个页面
component: A,
meta: {
noCache: false //true为不缓存,false为缓存
}
},
{
path: '/b',
name: 'bbb',//跟b.vue页面的name一致,因为keep-alive根据这个来知道这是哪个页面
component: B,
meta: {
noCache: false //true为不缓存,false为缓存
}
},
{
path: '/c',
name: 'ccc',//跟c.vue页面的name一致,因为keep-alive根据这个来知道这是哪个页面
component: C,
meta: {
noCache: false //true为不缓存,false为缓存
}
},
]
const router = new VueRouter({
mode: 'history',
routes
})
export default router
- 配置store(vuex)
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
state: {
keepAliveComponents: []//需要缓存页面的name
},
mutations: {
// push到keepAliveComponents数组,并去重
keepAlive(state, component) {
// 注:防止重复添加(当然也可以使用Set)
!state.keepAliveComponents.includes(component) && state.keepAliveComponents.push(component);
},
// 跳转的不是想要的,去除当前路由缓存
noKeepAlive(state, component) {
const index = state.keepAliveComponents.indexOf(component);
index !== -1 && state.keepAliveComponents.splice(index, 1);
}
},
actions: {},
modules: {}
})
- App.vue(包裹所以页面的,也可以是其他的.vue文件)
<template>
<div>
<keep-alive :include="keepAliveComponents">
<router-view></router-view>
</keep-alive>
</div>
</template>
<script>
export default {
computed: {
//此处获取vuex的keepAliveComponents数组
keepAliveComponents() {
return this.$store.state.keepAliveComponents;
},
},
};
</script>
- 现在就在路由上监听是否缓存了,用路由守卫
-----router.js(路由文件)
import Vue from 'vue'
import VueRouter from 'vue-router'
import A from '../views/a.vue';
import B from '../views/b.vue';
import C from '../views/c.vue';
import store from '../store';//需要引入store
Vue.use(VueRouter)
const routes = [
.... 这里的代码跟上面的router.js一样
]
const router = new VueRouter({
..... 这里的代码跟上面的router.js一样
})
//路由守卫监控
router.beforeEach((to, from, next) => {
// 在路由全局钩子beforeEach中,根据keepAlive属性,统一设置页面的缓存性
// 作用是每次进入该组件,就将它缓存
if (!to.meta.noCache) {
store.commit('keepAlive', to.name);//调用vuex的keepAlive方法,并把路由的name传过去了
}
next();
});
export default router
- 现在B跳转到C可以缓存,B跳A就不缓存,用路由独享守卫
-----b.vue
<template>
<div>
.....
</div>
</template>
<script>
export default {
name: "bbb",
methods: {
handleGo() {
.....
},
},
//路由独享守卫,监控跳转谁
beforeRouteLeave(to, from, next) {
// 如果下一个页面不是C页,则取消B的缓存
if (to.name !== "ccc") {
this.$store.commit("noKeepAlive", from.name);
}
next(); // next 方法不能忘记,不然程序不会往下走
},
};
</script>
你们代码复制一下,运行一下就可以实现了。
重要的事情说三遍:**注意看注释!注意看注释!注意看注释!**不然你不知道怎么写的。
有用记得三连!拒绝白嫖!