vue 實現前進不刷新后退刷新


引言:

最近的vue單頁面項目要實現一個利用頁面緩存的優化, 即前進刷新頁面,后退不刷新頁面的功能, 並且並列的頁面也要實現緩存的效果.

舉例: A頁面, B頁面, C頁面

keep-alive:

想要是頁面緩存就要用到keep-alive這個標簽, 

把keep-aline包裹router-view就能事項頁面緩存:

<keep-alive>
        <router-view class="Router" ></router-view>        
</keep-alive>

  但是,並不是所有的頁面都要緩存, 有些需要,有些又不需要緩存, 這時候就要用到找個東西來區分他,

meta:路由原信息,

我們利用這個來區分哪些是要緩存,哪些是不要緩存的

在router.js里面給每個路由都添加

        {
            path: '/home',
            name: 'home',
            component: () =>
                import ('@/views/Home.vue'),
            meta: {
                keepAlive: true, //此組件需要被緩存
            },
        },

        {
            path: '/home',
            name: 'home',
            component: () =>
                import ('@/views/Home.vue'),
            meta: {
                keepAlive: false, //此組件不需要被緩存
            },
        },

在app.vue里面通用meta來區分

  <keep-alive>
        <router-view class="Router" v-if="$route.meta.keepAlive"></router-view>        
  </keep-alive>
  <router-view class="Router" v-if="!$route.meta.keepAlive"></router-view>  

  

實現動態緩存:

做了上面的處理后, 就已經可以實現緩存了, 但是如果一個頁面有多個入口進入, 第一個入口進入了,第二個再進入,那么就會造成數據不會刷新的后果, 

這時候我們可以給每個路由在添加一個用於刷新: isBack

 

        {
            path: '/home',
            name: 'home',
            component: () =>
                import ('@/views/Home.vue'),
            meta: {
                keepAlive: true, //此組件需要被緩存
                isBack: false
            },
        },

  

  

使用:beforeRouteEnter, beforeRouteLeave, activated, 

他們執行的順序是 :beforeRouteEnter ---- > beforeRouteLeave --------> activated, 

beforeRouteEnter 和 beforeRouteLeave都是組件內部的導航鈎子, 每次離開和進入都會觸發,

activated:是只有在keep-alive有的情況下才出現的鈎子, 每次進入組件都會觸發, (create只有在第一次進入組件才會觸發)

比如從B頁面進入A頁面:

判斷是不是B頁面來的, 如果是B頁面來的就設置isBack=true, activated中就不會執行初始化的代碼,  如果不是B頁面來就是false(說明是A頁面來的),就執行初始化的代碼

這樣就實現了動態緩存了:

 beforeRouteEnter(to, from, next) {
            if (from.name == 'B頁面') {
                to.meta.isBack = true;
            }
            next();
        },

        activated() {
            if (!this.$route.meta.isBack) {
                this.inits();
            }
            this.$route.meta.isBack = false
            this.isFirstEnter = false;
        },

  刷新后的出現的問題:

如果我現在從B到了C頁面, 這時候我刷新了頁面, 那么頁面上的所有數據都會初始化, 然后我在回到B頁面,這時,from.name == 'C頁面', to.meta.isBack= true,

這時候就不會重新加載數據了,但是問我原來的數據也初始化了,這就會出現問題.

解決辦法:添加另外一個參數 isFirstEnter = true

        created() {
            this.isFirstEnter = true;
        },
        beforeRouteEnter(to, from, next) {
            if (from.name == 'C頁面') {
                to.meta.isBack = true;
            }
            next();
        },

        activated() {
            if (!this.$route.meta.isBack || this.isFirstEnter) {
                this.inits();
            }
            this.$route.meta.isBack = false
            this.isFirstEnter = false;
        },

  內存過多導致頁面遲緩:

當點擊的頁面越多的時候,緩存就會越多,緩存 太多之越來越多之后頁面就會越來越卡,

  解決辦法 - - 每次返回之后都銷毀掉組件: 

使用: beforeRouteLeave 判斷將要去的是哪個頁面, 如果不是去的下個頁面(那肯定是上個頁面), 那么就直接銷毀掉本頁面

 

beforeRouteEnter(to, from, next) {
            if (from.name == 'detail') {
                to.meta.isBack = true;
            }
            next();
        },
        beforeRouteLeave(to, from, next) {
            if (to.name != '下個頁面') {
                this.$destroy()
            }
            next();
        },
        activated() {
            if (!this.$route.meta.isBack || this.isFirstEnter) {
                this.inits();
            }
            this.$route.meta.isBack = false
            this.isFirstEnter = false;
        },

 

記錄滾動的位置:

beforeRouteLeave(to, from, next) {          
            this.scrollTop = document.querySelector("#scrollRef").scrollTop //記錄位置
            if (to.name != 'detail') {
                this.$destroy()
            }
            next();
        },
        activated() {
            if (!this.$route.meta.isBack || this.isFirstEnter) {
                this.inits();
            }
            if (this.scrollTop) {
                document.querySelector("#scrollRef").scrollTop = this.scrollTop //設置位置
            }
            this.$route.meta.isBack = false
            this.isFirstEnter = false;
        },

  

 這樣就實現前進不刷新后退刷新的功能, 但是我這樣做需要每個頁面都去寫一遍這些步驟,這樣感覺不是特別好, 希望能有大神能有更好的辦法,

參考文章:https://www.cnblogs.com/wonyun/p/8763314.html

補充:

這種方法,是為了實現同級路由切換也做到緩存效果例如大多數的App, 如果我們同級不不需要做到緩存,那么可以使用一個更加簡單的東西:

使用vue-navigation這個插件:
 

 

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM