keep-alive方案
1、模板中使用keep-alive来缓存对应的路由组件
<keep-alive>
<router-view v-if="$route.meta.keepAlive">
<!-- 这里是会被缓存的视图组件,比如列表A页面 -->
</router-view>
</keep-alive>
<router-view v-if="!$route.meta.keepAlive">
<!-- 这里是不被缓存的视图组件,比如详情B页面-->
</router-view>
<keep-alive include="A">
<router-view>
<!-- 只有路径匹配到的视图组件,如上面的列表A页面会被缓存! -->
</router-view>
</keep-alive>
2、在路由配置文件中配置路由元信息
routes: [{
path: '/',
name: 'home',
component: Home,
meta: {
keepAlive: false //此组件不需要被缓存
}
},
{
path: '/list',
name: 'list',
component: List,
meta: {
keepAlive: true //此组件需要被缓存
}
},
{
path: '/detail',
name: 'detail',
component: Detail,
meta: {
keepAlive: false // 此组件需要被缓存
}
}
]
3、在keep-alive组件提供activated钩子函数实现数据更新逻辑
第一次进入keep-alive组件时,其生命周期执行顺序:
beforeRouteEnter --> created --> mounted --> activated --> deactivated
非首次进入时,其生命周期执行顺序:
beforeRouteEnter -->activated --> deactivated
我们需要知道列表A页面对应的keep-alive组件在什么时候进行更新,因为进入A页面的入口可以是从B页面后退而来,也可能从其他页面前进而来;当然需要对这两种不同情况需要加以区分,否则A页面的数据就一直是第一次缓存过的数据。
{
path: '/list',
name: 'list',
component: List,
meta: {
keepAlive: true, //此组件需要被缓存
isBack: false
}
}
然后,借助beforeRouteEnter钩子函数来判断页面来源:
beforeRouteEnter(to, from, next) {
if(from.name === 'detail') { //判断是从哪个路由过来的,若是detail页面不需要刷新获取新数据,直接用之前缓存的数据即可
to.meta.isBack = true;
}
next();
},
最后,需要借助keep-alive提供钩子函数activated来完成是否更新
activated() {
if(!this.$route.meta.isBack) {
// 如果isBack是false,表明需要获取新数据,否则就不再请求,直接使用缓存的数据
this.getData(); // ajax获取数据方法
}
// 恢复成默认的false,避免isBack一直是true,导致下次无法获取数据
this.$route.meta.isBack = false
},
在keep-alive组件前进的页面刷新导致keep-alive组件状态丢失
由于keep-alive第一次进入时会执行created方法,所以利用这点加一个标识来加以判断:
//第一次进入keep-alive路由组件时
created() {
this.isFirstEnter = true;
// 只有第一次进入或者刷新页面后才会执行此钩子函数,使用keep-alive后(2+次)进入不会再执行此钩子函数
},
activated() {
if(!this.$route.meta.isBack || this.isFirstEnter){
// 如果isBack是false,表明需要获取新数据,否则就不再请求,直接使用缓存的数据
// 如果isFirstEnter是true,表明是第一次进入此页面或用户刷新了页面,需获取新数据
this.data = ''// 把数据清空,可以稍微避免让用户看到之前缓存的数据
this.getData();
}
// 恢复成默认的false,避免isBack一直是true,导致下次无法获取数据
this.$route.meta.isBack=false
// 恢复成默认的false,避免isBack一直是true,导致每次都获取新数据
this.isFirstEnter=false;
},
嵌套路由
1、配置路由信息
{
path: '/order',
component: Order,
children: [
{
path: 'invoice',
component: Invoice
}, {
path: 'contact',
component: Contact
},
{
path: 'costrule',
component: CostRule
}, {
path: 'refundrule',
component: RefundRule
},{
path: 'useragreement',
component: UserAgreement
},{
path: 'payrule',
component: PayRule
}
]
}
2、在下单页Order组件模板中配置路由嵌套。
<div class="safe-area-pb">
<purchase />
<router-view />
</div>
1、进入子路由后,若是在子路由强制刷新后,父子路由的组件都会重新渲染,执行各自路由组件的生命周期;父路由中设置相关逻辑都会执行。
2、子路由若被其他页面共用,这时进入子路由时会触发第一点的情况,所以最好子路由是父路由独占的。
component组件配合路由方案
这种方案主要是利用vue提供的动态路由组件component来实现,页面组件的切换不再根据路由path来决定,而是根据不同的业务逻辑加载不同的动态组件。