做过后端管理系统的“猿们”都知道,后端界面的框架无非就是左右结构【左边是菜单栏,右边是具体业务的功能界面】。但是右边的功能界面,我们又能拆分出来一些公用的控件:搜索栏、操作按钮栏、列表【table、tree、treetable】等,今天小编大致说下自定义操作按钮栏控件的封装以及实现。

首先,在做自定义控件之前,我们要想清楚我们封装自定义控件的目的,以目标为导向去实现。(以上内容纯属片汤话儿)

1.目的:实现操作按钮的公用、以及按钮权限控制

2.实现结果:

<MenuBottomToolbar menuclass="BASE_USERINFOLIST" />

import MenuBottomToolbar from '@/layout/components/Controls/MenuBottomToolbar'

components: { MenuBottomToolbar }

以上代码是在列表页面调用MenuBottomToolbar自定义控件的核心代码,接下来重点说下MenuBottomToolbar控件的实现

3.实现逻辑

先上代码:

// 菜单按钮控件
<template>
  <div class="MenuButtomToolBarCon">
    <el-row v-if="TopMenu.length > 0">
      <el-button
        v-for="item in TopMenu"
        :key="item.ContextMenuNo"
        type="primary"
        icon="item.ImageName"
        plain
        @click="callFun(item.ContextMenuScript)"
      >{{ item.ContextMenuDesc }}</el-button>
      <!-- <el-button type="primary" icon="el-icon-search" size="mini" plain @click="Edit">编辑</el-button>
      <el-button type="primary" icon="el-icon-search" size="mini" plain>查看</el-button> -->
      <el-dropdown v-if="MoreMenu.length > 0" @command="handleCommand">
        <el-button type="primary">
          更多<i class="el-icon-arrow-down el-icon--right" />
        </el-button>
        <el-dropdown-menu slot="dropdown">
          <el-dropdown-item
            v-for="item in MoreMenu"
            :key="item.ContextMenuNo"
            :command="item.ContextMenuScript"
          >{{ item.ContextMenuDesc }}</el-dropdown-item>
        </el-dropdown-menu>
      </el-dropdown>
    </el-row>
  </div>
</template>

<script>
import menu from '@/api/system/menu'
export default {
  name: 'MenuBottomToolbar',
  props: {
    menuclass: { // 当前列表需要的按钮分类
      type: String,
      default: ''
    }
  },
  data() {
    return {
      TopMenu: [],
      MoreMenu: []
    }
  },
  created() {
    const menuno = this.$route.meta.menuno
    if (menuno && this.menuclass) {
      const param = {
        menuNo: menuno,
        menuclass: this.menuclass
      }
      menu.GetContextMenuList(param).then(res => {
        if (res.Issuccess) {
          const menuData = res.Data
          this.TopMenu = menuData.slice(0, 3)
          if (menuData.length >= 3) {
            this.MoreMenu = menuData.slice(3, menuData.length)
          }
        }
      })
    }
  },
  methods: {
    callFun(methodName) {
      // this.$parent[methodName].apply(this)
      // this.$parent.$emit(methodName)
      // this.$emit('cllFun', methodName)
      this.$bus.emit('cllFun', methodName)
    },
    handleCommand(command) {
      // 处理 下拉菜单中的事件
      // this.$parent[command].apply(this)
      this.$bus.emit('cllFun', command)
    }
  }
}
</script>
<style lang="scss" scoped>
    .MenuButtomToolBarCon{
        float:right;
        background-color: #fff;
        padding: 8px 10px;
    }
</style>

 细心的同学,有发现在调用自定义控件的时候,有传入一个"menuclass="BASE_USERINFOLIST"",此处说下,因为系统后端是使用menuclass和menuno来确定界面上的所有按钮,然后根据权限返回用户拥有的操作按钮。而menuno属性值,直接挂在了路由上,所以我们直接用this.$route.meta.menuno来获取路由的menuno的属性值,然后通过调用后端接口获取按钮数据。

拿到后端数据,将后端数据的值赋值前端的变量。基于有时候操作按钮太多,按钮栏太长,样式太丑,所以增加了一个判断,当按钮数量大于三的时候,将多余的按钮放到更多下面,通过下来框来实现。

重点来了:因为按钮的事件都是开发人员自己去配置的,无法再控件中写死按钮的事件,所以,我们需要将按钮的事件反馈调用到对应界面上的事件实现,但是,调用自定义控件的层级我们无法确定,如果使用$emit,在调用的不是非父子级关系时就会调用不到,所以此处,我们引入了bus(中央事件总线插件),所以我们定义了一个方法callFun,参数是按钮事件名称,通过this.$bus.emit('cllFun', methodName)的形式,将事件反射到列表上调用具体方法的实现,然后在列表页面上坚挺cllFun事件

cllFun(methodName) {
      this[methodName].apply(this)
    },

这样我们就可以将各个按钮的事件调用到了具体实现。到此,操作按钮的封装基本完整

4.最终效果

封装antd design vue table 组件_控件

操作按钮按照当前用户的授权,自动生成。

同时,也请其他高高手,批评改正,目前代码已上传到git,

这是传送门:https://github.com/GitHub-chao/SuperCodeVue