运行结果

在这里插入图片描述

参考博客:https://blog.csdn.net/weixin_43930186/article/details/86677941

存在缺陷:你点击标签页的时候路由里面颜色没有跳转,因为时间问题就没有深究了。后面如果还能再碰到就会去解决一下

1.安装相应的依赖

可以参考我的这篇博客:https://blog.csdn.net/weixin_45969142/article/details/114126518

2.工程目录结构

在这里插入图片描述
在这里插入图片描述

3.建立store文件夹,建立index.js文件

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

Vue.use(Vuex)

export default new Vuex.Store({
  state: {
    id: '123456',
    openedTab: ['首页','system'],
    activeTab: ''
  },
  mutations: {
    //将name参数加入到openedTab数组中
    addNameTab(state, name){
      state.openedTab.push(name)
    },
    //将componentName参数加入到openedTab数组中
    addTab (state, componentName) {
      // 传递参数
      state.openedTab.push(componentName)
    },
    changeTab (state, componentName) {
      state.activeTab = componentName
    },
    deductTab (state, componentName) {
      let index = state.openedTab.indexOf(componentName)
      let indextwo = index-1;
      state.openedTab.splice(index, 1)
      //删除一次后,数组减少一。所以删除一样的位置,就能删除前面的那个
      state.openedTab.splice(indextwo, 1)
    }
  }
})

4.App.vue

<template>
    <div id="app">
        <el-container>
            <el-header class="header">
                <NavigationTop></NavigationTop>
            </el-header>
            <el-container>
                <el-aside width="200px">
                    <NavigationLeft></NavigationLeft>
                </el-aside>
                <el-main>
                    <NavigationMainTab></NavigationMainTab>
                    <keep-alive>
                        <router-view/>
                    </keep-alive>
                </el-main>
            </el-container>
        </el-container>

    </div>
</template>

<script>

    import NavigationLeft from '@/components/NavigationLeft/NavigationLeft'
    import NavigationTop from '@/components/NavigationTop/NavigationTop'
    import NavigationMainTab from '@/components/navMain/NavigationMainTab'

    export default {
        name: 'App',
        components: {
            NavigationLeft,
            NavigationTop,
            NavigationMainTab
        }
    }
</script>

<style>
    .header{
        background: #636363;
        line-height: 60px;
    }
</style>

5.router文件下的index.js文件

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

import userManage from "../views/userManage";
import HomePage from "../components/navMain/mainComponents/HomePage"
import businessManagement from '../components/navMain/mainComponents/businessManagement'
import adminManagement from '../components/navMain/mainComponents/adminManagement'
import userManagement from '../components/navMain/mainComponents/userManagement'



Vue.use(VueRouter);

const routes = [
    {
        path: '/system',
        name: 'HomePage',
        component: HomePage
    },
    {
        path: '/businessManagement',
        name: 'businessManagement',
        component: businessManagement
    },
    {
        path: '/adminManagement',
        name: 'adminManagement',
        component: adminManagement
    },
    {
        path: '/userManagement',
        name: 'userManagement',
        component: userManagement
    }
];

const router = new VueRouter({
    routes,
    // 去掉#号
    mode: 'history'
});

export default router

6.导航栏的上部分NavgationTop.vue

<template>
    <div id="header">
            <span class="demonstration" style="float:left;padding-top:10px;color:white;">
                RetalLife管理员后台系统
            </span>
      <span class="demonstration" style="float:left;padding:5px;color:white;margin-left:2%;width:15%">
                <el-input
                  placeholder="请输入"
                  icon="search"
                  v-model="searchCriteria"
                  :on-icon-click="handleIconClick">
                </el-input>
            </span>

      <span class="demonstration" style="float:right;padding-top:10px;margin-right:1%">
                <el-dropdown trigger="click">
                  <span class="el-dropdown-link" style="color:white;margin-right: 0px">
      <el-avatar src="https://cube.elemecdn.com/0/88/03b0d39583f48206768a7534e55bcpng.png"></el-avatar>
                      <i class="el-icon-caret-bottom el-icon--right"></i>
                  </span>
                  <el-dropdown-menu slot="dropdown">
                    <el-dropdown-item>个人信息</el-dropdown-item>
                    <el-dropdown-item>退出登录</el-dropdown-item>
                  </el-dropdown-menu>
                </el-dropdown>
            </span>
    </div>
</template>

