vue使用element实现折叠面板---菜单的折叠与展开

参考:

https://www.jianshu.com/p/0ceef28f99f2

实现效果:

 

 

 

 

实现步骤:

1、vuex中menu.js

minLeftMenuWidth: 35, // 折叠时左侧菜单的宽度
maxLeftMenuWidth: 180, // 展开时左侧菜单的宽度
const types = {
  HANDLE_LEFT_MENU: 'HANDLE_LEFT_MENU', // 收缩左侧菜单
  INIT_LEFT_MENU: 'INIT_LEFT_MENU', // 初始化左侧菜单
  SET_LEFT_COLLAPSE: 'SET_LEFT_COLLAPSE', // 改变左边菜单的收缩宽度
  SET_FOOTER_SHOW: 'SET_FOOTER_SHOW' // 显示隐藏底部Layout
};

const menu = {
  state: {
    minLeftMenuWidth: 35,
    maxLeftMenuWidth: 180,
    sidebar: {
      opened: true,
      width: 180
    },
    isCollapse: false, // 菜单默认展开
    isFooter: false
  },
  getters: {
    sidebar: state => state.sidebar,
    isCollapse: state => state.isCollapse,
    isFooter: state => state.isFooter
  },
  mutations: {
    // 收缩菜单
    [types.HANDLE_LEFT_MENU](state) {
      if (state.sidebar.opened) {
        // true
        state.sidebar.width = state.minLeftMenuWidth;
      } else {
        state.sidebar.width = state.maxLeftMenuWidth;
      }
      state.sidebar.opened = !state.sidebar.opened;
    },
    // 初始化左侧菜单
    [types.INIT_LEFT_MENU](state) {
      // eslint-disable-next-line no-self-assign
      state.sidebar = state.sidebar;
    },
    // 改变左侧菜单的收缩宽度
    [types.SET_LEFT_COLLAPSE](state) {
      state.isCollapse = !state.isCollapse;
    },
    [types.SET_FOOTER_SHOW](state) {
      state.isFooter = true;
    }
  },
  actions: {
    handleLeftMenu: ({ commit }) => {
      commit(types.HANDLE_LEFT_MENU);
    },
    initLeftMenu: ({ commit }) => {
      commit(types.INIT_LEFT_MENU);
    },
    setLeftCollapse: ({ commit }) => {
      commit(types.SET_LEFT_COLLAPSE);
    }
  }
};

export default menu;

2、leftMenu.vue

DOM部分:

<template>
  <div class="left_menu" :style="{ width: sidebar.width + 'px' }"> // 根据菜单是否折叠整体设计左侧菜单的宽度
    <div class="menu_page_top">
      <img :src="logo" :class="['logo', { closeLogo: !sidebar.opened }]" />  // 根据左侧菜单是否展开设置折叠时logo的样式:closeLogo
      <!-- <span class="title">
        AI.
        <i>ADMIN</i>
      </span> -->
    </div>
    <div class="menu_page_bottom">
      <el-menu
        :default-active="activeIndex"
        :show-timeout="200"
        :active-text-color="menuObj.activeTextColor"
        :text-color="menuObj.textColor"
        router
        :collapse="isCollapse"
        :style="{ width: sidebar.width + 'px' }"
      >
        <!-- 只有一级菜单 -->
        <template v-for="item in permission_routers">
          <el-menu-item
            :index="item.path"
            :key="item.path"
            v-if="!item.hidden && item.noDropDown"
            :to="item.path + '/' + item.children[0].path"
          >
            <i class="iconfont icon" :class="item.meta.icon"></i>
            <span slot="title">{{ $t(`commons.${item.name}`) }}</span>
          </el-menu-item>
          <!-- 有二级或多级菜单 -->
          <el-submenu
            v-if="
              item.children &&
                item.children.length >= 1 &&
                !item.hidden &&
                !item.noDropDown
            "
            :index="item.path"
            :key="item.path"
            class="erji_menu"
          >
            <template slot="title">
              <i class="iconfont icon" :class="item.meta.icon"></i>
              <span slot="title" v-if="item.meta.title">{{
                $t(`commons.${item.name}`)
              }}</span>
            </template>
            <el-menu-item
              :index="item.path + '/' + item2.path"
              v-for="item2 in item.children"
              :key="item2.path"
              >{{ $t(`commons.${item2.name}`) }}</el-menu-item
            >
          </el-submenu>
        </template>
      </el-menu>
    </div>
  </div>
</template>

Script部分:

<script>
import { mapGetters } from 'vuex';
import * as mUtils from '@/utils/mUtils';
import logoImg from '@/assets/img/logo.png';
export default {
  data() {
    return {
      logo: logoImg,
      menuObj: {
        bgColor: '#fff',
        textColor: '#666',
        activeTextColor: '#ff6428'
      }
    };
  },
  computed: {
    // permission_routers:不需要权限的页面
    ...mapGetters(['permission_routers', 'isCollapse', 'sidebar', 'menuIndex']),
    activeIndex() {
      return this.$route.path;
    },
    childRouters() {
      return this.permission_routers.filter(item => {
        return (
          item.children &&
          item.children.length >= 1 &&
          !item.hidden &&
          !item.noDropDown
        );
      });
    }
  },
  methods: {
    getIindex(citem, item, cindex) {
      return citem.meta.titleList
        ? item.path + '/' + citem.path + '/' + citem.meta.titleList[0].path
        : item.path + '/' + citem.path;
    }
  }
};
</script>

点击右边的“折叠”与“展开”图标,实现左侧菜单的折叠与展开:

<template>
  <div class="bread">
    <span class="iconfont icon icon-zhedie1" @click="hanleLeftMenu"></span>
    <el-breadcrumb separator="/">
      <el-breadcrumb-item v-for="(item, index) in matchedArr" :key="index">{{
        $t(`commons.${item}`)
      }}</el-breadcrumb-item>
    </el-breadcrumb>
  </div>
</template>
<script>
export default {
  computed: {
    matchedArr() {
      const temp = [];
      const temps = [];
    // $route.matched: 一个数组,包含当前路由的所有嵌套路径片段的路由记录 。路由记录就是 routes 配置数组中的对象副本 (还有在 children 数组)。
this.$route.matched.filter(item => { if (item.name) { const name = item.name; temp.push(name); } }); console.log(temp); temp.filter(item => { if (!temps.includes(item)) { temps.push(item); } }); return temps; // return this.$route.matched; } }, methods: { hanleLeftMenu() { this.$store.dispatch('setLeftCollapse'); // 折叠菜单 this.$store.dispatch('handleLeftMenu'); // 改变宽度 } } }; </script> <style lang="less" scoped> .bread { margin-top: 60px; display: flex; justify-content: flex-start; padding: 10px; .icon { vertical-align: middle; margin-right: 10px; } // .el-breadcrumb { // line-height: 30px; // } } </style>

 vue+Element框架menu菜单刷新后保持选中状态

https://www.cnblogs.com/yzcwan/p/11348637.html

注:页面截图是在GitHub上找的学习的项目

posted @ 2020-07-09 16:05  haha-uu  阅读(36028)  评论(0编辑  收藏  举报