1. 程式人生 > 程式設計 >vue之keepAlive使用案例詳解

vue之keepAlive使用案例詳解

在開發中經常有從列表跳到詳情頁,然後返回詳情頁的時候需要快取列表頁的狀態(比如滾動位置資訊),這個時候就需要儲存狀態,要快取狀態;裡提供了keep-alive元件用來快取狀態。
可以用以下幾種方案解決問題;

一、利用meta標籤

1、首先在路由中的meta標籤中記錄keepAlive的屬性為true

path: '/classify',name: 'classify',component: () => import('@/views/classify/classify.vue'),meta: {
    title: '雷石淘券券',keepAlive: true
  }
},

2、在建立router例項的時候加上scrollBehavior方法

export default new Router({
  mode: 'history',base: process.env.BASE_URL,routes,scrollBehavior (to,from,savedPosition) {
    if (savedPosition) {
      return savedPosition
    } else {
      return {
        x: 0,y: 0
      }
    }
  }
})

3、在需要快取的router-view元件上包裹keep-alive元件

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

4、由於有些情況下需要快取有些情況下不需要快取,可以在快取的元件裡的路由鉤子函式中做判斷

beforeRouteLeave (to,next) {
    this.loading = true
    if (to.path === '/goods_detail') {
      from.meta.keepAlive = true
    } else {
      from.meta.keepAlive = false
     // this.$destroy()
    }
    next()
  },

可以支援元件的快取,但是這種方法有bug,首先第一次開啟頁面的時候並不快取,即第一次從列表頁跳到詳情頁,再回來並沒有快取,後面在進入詳情頁才會被快取

並且只會快取第一次進入的狀態,不會重新請求資料,如果當頁面A選中一個分類跳到B頁面,再從B列表頁面跳往詳情頁,此時會快取這個狀態,並且以後再從A頁面的其他分類跳到B頁面都不會重新被快取,以至於每次從詳情頁返回B頁面都會跳第一次快取的狀態;當你的專案只有一種狀態需要快取,可以考慮使用這種方法

二 使用include、exclude屬性和beforeRouteEnter鉤子函式

首先介紹一下include和exclude vue文件https://cn.vue.org/v2/api/#keep-alive
是在vue2.0以後新增的屬性
include是需要快取的元件;
exclude是除了某些元件都快取;
include 和 exclude 屬性允許元件有條件地快取。二者都可以用逗號分隔字串、正則表示式或一個數組來表示:

<keep-alive include="a,b">
  <component :is="view"></component>
</keep-alive>
 
<!-- 正則表示式 (使用 `v-bind`) -->
<keep-alive :include="/a|b/">
  <component :is="view"></component>
</keep-alive>
 
<!-- 陣列 (使用 `v-bind`) -->
<keep-alive :include="['a','b']">
  <component :is="view"></component>
</keep-alive>

匹配首先檢查元件自身的 name 選項,如果 name 選項不可用,則匹配它的區域性註冊名稱 (父元件 componehttp://www.cppcns.comnts 選項的鍵值)。匿名元件不能被匹配。

max只在2.5.0新增,最多可以快取多少元件例項。一旦這個數字達到了,在新例項被建立之前,已快取元件中最久沒有被訪問的例項會被銷燬掉。

<keep-alive :max="10">
  <component :is="view"></component>
</keep-alive>

activated 與 deactivated。

簡單介紹一下在被keep-alive包含的元件/路由中,會多出兩個生命週期的鉤子:activated 與 deactivated。
文件:在 2.2.0 及其更高版本中,activated 和 deactivated 將會在 樹內的所有巢狀元件中觸發。
activated在元件第一次渲染時會被呼叫,之後在每次快取元件被啟用時呼叫。
activated呼叫時機:
第一次進入快取路由/元件,在mounted後面,beforeRouteEnter守衛傳給 next 的回撥函式之前呼叫:

beforeMount=> 如果你是從別的路由/元件進來(元件銷燬destroyed/或離開快取deactivated)=>mounted=> activated 進入快取元件 => 執行 beforeRouteEnter回撥

因為元件被快取了,再次進入快取路由/元件時,不會觸發這些鉤子:// beforeCreate created beforeMount mounted 都不會觸發。

deactivated:元件被停用(離開路由)時呼叫
使用了keep-alive就不會呼叫beforeDestroy(元件銷燬前鉤子)和destroyed(元件銷燬),因為元件沒被銷燬,被快取起來了。
這個鉤子可以看作beforeDestroy的替代,如果你快取了元件,要在元件銷燬的的時候做一些事情,你可以放在這個鉤子裡。
如果你離開了路由,會依次觸發:

元件內的離開當前路由鉤子beforeRouteLeave => 路由前置守衛 beforeEach =>全域性後置鉤子afterEach => deactivated 離開快取元件 => activated 進入快取元件(如果你進入的也是快取路由

專案中快取使用方法:
1、在建立的router物件上加scrollBehavior方法,同上;
2、將需要快取的元件加在include屬性裡

<keep-alive :include="['home','classify','search']">
      <router-view></router-view>
</keep-alive>

3、在beforeRouteEnter的next回掉函式裡,對返回A頁面不需要快取的的情況初始化,即將本來需要寫在created裡的東西寫在這裡;注意一定要將所有的需要初始化的資料要寫一遍,不然會有bug;所以不太推薦

beforeRouteEnter (to,next) {
    next(vm => {
      // 通過 `vm` 訪問元件例項
      if (from.path !== '/goods_detail') { // 一定是從A進到B頁面才重新整理
        vm.titleText = vm.$route.query.name
        vm.categoryUpper = vm.$route.query.categoryUpper
        vm.goods = []
        vm.page = 1
        vm.catsIndex = 0
        vm.is_search = false
        vm.getCats2()//kARSHk 是本來寫在created裡面的各種
      }
    })
  }

三、使用include、exclude屬性和beforeRouteLeave鉤子函式和vuex (推薦使用)

第三種方法和第二種相似,不同的地方在於,將需要快取的元件儲存到全域性變數,可以在路由的鉤子函式裡靈活的控制哪些元件需要快取,那些不需要快取;跟第二種方法相比,不需要每次再重新初始化資料,但是需要在vuex中儲存資料;
上程式碼
1、在建立的router物件上加scrollBehavior方法,同上;
2、將需要快取的元件加在include屬性裡

<keep-alive :include="catch_components">
      <router-view></router-view>
</keep-alive&http://www.cppcns.comgt;

3、在store里加入需要快取的的元件的變數名,和相應的方法;

export default new Vuex.Store({
  state: {
    catch_components: []
  },mutations:{
    GET_CATCHE_COMPONENTS (state,data) {
      state.catch_components = data
    }
}
})

4、在beforeRouteLeave鉤子函式裡控制需要快取的元件

beforeRouteLeave (to,next) { //要在離開該元件的時候控制需要快取的元件,否則將出現第一次不快取的情況
    this.busy = true
    if (to.path === '/goods_detail') { // 去往詳情頁的時候需要快取元件,其他情況下不需要快取
      this.$store.commit('GET_CATCHE_COMPONENTS',['home'])
    } else {
      this.$store.commit('GET_CATCHE_COMPONENTS',[])
    }
    next()
  },

另外,在我們的專案中遇到路由相同但引數不同的情況元件被複用,不更新的問題,vue官方給出了 響應路由引數變化

watch: {
    '$route' (to,from) {
      document.title = this.$route.query.name
      this.getDefault() //根據引數資料響應
    }

  },

到此這篇關於vue之keepAlive使用案例詳解的文章就介紹到這了,更多相關vue之keepAlive使用內容請搜尋我們以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援我們!