接上篇 https://www.cnblogs.com/wangmaoling/p/9803960.html
本文很長,請耐心看完分析。
4.高級用法,指定從什么組件進入才緩存,以及銷毀緩存:先介紹我發現的網上一些博主寫的有bug的方法,在介紹自己的方法。
假設這里有 3 個路由: A、B、C。要求:
1. 默認顯示 A
2. B 跳到 A,A 不刷新
3. C 跳到 A,A 刷新
先上一些發現博客上有些博主寫的實現方式:
方式1:有bug
在 A 路由里面設置 meta 屬性:
{ path: '/', name: 'A', component: A, meta: { keepAlive: true // 需要被緩存 } }
在 B 組件里面設置 beforeRouteLeave:
export default { data() { return {}; }, methods: {}, beforeRouteLeave(to, from, next) { // 設置下一個路由的 meta to.meta.keepAlive = true; // 讓 A 緩存,即不刷新 next(); } };
在 C 組件里面設置 beforeRouteLeave:
export default { data() { return {}; }, methods: {}, beforeRouteLeave(to, from, next) { // 設置下一個路由的 meta to.meta.keepAlive = false; // 讓 A 不緩存,即刷新 next(); } };
這樣便能實現 B 回到 A,A 不刷新;而 C 回到 A 則刷新。但是問題來了:
1. 只要是從C到了A(A即為false),A在到B的時候也是false,B返回A后A才變為true。
這個方法沒弄明白,true跟緩存的關系,只有首先設置了true才可以被緩存,而不是后設置true讓他緩存下。
2. 如果是多頁面就麻煩了,每個組件都得寫,並且還不知道,to的組件是什么。
方式2:有bug - $destroy()銷毀后就永遠不會被緩存了
//在router的js里面 加上全局
Vue.mixin({ beforeRouteLeave: function (to, from, next) { // 省略若干代碼this.$destroy(); next(); } } })
方式3:有bug。比較暴力的方法,已經很好的方法,根據源碼看來緩存的組件都會設置一個cache屬性,可以通過代碼強行移除掉。缺點就是沒有徹底銷毀依舊占內存。
路由設置:
公共組件設置:
實現:
Vue.mixin({
beforeRouteLeave: function (to, from, next) { // 默認是緩存的 在來清除 // 1.用tag標記控制 判斷上下級 // if (from && from.meta.tag && to.meta.tag && (from.meta.tag-to.meta.tag<1)) // 2.直接用組件名字來寫 不夠通用 // if (from.path == '/docMng' && to.path == '/docMng/docDetail') { // 3. 用包含關系來判斷 通用 if(to.path.indexOf(from.path)!=-1){ }else{ // if (from && from.meta.tag && to.meta.tag && (from.meta.tag-to.meta.tag<1)){ if (this.$vnode && this.$vnode.data.keepAlive) { if (this.$vnode.parent && this.$vnode.parent.componentInstance && this.$vnode.parent.componentInstance.cache) { if (this.$vnode.componentOptions) { var key = this.$vnode.key == null ? this.$vnode.componentOptions.Ctor.cid + (this.$vnode.componentOptions.tag ? `::${this.$vnode.componentOptions.tag}` : '') :this.$vnode.key; var cache = this.$vnode.parent.componentInstance.cache; var keys = this.$vnode.parent.componentInstance.keys; if (cache[key]) { if (keys.length) { var index = keys.indexOf(key); if (index > -1) { keys.splice(index, 1); } } delete cache[key]; } } } } this.$destroy(); // } } next() } })
此方法可以用了下面說下問題:
從A組件的詳情(A1)直接跳到另一個組件(B),然后在從B到A會發現A沒有刷新,按道理是需要刷新的。
方式4:比較好的解決方法,用到了keep-alive的 include屬性。通過vuex動態控制include達到可緩存狀態。
思路:一般設置緩存就是 從A1->A2 這個過程A1需要設置緩存,A1->B1一般是不需要的(tab切換暫不考慮,以后可能會在分析設計)。
通過vuex要緩存的組件存起來加載到include,來動態控制include。下面上項目截下來的圖:
步驟一路由設置:我這里是用層級表示的路由。這里如果不用層級可以用標記來表示例如:tag1.0 tag1.1 tag1.2 tag2.... 用這個方法來表示的時候需要多處理一 下,這里不做分析了
步驟二vuex設置
步驟三組件內設置在公共main設置觀察屬性include屬性。
步驟四在路由里面進行攔截