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 showModalDialog 内跳转页面的问题
Nov 25 Javascript
JavaScript高级程序设计(第3版)学习笔记12 js正则表达式
Oct 11 Javascript
jquery中插件实现自动添加用户的具体代码
Nov 15 Javascript
浅谈JavaScript字符串拼接
Jun 25 Javascript
jquery跟随屏幕滚动效果的实现代码
Apr 13 Javascript
javascript实现的左右无缝滚动效果
Sep 19 Javascript
Bootstrap3 内联单选和多选框
Dec 29 Javascript
理解javascript中的Function.prototype.bind的方法
Feb 03 Javascript
Mint UI 基于 Vue.js 移动端组件库
Nov 07 Javascript
vue debug 二种方法
Sep 16 Javascript
pageGroup.js实现分页功能
Jul 27 Javascript
vue结合el-upload实现腾讯云视频上传功能
Jul 01 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
萌王史莱姆”萌王性别尴尬!那“萌战”归女组还是男?
2018/12/17 日漫
Terran热键控制
2020/03/14 星际争霸
5种PHP创建数组的实例代码分享
2014/01/17 PHP
PHP实现单文件、多个单文件、多文件上传函数的封装示例
2019/09/02 PHP
Code:loadScript( )加载js的功能函数
2007/02/02 Javascript
js 禁用浏览器的后退功能的简单方法
2008/12/10 Javascript
深入了解javascript中的prototype与继承
2013/04/14 Javascript
jQuery实现HTML5 placeholder效果实例
2014/12/09 Javascript
js的回调函数详解
2015/01/05 Javascript
jQuery中live()方法用法实例
2015/01/19 Javascript
理解JavaScript的变量的入门教程
2015/07/07 Javascript
javascript实现别踩白块儿小游戏程序
2015/11/22 Javascript
js实现图片无缝滚动特效
2020/03/19 Javascript
全面解析Bootstrap中tooltip、popover的使用方法
2016/06/13 Javascript
JS+CSS3模拟溢出滚动效果
2016/08/12 Javascript
AngularJs Understanding the Model Component
2016/09/02 Javascript
前端实现文件的断点续传(前端文件提交+后端PHP文件接收)
2016/11/04 Javascript
TableSort.js表格排序插件使用方法详解
2017/02/10 Javascript
jQuery中的on与bind绑定事件区别实例详解
2017/02/28 Javascript
关于angular js_$watch监控属性和对象详解
2017/04/24 Javascript
微信小程序 页面跳转事件绑定的实例详解
2017/09/20 Javascript
基于vue2.0动态组件及render详解
2018/03/17 Javascript
微信小程序以7天为周期连续签到7天功能效果的示例代码
2020/08/20 Javascript
[51:32]Optic vs Serenity 2018国际邀请赛淘汰赛BO3 第一场 8.22
2018/08/23 DOTA
Python实现批量读取word中表格信息的方法
2015/07/30 Python
python实现list元素按关键字相加减的方法示例
2017/06/09 Python
Python退火算法在高次方程的应用
2018/07/26 Python
TensorFlow 合并/连接数组的方法
2018/07/27 Python
使用python实现kNN分类算法
2019/10/16 Python
详解基于python的图像Gabor变换及特征提取
2020/10/26 Python
科沃斯机器人官网商城:Ecovacs
2016/08/29 全球购物
C#里面可以避免一个类被其他类继承么?如何?
2013/09/26 面试题
网页美工求职信
2014/02/15 职场文书
医药营销个人求职信
2014/04/12 职场文书
大学生职业生涯规划大赛作品(精品)
2014/09/17 职场文书
工作经历证明书范文
2014/11/02 职场文书