關於vue里頁面的緩存


keep-alive是vue內置的一個組件,可以使被它包含的組件處於保留狀態,或避免被重新渲染。

用法:

運行結果描述:

input輸入框內,路由切換輸入框內部的內容不會發生改變。
在keep-alive標簽內部添加

include:字符串或正則表達式。只有匹配的組件會被緩存

exclude: 字符串或正則表達式。任何匹配的組件都不會被緩存。


結合router緩存部分頁面:

比較實用的例子:

思路:通過beforeRouterLeave這個鈎子來對路由里面的keepAlive進行賦值。從而動態的確定A頁面是否需要被緩存。

以上轉載自:https://blog.csdn.net/qq_38614249/article/details/79468609
【Vue】Vue2.0頁面緩存和不緩存的方法,以及watch監聽會遇到的問題vue2.0頁面
緩存和不緩存的方法:
1、在app中設置需要緩存的div

<keep-alive>//緩存的頁面
   <router-view v-if="$route.meta.keepAlive"></router-view>
</keep-alive>
<router-view v-if="!$route.meta.keepAlive"></router-view>//不緩存的頁面
2、在路由router.js中設置.vue頁面是否需要緩存
{
   path: '/home',
   component: home,
   meta: { keepAlive: true },//當前的.vue文件需要緩存
},
{
   path: '/notice',
   component: notice,//當前頁面不需要緩存
}
3、從緩存頁面跳轉到不緩存頁面,或者從不緩存頁面跳轉到緩存頁面的時候,會發現watch是不能監聽路由的,是因為緩存和不緩存頁面分別在不同的div里面,一個div里面是不可能監聽到另一個div的路由的,所有需要把監聽的路由都加上緩存(在路由添加 meta: { keepAlive: true }),路由在緩存頁面之間進行跳轉的時候,就可以通過監聽路由來進行判斷數據是否需要更新。

vue中前進刷新、后退緩存用戶瀏覽數據和瀏覽位置的實踐
vue中,我們所要實現的一個場景就是:

1.搜索頁面==>到搜索結果頁時,搜索結果頁面要重新獲取數據,

2.搜索結果頁面>點擊進入詳情頁>從詳情頁返回列表頁時,要保存上次已經加載的數據和自動還原上次的瀏覽位置。

最近在項目中遇到這個問題,思考了幾套方案,總是不太完善。百度搜到的方案也基本都只能滿足一些很簡單的需求。對於復雜一些的情況,還是有些不完善的地方。以下是個人對於這種場景的一個摸索,也參考了百度。如有更好的方案,歡迎指出。

緩存組件,vue2中提供了keep-alive。首先在我們的app.vue中定義keep-alive:

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

這里是根據路由中的meta源信息中的keepAlive字段來判斷當前路由組件是否需要緩存。這里的meta的keepAlive是我們自定義的,當然你也可以叫別的名字。

下面在router/index.js即我們的路由文件中,定義meta信息:

// list是我們的搜索結果頁面

{      
    path: '/list',  
    name: 'List',      
    component: resolve => require(['@/pages/list'], resolve),    
    meta: {        
        isUseCache: false,  // 這個字段的意思稍后再說      
        keepAlive: true  // 通過此字段判斷是否需要緩存當前組件  
    }    
},

上面的component: resolve => require(['@/pages/list'], resolve)這里的組件引入方式可能和大家平時寫的有些不一樣,這里是為了路由的懶加載用的,大家可以忽略。按照正常的import引入也可以,這個和本次的主題無關。如此一來,vue的路由會幫我們去緩存list頁面。

刷新數據or緩存數據的實現:
說這之前,先簡單說一下和緩存相關的vue鈎子函數。

設置了keepAlive緩存的組件:

   第一次進入:beforeRouterEnter ->created->…->activated->…->deactivated

   后續進入時:beforeRouterEnter ->activated->deactivated

可以看出,只有第一次進入該組件時,才會走created鈎子,而需要緩存的組件中activated是每次都會走的鈎子函數。所以,我們要在這個鈎子里面去判斷,當前組件是需要使用緩存的數據還是重新刷新獲取數據。思路有了,下面我們來實現:

// list組價的activated鈎子
 activated() {
    // isUseCache為false時才重新刷新獲取數據
    // 因為對list使用keep-alive來緩存組件,所以默認是會使用緩存數據的         
    if(!this.$route.meta.isUseCache){            
        this.list = []; // 清空原有數據
        this.onLoad(); // 這是我們獲取數據的函數
    } 
},

