Vue + Elementui实现多标签页共存的方法


Posted in Javascript onJune 12, 2019

这个主题,早在一年前就已经创建,也写了一些内容,碍于在应用上体验始终不够完美,一直只存着草稿。

经过多个平台实践,多次迭代,一些功能加了又减了,最后还是回归了最精简的版本,已适用于大部分的场景,若有需要,可自行扩展。

关键逻辑

  • 使用 keep-alive 来缓存各标签页
  • 通过 vue-router 的 beforeEach 方法来更新标签信息
  • 通过 vuex 来保存标签信息
  • 通过 vuex 来使关闭页不被缓存

核心代码

定义 vuex 的跨页变量(store/index.js)

import Vuex from 'vuex'
 Vue.use(Vuex)
 export default new Vuex.Store({
  state: {
   worktab: {
    list: [
     {
      name: 'my',
      tabname: '主页',
      path: '/page/my'
     }
    ],
    current: {
     name: 'my',
     tabname: '主页',
     path: '/page/my'
    }
   },
   closingPage: ''
  },
  mutations: {
   worktabRemove (state, p) {
    // 关闭标签
    let ind = state.worktab.list.findIndex(s => s.name === p)
    if (ind > -1) {
     // 清理 keep alive - start
     state.closingPage = state.worktab.list[ind].name
     // 清理 keep alive - end
     state.worktab.list.splice(ind, 1)
    }
    if (p === state.worktab.current.name) {
     // 是当前页,返回上一页
     router.back()
    }
   },
   worktabRoute (state, p) {
    let ind = state.worktab.list.findIndex(s => s.name === p.to.name)
    if (ind > -1) {
     // 标签已存在
     state.worktab.current = state.worktab.list[ind]
    } else {
     // 标签不存在,现在新建
     state.worktab.list.push(p.to)
     state.worktab.current = p.to
    }
    state.closingPage = ''
   }
  },
  actions: {
   worktabRemove ({commit}, p) {
    commit('worktabRemove', p)
   },
   worktabRoute ({commit}, p) {
    commit('worktabRoute', p)
   }
  },
  strict: debug
 })

定义 worktab 标签栏组件,在主容器引用

<template>
  <div class="cp-worktab">
   <el-tabs v-model="activeTab" type="card" @tab-remove="removeTab" @tab-click="clickTab">
    <el-tab-pane
     v-for="t in worktabs"
     :key="t.name"
     :label="t.tabname"
     :name="t.name"
     :closable="t.name !== 'my'"
    >
    </el-tab-pane>
   </el-tabs>
  </div>
 </template>
 <script>
 export default {
  created () {
   // 进来不是主页时等list加载后再更新一次current
   setTimeout(() => {
    this.activeTab = this.$store.state.worktab.current.name
   }, 500)
  },
  watch: {
   '$store.state.worktab.current' (tab) {
    this.activeTab = tab.name
   }
  },
  computed: {
   worktabs () {
    return this.$store.state.worktab.list
   }
  },
  data () {
   return {
    activeTab: 'name'
   }
  },
  methods: {
   clickTab (tab) {
    this.$router.push(this.worktabs[1 * tab.index].path)
   },
   removeTab (name) {
    this.$store.dispatch('worktabRemove', name)
   }
  }
 }
 </script>

路由控制通过beforeEach来更新标签信息

import Vue from 'vue'
 import VueRouter from 'vue-router'
 import store from '@/store'
 import Page from '../components/console/Page.vue'
 import My from '../components/console/My.vue'
 Vue.use(VueRouter)
 // 关联路由与组件
 const routes = [
  {
   name: 'root',
   path: '/'
  },
  {
   path: '/page',
   component: Page,
   children: [
    {
     name: 'my',
     path: 'my',
     component: My,
     meta: {
      tabname: '个人主页'
     }
    }
   ]
  }
 ]
 // 创建路由器
 const router = new VueRouter({
  routes
 })
 router.beforeEach((to, from, next) => {
  next()
  store.dispatch('worktabRoute', {
   to: {
    name: to.name ? to.name : '',
    tabname: (to.meta && to.meta.tabname) ? to.meta.tabname : '',
    path: to.path
   },
   from: {
    name: from.name ? from.name : '',
    tabname: (from.meta && from.meta.tabname) ? from.meta.tabname : '',
    path: from.path
   }
  })
  return
 })
 export default router

主容器通过 closingPage 变量来及时清理关闭页面的缓存

<template>
  <div>
   <cp-worktab></cp-worktab>
   <div class="cp-content">
    <keep-alive :exclude="closingPage">
     <router-view></router-view>
    </keep-alive>
   </div>
  </div>
 </template>
 <script>
 import Worktab from '../module/Worktab'
 export default {
  components: {
   cpWorktab: Worktab
  },
  data () {
   return {}
  },
  computed: {
   closingPage () {
    return this.$store.state.closingPage
   }
  }
 }
 </script>

