vue2中左侧菜单和头部tab标签联动

效果图

我这里是使用的vue2 + element-ui来实现的,代码可以直接拿来使用

一、首先先安装element-ui

element-ui官网

npm i element-ui -S

 然后在main.js里面配置,安装官网的步骤来就可以了,这里就不一一介绍了

import Vue from 'vue';
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
import App from './App.vue';

Vue.use(ElementUI);

new Vue({
  el: '#app',
  render: h => h(App)
});

二、vue页面 

home页面 

这个页面也就是主页,这里我把左侧菜单,中间内容的头部tab标签页给拆成了两个子组件他们分别是leftMenu.vue和multipleTabs.vue页面

<template>
  <el-container>
    <el-aside width="collapse ? 200px : 70px">
      <el-button color="#626aef" @click="collapseToggle()">
        <el-icon>
          <Expand v-if="collapse" />
          <Fold v-else />
        </el-icon>
      </el-button>
      <el-menu
          :collapse="collapse"
          :default-active="store.bbc"
          class="el-menu-vertical-demo"
          unique-opened
          active-text-color="#ffd04b"
          text-color="#fff"
          background-color="transparent"
          @select="store.vv"
         >
       <left :dataToSon="store.mm" />
      </el-menu>
    </el-aside>
    <el-container>
      <el-header height="80px">
        <h1 @click="fff">大可的管理系统 - v1.0</h1>
        <div>
          <img src="@/assets/111.jpg" alt="">
          <span></span>
          <el-button type="primary" @click="LogOut">退出登录</el-button>
        </div>
      </el-header>
      <el-main>
        <tab></tab>
      </el-main>
      <el-footer height="50px">
        <p>&copy; 版权所有: 大可</p>
      </el-footer>
    </el-container>
  </el-container>
</template>

<script setup lang="ts">
import { ref } from 'vue';
import { useRouter } from "vue-router";
import left from "../left.vue";
import  tab from '../tab.vue';
import { ElMessage, ElMessageBox} from "element-plus";
import { useAuthStore } from '@/store';
import preventBack from 'vue-prevent-browser-back';//组件内单独引入
const mixins = [preventBack];
const store = useAuthStore();
const collapse = ref<boolean>(false)
const router = useRouter();
const tiao = () => {
  console.log('路由')
  router.push('/son1')
}
const fff = () => {
  router.replace('/son2')
}
const collapseToggle = () => {
  collapse.value = !collapse.value
}
const ggvv  = ref([1,2,3])
const handleOpen = () => {
  console.log()
}
const gg = (e) => {
  console.log(e)
}
const handleClose = () => {
  console.log()
}
const LogOut = () => {
  ElMessageBox.confirm(
      '确定要退出登录?',
      'Warning',
      {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning',
      }
  )
      .then(() => {
        router.replace('/login')
        ElMessage({
          type: 'success',
          message: '退出成功',
        })
      })
      .catch(() => {
        ElMessage({
          type: 'info',
          message: '您取消了退出',
        })
      })
}
</script>

<style scoped>
.el-header {
  background: url("@/assets/111.jpg");
  background-color: #f3d19e;
  display: flex;
  align-items: center;
  justify-content: space-between;
}
.el-header h1 {
  font-size: 26px;
  color: #fff;
  letter-spacing: 10px;
}
.el-header div {
  margin-right: 30px;
}
.el-header img {
  width: 40px;
  border-radius: 40px;
  vertical-align: middle;
  margin-right: 10px;
}
.el-header span {
  font-size: 18px;
  color: #fff;
  margin-right: 10px;
}
.el-header el-button {
  margin-left: 10px;
}

.el-aside {
  height: 100vh;
  background: url('@/assets/111.jpg');
  transition: width 0.3s;
  text-align: right;
}
.el-aside .el-button {
   margin: 20px 10px 20px 0;
 }
.el-aside .el-menu {
  border-right: none;
}
.el-footer {
  background-color: #EBEEF5;
  display: flex;
  align-items: center;
}
.el-footer p {
  font-size: 12px;
  color: #666;
}


</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>

头部tab标签页multipleTabs.vue

<template>
  <div>
    <el-tabs v-model="activeTab" type="card" closable >
      <el-tab-pane
        v-for="item in this.$store.state.tabOne"
        :key="item.id"
        :label="item.name"
        :name="item.path"
      >
        {{item.content}}
      </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)
    }
  }
}
</script>

<style scoped>

</style>

最后就是vuex里面的代码了

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

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: 'vv'
  },
  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 === item)
          state.title = item.path
          if (ind === -1) {
            state.tabOne.push(item)
          }
        }
      })
      console.log(state.tabOne)
    },
    SET_ACTIVE_TAB (state, newValue) {
      state.title = newValue
    }
  },
  actions: {
  },
  modules: {
  }
})

到此左侧菜单和头部tab标签联动就已经完成了

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

大可-

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

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

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

打赏作者

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

抵扣说明:

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

余额充值