vue 後退不刷新,前進刷新 keep-alive

最近在開發中遇到了這樣的一個問題:vue

A、B、C三個頁面,有以下這樣的場景:node

(1)從頁面A離開進入B或C的時候,緩存A頁面的數據,而且返回到A後,能保持A頁面的跳轉前職位數組

(2)離開B進入C的時候,緩存B緩存

(3)離開B進入A的時候,不緩存app

如今開始分步解決:異步

方案一:函數

從場景中但是看出A、B是須要緩存的,測試

首先修改app.vuethis

<template>
  <div id="app">
    <keep-alive :include="['Index', 'List']">
      <router-view/>
    </keep-alive>
  </div>
</template>

include是A、B頁面中的name值,注意,include接受的是數組字符串url

而後就是A頁面進入B頁面的時候刷新,即離開B進入A的時候不緩存,那麼就須要用到beforeRouteEnter(),此函數在mounted()執行後執行,不是methods中的自定義函數

export default {
  name: "List",
  beforeRouteEnter(to, from, next) {
      next(vm => {
        // 經過 `vm` 訪問組件實例
        if (from.fullPath == '/' && to.fullPath.indexOf('/list') > -1) { //必定是從A進到B頁面才刷新
           vm.initFn(); //initFn是原本寫在mounted裏面的各類, 執行順序是:先執行mounted,而後是此處
        }
      })
   },
  methods: {
    initFn() {
      ... //獲取數據
    }
  } }

返回到原來的位置用到的是router中的scrollBehavior():

router.js:

new Router({
    routes: [],
    scrollBehavior(to, from, savedPosition) {
      // keep-alive 返回緩存頁面後記錄瀏覽位置
      if (savedPosition && to.meta.isKeepAlive) {
        return savedPosition;
      }
      // 異步滾動操做
      return new Promise((resolve) => {
        setTimeout(() => {
          resolve({ x: 0, y: 1 });
        }, 0);
      });
    }
})
有時候會有返回不回去的狀況,可作延時處理:
new Router({
    routes: [],
    scrollBehavior(to, from, savedPosition) {
      // keep-alive 返回緩存頁面後記錄瀏覽位置
      if (savedPosition && to.meta.isKeepAlive) {
         setTimeout(() => { //延時
           window.scrollTo(savedPosition.x, savedPosition.y)
         }, 10);
      }
      // 異步滾動操做
      return new Promise((resolve) => {
        setTimeout(() => {
          resolve({ x: 0, y: 1 });
        }, 0);
      });
    }
})

除了使用keep-alive的include屬性,可經過給router中添加mate參數控制

app.vue:

<template>
  <div id="app">
    <keep-alive>
      <router-view v-if="$route.meta.isKeepAlive"/>
    </keep-alive>
    <router-view v-if="!$route.meta.isKeepAlive"/>
  </div>
</template>

注意此處if判斷中的meta後的值要與router中的一致

router.js

const router = new Router({
  routes: [
    {
      path: '/',
      name: 'Index',
      component: Index,
      meta: {
        isKeepAlive: true
      }
    },
    {
      path: '/list/:id', 
      name: 'List',
      component: List,
      meta: {
        isKeepAlive: true
      }
    }
  ],
  scrollBehavior(to, from, savedPosition) {
    // keep-alive 返回緩存頁面後記錄瀏覽位置
    if (savedPosition && to.meta.isKeepAlive) {
      return savedPosition;
    }
    // 異步滾動操做
    return new Promise((resolve) => {
      setTimeout(() => {
        resolve({ x: 0, y: 1 });
      }, 0);
    });
  }
});
export default router;

固然還有其餘的解決方法,如destory()。

方案二:

利用$destroy()銷燬:

beforeRouteLeave (to: any, from: any, next: any) {
  // 導航離開該組件的對應路由時調用
  // 判斷是不是去往頁面 C 
  if (to.name !== 'C') {
    // 不是去 C 頁面,不緩存
    this.$destroy()
  }
  next()
}

但bug是銷燬後將永遠不會再次緩存。

網上還有給出其餘方案,查看源碼能夠發現緩存是經過添加cache屬性存儲vnode的,如經過源碼的cache屬性,強制移除某個對象,缺點是沒有完全銷燬依舊佔內存,不過我沒有實驗,具體的就不知道了。

還有就是動態設置router.js中的keepAlive值,經過beforeRouteLeave(to, from, next)中的to,from判斷url,動態設置keepAlive是true仍是false,但設置爲true緩存後,即便再設置爲false也不會清除緩存,那麼會出現bug,列表頁不一樣id的進入,始終是第一次進入時的數據。

通過屢次測試,發現方案一的兩種寫法均是可行且沒出現bug的,記錄下,方便之後複習

相關文章
相關標籤/搜索