vuex+ keep-alive搭建一套可缓存tab页的web框架
当你在用vue+element开发web端的多页签应用时,大部分是需要缓存的用keep-alive通过配置router.js的方案很好实现
原理
Vue 提供的 keep-alive API实现对路由组件的缓存。 include 属性可以绑定一个数组,里面是需要路由组件的 name 值,可以实现对该路由组件进行缓存,如果不需要对路由进行缓存,直接移除该项元素即可。
代码组织和设计
实现上面的功能,采用 vuex 进行全局的缓存数据保存,定义为 cacheView ;已经打开的路由页面用 toolBarData 进行保存。下图是代码是代码设计整体图:
需要添加一个路由页面到 cacheView ,需要有 actions setCacheView 来 commit 一个 change Event 对 state 数据进行更改,然后修改后的数据会自动派发到 App.vue 中使用到该数据的位置(即 keep-alive处)。而添加标签页也是类似的流程,不再描述。至于为什么要把标签页和路由缓存页面分离成两个数组,主要是有两方面的考虑:
主要是通过name的对比来确定是否需要缓存,当name不匹配是默认不缓存
入口文件缓存路由
在 App.vue 入口文件,使用 keep-alive 对匹配的路由组件进行缓存,监听当前路由变化,添加缓存路由和标签。
<template> <el-main> <!--渲染标签的地方--> <ToolBar></ToolBar> <div class="routeWrap"> <transition name="fade-transform"> <keep-alive :include="cachedViews"> <router-view></router-view> </keep-alive> </transition> </div> </el-main> </template> <script> export default { watch: { $route() { // 路由组件名称(自定义) const componentName =this.$route.matched[0]["components"]["default"][ "name"]; const detail = this.$route.path; // 当前路由匹配到name const name = this.$route.meta[0]["name"]; this.$store.dispatch("commitToolBar", { name, detail, componentName }); } } } </script>
关于store代码
store 代码实现如下所示,主要需要比较详细说明的是 clearToolItem ,这个函数是清除标签页。涉及两个规则:
如果关闭是当前处于激活的标签页,关闭之后。处于激活的标签页就默认是最后一个打开的标签页。
如果当前标签页是最后一个(处于激活状态),则关闭后自动默认它的前一个为默认激活标签页。
import router from '../router'export default {
state: {
toolBarData:[],// 保存标签button的数组
cacheView:[] // 保存需要缓存的数组
},
getters: {
getToolData(state){
return state.toolBarData;
},
getCacheView(state){
return state.cacheView;
}
},
mutations: {
setToolData(state, data) { // 添加标签按钮,如果当前路由已经打开,则不再重复添加
const inToolbar = state.toolBarData.find(item => item.detail === data.detail)
!inToolbar && state.toolBarData.push({
...data
});
},
setCacheView(state,data){ // 与setToolData类似
if(state.cacheView.includes(data.componentName))
return;
state.cacheView.push(data.componentName);
},
clearToolItem(state,detail){
const index = state.toolBarData.findIndex(item => item.detail === detail);
const isActive = router.app.$route.path == state.toolBarData[index]["detail"];
const len = state.toolBarData.length - 1;
state.toolBarData.splice(index,1);
(index == len || isActive) && router.push({path:state.toolBarData[state.toolBarData.length - 1]["detail"]});
},
clearCacheView(state,viewName){
const index = state.cacheView.findIndex(item => item == viewName);
state.cacheView.splice(index,1);
}
},
actions: {
commitToolBar({commit},data) {
commit("setToolData",data);
commit("setCacheView",data);
},
clearToolBar({commit},data){
commit("clearToolItem",data.detail);
},
clearCache({commit},data){
commit("clearCacheView",data);
}
}
}
生命周期 activated、deactivated
采用了 keep-alive 缓存的路由组件,重新进入该路由,路由组件不会重新创建,所以也就不会触发组件的生命周期函数(比如说 beforeCreate 、 mounted 等)。所以在对该页面进行数据更新或者清除数据。 vue 为我们提供了 activated 和 deactivated 生命周期函数,当重新进入路由组件会触发 activated 函数,离开则会触发 deactivated 。
<template><div> A page</div>
</template>
<script>
export default {
data(){
return {
form :{
name:'',
password:''
}
}
},
activated(){
this.getList()
},
deactivated(){
Object.keys(this.form).map(key => {
this.form[key] = ''
})
}
}
</script>
入口文件缓存路由App.vue
在 App.vue 入口文件,使用 keep-alive 对匹配的路由组件进行缓存,监听当前路由变化,添加缓存路由和标签。
<template><el-main>
<!--渲染标签的地方-->
<ToolBar></ToolBar>
<div class="routeWrap">
<transition name="fade-transform">
<keep-alive :include="cachedViews">
<router-view></router-view>
</keep-alive>
</transition>
</div>
</el-main>
</template>
<script>
export default {
watch: {
$route() {
// 路由组件名称(自定义)
const componentName =this.$route.matched[0]["components"]["default"][ "name"];
const detail = this.$route.path;
// 当前路由匹配到name
const name = this.$route.meta[0]["name"];
this.$store.dispatch("commitToolBar", { name, detail, componentName });
}
}
}
</script>
总结
以上所述就是vuex + keep-alive实现tab标签页面缓存问题,希望对大家有所帮助,如果大家有任何疑问请抛出问题。
想了解移动端应用的vuex+keep-alive缓存
以上是 vuex+ keep-alive搭建一套可缓存tab页的web框架 的全部内容, 来源链接: utcz.com/a/23127.html