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编程起步(第五课)
Jan 10 Javascript
Javascript String.replace的妙用
Sep 08 Javascript
javascript中的prototype属性实例分析说明
Aug 09 Javascript
js鼠标悬浮出现遮罩层的方法
Jan 28 Javascript
JS全局变量和局部变量最新解析
Jun 24 Javascript
JS回调函数基本定义与用法实例分析
May 24 Javascript
10 种最常见的 Javascript 错误(频率最高)
Feb 08 Javascript
vue后台管理之动态加载路由的方法
Aug 13 Javascript
Javascript中parseInt的正确使用方式
Oct 17 Javascript
利用Webpack实现小程序多项目管理的方法
Feb 25 Javascript
优化Vue中date format的性能详解
Jan 13 Javascript
vue 使用v-for进行循环的实例代码详解
Feb 19 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扩展图文教程
2008/12/12 PHP
apache配置虚拟主机的方法详解
2013/06/17 PHP
关于PHP自动判断字符集并转码的详解
2013/06/26 PHP
php使用百度天气接口示例
2014/04/22 PHP
php操作xml入门之cdata区段
2015/01/23 PHP
54个提高PHP程序运行效率的方法
2015/07/19 PHP
php实现搜索类封装示例
2016/03/31 PHP
php array_udiff_assoc 计算两个数组的差集实例
2016/11/12 PHP
PHP框架laravel的.env文件配置教程
2017/06/07 PHP
PHP实现数组根据某个字段进行水平合并,横向合并案例分析
2019/10/08 PHP
laravel框架使用阿里云短信发送消息操作示例
2020/02/15 PHP
原生JS封装Ajax插件(同域、jsonp跨域)
2016/05/03 Javascript
详解微信小程序 页面跳转 传递参数
2016/12/08 Javascript
Bootstrap表单控件使用方法详解
2017/01/11 Javascript
easyui-datagrid开发实践(总结)
2017/08/02 Javascript
canvas轨迹回放功能实现
2017/12/20 Javascript
Vue打包后出现一些map文件的解决方法
2018/02/13 Javascript
ES6基础之展开语法(Spread syntax)
2019/02/21 Javascript
layer实现弹出层自动调节位置
2019/09/05 Javascript
jQuery实现验证用户登录
2019/12/10 jQuery
JavaScript中交换值的10种方法总结
2020/08/18 Javascript
Python科学计算环境推荐——Anaconda
2014/06/30 Python
Python压缩解压缩zip文件及破解zip文件密码的方法
2015/11/04 Python
python3实现UDP协议的服务器和客户端
2017/06/14 Python
python 设置输出图像的像素大小方法
2019/07/04 Python
Python3实现飞机大战游戏
2020/04/24 Python
python如何遍历指定路径下所有文件(按按照时间区间检索)
2020/09/14 Python
英国排名第一的礼品体验公司:Red Letter Days
2018/08/16 全球购物
What is EJB
2016/07/22 面试题
主题酒店策划书
2014/01/28 职场文书
员工试用期自我评价
2014/09/18 职场文书
2014年保卫科工作总结
2014/12/05 职场文书
2015年司法所工作总结
2015/04/27 职场文书
2015年小学教导处工作总结
2015/05/26 职场文书
小学信息技术教学反思
2016/02/16 职场文书
Pytest实现setup和teardown的详细使用详解
2021/04/17 Python