创建文件

import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

// 应用初始状态
const state = () => ({
  options: [],
  activeIndex: '/',
  includePage: [],
})

// getters
const getters = {

}

// actions
const actions = {

}

// mutations
const mutations = {
  // 添加tabs
  addTabs (state, data) {
    state.options.push(data)
    state.activeIndex = data.href
    const reg = /\/(\w+)$/
    const match = reg.exec(data.href)
    match[1] ? state.includePage.push(match[1]) : ''
  },

  // 删除tabs
  deleteTabs (state, path) {
    const index = state.options.findIndex(item => item.href === path);
    state.options.splice(index, 1)
    state.includePage.splice(index, 1)
    const href = state.options.at(-1).href
    state.activeIndex = href
    router.push(href)
  },

  // 设置当前激活的tab
  setActiveIndex (state, index) {
    if (state.activeIndex === index) return
    state.activeIndex = index
    router.push(index)
  },

  //初始化添加tabs
  initTabs (state) {
    state.options = []
    state.activeIndex = '/'
    state.includePage = []
  },

  //刷新页面
  getRefreshTabs (state) {
    const obj = { href: '/Main', title: '主页' }
    state.options.push(obj)
    state.includePage.push('Main')
    state.activeIndex = '/Main'
    router.push('/Main')
  },
}

// 创建 store 实例
export default new Vuex.Store({
    state,
    mutations
})

首页代码

<el-tabs :value="activeIndex"
         type="card"
         closable
         @tab-click="tabClick"
         @tab-remove="tabRemove">
  <el-tab-pane v-for="item in options"
               :key="item.href"
               :label="item.title"
               :name="item.href">
  </el-tab-pane>
</el-tabs>

 <!-- 这里是会被缓存的视图组件 -->
<keep-alive :include="includePage">
  router-view></router-view>
</keep-alive>

动态渲染逻辑

methods: {
  ...mapMutations('tabs', ['addTabs', 'deleteTabs', 'setActiveIndex', 'initTabs',]),
    //选中的菜单项
    handleSelect (path, keyPath) {
      console.log(path, keyPath)
      const isHref = this.options.some(item => item.href === path)
      const data = this.menus.find(item => item.href === path)
      this.$router.push(data.href)
      isHref ? this.setActiveIndex(path) : this.addTabs(data)
    },

    // tab切换时,动态的切换路由
    tabClick (tab) {
      this.setActiveIndex(tab.name)
    },

    tabRemove (tab) {
      // 首页不可删除
      if (tab === '/Main') return
      this.deleteTabs(tab)
    },

},

 // 计算路由缓存
computed: {
    ...mapState('tabs', ['options', 'includePage', 'activeIndex']),
    
},

  // 监听路由
watch: {
    '$route' (to) {
      let { name, path } = to
      const isHref = this.options.some(item => item.href === path)
      let data = { title: name, href: path }
      isHref ? this.setActiveIndex(path) : this.addTabs(data)
    }
}

//初始化路由
created () {
  this.initTabs()
},
  

路由配置

const router = new VueRouter({
    routes = [
    	{
        path: '/',
        component: Home,
        name: '导航一',
        iconCls: 'el-icon-message',//图标样式class
        children: [
            { path: '/main', component: Main, name: '主页', hidden: true },
            { path: '/table', component: Table, name: 'Table', meta: { keepAlive: false} },
            { path: '/form', component: Form, name: 'Form', meta: { keepAlive: true}  },
            { path: '/user', component: user, name: '列表' },
        	]
    	}
	]
})
Last Updated:
Contributors: pengrengui