vuex + keep-alive实现tab标签页面缓存功能


Posted in Javascript onOctober 17, 2019

在开发很多管理系统过程之中,常遇到这种需求,需要对打开路由页面进行缓存,然后在系统页眉提供方便查阅的tab标签进行切换以及对已经缓存页面进行数据刷新和清除数据操作。具体演示如下图所示:

vuex + keep-alive实现tab标签页面缓存功能 

在上面演示中实现了类似 window tab 标签页效果,会对当前数据进行缓存。在浏览器中实现对路由页面的缓存可以减少接口请求,也方便了用户来回切换想搜索的数据列表。

原理

Vue 提供的 keep-alive API实现对路由组件的缓存。 include 属性可以绑定一个数组,里面是需要路由组件的 name 值,可以实现对该路由组件进行缓存,如果不需要对路由进行缓存,直接移除该项元素即可。

vuex + keep-alive实现tab标签页面缓存功能 

代码组织和设计

实现上面的功能,采用 vuex 进行全局的缓存数据保存,定义为 cacheView ;已经打开的路由页面用 toolBarData 进行保存。下图是代码是代码设计整体图:

vuex + keep-alive实现tab标签页面缓存功能 

需要添加一个路由页面到 cacheView ,需要有 actions setCacheView 来 commit 一个 change Event 对 state 数据进行更改,然后修改后的数据会自动派发到 App.vue 中使用到该数据的位置(即 keep-alive
处)。而添加标签页也是类似的流程,不再描述。至于为什么要把标签页和路由缓存页面分离成两个数组,主要是有两方面的考虑:

name

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);
    }
  }
}

入口文件缓存路由

在 App.vue 入口文件,使用 keep-alive 对匹配的路由组件进行缓存,监听当前路由变化,添加缓存路由和标签。

<template>
  <el-main style="position:relative;margin-top:45px;">
    <!--渲染标签的地方-->
    <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>

ToolBar代码

这里使用了 elementui 的 el-tag 标签, el-tag 标签带有动画、关闭按钮、主题color等属性, close 函数是清除该标签和清除缓存路由(已访问过)。 click 主要是当对该标签项点击操作,则切换到该路由页面。其中 active 是该标签匹配到当前路由时候处于激活状态(颜色高亮), el-tag 的动画比较生硬,所以关闭了。

<template>
 <div class="toolbar">
  <el-tag
   class="toolItem"
   type="info"
   :disable-transitions="false"
   :closable="item.id != 0"
   effect="plain"
   v-for="(item,index) in getToolData"
   :key="index"
   :class="{active:$route.path == item.detail}"
   @click="redirect(item)"
   @close="closeToolItem(item)"
  >
   <span class="dot" v-if="$route.path == item.detail"></span>
   {{item.name}}
  </el-tag>
 </div>
</template>

<script>
import { mapGetters } from "vuex";
export default {
 methods: {
  closeToolItem(item, index) {
   this.$store.dispatch("clearToolBar", item);
   this.$store.dispatch("clearCache", item.componentName);
  },
  redirect(item) {
   this.$router.push({ path: item.detail });
  }
 },
 computed: {
  ...mapGetters(["getToolData", "getCacheView"])
 }
};
</script>

生命周期 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>

总结

以上所述是小编给大家介绍的vuex + keep-alive实现tab标签页面缓存问题,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!
如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!

