背景描述:
最近在做移動端前端專案中,需要實現以下場景:
1.在頁面查詢列表,進入詳情頁時,返回需要頁面返回到上次瀏覽的位置
2.由於查詢列表獲取的資料可能會短時間改變,如果前端長時間快取資料,並不符合業務要求。
3.我在進入詳情頁時可以修改列表的資料,返回時滾動到,使用者看到的應該是最新的資料
4.每個列表頁面需要用到滑動載入更多資料。
專案中vue的使用:
1.用到keep-alive來快取頁面
2.當詳情頁中改變列表資料時,配合keep-alive,需要在vue鉤子函式activated中,對資料進行更改
3.在從其他頁面進入時,頁面要重新載入資料。頁面從列表進入其他頁面(非詳情頁)時,銷燬當前的vue例項。此時需用到元件內的路由守衛,beforeRouteEnter和beforeRouteLeave
4.列表頁滑動載入
具體實現:
針對以上前三點,頁面的快取,我們需要用到vue的內建元件keep-alive,來快取列表頁面,同時配合路由選項來更改頁面的資料。
在設定keep-alive快取的元件中,首次進入元件,會一次呼叫元件的鉤子函式:created --> mounted -->activated 再次進入時,只觸發activated鉤子函式
1.在路由出口渲染元件時配置:
<keep-alive>
<router-view v-if="$route.meta.keepAlive" class="router-view">
</router-view>
</keep-alive>
<router-view v-if="!$route.meta.keepAlive" class="router-view" ></router-view>
複製程式碼
2.在路由選項中,配置meta屬性,keepAlive為true即為需要快取的元件,同時設定isBack屬性,用來標示頁面是否是從詳情頁面返回的。
{
name: '首頁',
path: 'index',
component: Index,
meta: {
keepAlive: true,
isBack: false
}
},
複製程式碼
3.在元件例項中,通過beforeRouteEnter(to, from, next)路由守衛,來判斷路由是從哪裡跳轉的,如果是從詳情頁跳轉的,則將當前路由物件的meta.isBack 設定為true,否則設為false
beforeRouteEnter(to, from, next) {
if (from.path == "/detail") {
to.meta.isBack = true;
} else {
to.meta.isBack = false;
}
next();
},
複製程式碼
為了在其他頁面進入時,更新頁面中的列表資料,我們將在activated鉤子函式中掛載頁面初次進入時的請求資料:
activated() {
if (!this.$route.meta.isBack) {
this.list = [];
this.pageNum = 1;
this.getList();
}
this.$route.meta.isBack = false;
},
複製程式碼
4.在進入詳情頁,需要對該條資料進行修改時,修改成功後返回,應該更新列表。
由於我們要在返回時滾動到瀏覽位置,因此不能去後臺重新請求資料(否則無法回到之前瀏覽的位置),而是採用前端儲存修改的資料,並在返回的activated鉤子中對當前列表資料修改。
需要注意的事項:
由於vue自身限制,不能檢測到陣列直接修改長度和利用索引設值 因此,需要使用vm.$set(vm.array,index,newValue)或者vm.array.splice(index,1,newValue)
然後根據頁面離開時儲存的滾動位置,將頁面滾動到瀏覽位置。在router-view入口處,watch,$route物件,將keep-alive為true的頁面,滾動到上次瀏覽位置。
5.在頁面列表中,我們需要用到分頁載入資料,即滑動載入
在keep-alive元件中,頁面離開時,並不會銷燬當前的vue例項,而是儲存在記憶體中。因此就會造成問題:頁面跳轉時,觸發了滑動事件,載入所有儲存在記憶體中的滑動事件,改變了vue例項的資料。
因此,我們需要在元件的路由守衛中,在頁面離開時beforeRouteLeave中把滑動事件禁用,然後再在頁面進入的時候,在activated鉤子中恢復滑動事件的。
注意: 使用keep-alive不能銷燬例項,vm.$destroy(); 否則再進入頁面,即使keep-alive為true也不會儲存元件。如果keep-alive的頁面較多,可以使用,在路由守衛中修改vuex的變數動態改變keep-alive的頁面變數。
簡單寫了個demo,用的移動端ui框架是vux,其中用到的view-box元件,有自己的scroll方法(documment.documentElement.scroll為0)