做过后端管理系统的“猿们”都知道,后端界面的框架无非就是左右结构【左边是菜单栏,右边是具体业务的功能界面】。但是右边的功能界面,我们又能拆分出来一些公用的控件:搜索栏、操作按钮栏、列表【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.最终效果

操作按钮按照当前用户的授权,自动生成。
同时,也请其他高高手,批评改正,目前代码已上传到git,
















