赞
踩
效果图
我这里是使用的vue2 + 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)
- });
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>© 版权所有: 大可</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标签联动就已经完成了
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。