目录

  • 一、实现效果
  • 二、原理
  • 1. 折叠菜单栏
  • 2. 面包屑
  • 三、全部源码:
  • 我的折叠菜单栏+面包屑

一、实现效果

动画演示效果

之前的登录+++++++++++++++++++++++++++本次:折叠菜单栏+面包屑

ant design vue 折叠面板上下折叠 vue 折叠菜单_面包屑

ant design vue 折叠面板上下折叠 vue 折叠菜单_折叠菜单栏_02


此部分全部源码见本文末或github:

Cungudafa:Vue_SpringbootDay3


二、原理

1. 折叠菜单栏

参考链接:element-ui 官网api:https://element.eleme.cn/#/zh-CN/component/menu

划重点:collapse 是否水平折叠收起菜单(仅在 mode 为 vertical 时可用) 在el-menu标签中加上此属性即可,官网示例:

<el-radio-group v-model="isCollapse" style="margin-bottom: 20px;">
  <el-radio-button :label="false">展开</el-radio-button>
  <el-radio-button :label="true">收起</el-radio-button>
</el-radio-group>
<el-menu default-active="1-4-1" class="el-menu-vertical-demo" @open="handleOpen" @close="handleClose" :collapse="isCollapse">
  <el-submenu index="1">
    <template slot="title">
      <i class="el-icon-location"></i>
      <span slot="title">导航一</span>
    </template>
    <el-menu-item-group>
      <span slot="title">分组一</span>
      <el-menu-item index="1-1">选项1</el-menu-item>
      <el-menu-item index="1-2">选项2</el-menu-item>
    </el-menu-item-group>
    <el-menu-item-group title="分组2">
      <el-menu-item index="1-3">选项3</el-menu-item>
    </el-menu-item-group>
    <el-submenu index="1-4">
      <span slot="title">选项4</span>
      <el-menu-item index="1-4-1">选项1</el-menu-item>
    </el-submenu>
  </el-submenu>
  <el-menu-item index="2">
    <i class="el-icon-menu"></i>
    <span slot="title">导航二</span>
  </el-menu-item>
  <el-menu-item index="3" disabled>
    <i class="el-icon-document"></i>
    <span slot="title">导航三</span>
  </el-menu-item>
  <el-menu-item index="4">
    <i class="el-icon-setting"></i>
    <span slot="title">导航四</span>
  </el-menu-item>
</el-menu>

<style>
  .el-menu-vertical-demo:not(.el-menu--collapse) {
    width: 200px;
    min-height: 400px;
  }
</style>

<script>
  export default {
    data() {
      return {
        isCollapse: true//默认折叠
      };
    },
    methods: {
      handleOpen(key, keyPath) {
        console.log(key, keyPath);
      },
      handleClose(key, keyPath) {
        console.log(key, keyPath);
      }
    }
  }
</script>

2. 面包屑

面包屑参考:

面包屑组件:el-breadcrumb、将需要打印的部分打印在el-breadcrumb-item中,

重点与难点是在于对router路由的监听,当前的位置,用到了watch方法! 参考示例:监听的是name属性,

<template>
  <div class="bread">
     <el-breadcrumb class="breadcrumb" separator="/">
            <el-breadcrumb-item>主页</el-breadcrumb-item>
            <el-breadcrumb-item 
                v-for='(item,index) in levelList'
                :key='index'
                v-if='item.name'>
                {{item.name}}
            </el-breadcrumb-item>
    </el-breadcrumb>
  </div>
</template>

<script>
export default {
  name: '',
  data () {
      return {
          levelList: null//监听的结果放在一个集合中
      }
  },
  created () {
      this.getBreadcrumb();//进入页面就开始对面包屑进行监听
  },
  methods: {
    getBreadcrumb () {
        let matched = this.$route.matched.filter(item => item.name);
        //监听的是name属性,与我们跳转时用”this.$router.push({ name: 'layoutYHGL'})//结合router/index.js规则,根据name跳转到指定url”极其相似
        const first = matched[0];//清空面包屑中已匹配的路径
        this.levelList = matched;//把新监听到的记录存入监听集合
    }
  },
  watch: {
      $route() {
        console.log(1111)
        this.getBreadcrumb();//面包屑监听
      }
  }
}
</script>

<style lang="less" scoped>
 .bread {
   background-color: #f2f2f2;
   padding: 15px;
   margin: -12px -12px 10px -12px;
 }
</style>

三、全部源码:

综合前面两种样式,修改如下,这里采用的是router配置,没有写死。

如何配置,具体参考我前面两篇博客:【第一个Vue上手小项目】Vue-router+Element-ui+Vuex+axios实现前后端分离–登录实例【第一个Vue上手小项目Day2】Element-ui+SvgIcon优雅的登录界面+导航栏

本次仅仅更新了router/index.js,简单的对应了一下每个vue(不是重点就不贴代码了,此部分参考github)

ant design vue 折叠面板上下折叠 vue 折叠菜单_折叠菜单栏_03

Layout.vue:

