vue-router數據加載與緩存使用總結

以前開發了一個單頁面應用,按照深度,分爲三層:目錄頁、一級子頁(標籤頁、故事頁等)、二級子頁(故事編輯頁)。javascript

這三類頁面都共享一個完整的數據model,從上級頁面進入下一級頁面時,可以加載相應數據;回到上一級時,數據有更新。舉個栗子,從故事頁點擊「編輯」按鈕,進入故事編輯頁則默認填充點擊的「編輯」按鈕所對應的故事數據;而當在故事編輯頁更新數據,返回到故事頁時,剛剛更新的信息也能在故事頁展現。html

圖片描述

對於這項需求,咱們須要解決以下幾個問題:vue

  • 三層頁面共享數據;
  • 進入或退回當前路由時,數據更新;
  • 對於故事列表頁,返回時保留以前瀏覽位置;

本文後面內容,將對如上問題一一提出解決方案。java

共享數據

多個路由共享數據,可使用vuex作數據中心,因爲需求對數據處理並不複雜,爲了簡便就使用window全局對象做爲路由間傳遞數據的工具。
核心數據咱們能夠設計爲以下結構,以故事爲例:vue-router

window.profileData = {
    storyList: [{
        content: 'xxx',
        type: 0,
        picList: [...],
    }, ...],
    description: {...},    // 其餘字段數據
}

注意到,若是須要更新storyList,則應該使用可以被檢測到的方法,如push, splice等。vuex

數據更新與緩存

數據更新與緩存大體有兩種方案:
第一種,利用vue-router的導航守衛(見文檔:https://router.vuejs.org/zh/g...),主要使用路由組件內導航 beforeRouteEnter 和 beforeRouteLeave;
第二種,在路由組件中監聽$route,每次路由變化就會調用其中方法加載數據,須要注意的是第一次進入路由組件$route的監聽不會觸發,咱們須要在mounted方法中調用相同加載數據的方法;緩存

咱們在代碼中使用的是方法一,以故事列表進入到故事編輯頁爲例,從列表傳遞index給編輯頁,利用beforeRouteEnter進入路由時就加載新的數據。
編輯頁中關鍵代碼,即加載數據、更新本地共享數據:ide

export default {
    // 編輯頁中, 進入路由前加載數據
    beforeRouteEnter(to, from, next) {
        next(vm => {
            const index = vm.$route.params.storyIndex
            vm.storyIndex = index
            vm.storyData = window.profile.storyList[index]
        })
    },

    methods: {
        // 提交成功後,更新本地共享數據
        submit() {
            Adapter.post('...').then(result => {
                window.profile.storyList.splice(this.storyIndex, 1, result)
            })    
        },
    },
}

列表頁中關鍵代碼,即返回時更新數據:工具

export default {
    beforeRouteEnter(to, from, next) {
        next(vm => {
            vm.storyList = window.profileData.storyList
        })
    },
}

這部分須要注意的有兩點:post

  • beforeRouteEnter中沒法調用組件實例,由於執行時還在組件生命週期的beforeCreate以前,而其中的next方法是在組件mounted以後執行,如需引用可在next方法中,引用其參數,該參數就是組件實例;
  • 若是發現你的next方法沒法執行,請升級到2.6+版本,以前的版本這部分有些問題;

保留瀏覽位置

從故事編輯頁回到故事列表頁,咱們但願能夠保存以前瀏覽的位置。思路也很簡單,進入編輯頁時保存scrollTop,返回時scrollTo便可。並且vue-router對象有屬性能夠實現這個功能,這就簡潔多了。
因爲咱們過渡動畫中間,有將路由組件定位成fixed的操做,因此,動畫結束後再手動滾動到目標位置:

new VueRouter({
    routes,
    scrollBehavior (to, from, savedPosition) {
        const y = savedPosition && savedPosition.y || 0
        setTimeout(() => { window.scrollTo(0, y) }, 300)
    }
})

總結

vue-router咱們在偏B端的場景中常常用到,尤爲是分步驟填寫表單的頁面。前期在使用過程當中老是不太順暢,摸索幾回後,最終找到比較「溫馨」的使用方法,索性就梳理成文。
固然,還有其餘一些特殊場景的用法,這裏暫時不說了,等項目中用事後再另起一文,繼續研究。

參考文獻

1.《官方文檔》
2.《滾動行爲》

相關文章
相關標籤/搜索