搬運自: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()
}