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鉤子函數(shù)實現(xiàn)數(shù)據(jù)更新邏輯
第一次進入keep-alive組件時,其生命周期執(zhí)行順序:
beforeRouteEnter --> created --> mounted --> activated --> deactivated
非首次進入時,其生命周期執(zhí)行順序:
beforeRouteEnter -->activated --> deactivated
我們需要知道列表A頁面對應的keep-alive組件在什么時候進行更新,因為進入A頁面的入口可以是從B頁面后退而來,也可能從其他頁面前進而來;當然需要對這兩種不同情況需要加以區(qū)分,否則A頁面的數(shù)據(jù)就一直是第一次緩存過的數(shù)據(jù)。
{
path: '/list',
name: 'list',
component: List,
meta: {
keepAlive: true, //此組件需要被緩存
isBack: false
}
}
然后,借助beforeRouteEnter鉤子函數(shù)來判斷頁面來源:
beforeRouteEnter(to, from, next) {
if(from.name === 'detail') { //判斷是從哪個路由過來的,若是detail頁面不需要刷新獲取新數(shù)據(jù),直接用之前緩存的數(shù)據(jù)即可
to.meta.isBack = true;
}
next();
},
最后,需要借助keep-alive提供鉤子函數(shù)activated來完成是否更新
activated() {
if(!this.$route.meta.isBack) {
// 如果isBack是false,表明需要獲取新數(shù)據(jù),否則就不再請求,直接使用緩存的數(shù)據(jù)
this.getData(); // ajax獲取數(shù)據(jù)方法
}
// 恢復成默認的false,避免isBack一直是true,導致下次無法獲取數(shù)據(jù)
this.$route.meta.isBack = false
},
在keep-alive組件前進的頁面刷新導致keep-alive組件狀態(tài)丟失
由于keep-alive第一次進入時會執(zhí)行created方法,所以利用這點加一個標識來加以判斷:
//第一次進入keep-alive路由組件時
created() {
this.isFirstEnter = true;
// 只有第一次進入或者刷新頁面后才會執(zhí)行此鉤子函數(shù),使用keep-alive后(2+次)進入不會再執(zhí)行此鉤子函數(shù)
},
activated() {
if(!this.$route.meta.isBack || this.isFirstEnter){
// 如果isBack是false,表明需要獲取新數(shù)據(jù),否則就不再請求,直接使用緩存的數(shù)據(jù)
// 如果isFirstEnter是true,表明是第一次進入此頁面或用戶刷新了頁面,需獲取新數(shù)據(jù)
this.data = ''// 把數(shù)據(jù)清空,可以稍微避免讓用戶看到之前緩存的數(shù)據(jù)
this.getData();
}
// 恢復成默認的false,避免isBack一直是true,導致下次無法獲取數(shù)據(jù)
this.$route.meta.isBack=false
// 恢復成默認的false,避免isBack一直是true,導致每次都獲取新數(shù)據(jù)
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、進入子路由后,若是在子路由強制刷新后,父子路由的組件都會重新渲染,執(zhí)行各自路由組件的生命周期;父路由中設置相關邏輯都會執(zhí)行。
2、子路由若被其他頁面共用,這時進入子路由時會觸發(fā)第一點的情況,所以最好子路由是父路由獨占的。
component組件配合路由方案
這種方案主要是利用vue提供的動態(tài)路由組件component來實現(xiàn),頁面組件的切換不再根據(jù)路由path來決定,而是根據(jù)不同的業(yè)務邏輯加載不同的動態(tài)組件。