总结

以上所述是小编给大家介绍的Vue + Elementui实现多标签页共存的方法,希望对大家有所帮助,如果大家有任何疑问欢迎给我留言,小编会及时回复大家的!

Javascript 相关文章推荐
在JavaScript中监听IME键盘输入事件
May 29 Javascript
学习从实践开始之jQuery插件开发 对话框插件开发
Apr 26 Javascript
jquery配合css简单实现返回顶部效果
Sep 30 Javascript
JavaScript使用键盘输入控制实现数字验证功能
Aug 19 Javascript
基于vue.js实现侧边菜单栏
Mar 20 Javascript
Javascript实现登录记住用户名和密码功能
Mar 22 Javascript
详解基于webpack2.x的vue2.x的多页面站点
Aug 21 Javascript
Node.js中环境变量process.env的一些事详解
Oct 26 Javascript
vuex2中使用mapGetters/mapActions报错的解决方法
Oct 20 Javascript
vue使用原生js实现滚动页面跟踪导航高亮的示例代码
Oct 25 Javascript
JS开发常用工具函数(小结)
Jul 04 Javascript
node 解析图片二维码的内容代码实例
Sep 11 Javascript
JavaScript使用面向对象实现的拖拽功能详解
Jun 12 #Javascript
JS实现点击生成UUID的方法完整实例【基于jQuery】
Jun 12 #jQuery
小程序组件之自定义顶部导航实例
Jun 12 #Javascript
vue项目中将element-ui table表格写成组件的实现代码
Jun 12 #Javascript
React 全自动数据表格组件——BodeGrid的实现思路
Jun 12 #Javascript
详解如何提升JSON.stringify()的性能
Jun 12 #Javascript
基于vue-cli搭建多模块且各模块独立打包的项目
Jun 12 #Javascript
You might like
人工智能开始玩《星际争霸2》 你的操作跟得上吗?
2017/08/11 星际争霸
PHP控制网页过期时间的代码
2008/09/28 PHP
php curl常见错误:SSL错误、bool(false)
2011/12/28 PHP
php后台多用户权限组思路与实现程序代码分享
2012/02/13 PHP
PHP对表单提交特殊字符的过滤和处理方法汇总
2014/02/18 PHP
重新认识php array_merge函数
2014/08/31 PHP
php函数与传递参数实例分析
2014/11/15 PHP
Yii2中多表关联查询hasOne hasMany的方法
2017/02/15 PHP
JScript内置对象Array中元素的删除方法
2007/03/08 Javascript
JavaScript 编程引入命名空间的方法
2007/06/29 Javascript
一个JS翻页效果
2007/07/23 Javascript
Extjs入门之动态加载树代码
2010/04/09 Javascript
基于Jquery的温度计动画效果
2010/06/18 Javascript
jquery自动切换tabs选项卡的具体实现
2013/12/24 Javascript
js jquery ajax的几种用法总结(及优缺点介绍)
2014/01/28 Javascript
$.each与$().each的区别示例介绍
2014/03/20 Javascript
从零学JSON之JSON数据结构
2014/05/19 Javascript
微信小程序 时间格式化(util.formatTime(new Date))详解
2016/11/16 Javascript
vue2.0 element-ui中el-select选择器无法显示选中的内容(解决方法)
2018/08/24 Javascript
JS前端知识点 运算符优先级,URL编码与解码,String,Math,arguments操作整理总结
2019/06/27 Javascript
python sqlobject(mysql)中文乱码解决方法
2008/11/14 Python
python获取局域网占带宽最大3个ip的方法
2015/07/09 Python
Python多线程结合队列下载百度音乐的方法
2015/07/27 Python
pyenv命令管理多个Python版本
2017/03/26 Python
python中找出numpy array数组的最值及其索引方法
2018/04/17 Python
利用Python在一个文件的头部插入数据的实例
2018/05/02 Python
python MNIST手写识别数据调用API的方法
2018/08/08 Python
python  创建一个保留重复值的列表的补码
2018/10/15 Python
对Python3中列表乘以某一个数的示例详解
2019/07/20 Python
Python selenium页面加载慢超时的解决方案
2020/03/18 Python
Django model.py表单设置默认值允许为空的操作
2020/05/19 Python
英国皇家造币厂:The Royal Mint
2018/10/05 全球购物
销售主管竞聘书
2014/03/31 职场文书
2015年党员创先争优承诺书
2015/01/22 职场文书
销售会议开幕词
2016/03/04 职场文书
javascript中Set、Map、WeakSet、WeakMap区别
2022/12/24 Javascript