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>
https://www.cnblogs.com/yzcwan/p/11348637.html
注:页面截图是在GitHub上找的学习的项目
记录自己的采坑之路,需要时方便查找