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
