vue keep-alive組件的使用

1、問題觸發並解決

最近本身在寫vue練習,內容相對簡單,主要是對vue進行熟悉和相關問題發現,查漏補缺。簡單說下練習的項目內容及問題的產生:vue

練習使用的vue-cli 2.0腳手架搭建,內容就是簡單的仿音樂播放app,功能也相對簡單,大致就是單頁router切換各個專輯列表,點擊進入專輯內容頁面,單擊歌曲名稱能夠進行播放、暫停、下一曲功能。vuex

簡單的背景介紹完了,說下問題產生的情形:在從整個歌曲列表頁點擊跳轉到單個專輯列表頁,而後點擊返回按鈕返回歌曲列表頁時,頁面保存了以前的瀏覽位置,可是接口從新請求了數據,由於歌曲列表頁有滾動加載效果,因此數據獲取在vuex裏用了數組的concat方法,致使返回請求的數據從新加載了列表裏,而v-for循環因爲key值有了重複,致使控制檯報錯;提及來可能比較難懂,上一些基本的代碼部分:vue-cli

vuex裏獲取列表數據:
GET_COLLECTION_LIST(state, val) {  state.collectionList = state.collectionList.concat(val)}

歌曲列表裏created獲取數據,mounted監聽滾動事件滾動加載,destroyed取消監聽:
created(){  this.collectionListMethod({limit: this.limit, offset: this.offset})},
mounted(){  window.addEventListener('scroll', this.isScrollBot)}
destroyed(){  window.removeEventListener('scroll', this.isScrollBot)}

專輯列表頁返回使用的是  this.$router.go(-1)複製代碼

有問題就要解決問題,經過查詢瞭解到keep-alive能夠對數據進行緩存,路由切換的時候可使用緩存不用從新觸發接口請求,貌似能夠很完美解決問題,實踐出真知,在代碼裏添加:api

首先在歌曲列表路由裏添加meta:{keepAlive: true}爲後面的router-view是否須要緩存提供標識
{  path: '/songLis',  component: SongLis,  meta: { keepAlive: true  }}
而後在router-view外層添加keep-alive,並根據meta參數判斷是否全部路由都須要緩存
<keep-alive>
    <router-view v-if="$route.meta.keepAlive" />
</keep-alive>
<router-view v-if="!$route.meta.keepAlive"/>複製代碼

添加完畢,回到頁面看效果!可喜可賀的是控制檯不報錯了,說明keep-alive起做用了,撒花慶祝~~~ 可是事情並無那麼簡單,當咱們從專輯列表切到其餘路由,滾動鼠標會發現滾動加載的監聽事件沒有取消,組件destroyed的時候明明取消監聽了啊!並且再切回到專輯列表頁的時候,滾動加載反而不執行了,表示一臉懵~數組

通過查看vue文檔,發現文檔有這麼一句話:緩存

<keep-alive> 包裹動態組件時,會緩存不活動的組件實例,而不是銷燬它們。
bash

也就是說使用keep-alive的組件不會觸發destroyed鉤子方法,這就是取消監聽失敗的緣由。根據文檔介紹,keep-alive切換時,會觸發本身的activeted和deactiveted兩個鉤子函數,能夠理解爲vue的created和destroyed兩個鉤子,所以須要修改代碼,在deactivated時候取消監聽,同時在activated的時候恢復監聽,不然切回去的時候滾動監聽也不會有效果:app

//keep-alive鉤子函數,組件恢復時觸發
activated(){  window.addEventListener('scroll', this.isScrollBot)},
//keep-alive鉤子函數,組件變爲不可用時觸發
deactivated(){  window.removeEventListener('scroll', this.isScrollBot)}複製代碼

修改後的效果徹底符合預期,切換路由頁面保留當位置,不會重複請求接口並且也不會在專輯列表組件外部觸發滾動加載。函數

2、關於keep-alive

既然用到了keep-alive,就經過文檔簡單總結下相關使用:ui

上面已經說過,經過keep-alive包裹的組件,在不活動時會緩存組件實例,不會對組件進行銷燬,再次處於活動狀態時,會讀取緩存的內容並保存組件狀態,不用重複請求接口獲取數據。

(1)最基本使用

基本用法:
<keep-alive>
  <component :is="view"></component>
</keep-alive>

也能夠根據條件判斷:
<keep-alive>
  <comp-a v-if="a > 1"></comp-a>
  <comp-b v-else></comp-b>
</keep-alive>
這個時候觸發兩個組件切換時,組件內的數據和狀態都會獲得保存,若是有input輸入框,輸入框內容會保留複製代碼

(2)有條件的緩存

keep-alive提供了include、exclude、max三個參數,前兩個容許組件有條件的進行緩存,二者均可以接受字符串、正則、數組形式;max表示最多能夠緩存多少個組件,接受一個number類型。

<keep-alive include="a,b">
  <component :is="view"></component>
</keep-alive>
此時只有a、b兩個組件會觸發keep-alive,此處的名字是組件內部name對應名字,若是name不存在,會查找父組件裏components裏註冊的名字,若是也不存在則不會匹配。
正則和數組方法同上,可是須要用v-bind:include=''方式。

<keep-alive :max="10">
  <component :is="view"></component>
</keep-alive>
複製代碼

(3)鉤子函數

兩個鉤子函數activated和deactivated,上面已經說過,分別在組件恢復活動狀態和組件失去活動狀態時觸發,能夠起到相似created和destroyed鉤子做用。


以上是對keep-alive的我的使用和理解,若有不足還望指正~

相關文章
相關標籤/搜索