vue——keepAlive第一次無效問題及解決方法


搬運自:https://segmentfault.com/a/1190000019610283?utm_source=tag-newest

vue官方API: https://cn.vuejs.org/v2/api/#keep-alive

 

例:

router.js:

 
         
{
    path: '/home', name: 'Home', meta: { index: 0, keepAlive: true, title: '首頁' }, component: resolve => require(['../../../modules/Home'], resolve) },
{
    path: '/list',
      name: 'List',
      meta: {
        index: 1,
        keepAlive: true,
        title: '列表頁'
      },
      component: resolve => require(['../../../modules/List'], resolve)
},
{
      path: '/detail',
      name: 'Detail',
      meta: {
        index: 2,
        keepAlive: false,
        title: '詳情頁'
      },
      component: resolve => require(['../../../modules/Detail'], resolve)
}

問題:列表頁進詳情頁時,首先第一次打開頁面的時候並不緩存,即第一次從列表頁跳到詳情頁,再回來並沒有緩存。后面再進入詳情頁才會被緩存,並且只會緩存第一次進入的狀態,不會重新請求數據。如果當首頁選中一個分類跳到列表頁,再從列表頁面跳往詳情頁,此時會緩存這個狀態,並且以后再從首頁的其他分類跳到列表頁都不會重新被緩存,以至於每次從詳情頁返回列表頁都會跳第一次緩存的狀態。當你的項目只有一種狀態需要緩存,可以考慮使用這種方法。

 

 

解決:使用 include + beforeRouteLeave 或者使用 include + beforeRouteLeave + vuex。

 

方法一:使用 include + beforeRouteLeave 

 

 

1、在創建router實例的時候加上scrollBehavior方法

 

export default new Router({ routes, scrollBehavior (to, from, savedPosition) { if (savedPosition) { return savedPosition } else { return { x: 0, y: 0 } } } })

 

2、將需要緩存的組件加在include屬性里

 

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

 

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

beforeRouteEnter (to, from, 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()// 是本來寫在created里面的各種
      }
    })
  }

 

 

 

方法二:使用 include + beforeRouteLeave + vuex 與方法一相似,不同的地方在於,將需要緩存的組件保存到全局變量,可以在路由的鈎子函數里靈活的控制哪些組件需要緩存,那些不需要緩存;跟方法一相比,不需要每次再重新初始化數據,但是需要在vuex中保存數據;

 

1、在創建router實例的時候加上scrollBehavior方法

 

export default new Router({
  routes,
  scrollBehavior (to, from, savedPosition) {
    if (savedPosition) {
      return savedPosition
    } else {
      return {
        x: 0,
        y: 0
      }
    }
  }
})

2、將需要緩存的組件加在include屬性里

<keep-alive :include="catch_components">
      <router-view></router-view>
</keep-alive>

 

3、在store里加入需要緩存的的組件的變量名,和相應的方法;

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

 

4、在beforeRouteLeave鈎子函數里控制需要緩存的組件

beforeRouteLeave (to, from, next) { //要在離開該組件的時候控制需要緩存的組件,否則將出現第一次不緩存的情況
    this.busy = true
    if (to.path === '/goods_detail') { // 去往詳情頁的時候需要緩存組件,其他情況下不需要緩存
      this.$store.commit('GET_CATCHE_COMPONENTS', ['home']) //注意,'home'將匹配首先檢查組件自身的 name 選項(非router.js里的),如果 name 選項不可用,則匹配它的局部注冊名稱 (父組件 components 選項的鍵值)。匿名組件不能被匹配。
    } else {
      this.$store.commit('GET_CATCHE_COMPONENTS', [])
    }
    next()
}

 

 

 


免責聲明!

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



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