<script>
export default {
  name: 'navHeader'
}
</script>

<style scoped>

</style>

7.导航栏的左边部分NavigationLeft.vue

<!--本页为左侧下拉菜单-->
<template>
    <div id="nav" style="margin-top: 0px">
        <el-row class="tac">
            <el-col :span="24">
                <el-menu
                        default-active="1"
                        class="el-menu-vertical-demo"
                        background-color="#545c64"
                        text-color="#fff"
                        unique-opened
                        router
                        active-text-color="#409EFF"
                        :collapse="isCollapse"
                >
                    <el-menu-item index="1" >
                        <i :class="{'el-icon-s-fold': isCollapse == false?true:false, 'el-icon-s-unfold': isCollapse == true?true:false}" @click="isC"></i>
                    </el-menu-item>
                    <el-menu-item index="system" @click="clickMenu('system')">
                        <i class="el-icon-s-home"></i>
                        <span slot="title">首页</span>
                    </el-menu-item>
                    <el-submenu index="2">
                        <template slot="title">
                            <i class="el-icon-setting"></i>
                            <span>系统管理</span>
                        </template>
                        <el-menu-item-group>
                            <el-menu-item index="userManagement" @click="clickMenu('userManagement','用户管理')">
                                <i class="el-icon-user"></i>
                              <span slot="title">用户管理</span>
                            </el-menu-item>
                            <el-menu-item index="adminManagement" @click="clickMenu('adminManagement','管理员管理')">
                                <i class="el-icon-admin"></i>
                              <span slot="title">管理员管理</span>
                            </el-menu-item>
                            <el-menu-item index="businessManagement"  @click="clickMenu('businessManagement','厂商管理')">
                                <i class="el-icon-business"></i>
                              <span slot="title">厂商管理</span>
                            </el-menu-item>
                        </el-menu-item-group>
                    </el-submenu>

                    <el-menu-item index="4">
                      <i class="el-icon-s-comment"></i>
                      <span slot="title">聊天窗口</span>
                    </el-menu-item>
                </el-menu>
            </el-col>
        </el-row>
    </div>
</template>

<script>
    export default {
        name: 'navMenu',
        methods: {
            isC() {
                this.isCollapse = !this.isCollapse
            },
            clickMenu(componentName,name) {
                this.openedTab = this.$store.state.openedTab
                // tabNum 为当前点击的列表项在openedTab中的index,若不存在则为-1
                let tabNum = this.openedTab.indexOf(componentName)
                if (tabNum === -1) {
                    // 该标签当前没有打开
                    // 将name、componentName加入到已打开标签页state.openedTab数组中
                    this.$store.commit('addNameTab', name)
                    this.$store.commit('addTab', componentName)
                } else {
                    // 该标签是已经打开过的,需要激活此标签页
                    this.$store.commit('changeTab', componentName)

                }
            }
        },
        data() {
            return {
                openedTab: [],
                isCollapse: false
            }
        }
    }
</script>

<style scoped>

    .el-icon-user {
        background: url('../../assets/yonghu.png') center center no-repeat;
        background-size: 20px;
    }

    .el-icon-user:before {
        content: "代替";
        font-size: 16px;
        visibility: hidden;
    }

    .el-icon-admin {
        background: url('../../assets/guanliyuan.png') center center no-repeat;
        background-size: 20px;
    }

    .el-icon-admin:before {
        content: "代替";
        font-size: 16px;
        visibility: hidden;
    }

    .el-icon-business {
        background: url('../../assets/changshang.png') center center no-repeat;
        background-size: 20px;
    }

    .el-icon-business:before {
        content: "代替";
        font-size: 16px;
        visibility: hidden;
    }
</style>

8.导航栏的引起的标签页NavigationMainTab.Vue

<!--本页为tab标签-->
<template>
  <el-tabs
    v-model="editableTabsValue"
    type="card"
    closable
    @tab-remove="removeTab"
    @tab-click="handleClickTab($event.name)"
  >
    <el-tab-pane
      :key="item.name"
      v-for="item in editableTabs"
      :label="item.title"
      :name="item.name"
    >
    </el-tab-pane>
  </el-tabs>
</template>

<script>

