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 相关文章推荐
一个可以随意添加多个序列的tag函数
Jul 21 Javascript
JavaScript CSS修改学习第五章 给“上传”添加样式
Feb 19 Javascript
jquery等待效果示例
May 01 Javascript
简单易用的倒计时js代码
Aug 04 Javascript
node.js中的fs.link方法使用说明
Dec 15 Javascript
canvas实现手机端用来上传用户头像的代码
Oct 20 Javascript
JS实现移动端判断上拉和下滑功能
Aug 07 Javascript
Bootstrap 模态框自定义点击和关闭事件详解
Aug 10 Javascript
使用layui 渲染table数据表格的实例代码
Aug 19 Javascript
Layui数据表格之获取表格中所有的数据方法
Aug 20 Javascript
js根据json数据中的某一个属性来给数据分组的方法
Oct 08 Javascript
微信小程序加载机制及运行机制图解
Nov 27 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
第十节 抽象方法和抽象类 [10]
2006/10/09 PHP
那些年我们错过的魔术方法(Magic Methods)
2014/01/14 PHP
php实现批量下载百度云盘文件例子分享
2014/04/10 PHP
PHP使用ob_start生成html页面的方法
2014/11/07 PHP
php恢复数组的key为数字序列的方法
2015/04/28 PHP
PHP中的命名空间详细介绍
2015/07/02 PHP
PHP转换文本框内容为HTML格式的方法
2016/07/20 PHP
PHP生成唯一ID之SnowFlake算法
2016/12/17 PHP
网页和浏览器兼容性问题汇总(draft1)
2009/06/01 Javascript
js控制frameSet示例
2013/09/10 Javascript
jQuery中(function($){})(jQuery)详解
2015/07/15 Javascript
谈谈基于iframe、FormData、FileReader三种无刷新上传文件的方法
2015/12/03 Javascript
JavaScript的MVVM库Vue.js入门学习笔记
2016/05/03 Javascript
基于JQuery的$.ajax方法进行异步请求导致页面闪烁的解决办法
2016/05/10 Javascript
AngularJS报错$apply already in progress的解决方法分析
2017/01/30 Javascript
浅谈vue-lazyload实现的详细过程
2017/08/22 Javascript
js 倒计时(高效率服务器时间同步)
2017/09/12 Javascript
JavaScript中Require调用js的实例分享
2017/10/27 Javascript
mint-ui在vue中的使用示例
2018/04/05 Javascript
使用webpack4编译并压缩ES6代码的方法示例
2019/04/24 Javascript
微信小程序生成海报分享朋友圈的实现方法
2019/05/06 Javascript
element-ui 中使用upload多文件上传只请求一次接口
2019/07/19 Javascript
linux环境下安装pyramid和新建项目的步骤
2013/11/27 Python
基于DATAFRAME中元素的读取与修改方法
2018/06/08 Python
解决csv.writer写入文件有多余的空行问题
2018/07/06 Python
使用tensorflow DataSet实现高效加载变长文本输入
2020/01/20 Python
浅谈tensorflow之内存暴涨问题
2020/02/05 Python
python通用数据库操作工具 pydbclib的使用简介
2020/12/21 Python
ProBikeKit美国官网:自行车套件,跑步和铁人三项套件
2016/10/13 全球购物
世界首屈一指的在线男士内衣权威:HisRoom
2017/08/05 全球购物
本科生就业推荐信
2014/05/19 职场文书
商业项目策划方案
2014/06/05 职场文书
松材线虫病防治方案
2014/06/15 职场文书
感情真挚的毕业生求职信
2014/07/19 职场文书
财政局党的群众路线教育实践活动整改方案
2014/09/21 职场文书
sql注入报错之注入原理实例解析
2022/06/10 MySQL