主要修改了 keepAlive 的緩存機制, 可以像 APP 那樣前進刷新, 返回銷毀, 支持動態(tài)路由和功能性路由
改變了
keepAlive
的緩存機制, 可以像 APP 那樣前進重建
,返回銷毀
不過目前僅僅用于Page
級別, 也就是一級路由, 其他級路由似乎沒有需要
原本的keepAlive
默認(rèn)是以componentName
來做緩存的 key
當(dāng)然如果有vnode.key
的話則會使用vnode.key
, 所以網(wǎng)上很多通過$route.fullPath
當(dāng)作 key
可以實現(xiàn)params/query
的變更新建組件, 但是無法做到返回銷毀
如果使用$destroy()
去手動銷毀, 但是keepAlive
里面還是存在緩存標(biāo)記
導(dǎo)致從 3 級路由返回到 2 級路由時拿緩存的instance
是失效的, 進而導(dǎo)致重建
所以通過Page
前進返回行為分析, 總結(jié)出 key 的生成規(guī)則
解決的痛點
- 子路由的更新和父級路由無關(guān), 所以一級路由的緩存 key 是命中路由的父一級路由相關(guān), 目前是父路由的 path + 父子路由相同的 params
- 還有就是自己功能性路由的支持
- 比如使用支持返回鍵的 imgsViewer, 需要 history 壓棧而不觸發(fā) forward/backward 事件, 所以提供了 ignorePaths 參數(shù)
- 比如子路由不使用 router-view 來渲染, 而是使用 view-pager 來自行控制,
支持左右滑動切換, 如果 view-pager 的頁面狀態(tài)是需要保存到 url, 則需要一級路由的一個動態(tài)路由占位符, 充當(dāng)子路由, 所以提供了 ignoreParams 參數(shù)
- 比如子路由不使用 router-view 來渲染, 而是使用 view-pager 來自行控制,
Props
參數(shù) | 類型 | 默認(rèn)值 | 可選值 | 描述 |
---|---|---|---|---|
ignorePaths | Array, String, RegExp | 忽略符合條件的 URL,不壓棧 | ||
ignoreParams | Array, String | 忽略動態(tài)路由參數(shù)羡榴,不參與 key 的構(gòu)成 |
Events
事件名 | 參數(shù) | 描述 |
---|---|---|
init | Info | 組件初始化的時候 |
forward | Info | 路由前進的時候 |
replace | Info | 路由替換的時候 |
backward | Info | 路由返回的時候 |
Event Params: Info
參數(shù) | 類型 | 描述 |
---|---|---|
fromPath | String | 變化前 path |
nextPath | String | 變化后 path |
fromRouterKey | String | 變化前 key |
nextRouterKey | String | 變化后 key |
注: vc-keep-alive 將會把歷史棧儲存在 SessionStorage 的__VCKEEPALIVE__
字段里
Demo Code
npm install vc-keep-alive
<template>
<div id="app" :class="pageAct">
<transition name="page-slide">
<vc-keep-alive
:ignorePaths="ignorePaths"
:ignoreParams="ignoreParams"
@init="log('init', $event)"
@forward="log('forward', $event)"
@replace="log('replace', $event)"
@backward="log('backward', $event)"
>
<router-view />
</vc-keep-alive>
</transition>
</div>
</template>
<script>
import Vue from 'vue';
import VcKeepAlive from 'vc-keep-alive';
Vue.use(VcKeepAlive);
export default {
data() {
return {
pageAct: '',
ignorePaths: ['popup='],
ignoreParams: ['pagerTab']
};
},
methods: {
log(act, args) {
console.log(act, args);
this.pageAct = 'page-' + act;
}
}
};
</script>
TODO
License
MIT 一起來扣細(xì)節(jié)~