引言
在项目开发过程中,我们常常会遇到各种按钮组操作的需求。无论是表单区域,还是表格展示中的操作列,都可能包含大量的操作按钮。然而,过多的按钮不仅会让界面显得杂乱无章,还会占据大量空间,影响用户体验。在这种情况下,一个动态按钮组组件就显得尤为重要。
接下来,我将详细介绍如何在 Vue2 和 ElementUI 的框架下封装这样一个动态按钮组组件,帮助你在项目开发中更加高效地管理按钮操作。
需求分析
1. 基本功能需求
- 动态按钮组显示
- 接收一组按钮配置(
buttonList),并根据配置渲染按钮。 - 提供一个属性(如
maxVisibleButtons)用于控制最多显示几个按钮。超出部分的按钮将通过el-dropdown下拉菜单展示。 - 默认情况下,按钮显示其
label属性的内容,支持自定义按钮内容展示。
- 接收一组按钮配置(
- 事件支持
- 每个按钮点击时触发
click事件,事件参数为当前点击按钮的配置信息(info)。
- 每个按钮点击时触发
2. 组件功能扩展
- 支持 ElementUI 的
el-button属性- 动态按钮组支持传递
el-button的所有props,以便开发者可以自定义按钮的样式、类型、大小等属性。
- 动态按钮组支持传递
- 下拉菜单(
el-dropdown)功能- 支持自定义
el-dropdown的样式或行为(ElementUI 的el-dropdown部分属性,如:{ trigger: "click", placement: "bottom-start" })。 - 支持自定义
el-dropdown的触发内容,默认为el-button。 el-dropdown-item支持自定义内容展示,默认显示按钮配置中的label属性。
- 支持自定义
实现细节
定义 Props
props: {
// 按钮数组
buttonList: {
type: Array,
required: true,
},
// 最多显示的按钮数量
maxVisibleButtons: {
type: Number,
default: 3,
},
// 按钮公共Props
buttonProps: {
type: Object,
default: () => ({}),
}
// 下拉选择框Props
dropdownProps: {
type: Object,
default: () => ({}),
}
}
计算属性
computed: {
// 显示的按钮组
visibleButtons() {
return this.buttonList.slice(0, this.maxVisibleButtons);
},
// 隐藏的按钮组
hiddenButtons() {
return this.buttonList.slice(this.maxVisibleButtons);
},
// 是否有隐藏的按钮
hasHiddenButtons() {
return this.hiddenButtons.length > 0;
}
}
方法
methods: {
handleClick(button) {
this.$emit("click", button);
}
}
编写 template
<div>
<!-- 默认显示的按钮 -->
<el-button
v-for="btn in visibleButtons"
:key="btn.key"
v-bind="{...buttonProps,...btn.props}"
@click="handleClick(btn)"
>
<slot :name="btn.key" :scope="btn">
{{ btn.label }}
</slot>
</el-button>
<!-- 超出部分的下拉按钮 -->
<el-dropdown class="more-dropdown" v-if="hasHiddenButtons" v-bind="dropdownProps" @command="handleClick">
<slot name="dropdown">
<el-button type="primary">
更多<i class="el-icon-arrow-down el-icon--right"></i>
</el-button>
</slot>
<el-dropdown-menu>
<el-dropdown-item
v-for="btn in hiddenButtons"
:key="btn.key"
v-bind="{...buttonProps,...btn.props}"
:command="btn"
>
<slot :name="btn.key" :scope="btn">{{ btn.label }}</slot>
</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</div>
样式
<style scoped>
.more-dropdown {
margin-left: 10px;
}
</style>
组件源码
<script>
export default {
name: "DynamicButtonGroup",
props: {
// 按钮数组
buttonList: {
type: Array,
required: true,
},
// 最多显示的按钮数量
maxVisibleButtons: {
type: Number,
default: 3,
},
// 按钮公共Props
buttonProps: {
type: Object,
default: () => ({}),
}
// 下拉选择框Props
dropdownProps: {
type: Object,
default: () => ({}),
}
},
computed: {
// 显示的按钮组
visibleButtons() {
return this.buttonList.slice(0, this.maxVisibleButtons);
},
// 隐藏的按钮组
hiddenButtons() {
return this.buttonList.slice(this.maxVisibleButtons);
},
// 是否有隐藏的按钮
hasHiddenButtons() {
return this.hiddenButtons.length > 0;
},
},
methods: {
handleClick(button) {
this.$emit("click", button);
},
},
}
</script>
<template>
<div>
<!-- 默认显示的按钮 -->
<el-button
v-for="btn in visibleButtons"
:key="btn.key"
v-bind="{...buttonProps,...btn.props}"
@click="handleClick(btn)"
>
<slot :name="btn.key" :scope="btn">
{{ btn.label }}
</slot>
</el-button>
<!-- 超出部分的下拉按钮 -->
<el-dropdown class="more-dropdown" v-if="hasHiddenButtons" v-bind="dropdownProps" @command="handleClick">
<slot name="dropdown">
<el-button type="primary">
更多<i class="el-icon-arrow-down el-icon--right"></i>
</el-button>
</slot>
<el-dropdown-menu>
<el-dropdown-item
v-for="btn in hiddenButtons"
:key="btn.key"
v-bind="{...buttonProps,...btn.props}"
:command="btn"
>
<slot :name="btn.key" :scope="btn">{{ btn.label }}</slot>
</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</div>
</template>
<style scoped>
.more-dropdown {
margin-left: 10px;
}
</style>
FAQ
对于按钮权限处理,可以在 buttonList 的每个按钮中定义一个 permission 属性。在使用动态按钮组的页面中,通过一个计算属性调用权限判断方法,使用 filter 方法过滤出具有权限的按钮组。
感谢阅读,敬请斧正!