這里的isUseCache 其實就是我們用來判斷是否需要使用緩存數據的字段,我們在list的路由的meta中已經默認設置為false,所以第一次進入list時是獲取數據的。

當我們從詳情頁返回時,我們把list頁面路由的isUseCache設置成true,這樣我們在返回list頁面時會使用緩存數據:

// 詳情頁面的beforeRouteLeave鈎子函數
beforeRouteLeave (to, from, next) {        
    if (to.name == 'List') {
        to.meta.isUseCache = true;    
    }        
    next();
},

我們這里是在即將離開detail頁面前判斷是否返回的列表頁。如果是返回list頁面,則把list頁面路由的isUseCache字段設置成true。為什么這樣設置呢?因為我們對list組件使用的keep-alive進行緩存組件,其默認就是使用緩存的。而我們又在list組件的actived鈎子函數中進行了判斷:只有在list頁面的isUseCache==false時才會清空原有數據並重新獲取數據。所以此處設置isUseCache為true,此時返會list頁面是不會重新獲取數據的,而是使用的緩存數據。

detail返回list可以緩存數據了,那么search前往list頁面時怎么讓list頁面不使用緩存數據而是獲取新數據呢?我們重新回到list的activated鈎子中:

// list組價的activated鈎子
 activated() {
    // isUseCache為false時才重新刷新獲取數據
    // 因為對list使用keep-alive來緩存組件,所以默認是會使用緩存數據的         
    if(!this.$route.meta.isUseCache){            
        this.list = []; // 清空原有數據
        this.onLoad(); // 這是我們獲取數據的函數
        this.$route.meta.isUseCache = false;    } 
},

我們加了一行this.$route.meta.isUseCache=false;也就是從detail返回list后,將list的isUseCache字段為false,而從detail返回list前,我們設置了list的isUseCache為true。所以,只有從detail返回list才使用緩存數據,而其他頁面進入list是重新刷新數據的。

至此,一個前進刷新、后退返回的功能基本完成了。

如果場景再復雜一丟丟,比如,如果這個詳情頁是個訂單詳情,那么在訂單詳情頁可能會有刪除訂單的操作。那么刪除訂單操作后會返回訂單列表頁,是需要列表頁重新刷新的。那么我們需要此時在訂單詳情頁進行是否要刷新的判斷。簡單改造一下詳情頁:

data () {    
    return {
        isDel: false  // 是否進行了刪除訂單的操作       
    }
},
beforeRouteLeave (to, from, next) {        
    if (to.name == 'List') {
        // 根據是否刪除了訂單的狀態,進行判斷list是否需要使用緩存數據
        to.meta.isUseCache = !this.isDel;                
    }        
    next();    
},
methods: {        
    deleteOrder () {       
        // 這里是一些刪除訂單的操作
 
        // 將狀態變為已刪除訂單
        // 所以beforeRouteLeave鈎子中就會將list組件路由的isUseCache設置為false    
        // 所以此時再返回list時,list是會重新刷新數據的 
        this.isDel = true; 
        this.$router.go(-1)
    }
}

至此,算是解決了我的vue項目中的這個前進刷新、后退緩存數據和瀏覽位置的問題。

最后再提一下,頁面滾動位置的問題。

問題1:我們知道,在vue這種單頁應用中,如果你在a頁面滾動了一段距離后,此時前往b頁面后,b頁面也會停留在a頁面的滾動位置。這個問題的解決,我們可以利用router本身提供的功能來解決:

routes: [    
    {      
        path: '/detail',      
        name: 'Detail',      
        component: resolve => require(['@/pages/detail'], resolve)    
    }    
],
scrollBehavior (to, from, savedPosition) {
    if (savedPosition) {        
          return savedPosition    
    } else {      
          if (from.meta.keepAlive) {        
               from.meta.savedPosition = document.body.scrollTop;      
          }        
          return { x: 0, y: to.meta.savedPosition || 0 }    
    }  
}

scrollBehavior是路由提供的基礎功能,這段函數寫的是:

1.如果通過瀏覽器自帶的前進后退按鈕切換的路由,那么會自動使用瀏覽默認的回滾上次頁面的瀏覽位置。

