vue + element-ui制作折叠式菜单

近期打算做一个进销存系统,因为好久没做前端了,花了一天的时间复习了下vue,用element-ui做了个折叠式菜单。其中复习到的知识点有

transition动画,vuex状态管理,vue-route路由。

1.设置路由

import Vue from 'vue'
import VueRouter from 'vue-router'

import Home from '../pages/Home'
import Sale from '../pages/sale/index'
import Stock from '../pages/stock/index'

Vue.use(VueRouter)

//将路由配置在数组对象中
export const mapMenu = [
  {
    path: '/',
    name: 'home',
    component: Home,
    noMenu: true
  },
  {
    path: '/lock',
    name: '锁屏页',
    component: Sale,
    noMenu: true
  },
  {
    path: '/dashboard',
    name: '首页',
    meta: { title: '首页', icon: '' },
    component: null
  },
  {
    path: '/sale',
    name: 'sale',
    component: Home,    //设置字组件的父组件
    meta: { title: '销售管理', icon: '' },
    children: [
      {
        path: '/sale/offer',
        name: 'offer',
        component: Sale,    
        meta: { title: '销售报价单', icon: '' }
      },
      {
        path: '/sale/indent',
        name: 'indent',
        component: Stock,
        meta: { title: '销售订货单', icon: '' }
      }
    ]
  },
  {
    path: '/stock',
    name: '库存管理',
    component: Home,
    meta: { title: '库存管理', icon: '' },
    children: [{
      path: '/stock/outStock',
      name: '出库管理',
      meta: { title: '出库管理', icon: '' },
      component: null
    },
    {
      path: '/stock/putStock',
      name: '入库管理',
      meta: { title: '入库管理', icon: '' },
      component: null
    },
    {
      path: '/stock/endMonthHandle',
      name: '月末处理',
      meta: { title: '月末处理', icon: '' },
      component: null
    }
    ]
  }
]
//实例化路由
const router = new VueRouter({
  routes: mapMenu
})

export default router

 新手在使用嵌套路由时,容易弄混子路由和父路由之间的建立关系。子路由的组件必须包含在父路由中,父组件下的router-view才能接受到信息,进行跳转。反之不会发生跳转。

2.vuex状态管理

因为后期需要进行前后端交互,涉及到用户的权限问题,所以把路由信息放进vuex状态管理中。这里我新建一个user.js,主要用来管理用户信息(以后的文章中会讲解)

import { mapMenu } from '../../router'

const user = {
  state: {
    menus: mapMenu
  }
}
export default user

 通过getters来获取用户信息。

const getters = {
  menus: state => state.user.menus,
  barEffect: state => state.app.barEffect
}

export default getters

现在为大家讲解一下vuex的几个知识点。

state:定义状态存储的对象和对象初始化,state确认之后,程序运行时便不可动态添加对象。
mutations:对state的对象进行操作,切记,该操作为同步

actions:同样是对state的对象进行操作,那有了mutations,为什么还要用actions呢?mutations是只支持同步,而actions能通过异步来触发mutations里的操作。

const app = {
  state: {
    barEffect: {
      open: true
    }
  },
  mutations: {
    TOGGLE_BAREFFECT: state => {              //建议用大写加下划线定义mutations的方法
      state.barEffect.open = !state.barEffect.open
    }
  },
  actions: {
    ToggleBarEffect: ({ commit }) => {
      commit('TOGGLE_BAREFFECT')    //触发mutations中的TOGGLE_BAREFFECT
    }
  }
}

以上定义了一个barEffect对象,用来存储菜单栏是否折叠的状态

扫描二维码关注公众号,回复: 2556718 查看本文章

3.菜单栏

首先我们需要编写一个LeftMenu组件

<template>
  <el-scrollbar wrapClass="scrollbar-wrapper">
    <el-menu mode="vertical"
             background-color="#545c64"
             text-color="#fff"
             active-text-color="#ffd04b"
             :collapse="isCollapse"
             :default-active="$route.path">
         <menu-item :menus="menus"></menu-item>   //传递的是user中的menus
    </el-menu>
  </el-scrollbar>
</template>

import { mapGetters } from 'vuex'
  import MenuItem from './modules/MenuItem'
  export default {
    name: 'left-menus',
    components: { MenuItem },
    computed: {
      ...mapGetters([
        'menus',
        'barEffect'
      ]),
      isCollapse() {
        return !this.barEffect.open
      }
    }
  }

el-scrollbar是element默认的滚动条,可通过wrapClass和viewClass设置外部样式和内部样式。

el-menu中的属性自己去element-ui中查看。

接下来我们在定义menu-item菜单项

<template>
  <div class="menu-item-wrapper">
    <template v-for="item in menus" v-if="!item.noMenu">  //遍历路由信息,排除非菜单路由
      <el-submenu v-if="item.children" :index="item.name" :key="item.name"> //判断是否有子路由,有的话需要遍历子路由
        <template slot="title">
          <i class="fa fa-bath" aria-hidden="true"></i>
          <span v-if="item.meta&&item.meta.title">{{item.meta.title}}</span>
        </template>
        <template v-for="child in item.children">
          <router-link :to="child.path" :key="child.name">
            <el-menu-item :index="item.path + child.path" >
              <i class="fa fa-bath" aria-hidden="true"></i>
              <span v-if="child.meta&&child.meta.title" slot="title">{{child.meta.title}}</span>
            </el-menu-item>
          </router-link>
        </template>
      </el-submenu>
      <router-link v-else :to="item.path" :key="item.name">  //没有子路由则直接进入这一步
        <el-menu-item :index="item.path" class="submenu-title-noDropdown">
          <i class="fa fa-bath" aria-hidden="true"></i>
          <span v-if="item.meta&&item.meta.title" slot="title">{{item.meta.title}}</span>
        </el-menu-item>
      </router-link>
    </template>
  </div>
</template>

到了这一步我们的折叠菜单基本就完成了,实现的效果如下

猜你喜欢

转载自blog.csdn.net/qq_33483829/article/details/81276733