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 日期常用的方法
Nov 11 Javascript
js unicode 编码解析关于数据转换为中文的两种方法
Apr 21 Javascript
Jquery性能优化详解
May 15 Javascript
教你如何使用PHP输出中文JSON字符串
May 22 Javascript
JavaScript中神奇的call()方法
Mar 12 Javascript
kindeditor修复会替换script内容的问题
Apr 03 Javascript
简单的JS轮播图代码
Jul 18 Javascript
jquery ui sortable拖拽后保存位置
Apr 27 jQuery
vue中的自定义分页插件组件的示例
Aug 18 Javascript
Vue实现按钮级权限方案
Nov 21 Javascript
React.js组件实现拖拽排序组件功能过程解析
Apr 27 Javascript
vue3+typescript实现图片懒加载插件
Oct 26 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
PHP冒泡算法详解(递归实现)
2014/11/10 PHP
php实现数组中索引关联数据转换成json对象的方法
2015/07/08 PHP
PHP直接修改表内容DataGrid功能实现代码
2015/09/24 PHP
javascript XMLHttpRequest对象全面剖析
2010/04/24 Javascript
jquery 操作DOM案例代码分享
2012/04/05 Javascript
JavaScript之IE的fireEvent方法详细解析
2013/11/20 Javascript
jquery ajax跨域解决方法(json方式)
2014/02/04 Javascript
JavaScript动态修改背景颜色的方法
2015/04/16 Javascript
jQuery实现点击后标记当前菜单位置(背景高亮菜单)效果
2015/08/22 Javascript
js实现tab切换效果实例
2015/09/16 Javascript
Vue声明式渲染详解
2017/05/17 Javascript
vue-router单页面路由
2017/06/17 Javascript
基于angular-utils-ui-breadcrumbs使用心得(分享)
2017/11/03 Javascript
微信小程序左右滑动的实现代码
2017/12/15 Javascript
nodejs基于mssql模块连接sqlserver数据库的简单封装操作示例
2018/01/05 NodeJs
JS module的导出和导入的实现代码
2019/02/25 Javascript
JS字符串和数组如何实现相互转化
2020/07/02 Javascript
Vue element-ui父组件控制子组件的表单校验操作
2020/07/17 Javascript
Python 26进制计算实现方法
2015/05/28 Python
Django框架中render_to_response()函数的使用方法
2015/07/16 Python
python中执行shell的两种方法总结
2017/01/10 Python
pycharm中连接mysql数据库的步骤详解
2017/05/02 Python
对Python 中矩阵或者数组相减的法则详解
2019/08/26 Python
python对象转字典的两种实现方式示例
2019/11/07 Python
基于python实现学生信息管理系统
2019/11/22 Python
解决tensorflow由于未初始化变量而导致的错误问题
2020/01/06 Python
jupyter notebook 重装教程
2020/04/16 Python
使用anaconda安装pytorch的实现步骤
2020/09/03 Python
Python列表推导式实现代码实例
2020/09/09 Python
通信工程毕业生自荐信
2013/11/01 职场文书
高中自我鉴定范文
2013/11/03 职场文书
市场专员岗位职责
2014/02/14 职场文书
股份合作协议书
2014/09/10 职场文书
2014年科室工作总结
2014/11/20 职场文书
2014年司法所工作总结
2014/11/22 职场文书
酒店仓管员岗位职责
2015/04/01 职场文书