Javascript 相关文章推荐
web 页面分页打印的实现
Jun 22 Javascript
jQuery制作效果超棒的手风琴折叠菜单
Apr 03 Javascript
使用node+vue.js实现SPA应用
Jan 28 Javascript
微信小程序 页面传参实例详解
Nov 16 Javascript
原生JS获取元素集合的子元素宽度实例
Dec 14 Javascript
JavaScript数据类型和变量_动力节点Java学院整理
Jun 26 Javascript
vue登录注册及token验证实现代码
Dec 14 Javascript
layui导出所有数据的例子
Sep 10 Javascript
vue中使用element ui的弹窗与echarts之间的问题详解
Oct 25 Javascript
JQuery通过键盘控制键盘按下与松开触发事件
Aug 07 jQuery
vue video和vue-video-player实现视频铺满教程
Oct 30 Javascript
jquery实现加载更多&quot;转圈圈&quot;效果(示例代码)
Nov 09 jQuery
Weex开发之地图篇的具体使用
Oct 16 #Javascript
WEEX环境搭建与入门详解
Oct 16 #Javascript
Weex开发之WEEX-EROS开发踩坑(小结)
Oct 16 #Javascript
适合前端Vue开发童鞋的跨平台Weex的使用详解
Oct 16 #Javascript
微信公众号开发之微信支付代码记录的实现
Oct 16 #Javascript
关于JS模块化的知识点分享
Oct 16 #Javascript
vue-cli+iview项目打包上线之后图标不显示问题及解决方法
Oct 16 #Javascript
You might like
10个实用的PHP代码片段
2011/09/02 PHP
php中防止伪造跨站请求的小招式
2011/09/02 PHP
php使用正则表达式提取字符串中尖括号、小括号、中括号、大括号中的字符串
2020/04/05 PHP
PHP和MySql中32位和64位的整形范围是多少
2016/02/18 PHP
php swoole多进程/多线程用法示例【基于php7nts版】
2019/08/12 PHP
Code:loadScript( )加载js的功能函数
2007/02/02 Javascript
js字符编码函数区别分析
2011/12/28 Javascript
从数据结构的角度分析 for each in 比 for in 快的多
2013/07/07 Javascript
js形成页面的一种遮罩效果实例代码
2014/01/04 Javascript
Jquery获得控件值的三种方法总结
2014/02/13 Javascript
js浏览器本地存储store.js介绍及应用
2014/05/13 Javascript
JS+CSS实现自动改变切换方向图片幻灯切换效果的方法
2015/03/02 Javascript
实例代码详解jquery.slides.js
2015/11/16 Javascript
jquery判断复选框选中状态以及区分attr和prop
2015/12/18 Javascript
javascript中apply、call和bind的使用区别
2016/04/05 Javascript
jQuery插件dataTables添加序号列的方法
2016/07/06 Javascript
JS解决iframe之间通信和自适应高度的问题
2016/08/24 Javascript
Jquery Easyui对话框组件Dialog使用详解(14)
2016/12/19 Javascript
关于vue.extend和vue.component的区别浅析
2017/08/16 Javascript
VUE table表格动态添加一列数据,新增的这些数据不可以编辑(v-model绑定的数据不能实时更新)
2020/04/03 Javascript
[01:51]开启你的城市传奇 完美世界城市挑战赛开始报名
2018/10/09 DOTA
python抽象基类用法实例分析
2015/06/04 Python
Python发送http请求解析返回json的实例
2018/03/26 Python
pandas分别写入excel的不同sheet方法
2018/12/11 Python
TensorFlow 输出checkpoint 中的变量名与变量值方式
2020/02/11 Python
python字符串,元组,列表,字典互转代码实例详解
2020/02/14 Python
Python pip install如何修改默认下载路径
2020/04/29 Python
Python简单实现词云图代码及步骤解析
2020/06/04 Python
keras绘制acc和loss曲线图实例
2020/06/15 Python
python打包多类型文件的操作方法
2020/09/21 Python
Johnston & Murphy官网: 约翰斯顿·墨菲牛津总统鞋
2018/01/09 全球购物
党员承诺书格式范文
2015/04/28 职场文书
大学生干部培训心得体会
2016/01/06 职场文书
辞职信怎么写?你都知道吗?
2019/06/24 职场文书
CSS3实现模糊背景的三种效果示例
2021/03/30 HTML / CSS
MySQL为数据表建立索引的原则详解
2022/03/03 MySQL