威尔和格蕾丝第一季,闪点帝王水行侠,拆弹英雄在线观看
写在前面
一个web app的实际使用场景中,有一些情景的交互要求,是记录用户的浏览状态的。最常见的就是在列表页进入详情页之后,再返回到列表页,用户希望返回到进入详情页之前的状态继续操作。但是有些使用场景,用户又是希望能够获取最新的数据,例如同级列表页之间切换的时候。
如此,针对上述两种使用场景,需要实现按需读取页面缓存。由于spa应用的路由逻辑也是在前端实现的,因此可以在前端对路由的逻辑进行设置以实现所需效果。
使用技术
总体思路
keep-alive判断当前组件是否读取缓存的节点,在整个生命周期里面非常靠后,在aftereach之后,基本在组件实例创建之前。(因此在此之前对当前组件是否读取缓存进行处理都是可行的,我选择在全局前置守卫进行处理)
而判断当前组件是否缓存的节点,则早于组件的beforerouteleave钩子。
基于上述逻辑,本方案解决的逻辑是,对当前打开的页面进行判断,动态生成需要keepalive的组件数组配置,对有可能需要缓存的先行进行缓存,然后在每次路由切换的时候,再进行判断,按需读取页面缓存。
具体实现
1. 使用include属性控制路由缓存
但是vue-router的环境下,是没有局部注册名称的,只能为组件补全name属性。
因此,请务必给组件添加 name 选项,否则匿名组件将全部应用缓存。
<keep-alive :include="$store.state.cachedroutenames"> <router-view /> </keep-alive>
2. 添加全局路由缓存配置
// store/index.js const store = new vuex.store({ state: { // 缓存的路由列表 cachedroutenames: [], }, mutations: { update_cachedroutenames(state,{ action, route }) { const methods = { 'add': () => { state.cachedroutenames.push(route) }, 'delete': () => { state.cachedroutenames.splice(state.cachedroutenames.findindex((e) => { return e === route}),1) } } methods[action]() } } })
3. 配置路由元信息,对需要缓存的路由进行配置
keepalive表明路由需要被缓存,必须,否则不缓存
cachewhenfromroutes为数组,非必须,若为falsy值,则任何时候均缓存;若为空数组,则任何时候均不缓存
// router/index.js { path: '/productslist', name: 'productslist', component: productslist, meta: { keepalive: true, cachewhenfromroutes: ['productdetail'] // 此处配置的是路由的name } },
4. 配置全局前置守卫,按需读取缓存
// routecontrol.js // 需要缓存的路由名称数组 const cachedroutenames = store.state.cachedroutenames; // 定义添加缓存组件name函数,设置的是组件的name const addroutes = (route) => { const routename = route.components.default.name if (routename && cachedroutenames.indexof(routename) === -1) { store.commit('update_cachedroutenames', { action: 'add', route: routename }) } } // 定义删除缓存组件name函数,设置的是组件的name const deleteroutes = (route) => { const routename = route.components.default.name if (routename && cachedroutenames.indexof(routename) !== -1) { store.commit('update_cachedroutenames', { action: 'delete', route: routename }) } } router.beforeeach((to, from, next) => { // 处理缓存路由开始 // 在读取缓存之前,先对该组件是否读取缓存进行处理 to.matched.foreach((item, index) => { const routes = item.meta.cachewhenfromroutes; /** * 此处有几种情况 * 1. 没有配置cachewhenfromroutes, 则一直缓存; * 2. 配置了cachewhenfromroutes,但是首次打开此web app,则from.name为空,此时应该将该页面组件的name添加到缓存配置文件中 * 3. 配置了cachewhenfromroutes,from.name不为空,若命中cachewhenfromroutes,则添加该页面组件的name到缓存配置文件中,否则删除。 * **/ if (item.meta.keepalive && (!routes || (routes && (!from.name || routes.indexof(from.name) !== -1)))) { addroutes(item) } else { deleteroutes(item) } }) // 处理缓存路由结束 new promise(( resolve, reject ) => { // ..other codes }).then( res => { if ( res ) { next(res) } else { next() } }) }) // 全局混入。此步骤的目的是在该组件被解析之后,若是属于需要缓存的组件,先将其添加到缓存配置中,进行缓存。 // 导航守卫的最后一个步骤就是调用 beforerouteenter 守卫中传给 next 的回调函数,此时整个组件已经被解析,dom也已经更新。 vue.mixin({ beforerouteenter(to, from, next) { next(vm => { to.matched.foreach((item) => { const routename = item.components.default.name if (to.meta.keepalive && routename && cachedroutenames.indexof(routename) === -1) { store.commit('update_cachedroutenames', { action: 'add', route: routename }) } }) }) }, })
写在最后
坑点
以上是实践过程中摸索出来的一种解决方案,我相信存在更加优雅高效的解决方式。如果你正好实践过相关方法,烦请指正,谢谢。
更多参考
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对移动技术网的支持。
如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复
VUE+elementui组件在table-cell单元格中绘制微型echarts图
Vue通过getAction的finally来最大程度避免影响主数据呈现问题
vue 路由懒加载中给 Webpack Chunks 命名的方法
网友评论