vue keep-alive保存路由状态2 (高级用法,接上篇)
接上篇?https://www.cnblogs.com/wangmaoling/p/9803960.html
本文很長(zhǎng),請(qǐng)耐心看完分析。
4.高級(jí)用法,指定從什么組件進(jìn)入才緩存,以及銷毀緩存:先介紹我發(fā)現(xiàn)的網(wǎng)上一些博主寫的有bug的方法,在介紹自己的方法。?
假設(shè)這里有 3 個(gè)路由: A、B、C。要求:
1.? ?默認(rèn)顯示 A? ??
2.? B 跳到 A,A 不刷新?
3.? C 跳到 A,A 刷新
先上一些發(fā)現(xiàn)博客上有些博主寫的實(shí)現(xiàn)方式:
方式1:有bug
在 A 路由里面設(shè)置?meta?屬性:
{path: '/',name: 'A',component: A,meta: {keepAlive: true // 需要被緩存} }在 B 組件里面設(shè)置?beforeRouteLeave:
export default {data() {return {};},methods: {},beforeRouteLeave(to, from, next) {// 設(shè)置下一個(gè)路由的 metato.meta.keepAlive = true; // 讓 A 緩存,即不刷新next();} };在 C 組件里面設(shè)置?beforeRouteLeave:
export default {data() {return {};},methods: {},beforeRouteLeave(to, from, next) {// 設(shè)置下一個(gè)路由的 metato.meta.keepAlive = false; // 讓 A 不緩存,即刷新next();} };這樣便能實(shí)現(xiàn) B 回到 A,A 不刷新;而 C 回到 A 則刷新。但是問(wèn)題來(lái)了:
1. 只要是從C到了A(A即為false),A在到B的時(shí)候也是false,B返回A后A才變?yōu)閠rue。
這個(gè)方法沒(méi)弄明白,true跟緩存的關(guān)系,只有首先設(shè)置了true才可以被緩存,而不是后設(shè)置true讓他緩存下。
2. 如果是多頁(yè)面就麻煩了,每個(gè)組件都得寫,并且還不知道,to的組件是什么。
方式2:有bug - $destroy()銷毀后就永遠(yuǎn)不會(huì)被緩存了?
//在router的js里面 加上全局Vue.mixin({beforeRouteLeave: function (to, from, next) {// 省略若干代碼this.$destroy();next();}} })
方式3:有bug。比較暴力的方法,已經(jīng)很好的方法,根據(jù)源碼看來(lái)緩存的組件都會(huì)設(shè)置一個(gè)cache屬性,可以通過(guò)代碼強(qiáng)行移除掉。缺點(diǎn)就是沒(méi)有徹底銷毀依舊占內(nèi)存。
路由設(shè)置:
公共組件設(shè)置:
實(shí)現(xiàn):
Vue.mixin({beforeRouteLeave: function (to, from, next) {// 默認(rèn)是緩存的 在來(lái)清除// 1.用tag標(biāo)記控制 判斷上下級(jí)// if (from && from.meta.tag && to.meta.tag && (from.meta.tag-to.meta.tag<1))// 2.直接用組件名字來(lái)寫 不夠通用// if (from.path == '/docMng' && to.path == '/docMng/docDetail') {// 3. 用包含關(guān)系來(lái)判斷 通用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() } })? 此方法可以用了下面說(shuō)下問(wèn)題:
從A組件的詳情(A1)直接跳到另一個(gè)組件(B),然后在從B到A會(huì)發(fā)現(xiàn)A沒(méi)有刷新,按道理是需要刷新的。
?
方式4:比較好的解決方法,用到了keep-alive的 include屬性。通過(guò)vuex動(dòng)態(tài)控制include達(dá)到可緩存狀態(tài)。
思路:一般設(shè)置緩存就是 從A1->A2 這個(gè)過(guò)程A1需要設(shè)置緩存,A1->B1一般是不需要的(tab切換暫不考慮,以后可能會(huì)在分析設(shè)計(jì))。
通過(guò)vuex要緩存的組件存起來(lái)加載到include,來(lái)動(dòng)態(tài)控制include。下面上項(xiàng)目截下來(lái)的圖:
步驟一路由設(shè)置:我這里是用層級(jí)表示的路由。這里如果不用層級(jí)可以用標(biāo)記來(lái)表示例如:tag1.0 tag1.1 tag1.2? ? ?tag2.... 用這個(gè)方法來(lái)表示的時(shí)候需要多處理一 ? 下,這里不做分析了
步驟二vuex設(shè)置
步驟三組件內(nèi)設(shè)置在公共main設(shè)置觀察屬性include屬性。
步驟四在路由里面進(jìn)行攔截
?
轉(zhuǎn)載于:https://www.cnblogs.com/wangmaoling/p/9826063.html
總結(jié)
以上是生活随笔為你收集整理的vue keep-alive保存路由状态2 (高级用法,接上篇)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 阿里云IoT百万资源,寻找极客合作伙伴
- 下一篇: vue通过监听实现相同路径的视图重新加载