当在这些组件之间切换的时候,你有时会想保持这些组件的状态,以避免反复重渲染导致的性能问题。
包裹动态组件时,会缓存不活动的组件实例,而不是销毁它们,同时
是一个抽象组件:它自身不会渲染一个 DOM 元素,也不会出现在父组件链中。
mounted(){
console.log('mounted')
},
activated(){
console.log('activated')
},
deactivated(){
//离开页面时执行
}
//第一次进入页面执行结果:mounted activated
//第一次进入页面执行结果:activated,第二次进入不会再走mounted钩子
父组件会缓存不活动组件实例,所以页面上的子组件也会是keep-alive会缓存,即在activated钩子里面需要对获取数据等逻辑进行处理
在路由引入时采用: keep-alive页面需要使用< keep-alive>包裹
//路由配置
{
path: 'A',
name: 'A',
component:'',
meta: {
keepAlive: true,
}
},
(1)假设这里有3个路由:A、B、C
// A组件设置
{
name: 'A',
component: A,
meta: {
keepAlive: true // 需要被缓存
}
}
//B组件设置
beforeRouteLeave(to, from, next) {
// 设置下一个路由的 meta
to.meta.keepAlive = true; // 让 A 缓存,即不刷新
next();
}
//C组件设置
beforeRouteLeave(to, from, next) {
// 设置下一个路由的 meta
to.meta.keepAlive = false; // 让 A 不缓存,即刷新
next();
}
(2)假设这里有2个路由:D、E、F 。D页面跳转到F页面后,由E页面返回需要保持页面数据;F页面和D页面相互跳转不需要保持任何数据,换句话说此时的D页面不再是一个keepAlive页面
//D页面路由配置
{
name: 'D',
component: D,
meta: {
keepAlive: true // 需要被缓存
}
}
D页面点击跳转到E页面时:
let initialData = {};
mounted: function () {
// 保存初始化data数据 ,
initialData = JSON.parse(JSON.stringify(this.$data));
},
activated: function () {
if (!this.$route.query.aliveBack) {
// 将初始化定义的data设置的默认值写入现在的$data里面
Object.assign(this.$data, JSON.parse(JSON.stringify(initialData)));
this.ready();// 在重新调用页面初始化
} else {
// E页面跳回D页面执行
// 取到跳转之前的
let aliveQuery = JSON.parse(JSON.stringify(this.$store.state.alivePops.query));
aliveQuery.aliveBack = '';// 来自E页面的特征值,从路由之中删除
// 将路由参数还原:D页面跳转到E页面之前状态
this.$router.replace({ name: this.$route.name, query: aliveQuery });
}
},
methods:{
//D页面跳转到E页面
routerLink:function(){
let aliveQuery = {
query: this.$route.query //取到当前D页面的路由保存到vuex里面
};
this.$store.commit('saveAlive', aliveQuery);
this.$router.push({
name: name,
query: {
// aliveFrom告诉E页面点击然后时,需要跳转回哪个路由。
// 可能存在除了D页面跳转到E页面,所以采用aliveFrom标志
aliveFrom: this.$route.name
}
});
}
}
E页面逻辑
mounted: function () {
// 从原页面跳转进入该页面后,点击返回原页面调用函数
aliveBack: function () {
// 点击返回到原页面,aliveFrom表示原页面的name,aliveBack表示跳转的目标页面的name,alivePops存跳转页面需要继承的数据
let query = {
aliveBack: 'E'
};
this.$router.push({ name: this.$route.query.aliveFrom, query: query });
},
},