关于vue-navigation
- A page navigation library, record routes and cache pages, like native app navigation. 一个页面导航库,记录路由并缓存页面,像原生APP导航一样。
github——zack24q
目录结构
1 | |-- src //根路径 |
文件初始化
初始化index.js
main.js
1 | import Navigation from 'vue-navigation' |
源码:
1 | install: (Vue, { router, store, moduleName = 'navigation', keyName = 'VNK' } = {}) => {} |
moduleName
默认参数navigation
:store
中缓存的路由名称keyName
默认参数VNK
:路径中query
的key
初始化navigation.js
初始化index.js
之后,随即就会初始化bus
以及navigation.js
bus
主要是在触发navigation
中的前进、后退等方法的时候通知触发回调事件
1 | // app.vue |
navigation
中主要是对前进,后退等方法的封装,其中会涉及到通过store
以及sessionStorage
做的路由缓存和bus
方法的调用
初始化组件components/Navigation.js
app.vue(根路径)
1 | <navigation> |
实现逻辑
全局前置守卫beforeEach
1 | // index.js |
- 判断前后路由是否一致,如果一直,获取
from
的路由版本号,不进行版本更新 - 如果不一致,获取新的
keyName
并且放置到新的路由地址中
全局后置钩子afterEach
1 | // index.js |
1 | // navigation.js |
- 触发路由后置函数
afterEach
,调用navigator
的record
方法 Routes
为store
以及sessionStorage
做的路由缓存- 根据
Routes
中缓存判断是前进,还是后退,还是刷新,调用不同的事件 forward
中向缓存新增一条记录,记录的结果如下,并且触发store
的navigation/FORWARD
方法1
["index?a28ae28e","list?ff674e47"]
refresh
触发store
的navigation/REFRESH
方法back
触发store
的navigation/BACK
方法,删除一条记录
components/Navigation.js
在
Navigation
中检测了缓存routes
的变化1
2
3
4
5
6
7
8
9
10
11watch: {
routes(val) {
for (const key in this.cache) {
if (!matches(val, key)) {
const vnode = this.cache[key]
vnode && vnode.componentInstance.$destroy()
delete this.cache[key]
}
}
},
}会根据
routes
中的变化,改变cache
的缓存- 在
render
函数中根据cache
的缓存渲染组件1
2
3
4
5
6
7
8
9
10
11
12
13if (this.cache[key]) {
if (vnode.key === this.cache[key].key) {
// restore vnode from cache
vnode.componentInstance = this.cache[key].componentInstance
} else {
// replace vnode to cache
this.cache[key].componentInstance.$destroy()
this.cache[key] = vnode
}
} else {
// cache new vnode
this.cache[key] = vnode
}
问题
关于路由版本号keyName
- 只有在前往的页面路径没有
keyName
并且不是刷新操作的情况下才会生成新的keyName
; - 页面是否读取缓存是由路径以及
genKey
的值来决定的 - 页面返回会清除上一个页面的缓存
- 刷新页面
keyName
的值不会发生改变,但是因为组件的缓存是由一个变量cacha
来实现的,所以依旧会触发created
方法
关于路由不设置name
属性路径没有keyName
参数的问题
不设置
name
页面依旧会缓存,只不过缓存的数据是:1
["/?undefined","/list?undefined"]
原因是在全局前置钩子
beforeEach
中调用next
函数的时候,用的是路由name
字段,如果没有该字段,设置的query
就无效,在afterEach
中就无法获取keyName
导致缓存为undefined
,此种情况下虽然缓存依旧有效,但是不太安全
其他
- 关于其他的地方,比如
replace
方法,navigation
提供的getRoutes
和cleanRoutes
因为跟主要功能关系不大,未做详细说明 navigation
在没有store
缓存的情况下会使用sessionStorage
作为缓存路径- 无论是
store
和sessionStorage
都没有对组件进行缓存,所以页面刷新必定会引起组件的重新加载