<template>
  <el-container style="height: 100%;">
    <!-- 头部 -->
    <el-header>
      <el-radio-group v-model="isCollapse" style="margin-bottom: 20px;">
        <el-radio-button :label="false">展开</el-radio-button>
        <el-radio-button :label="true">收起</el-radio-button>
      </el-radio-group>
      <el-dropdown>
        <i class="el-icon-setting"></i>
        <el-dropdown-menu slot="dropdown">
          <el-dropdown-item>查看</el-dropdown-item>
          <el-dropdown-item>新增</el-dropdown-item>
          <el-dropdown-item>删除</el-dropdown-item>
        </el-dropdown-menu>
      </el-dropdown>
      <span v-if="user"> {{}}
        <el-button type="warning" @click="logout">注销</el-button>
      </span>
    </el-header>
    <el-container>
      <!-- 左侧栏 -->
      <el-menu default-active="1-1" class="el-menu-vertical-demo" @open="handleOpen" @close="handleClose" :collapse="isCollapse">
        <!--如果菜单(menu)是true 循环侧栏路由列表  -->
        <template v-for="item in menuData" v-if="item.meta.menu">
          <!-- 这里必须设置index,相当唯一标识这个菜单标签,否则菜单列表点击后随意展开 -->
          <el-submenu :index="''+item.meta.funcNode" :key="item.meta.funcNode">
            <template slot="title">
              <i :class="item.meta.icon"></i>
              <span slot="title">{{item.meta.title}}</span>
            </template>
            <!-- 如果菜单有孩子菜单,则循环孩子菜单 -->
            <template v-for="itemC in item.children" v-if="item.children">
              <el-menu-item :index="''+itemC.meta.funcNode" @click="clickMenu(itemC)" :key="itemC.meta.funcNode">
                <i :class="itemC.meta.icon"></i>
                <span slot="title">{{itemC.meta.title}}</span>
              </el-menu-item>
            </template>
          </el-submenu>
        </template>
      </el-menu>
      <!-- 内容渲染 -->
      <el-main style="background-color: white;">
      <!-- 面包屑渲染 -->
        <el-breadcrumb separator-class="el-icon-arrow-right">
          <el-breadcrumb-item :to="{ path: '/user' }">首页</el-breadcrumb-item>
          <el-breadcrumb-item
                  v-for='(item,index) in levelList'
                  :key='index'
                  v-if='item.name'>
                  {{item.meta.title}}
              </el-breadcrumb-item>
        </el-breadcrumb>
        <!-- 具体内容 -->
        <router-view />
      </el-main>
    </el-container>
  </el-container>
</template>

<script>
  export default {
    data() {
      return {
        isCollapse: true,//默认折叠
        levelList: null//监听的结果放在一个集合中
      };
    },
    created () {
      this.getBreadcrumb();
    },
    methods: {
      handleOpen(key, keyPath) {
        console.log(key, keyPath);
      },
      handleClose(key, keyPath) {
        console.log(key, keyPath);
      },
      clickMenu(item) {
        this.$router.push({
          path: item.path
        }) //跳转的路由对象
        //this.$router.push({name:item.name})    通过name跳转
      },
      logout() {
        this.$store.dispatch('logout').then(() => {
          this.$router.replace('/login')
        })
      },
      getBreadcrumb () {
        let matched = this.$route.matched.filter(item => item.name);
        //监听的是name属性,与我们跳转时用”this.$router.push({ name: 'layoutYHGL'})//结合router/index.js规则,根据name跳转到指定url”极其相似
        const first = matched[0];//清空面包屑中已匹配的路径
        this.levelList = matched;//把新监听到的记录存入监听集合
      }
    },
    watch: {
      $route() {
        console.log(1111)
        this.getBreadcrumb();//面包屑监听
      }
    },
    computed: {
      menuData() {
        return this.$router.options.routes
      },
      user() {
        //console.log(this.$store.state)
        return this.$store.state.user
      },
      onRoutes() { //点击时此处高亮
        let path = this.$route.path.replace('/', '');
        return path ? path : '/';
      }
    }
  }
</script>

<style>
  .el-header{
    background-color: #FF9999;
  }
  .el-menu,
  .el-submenu,
  .el-menu-item {
    background-color: #FFCCCC;
  }

  .el-menu-vertical-demo:not(.el-menu--collapse) {
    width: 200px;
    min-height: 400px;
  }
 .el-breadcrumb {
   background-color: #f2f2f2;
   padding: 5px;
   margin: -12px -12px 10px -12px;
 }
  body {
    margin: 0px;
  }
</style>

我的折叠菜单栏+面包屑

收起、展开效果:

ant design vue 折叠面板上下折叠 vue 折叠菜单_折叠菜单栏_04

ant design vue 折叠面板上下折叠 vue 折叠菜单_ico_05

面包屑效果:

ant design vue 折叠面板上下折叠 vue 折叠菜单_ico_06

ant design vue 折叠面板上下折叠 vue 折叠菜单_折叠菜单栏_07

全部项目源码见github:

Cungudafa:Vue_SpringbootDay3