Vue + Elementui实现多标签页共存的方法

 更新时间:2019年06月12日 14:41:47   作者:关鑫贤  
这篇文章主要介绍了Vue + Elementui实现多标签页共存的方法,本文通过实例代码给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下

这个主题,早在一年前就已经创建,也写了一些内容,碍于在应用上体验始终不够完美,一直只存着草稿。

经过多个平台实践,多次迭代,一些功能加了又减了,最后还是回归了最精简的版本,已适用于大部分的场景,若有需要,可自行扩展。

关键逻辑

  • 使用 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实现多标签页共存的方法,希望对大家有所帮助,如果大家有任何疑问欢迎给我留言,小编会及时回复大家的!

相关文章

  • vue3使用video.js播放m3u8格式视频的操作指南

    vue3使用video.js播放m3u8格式视频的操作指南

    有时候我们需要播放 m3u8 格式的视频,或者实现视频播放器更多定制化需求,HTML 的 video 元素无法实现这些需求,这时候可以考虑使用 Video.js,本文给大家介绍了vue3使用video.js播放m3u8格式视频的操作指南,需要的朋友可以参考下
    2024-07-07
  • Vue子父组件之间传值的三种方法示例

    Vue子父组件之间传值的三种方法示例

    Vue的组件化给前端开发带来极大的便利,下面这篇文章主要给大家介绍了关于Vue子父组件之间传值的三种方法,文中通过代码介绍的非常详细,需要的朋友可以参考下
    2024-02-02
  • vue插件tab选项卡使用小结

    vue插件tab选项卡使用小结

    这篇文章主要为大家详细介绍了vue插件tab选项卡的使用方法,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2016-10-10
  • 前端Vue select下拉框使用以及监听事件详解

    前端Vue select下拉框使用以及监听事件详解

    由于前端项目使用的是Vue.js和bootstrap整合开发,中间用到了select下拉框,这篇文章主要给大家介绍了关于前端Vue select下拉框使用以及监听事件的相关资料,需要的朋友可以参考下
    2024-03-03
  • Vue3.0版本强势升级点特性详解

    Vue3.0版本强势升级点特性详解

    这篇文章主要介绍了Vue3.0版本强势升级点特性详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪<BR>
    2022-06-06
  • Vue手机号正则匹配姓名加密展示功能的实现

    Vue手机号正则匹配姓名加密展示功能的实现

    这篇文章主要介绍了Vue手机号正则匹配,姓名加密展示,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-08-08
  • vue中的input框点击后不聚焦问题

    vue中的input框点击后不聚焦问题

    这篇文章主要介绍了vue中的input框点击后不聚焦问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-04-04
  • vue循环el-button实现点击哪个按钮,那个按钮就变色

    vue循环el-button实现点击哪个按钮,那个按钮就变色

    这篇文章主要介绍了vue循环el-button实现点击哪个按钮,那个按钮就变色问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-10-10
  • vue前端获取不同客户端mac地址最详细步骤(避免踩坑)

    vue前端获取不同客户端mac地址最详细步骤(避免踩坑)

    在开发过程中,绑定账号和电脑的功能可以通过获取电脑的MAC地址实现,下面这篇文章主要介绍了vue前端获取不同客户端mac地址的相关资料,文中通过代码介绍的非常详细,需要的朋友可以参考下
    2024-10-10
  • vue如何动态修改meta的title

    vue如何动态修改meta的title

    这篇文章主要介绍了vue如何动态修改meta的title,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-06-06

最新评论