keep-alive + router meta
在router 的meta添加 keepAlive 属性 使用keep-alive包过router-view组件,并使用meta中的keepAlive判断
// router 路由配置 keepAlive属性
{
path: "/",
component: Layout,
redirect: "/home",
children: [
{
path: "home",
name: "Home",
meta: {
keepAlive: true
},
component: () => import("@/views/Home.vue")
},
{
path: "about",
name: "About",
component: () => import("@/views/About.vue")
}
]
}
// keep-alive组件包裹router-view组件<keep-alive>
<router-view v-if="$route.meta.keepAlive" :key="key"></router-view> </keep-alive>
<router-view v-if="!$route.meta.keepAlive" :key="key"></router-view>
keep-alive + component name
使用keep-alive的prop属性 include 设置需要缓存的组件,exclude排除不需要缓存的组件名字,max属性课配置最多缓存数量,超过该数量时会把已缓存组件中最久没有被访问的实例会被销毁掉。 此种方式一定要注意设置正确组件的name
以上两种可以实现指定页面,但是有个问题,不管从缓存的页面跳转到其他任何页面,都缓存了该页面。不能控制缓存页面跳转到指定页面才进行缓存。比如需要缓存的页面A,从A页面可以跳转到B、C页面。现在想实现只有跳转到B页面时才缓存A页面,跳转到C页面不进行缓存。要实现这种动态缓存需要可以使用下面的方法,直接操纵keepalive组件实例的cache属性。
动态移除keepalive组件缓存: 参考 zhuanlan.zhihu.com/p/40374425 keep-alive 默认不支持动态销毁已缓存的组件,所以此处给出的解决方案是通过直接操控 keep-alvie 组件里的 cahce 列表
beforeRouteLeave:function(to, from, next){
if (from && from.meta.rank && to.meta.rank && from.meta.rank>to.meta.rank)
{//此处判断是如果返回上一层,你可以根据自己的业务更改此处的判断逻辑,酌情决定是否摧毁本层缓存。
if (this.$vnode && this.$vnode.data.keepAlive)
{
if (this.$vnode.parent && this.$vnode.parent.componentInstance && this.$vnode.parent.componentInstance.cache)
{
if (this.$vnode.componentOptions)
{
var key = this.$vnode.key == null
? this.$vnode.componentOptions.Ctor.cid + (this.$vnode.componentOptions.tag ? `::${this.$vnode.componentOptions.tag}` : '')
: this.$vnode.key;
var cache = this.$vnode.parent.componentInstance.cache;
var keys = this.$vnode.parent.componentInstance.keys;
if (cache[key])
{
if (keys.length) {
var index = keys.indexOf(key);
if (index > -1) {
keys.splice(index, 1);
}
}
delete cache[key];
}
}
}
}
this.$destroy();
}
next();
},
vuex 或 localStorage 储存状态数据
在beforeRouterLeave里在路由跳转前保存页面状态数据 在路由跳转回来时在mounted里面设置页面状态数据 注意使用beforeRouterLeave时,只能在配置路由的组件里面生效,在配置路由组件的子组件内拦截不成功,需要在父组件中使用$refs 访问子组件的data和method 路由参数存储数据
- 使用watch监听页面状态数据变化,
$route.qeury设置路由参数,query对象一定要拷贝,然后调用用$router.push方法,浏览器地址栏参数才会变化- 在页面返回时,在
mounted或created中读取保存路由参数并进行赋值
detailLessonRadioBtn: {
handler(val) {
let query = Object.create(this.$route.query);
query.tab = this.formModel.tabModel;
query.subtab = this.detailLessonRadioBtn;
this.$router.push({ path: this.$route.path, query });
}
}
},
created() {
if (this.$route.query.tab) {
this.formModel.tabModel = this.$route.query.tab;
if (this.$route.query.subtab) {
this.detailLessonRadioBtn = this.$route.query.subtab;
}
}
}
localStorage vs sessionStorage
localStorage:
- 存储的数据在浏览器的不同tab页和窗口页是共享的,只要有相同的origin
- 没有过期时间,即使浏览器关闭电脑关机,数据依然不会被清除 sessionStorage:
- 保存的数据只对当前tab页有效,其他tab页访问不到,即使origin相同。不同的tab页拥有不同的sessionStorage
- 页面被关闭时,数据会被清除。页面刷新时数据不会清除
- 数据可在同一tab页下的不同iframe共享 总结:sessionStorage和localStorage的属性和方法是同样的,sessionStorage在功能上相比localStorage受到了更多的限制