Vue2项目练手——通用后台管理项目第二节

路由限制重复跳转

路由重复跳转会出现bug
请添加图片描述
解决路由重复bug问题:

clickMenu(item){
      // console.log(item)
      // console.log(this.$route.path)
      // 当页面的路由与跳转的路由不一致才允许跳转
      if(this.$route.path!==item.path && !(this.$route.path==='/home'&&(item.path==='/'))){
        this.$router.push(item.path)
      }
    }

CommonAside.vue

<template>
    <el-menu default-active="1-4-1" class="el-menu-vertical-demo" @open="handleOpen" @close="handleClose"
             :collapse="isCollapse" background-color="#545c64" text-color="#fff"
             active-text-color="#ffd04b">
      <h3>通用后台管理系统</h3>
      <el-menu-item @click="clickMenu(item)"  v-for="item in noChildren" :key="item.name" :index="item.name">
        <i :class="`el-icon-${item.icon}`"></i>
        <span slot="title">{{item.label}}</span>
      </el-menu-item>
      <el-submenu :index="item.label" v-for="item in hasChildren" :key="item.label">
        <template slot="title">
          <i :class="`el-icon-${item.icon}`"></i>
          <span slot="title">{{item.label}}</span>
        </template>
        <el-menu-item-group>
          <el-menu-item @click="clickMenu(subItem)" :index="subItem.path" :key="subItem.path" v-for="subItem in item.children">
            {{subItem.label}}
          </el-menu-item>
        </el-menu-item-group>
      </el-submenu>
    </el-menu>

</template>



<style lang="less" scoped>
.el-menu-vertical-demo:not(.el-menu--collapse) {
  width: 200px;
  min-height: 400px;
}
.el-menu{
  height: 100vh;  //占据页面高度100%
  h3{
    color: #fff;
    text-align: center;
    line-height: 48px;
    font-size: 16px;
    font-weight: 400;
  }
}
</style>

<script>
export default {
  data() {
    return {
      isCollapse: false,
      menuData:[
        {
          path:'/',
          name:"home",
          label:"首页",
          icon:"s-home",
          url:'Home/Home'
        },
        {
          path:'/mall',
          name:"mall",
          label:"商品管理",
          icon:"video-play",
          url:'MallManage/MallManage'
        },
        {
          path:'/user',
          name:"user",
          label:"用户管理",
          icon:"user",
          url:'userManage/userManage'
        },
        {
          label:"其他",
          icon:"location",
          children:[
            {
              path:'/page1',
              name:"page1",
              label:"页面1",
              icon:"setting",
              url:'Other/PageOne'
            },
            {
              path:'/page2',
              name:"page2",
              label:"页面2",
              icon:"setting",
              url:'Other/PageTwo'
            },
          ]
        },
      ]
    };
  },
  methods: {
    handleOpen(key, keyPath) {
      console.log(key, keyPath);
    },
    handleClose(key, keyPath) {
      console.log(key, keyPath);
    },
    clickMenu(item){
      // console.log(item)
      // console.log(this.$route.path)
      // 当页面的路由与跳转的路由不一致才允许跳转
      if(this.$route.path!==item.path && !(this.$route.path==='/home'&&(item.path==='/'))){
        this.$router.push(item.path)
      }
    }
  },
  mounted() {
    console.log(this.$route.path)
  },
  computed:{
    //没有子菜单的数据
    noChildren(){
      return this.menuData.filter(item=>!item.children)
    },
    //有子菜单数组
    hasChildren(){
      return this.menuData.filter(item=>item.children)
    }
  }
}
</script>

顶部header组件搭建与样式修改

右边用户菜单栏

使用的组件

在这里插入图片描述

图片

在这里插入图片描述

CommonHeader.vue

<template>
  <div class="header-container">
    <div class="l-content">
      <el-button icon="el-icon-menu" size="mini"></el-button>
      <!--      面包屑-->
      <span class="text">首页</span>
    </div>
    <div class="r-content">
      <el-dropdown>
          <span class="el-dropdown-link">
            <img src="@/assets/user.webp" alt="">
          </span>
                <el-dropdown-menu slot="dropdown">
                  <el-dropdown-item>个人中心</el-dropdown-item>
                  <el-dropdown-item>退出</el-dropdown-item>
                </el-dropdown-menu>
              </el-dropdown>
    </div>
  </div>

</template>

<script>
export default {
  name: "CommonHeader",
}
</script>

<style scoped lang="less">
.header-container {
  height: 60px;
  background-color: #333;
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 0 20px;

  .text {
    color: #fff;
    font-size: 14px;
    margin-left: 10px;
  }
  .r-content{
    img{
      width: 40px;
      height: 40px;
      border-radius: 50%;
    }
  }
}
</style>

在这里插入图片描述

Vuex实现左侧折叠

文件目录

在这里插入图片描述

store/index.js

import Vue from 'vue'
import Vuex from 'vuex'
import tab from './tab'

Vue.use(Vuex)
export default new Vuex.Store({
    modules:{
        tab
    }
})

store/tab.js

export default {
    state:{
        isCollapse:false  //控制菜单的展开还是收起
    },
    mutations:{
        //   修改菜单展开收起的方法
        collapseMenu(state){
            state.isCollapse=!state.isCollapse
        }
    }
}

main.js

