vue2 实现后台管理系统左侧菜单联动实现 tab根据路由切换联动内容

效果图:

话不多说上代码

一、vue页面

home页代码

<template>
  <div>
    <el-container>
      <el-aside width="collapse ? 200px : 35px">
        <el-menu
          :collapse="collapse"
          :default-active="this.$store.state.title"
          class="el-menu-vertical-demo"
          unique-opened
          active-text-color="#ffd04b"
          text-color="#fff"
          background-color="transparent"
          @select="hh"
        >
          <el-button @click="collapseToggle" style="margin-top: 10px; margin-bottom: 10px">
            <i class="el-icon-s-unfold" v-if="collapse" />
            <i class="el-icon-s-fold" v-else />
          </el-button>
          <leftMenu :dataToSon="this.$store.state.tree" />
        </el-menu>
      </el-aside>
      <el-container>
        <el-header class="header">Header</el-header>
        <el-main>
          <multipleTabs></multipleTabs>
        </el-main>
        <el-footer>Footer</el-footer>
      </el-container>
    </el-container>
  </div>
</template>

<script>
import leftMenu from '@/views/home/leftMenu'
import multipleTabs from '@/views/home/multipleTabs'

export default {
  // eslint-disable-next-line vue/multi-word-component-names
  name: 'home',
  components: {
    leftMenu,
    multipleTabs
  },
  data () {
    return {
      collapse: false
    }
  },
  mounted () {
  },
  methods: {
    hh (e) {
      this.$store.commit('tab', e)
    },
    collapseToggle () {
      this.collapse = !this.collapse
    }
  }
}
</script>

<style scoped>
.el-header, .el-footer {
  background: url("../../../src/assets/111.jpg");
  color: #333;
  text-align: center;
}

.el-aside {
  text-align: center;
}

.el-main {
  color: #333;
  text-align: center;
}

.el-menu-vertical-demo:not(.el-menu--collapse) {
  min-width: 200px;
  height: 100vh;
}

>>> .el-menu--collapse .menu {
  display: none;
}
>>> .el-menu--collapse .el-submenu__icon-arrow {
  display: none;
}
span {
  display: none;
}

.el-menu-vertical-demo {
  background: url("../../../src/assets/111.jpg");
  height: 100vh;
  border-right: 0;
}
</style>

 leftMenu.vue代码

<template>
  <div>
    <fragment v-for="(item, index) in list" :key="index">
      <!-- 非叶子节点 -->
      <el-submenu v-if="item.children" :index="item.path">
        <template slot="title">
          <i class="el-icon-location"></i>
          <span class="menu" slot="title">{{ item.name }}</span>
        </template>
        <left-menu :dataToSon="item.children"></left-menu>
      </el-submenu>
      <!-- 叶子节点(功能节点) -->
      <el-menu-item v-else :index="item.path">
        <i class="el-icon-menu"></i>
        <span class="menu" slot="title">{{ item.name }}</span>
      </el-menu-item>
    </fragment>
  </div>
</template>

<script>
import leftMenu from '../../../src/views/home/leftMenu.vue'

export default {
  // eslint-disable-next-line vue/multi-word-component-names
  name: 'leftMenu',
  components: {
    leftMenu
  },
  props: ['dataToSon'],
  data () {
    return {
      isCollapse: false,
      list: []
    }
  },
  mounted () {
    this.list = this.dataToSon
  },
  methods: {
    handleOpen (key, keyPath) {
      console.log(key, keyPath)
    },
    handleClose (key, keyPath) {
      console.log(key, keyPath)
    }
  }
}
</script>

<style scoped>

</style>
multipleTabs.vue代码
<template>
  <div>
    <el-tabs v-model="activeTab" type="card" closable @tab-remove="rem">
      <el-tab-pane
        v-for="item in this.$store.state.tabOne"
        :key="item.id"
        :label="item.name"
        :name="item.path"
      >
        <router-view :name="item.path" v-slot="{Component}">
          <keep-alive>
            <component :is="Component"></component>
          </keep-alive>
        </router-view>
      </el-tab-pane>
    </el-tabs>
  </div>
</template>

<script>
import { mapState, mapMutations } from 'vuex'
export default {
  name: 'MultipleTabs',
  computed: {
    ...mapState({
      vuexActiveTab: 'title'
    }),
    activeTab: {
      get () {
        return this.vuexActiveTab
      },
      set (newValue) {
        this.handleTabChange(newValue)
      }
    }
  },
  data () {
    return {
      editableTabsValue: this.$store.state.title
    }
  },
  mounted () {
    console.log(this.$store.state.title)
  },
  methods: {
    ...mapMutations(['SET_ACTIVE_TAB']),
    handleTabChange (tab) {
      this.SET_ACTIVE_TAB(tab)
    },
    rem (e) {
      this.$store.commit('remove', e)
    }
  }
}
</script>

