vue-router 中使用 keep-alive 控制 ajax 請求的緩存策略(二)

前文的解決方法 其實是有問題的。

1. 問題

前文提到 saved_position 的返回值有時是 undefined,有時是 null。經(jīng)過仔細調(diào)試,可以發(fā)現(xiàn) undefined 只會出現(xiàn)一次,以后都是出現(xiàn) null。出現(xiàn)的過程為:

  1. 用戶訪問具有 keep-alive 的 List 頁面
  2. 用戶點擊 router-link 切換到其他頁面
  3. 點擊瀏覽器后退按鈕,回到 List 頁面,此時的 saved_position 值即為 undefined
  4. 之后所有的后退前進都是 null,不再有 undefined。

但是步驟 3 當中,其實應該是有值的,但 vue 的實現(xiàn)中會生成很多的 _key,這個實現(xiàn)其實是有問題的,生成了很多多余的 _key,導致與用戶的瀏覽器歷史行為不一致,導致出現(xiàn) undefined。

2.終極解決文案

既然 vue-router 保存的滾動條值是錯誤的,那么我們自己保存好了,然后在適當?shù)臅r機進行“位置修復”。

# router.coffee
router = new VueRouter(
    mode: 'history'

    routes: [
        {
                path: '/list'
                name: 'list'
                meta:
                    title: '列表頁'
                    keep_alive: true
                    saved_position: {x: 0, y: 0}  # 這里新增設(shè)置默認值為頂頂
                component: require('../views/list.vue')
         },
        ...
    ]
    
    scrollBehavior: (to, from, saved_position) ->
        # 點擊了非瀏覽器按鈕,則設(shè)置為 null,方便組件中刷新 ajax 數(shù)據(jù)
        if saved_position == null
            if to.meta.keep_alive
                to.meta.saved_position = null
        # 點擊了瀏覽器前進/后退,則直接使用正確的位置,并且組件知道不是 null,
        # 不會刷新 ajax 數(shù)據(jù)
        else
            saved_position = to.meta.saved_position

        return saved_position ? {x: 0, y: 0}
) 

router.beforeEach (to, from, next) ->
    # 存儲滾動條位置
    if from.meta.keep_alive
        from.meta.saved_position =
            x: window.pageXOffset
            y: window.pageYOffset

    next()

我們在,router.beforeEach 中在頁面切換之前,保存當前滾動條的位置到相關(guān)的 meta.saved_position 中。
在 scrollBehavior 中還原,這樣位置就不會出現(xiàn) undefined 了。

接下來就是在組件中如何更新 ajax 數(shù)據(jù)了:

# list.coffee
export default Dashboard =
    name: 'Dashboard'

    data: ->
        posts: []

    beforeRouteEnter: (to, from, next) ->
        next (vm) ->
            # 如果為 null,則說明點擊了 router-link,此時可刷新 ajax 數(shù)據(jù)。
            # 否則,為點擊了瀏覽器后退/前進,什么也不做即可。
            # 交給 keep-alive 處理緩存,scrollBehavior 處理修復后的滾動條位置。
            if to.meta.saved_position == null
                vm.fetchPosts()

            # 或者你有其他控制邏輯,如:
            # 帖子列表為空時,也強制獲取 ajax 數(shù)據(jù):
            if (to.meta.saved_position == null) or (vm.posts.length == 0)
                vm.fetchPosts()

    methods:
        fetchPosts: (type) ->
            @$store
                .dispatch(types.dashboard.actions.GET_POSTS)
                .then (res) =>
                ...

以上。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容