import Vue from 'vue'
import App from './App.vue'
import VueRouter from "vue-router";
import router from "@/router";
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css'
import store from '@/store'
Vue.config.productionTip = false
Vue.use(VueRouter)
Vue.use(ElementUI)
new Vue({
  store,
  router,
  render: h => h(App),
}).$mount('#app')

CommonHeader.vue

<template>
  <div class="header-container">
    <div class="l-content">
      <el-button icon="el-icon-menu" size="mini" @click="handleMenu"></el-button>
      <!--      面包屑-->
      <span class="text">首页</span>
    </div>
    <div class="r-content">
      <el-dropdown>
          <span class="el-dropdown-link">
            <img src="@/assets/user.webp" alt="">
          </span>
                <el-dropdown-menu slot="dropdown">
                  <el-dropdown-item>个人中心</el-dropdown-item>
                  <el-dropdown-item>退出</el-dropdown-item>
                </el-dropdown-menu>
              </el-dropdown>
    </div>
  </div>

</template>

<script>
export default {
  name: "CommonHeader",
  methods:{
    handleMenu(){
      this.$store.commit('collapseMenu')
    }
  }
}
</script>

<style scoped lang="less">
.header-container {
  height: 60px;
  background-color: #333;
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 0 20px;

  .text {
    color: #fff;
    font-size: 14px;
    margin-left: 10px;
  }
  .r-content{
    img{
      width: 40px;
      height: 40px;
      border-radius: 50%;
    }
  }
}
</style>

CommonAside.vue

<template>
    <el-menu default-active="1-4-1" class="el-menu-vertical-demo" @open="handleOpen" @close="handleClose"
             :collapse="isCollapse" background-color="#545c64" text-color="#fff"
             active-text-color="#ffd04b">
      <h3>{{isCollapse?'后台':'通用后台管理系统'}}</h3>
      <el-menu-item @click="clickMenu(item)"  v-for="item in noChildren" :key="item.name" :index="item.name">
        <i :class="`el-icon-${item.icon}`"></i>
        <span slot="title">{{item.label}}</span>
      </el-menu-item>
      <el-submenu :index="item.label" v-for="item in hasChildren" :key="item.label">
        <template slot="title">
          <i :class="`el-icon-${item.icon}`"></i>
          <span slot="title">{{item.label}}</span>
        </template>
        <el-menu-item-group>
          <el-menu-item @click="clickMenu(subItem)" :index="subItem.path" :key="subItem.path" v-for="subItem in item.children">
            {{subItem.label}}
          </el-menu-item>
        </el-menu-item-group>
      </el-submenu>
    </el-menu>

</template>



<style lang="less" scoped>
.el-menu-vertical-demo:not(.el-menu--collapse) {
  width: 200px;
  min-height: 400px;
}
.el-menu{
  height: 100vh;  //占据页面高度100%
  h3{
    color: #fff;
    text-align: center;
    line-height: 48px;
    font-size: 16px;
    font-weight: 400;
  }
}
</style>

<script>
export default {
  data() {
    return {
      menuData:[
        {
          path:'/',
          name:"home",
          label:"首页",
          icon:"s-home",
          url:'Home/Home'
        },
        {
          path:'/mall',
          name:"mall",
          label:"商品管理",
          icon:"video-play",
          url:'MallManage/MallManage'
        },
        {
          path:'/user',
          name:"user",
          label:"用户管理",
          icon:"user",
          url:'userManage/userManage'
        },
        {
          label:"其他",
          icon:"location",
          children:[
            {
              path:'/page1',
              name:"page1",
              label:"页面1",
              icon:"setting",
              url:'Other/PageOne'
            },
            {
              path:'/page2',
              name:"page2",
              label:"页面2",
              icon:"setting",
              url:'Other/PageTwo'
            },
          ]
        },
      ]
    };
  },
  methods: {
    handleOpen(key, keyPath) {
      console.log(key, keyPath);
    },
    handleClose(key, keyPath) {
      console.log(key, keyPath);
    },
    clickMenu(item){
      // console.log(item)
      // console.log(this.$route.path)
      // 当页面的路由与跳转的路由不一致才允许跳转
      if(this.$route.path!==item.path && !(this.$route.path==='/home'&&(item.path==='/'))){
        this.$router.push(item.path)
      }
    }
  },
  mounted() {
    console.log(this.$route.path)
  },
  computed:{
    //没有子菜单的数据
    noChildren(){
      return this.menuData.filter(item=>!item.children)
    },
    //有子菜单数组
    hasChildren(){
      return this.menuData.filter(item=>item.children)
    },
    isCollapse(){
      return this.$store.state.tab.isCollapse
    }
  }
}
</script>

Main.vue

<template>
  <div>
    <el-container>
      <el-aside width="auto">
        <CommonAside></CommonAside>
      </el-aside>
      <el-container>
        <el-header>
          <CommonHeader></CommonHeader>
        </el-header>
        <el-main>
<!--         路由出口,路由匹配到的组件将渲染在这里 -->
          <router-view></router-view>
        </el-main>
      </el-container>
    </el-container>
  </div>

</template>

<script>
import CommonAside from "@/components/CommonAside.vue";
import CommonHeader from "@/components/CommonHeader.vue";
export default {
  name: "Main",
  components:{CommonAside,CommonHeader}
}
</script>

<style scoped>
.el-header{
  padding: 0;
  margin: 0;
}
.el-menu{
  border-right: none;
}
</style>

请添加图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值