<style scoped>

</style>

在写vuex代码前先安装一个vuex数据状态持久化-vuex-persistedstate插件来实现刷新页面数据还存在

我这里是直接用的总仓库来写的

vuex里的代码store/index.js

import Vue from 'vue'
import Vuex from 'vuex'
import createPersistedState from 'vuex-persistedstate'

Vue.use(Vuex)

export default new Vuex.Store({
  state: {
    tree: [
      {
        path: 'vv',
        name: '首页',
        func_fid: 0,
        id: '1000',
        children: [
          {
            path: 'sy',
            name: '首页儿子',
            func_fid: 1000,
            id: '1212'
          }
        ]
      },
      {
        path: 'hh',
        name: '系统管理',
        func_fid: 0,
        id: '1',
        children: [
          {
            id: '1-1',
            func_fid: 1,
            path: 'son1',
            name: '系统管理儿子'
          },
          {
            id: '2',
            func_fid: 1,
            path: 'hhh',
            name: '系统管理-角色',
            children: [
              {
                id: '222',
                func_fid: 1,
                path: 'son1-1-1',
                name: '角色管理',
                children: [
                  {
                    id: '12',
                    func_fid: 2,
                    path: 'son1-1-1',
                    name: '角色管理儿子',
                    children: [
                      {
                        id: '122',
                        func_fid: 2,
                        path: 'son1-1-1-1',
                        name: '角色管理儿子-----孙子'
                      }
                    ]
                  }
                ]
              }
            ]
          },
          {
            id: '122',
            path: 'son1-2',
            name: '用户管理'
          }

        ]
      },
      {
        path: 'ss',
        name: '教学管理',
        id: '22',
        func_fid: 0,
        children: [
          {
            path: 'son2',
            name: '教学管理儿子',
            id: '202',
            func_fid: 22
          }
        ]
      },
      {
        path: 'zz',
        name: '行政管理',
        id: '3',
        func_fid: 0,
        children: [
          {
            path: 'son3',
            name: '行政管理儿子',
            id: '33',
            func_fid: 3
          }
        ]
      },
      {
        path: 'cv',
        name: '测试管理',
        id: '4',
        func_fid: 0,
        children: []
      }
    ],
    tabs: [],
    tabOne: [],
    title: ''
  },
  getters: {
  },
  mutations: {
    tab (state, payload) {
      function recursion (t) {
        state.tabs.push(t)
        if (t.children && t.children.length > 0) {
          for (let i = 0; i < t.children.length; i++) {
            recursion(t.children[i])
          }
        }
      }
      state.tree.forEach(item => {
        recursion(item)
      })
      state.tabs.forEach(item => {
        if (item.path === payload) {
          const ind = state.tabOne.findIndex(i => i.path === item.path)
          state.title = item.path
          if (ind === -1) {
            state.tabOne.push(item)
          }
        }
      })
    },
    SET_ACTIVE_TAB (state, newValue) {
      state.title = newValue
    },
    remove (state, payload) {
      console.log(payload)
      const i = state.tabOne.findIndex(item => item.path === payload)
      if (payload !== state.title) {
        console.log(payload)
      } else if (state.tabOne.length === 1) {
        state.title = ''
      } else if (i === state.tabOne.length - 1) {
        state.title = state.tabOne[i - 1].path
      } else {
        state.title = state.tabOne[i + 1].path
      }
      state.tabOne.splice(i, 1)
    }
  },
  actions: {
  },
  modules: {
  },
  plugins: [createPersistedState({
    storage: window.sessionStorage
  })]
})

这个是我的git仓库地址有需要的可以自行拉取

https://gitee.com/Flechazo7/vue2.git

路由代码

import Vue from 'vue'
import VueRouter from 'vue-router'

Vue.use(VueRouter)

const routes = [
  {
    path: '/',
    name: 'home',
    component: () => import('../views/home/home.vue'),
    children: [
      {
        path: '',
        components: {
          son1: () => import('../views/home/son/sonOne.vue'),
          son2: () => import('../views/home/son/sonTwo.vue'),
          son3: () => import('../views/home/son/sonThree.vue')
        }
      }
    ]
  }
]

const router = new VueRouter({
  mode: 'hash',
  base: process.env.BASE_URL,
  routes
})

export default router

  • 7
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

大可-

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值