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使用过程中需要注意的地方和一些基本语法
Aug 26 Javascript
js星星评分效果
Jul 24 Javascript
轻松学习Javascript闭包函数
Dec 15 Javascript
Bootstrap学习笔记之css样式设计(1)
Jun 07 Javascript
AngularJS表格详解及示例代码
Aug 17 Javascript
require.js+vue开发微信上传图片组件
Oct 27 Javascript
jQuery的ajax中使用FormData实现页面无刷新上传功能
Jan 16 Javascript
jQuery DateTimePicker 日期和时间插件示例
Jan 22 Javascript
Angular4 组件通讯方法大全(推荐)
Jul 12 Javascript
bootstrap tooltips在 angularJS中的使用方法
Apr 10 Javascript
微信小程序以ssm做后台开发的实现示例
Apr 08 Javascript
react antd表格中渲染一张或多张图片的实例
Oct 28 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简单构造json多维数组的方法示例
2017/06/08 PHP
jquery中的sortable排序之后的保存状态的解决方法
2010/01/28 Javascript
extjs 04_grid 单击事件新发现
2012/11/27 Javascript
你必须知道的Javascript知识点之&quot;深入理解作用域链&quot;的介绍
2013/04/23 Javascript
jQuery使用addClass()方法给元素添加多个class样式
2015/03/26 Javascript
深入php面向对象、模式与实践
2016/02/16 Javascript
BootStrap下jQuery自动完成的样式调整
2016/05/30 Javascript
炫酷的js手风琴效果
2016/10/13 Javascript
JavaScript BASE64算法实现(完美解决中文乱码)
2017/01/10 Javascript
微信小程序实现自定义picker选择器弹窗内容
2020/05/26 Javascript
[00:43]FTP典藏礼包 DOTA2三大英雄霸气新套装
2014/03/21 DOTA
[58:25]VP vs RNG 2019国际邀请赛小组赛 BO2 第一场 8.15
2019/08/17 DOTA
python实现猜数字游戏(无重复数字)示例分享
2014/03/29 Python
python中使用xlrd读excel使用xlwt写excel的实例代码
2018/01/31 Python
Python Flask前后端Ajax交互的方法示例
2018/07/31 Python
Python爬虫小技巧之伪造随机的User-Agent
2018/09/13 Python
Python之两种模式的生产者消费者模型详解
2018/10/26 Python
Python语法之精妙的十个知识点(装B语法)
2020/01/18 Python
python集合能干吗
2020/07/19 Python
Python Opencv实现单目标检测的示例代码
2020/09/08 Python
详解HTML5中download属性的应用
2015/08/06 HTML / CSS
自我评价是什么
2014/01/04 职场文书
周年庆典主持词
2014/04/02 职场文书
巾帼文明岗申报材料
2014/05/01 职场文书
中华在我心中演讲稿
2014/09/13 职场文书
2014年国庆节庆祝建国65周年比赛演讲稿
2014/09/21 职场文书
小学三八妇女节活动总结
2015/02/06 职场文书
教师个人发展总结
2015/02/11 职场文书
敬老院义诊活动总结
2015/05/07 职场文书
党员转正党支部意见
2015/06/02 职场文书
摘录式读书笔记
2015/07/01 职场文书
大学校园招聘会感想
2015/08/10 职场文书
关于环保的广播稿
2015/12/17 职场文书
《童年》读后感(三篇)
2019/08/27 职场文书
MySQL 使用事件(Events)完成计划任务
2021/05/24 MySQL
python scrapy简单模拟登录的代码分析
2021/07/21 Python