vue单页缓存方案分析及实现

2020-06-14 06:18:16易采站长站整理

方案二:navigation组件,scrollbehavior 

github上找到类似功能的组件vue-navigation,这个vue组件可以实现返回走缓存,底层原理跟keep-alive一样,实际上是改写了keep-alive组件,前进刷新时新增了一个参数VNK,这样在路由发生变化的时候都会用给url带一个参数,并且cache的key取值依赖这个参数,借鉴这个组件的思路,做了一个类似keep-alive的组件,其中key的值是getKey方法获取的,改写以后的render方法如下


render () {
var vnode = this.$slots.default ? this.$slots.default[0] : null
if (vnode) {
vnode.key = vnode.key || (vnode.isComment ? 'comment' : vnode.tag)
const { cache, keys } = this
var key = getKey(this.$route, keyName)
if (vnode.key.indexOf(key) === -1) {
vnode.key = '__navigation-' + key + '-' + vnode.key
}
if (cache[key]) {
if (vnode.key === cache[key].key) {
vnode.componentInstance = cache[key].componentInstance
} else {
cache[key].componentInstance.$destroy()
cache[key] = vnode
}
remove(keys, key)
keys.push(key)
} else {
cache[key] = vnode
keys.push(key)
// prune oldest entry
if (this.max && keys.length > parseInt(this.max)) {
pruneCacheEntry(cache, keys[0], keys, this._vnode)
}
}
vnode.data.keepAlive = true
}
return vnode
}

getKey方法实现


//url上新增参数vnk的值

export function genKey() {
// const t = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'
const t = 'xxxxxxxx'
return t.replace(/[xy]/g, function (c) {
const r = Math.random() * 16 | 0
const v = c === 'x' ? r : (r & 0x3 | 0x8)
return v.toString(16)
})
}
//
export function getKey(route, keyName) {
return `${route.name || route.path}?${route.query[keyName]}`
}

通过新写一个install方法挂载这个导航组件到vue上就可以实现前进刷新,返回走缓存,并且可以配置最大缓存数,后续开源到github

最后剩下返回上一页记住上一页的位置,之所以没有用开源的这个组件的记位置,是因为直接套用需要改整体布局,height:100%;样式造成$(windows).scrollTop失效,整体考虑改造成本较大,还是使用了vue-router提供的scrollBehavior,在路由配置里引入

实现如下:


var scrollBehavior = async (to, from, savedPosition) => {
if (savedPosition) {
return savedPosition
} else {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve({ x: 0, y: to.meta.savedPosition || 0 })
}, 300)
})
}
}
const router = new VueRouter({
mode: 'history',