export default {
  name: 'navMain',
  data () {
    return {
      //做一个当时的状态网页
      editableTabsValue: 'system',
      editableTabs: [{
        title: '首页',
        name: 'system'
      }],
      //存储所有的路由网址
      openedTab: ['system']
    }
  },
  methods: {
    //点击切换标签页
    handleClickTab (route) {
        this.$store.commit('changeTab', route)
      //跳转该路由
        this.$router.push(route)
    },
    //删除标签页
    removeTab (targetName) {
      // 首页不允许被关闭(为了防止el-tabs栏中一个tab都没有)
      if (targetName === 'system') {
        return false
      }
      //下面这一部分,可以观看el里面自动的增加标签页的代码
      let tabs = this.editableTabs
      let activeName = this.editableTabsValue
      //editableTabsValue数组里面是否有与删除的标签页的路由相等
      if (activeName === targetName) {
        tabs.forEach((tab, index) => {
          if (tab.name === targetName) {
            let nextTab = tabs[index + 1] || tabs[index - 1]
            if (nextTab) {
              activeName = nextTab.name
            }
          }
        });
      }
      //删除标签页成功
      this.$store.commit('deductTab', targetName)

      //让openedTab,删除targetName这个下标对应的数据  openedTab存的是网址
      let deductIndex = this.openedTab.indexOf(targetName)
      this.openedTab.splice(deductIndex, 1)

      this.editableTabsValue = activeName

      //筛选出tabs中每一项的name值不等于targetName的项并返回一个新的数组举个栗子
      // :arr=[1,2,3,4,5]arr.filter(i=>i!=1)//[2,3,4,5]更新:
      // filter是已经封装好的方法,使用的时候只需要提供相应的参数就好了

      //targetName===businessManagement  !===  tab.name==editableTabs.name==英文构造
      this.editableTabs = tabs.filter(tab =>tab.name !== targetName )

      //跳转上一个标签,跳转成功
      this.$router.push(activeName)

      if (this.openedTab.length === 0) {
        this.$store.commit('addTab', 'system')
        this.$router.push('system')
      }
    }
  },
  computed: {
    //computed与watch中的方法对应起来了,可以写一个getTitle的方法  明天就直接换一个方法吧,简单些。空想又想不出来
    //得到openedTab数组里面的数据
    getOpenedTab () {
      return this.$store.state.openedTab
    },
    changeTab () {
      return this.$store.state.activeTab
    }
  },
  watch: {
    getOpenedTab (val) {
      //因为前面openedTab是个存路由网址的数组,所以需要this.openedTab.length*2
      if (val.length > this.openedTab.length*2) {
        // 添加了新的tab页
        // 导致$store.state中的openedTab长度
        // 大于
        // 标签页中的openedTab长度
        // 因此需要新增标签页
          //componentName里面的值
        let newTitle = val[val.length - 1] // 新增的肯定在数组最后一个
        let newTab = val[val.length - 2]

        this.editableTabs.push({
          title: newTab,
          name: newTitle,
          content: ''
        })
        this.editableTabsValue = newTitle
        this.openedTab.push(newTitle)
      }
    },
    changeTab (val) {
      // 监听activetab以实现点击左侧栏时激活已存在的标签
      if (val !== this.editableTabsValue) {
        this.editableTabsValue = val
      }
    }
  },
  created () {
    // 刷新页面时(F11)
    // 因为<router-view>的<keep-alive>,会保留刷新时所在的router
    // 但是tab标签页因为刷新而被重构了,tab没有了
    // 因此需要将router回到index
     this.$router.push('system')
  }
}
</script>

<style scoped>

</style>

9.标签页里面的内容为adminManagement.vue

<template>
  <div>
    <p>管理员管理</p>
  </div>
</template>

<script>
export default {
  name: 'BasicCheckbox'
}
</script>

<style scoped>

</style>

10.标签页里面的内容为businessManagement.vue

<template>
    <div>
      <p>厂商管理</p>
      <p><input type="text"></p>
    </div>
</template>

<script>
export default {
  name: 'BasicContainer'
}
</script>

<style scoped>

</style>

11.标签页里面的内容为HomePage.vue

<template>
    <div>
        <p>首页</p>
        <p><input type="text"></p>
    </div>
</template>

<script>
    export default {
        name: "HomePage"
    }
</script>

<style scoped>

</style>

12.标签页里面的内容为userManagement.vue

<template>
  <div>
    <p>用户管理</p>
  </div>
</template>

<script>
export default {
  name: 'BasicRadio'
}
</script>

<style scoped>

</style>

Logo

前往低代码交流专区

更多推荐