1. 程式人生 > 實用技巧 >vue使用element實現摺疊面板---選單的摺疊與展開

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>