2.如果是通過vue路由進行的頁面切換。例如a前往b,首先判斷a是不是通過keep-alive緩存的組件,如果是,則在a路由的meta中添加一個savedPosition字段,並且值為a的滾動位置。最后return的是頁面需要回滾的位置。如此一來,如果打開一個頁面,該頁面的組件路由中meta.savedPosition為undefined的話,則頁面滾動到(0,0)的位置,這樣解決了問題1。那么如果打開一個頁面,它的路由的meta.savedPosition有值的話,則滾動到上次瀏覽的位置,因為meta.savedPosition保存的就是上次瀏覽的位置。
vue中,在本地緩存中讀寫數據的方法
1.安裝good-storage插件
cnpm i good-storage --save
2.讀/寫的方法

common/js/cache.js:
import storage from 'good-storage'

const SEARCH_KEY = '__search__'
const SEARCH_MAX_LENGTH = 15

// compare:findindex傳入的是function,所以不能直接傳val
function insertArray(arr, val, compare, maxLen) {
  const index = arr.findIndex(compare)
  if (index === 0) {
    return
  }
  if (index > 0) {
    arr.splice(index, 1)
  }
  arr.unshift(val) // 插入到數組最前
  if (maxLen && arr.length > maxLen) {
    arr.pop() // 刪除末位元素
  }
}

// 存儲搜索歷史
export function saveSearch(query) {
  let searches = storage.get(SEARCH_KEY, [])
  insertArray(searches, query, (item) => {
    return item === query
  }, SEARCH_MAX_LENGTH)
  storage.set(SEARCH_KEY, searches)
  return searches
}
// 加載本地緩存的搜索歷史
export function loadSearch() {
  return storage.get(SEARCH_KEY, [])
}

3.數據用vuex傳遞
在store/actions.js中寫入數據:

import * as types from './mutation-types'
import {saveSearch} from 'common/js/cache'

export const saveSearchHistory = function({commit, state}, query) {
  commit(types.SET_SEARCH_HISTORY, saveSearch(query))
}

4.組件中調用vuex

import {mapActions} from 'vuex'

// methods內:
    saveSearch() {
      this.saveSearchHistory(this.query)
    },
    ...mapActions([
      'saveSearchHistory'
    ])

本文轉載自:https://blog.csdn.net/qq_31393401/article/details/79299606
vue列表進入詳情頁面返回時數據緩存
1.在app.vue中添加

2.在router.index中添加


3.在列表頁面添加

本文轉載自:https://blog.csdn.net/yanby921005/article/details/80360822
vue.js生命周期鈎子函數及緩存
在工作中用到最多的就是created,mounted,activated,deactivated.
由於系統需要緩存,使用了keep-alive

 <keep-alive :include="/keepalive[a-zA-Z]+/">
            <router-view></router-view>
        </keep-alive>

include 和 exclude 屬性允許組件有條件地緩存。二者都可以用逗號分隔字符串或正則表達式來表示
匹配首先檢查組件自身的 name 選項,如果 name 選項不可用,則匹配它的局部注冊名稱(父組件 components 選項的鍵值)。匿名組件不能被匹配。
//如果希望頁面緩存,就在當前頁的name屬性,加上符合正則條件的name名稱。不希望就加上不匹配的正則name名稱。
created
實例已經創建完成之后被調用。在這一步,實例已完成以下的配置:數據觀測(data observer),屬性和方法的運算, watch/event 事件回調。然而,掛載階段還沒開始,$el 屬性目前不可見。
//在剛進入頁面的時候,會觸發該函數的方法。只在頁面剛開始加載時執行一次。
mounted
el 被新創建的 vm.$el 替換,並掛載到實例上去之后調用該鈎子。如果 root 實例掛載了一個文檔內元素,當 mounted 被調用時 vm.$el 也在文檔內。
該鈎子在服務器端渲染期間不被調用。
//頁面已經完成會執行該函數。
activated
keep-alive 組件激活時調用。
該鈎子在服務器端渲染期間不被調用。
//當頁面存在緩存的時候執行該函數。
deactivated
keep-alive 組件停用時調用。
該鈎子在服務器端渲染期間不被調用。
//在頁面結束時觸發該方法,可清除掉滾動方法等緩存。
本文轉載自:https://blog.csdn.net/stubbor/article/details/73739765


免責聲明!

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



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