backend-management-ui
v1.7.16
Published
一个基于Vue+ElementUI封装的后台管理仓库,包含表格、表单、弹窗、按钮组、虚拟下拉框等常用组件
Maintainers
Readme
backend-management-ui
一个基于 ElementUI 封装的 Vue2 后台管理组件库,简化后台开发中表格、表单、弹窗、按钮组、虚拟下拉框等高频组件的使用。
现有组件:ui-form、ui-table、ui-btns、ui-dialog、ui-virtual-select、status
特性
- 基于ElementUI的二次封装,完全兼容ElementUI原有API与功能,无需额外适配
- 极简配置化开发:表格 / 表单 / 按钮组等组件通过 JSON 配置快速生成,无需重复写模板
- 高频业务场景全覆盖:内置配置化表格、表单、按钮组、虚拟滚动下拉框等核心组件
- 轻量无冗余:仅依赖 Vue2 + ElementUI + vue-virtual-scroll-list,无第三方冗余依赖,兼容低版本Node环境
- 基于 ElSelect + vue-virtual-scroll-list 实现海量数据下拉选择,解决大量数据渲染卡顿问题
安装
npm 安装
npm install backend-management-ui --save
如果安装报错,与 peerDependencies 冲突
npm install backend-management-ui --save --legacy-peer-deps
yarn 安装
yarn add backend-management-ui
安装虚拟滚动
npm install vue-virtual-scroll-list --save
快速上手
全局引入
// main.js
import Vue from 'vue'
import ElementUI from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css'
import BackendManagementUI from 'backend-management-ui'
Vue.use(ElementUI)
Vue.use(BackendManagementUI) // 全局注册所有组件,放在ElementUI后面按需引入
// main.js
import Vue from 'vue'
import { UiForm } from 'backend-management-ui'
// 全局注册单个组件
Vue.component('UiForm', UiForm)
// 组件内
import { UiForm } from 'backend-management-ui'
export default {
components: {
UiForm
}
}组件示例和文档
ui-form 表单
使用el-form进行的二次封装
基本用法
典型编辑型表单
<template>
<ui-form :model="searchForm" :formConfig="formConfig" label-width="100px"></ui-form>
</template>
<script>
export default {
data() {
return {
searchForm: {
orderNo: null,
status: null
},
formConfig: [
{
label: '订单号',
prop: 'orderNo',
component: 'el-input'
},
{
label: '状态',
prop: 'status',
component: 'el-select',
options: [
{ label: '成功', value: 0 },
{ label: '失败', value: 1 }
]
}
]
}
}
}
</script>典型展示表单
<template>
<ui-form :model="searchForm" :formConfig="formConfig" label-width="100px" :showOperateBtn="false">
<template #item-orderNo="{ item, model, index }">
<span>{{ model.orderNo }}</span>
</template>
<template #item-status="{ model }">
<span>{{ model.status }}</span>
</template>
</ui-form>
</template>
<script>
export default {
data() {
return {
searchForm: {
orderNo: "订单好xx",
status: "成功"
},
formConfig: [
{ label: '订单号', prop: 'orderNo', },
{ label: '状态', prop: 'status', }
]
}
}
}
</script>下拉类型接口获取数据
// 或者 :apiMapConfig="{ status: statusApi }"
<ui-form :model="searchForm" :formConfig="formConfig" label-width="100px" >
<template #customBtn>
<el-button type="primary">导出</el-button>
</template>
</ui-form>
<script>
import { statusApi } from "@/api/status"
export default {
data() {
return {
searchForm: {
orderNo: null,
status: null
},
formConfig: [
{
label: '订单号',
prop: 'orderNo',
component: 'el-input'
},
{
label: '状态',
prop: 'status',
component: 'el-select',
api: statusApi,
{/* 或者 */}
{/* api: {
url: statusApi,
params: {
page: 1,
pageSize: 10,
}
} */}
}
]
}
}
}
</script>其他用法
// Form Attributes/Methods直接传
<ui-form :model="searchForm" :formConfig="formConfig" inline label-width="100px">
</ui-form>
<script>
export default {
data() {
return {
searchForm: {
orderNo: "订单好xx",
status: "成功"
},
formConfig: [
{
label: "月份区间",
prop: "dates",
component: "el-date-picker",
attrs: {
type: "month",
"value-format": "yyyy-MM",
format: "yyyy年MM月",
clearable: false, // 所有的表单组件如果有clearable,默认是true
},
events: {
{/* el-date-picker的原生组件事件 */}
change: (val) => {
console.log(val)
},
},
}
{
label: '订单号',
prop: 'orderNo',
component: 'el-input',
{/* Form-Item Attributes */}
formItemAttrs: {
"label-width": "120px",
size: "small"
},
},
{
label: '状态',
prop: 'status',
component: 'el-select',
{/* 表单组件属性 */}
attrs: {
style: {
width: "200px", // 默认220px
},
filterable: true,
events: {
change: (val) => {
console.log(val)
}
}
},
{/* options有长度时不会触发api */}
options: [
{ label: "成功", value: 0 }
]
}
]
}
}
}
</script>props & slots & methods
props
| 参数 | 说明 | 类型 | 可选值 | 默认值 | | --------- | ----------- | -------- | ------ | --------- | | formRef | form的实例 | string | - | formRef | | model | 表单数据绑定对象 | object | - | {} | | formConfig | 表单配置项 | array | - | - | | showOperateBtn | 是否展示操作按钮 | boolean | - | true | | defaultBtn | 是否使用默认按钮 | boolean | - | true | | searchBtnText | 搜索按钮的文案 | string | - | 查询 | | resetBtnText | 重置按钮的文案 | string | - | 重置 | | apiMapConfig | api配置项 | object | - | - |
formConfig配置项
| name | 说明 | 类型 | 可选值 | 默认值 | | ----------- | ------------------- | ------- | --------- | ----------- | | label | 表单说明项 | string | - | - | | prop | 表单绑定的字段 | string | 必传 | - | | component | 绑定的组件, 当字段有插槽时不触发 | string | 组件名 | el-input | | formItemAttrs | el-form-item的属性项 | object | - | - | | attrs | 表单组件的属性和事件,当字段有插槽时不触发 | object | - | { style: { width: "220px" }} | | api | 组件为el-select/el-radio-group/virtual-select类型时不使用插槽且需要初始化时传入的api | object/ string | - | - | | options | 组件类型同上,当options有长度时api和apiMapConfig不会触发 | array | - | - |
slots
| name | 说明 | | ------ | ------ | | customBtn | 操作项的自定义的插槽 | | item-[prop字段名] | 表单组件的插槽 |
methods
| 方法名 | 说明 | | ----- | ---- | | search | 搜索按钮点击触发调用的方法 | | reset | 重置按钮点击触发调用的方法 |
ui-table 表格
使用el-table进行的二次封装
基本用法
表格用法
<ui-table show-selection show-operation :loading="loading" :table-columns="tableColumns" :data="tableData" :pagination-config="pagination" :total="total" :operation-config="{ width: 140 }" @change-pagination="handleChangePagination" @selectionChange="handleSelectionChange">
<template #header-test4>
<div>表头插槽</div>
</template>
<template #test4="{ row }">
<div>单元格插槽{{row.test4}}</div>
</template>
<template #operation="{ row }">
<ui-btns :btns="operateBtns" :context="row" />
</template>
</ui-table>
<script>
export default {
data() {
return {
loading: false,
tableColumns: [
{
label: "测试1",
prop: "test1",
"min-width": 150,
"show-overflow-tooltip": true,
fixed: "left",
},
{
label: "测试render一大一小的两行数据",
prop: "test2",
"min-width": 150,
"show-overflow-tooltip": true,
render: ({ row, column, $h, index }) => {
const { test2, test2Code } = row;
return $h("div", { style: { width: "100%" } }, [
$h("div", { class: "bm-table-cell" }, test2),
$h("div", { style: { color: "#AAAAAA", fontSize: "12px" } }, test2Code),
]);
}, // 单元格render形式
},
{
label: "测试组件",
prop: "test3",
width: 200,
component: 'Status', // 单元格使用component组件形式时,默认会把row,column,index 传入组件
componentProps: { statusName: "test3" }, // componentProps组件需要的参数
{/* componentEvents: {
change: (val) => {},
...
} // 组件的事件,如果有的话 */}
},
{
label: "测试4",
prop: "test4",
width: 100,
formatter: (val, row, index) => val || "-", // 单元格内容格式化
},
{
headerSlot: true, // 表头使用插槽
prop: "test5",
slot: true // 单元格插槽形式
},
{
label: "测试5-可点击的单元格", // 默认active样式
prop: "test5",
width: 100,
clickable: true, // 一直可点击 render形式、组件形式和插槽形式时不生效
{/* 或者使用条件判断
clickableClass: ({row}, col) => row[col.prop] > 0 */}
onCellClick: ({row, col, index}) => {} // 单元格可点击时触发的方法
}
],
tableData: [],
pagination: {
pageNum: 1,
pageSize: 10
},
total: 0,
operateBtns: [
{
label: "详情",
type: "text",
action: (params) => {
},
},
{
label: "操作记录",
type: "text",
action: ({ context }) => {
this.currentRow = context;
this.getOperateLogInfo();
},
},
],
currentRow: null
}
},
methods: {
init() {},
handleChangePagination(pagination) {
this.pagination = pagination
this.init()
},
handleSelectionChange(selection) {},
getOperateLogInfo() {}
}
}
</script>props & slots & methods
props
| 参数 | 说明 | 类型 | 可选值 | 默认值 | | --------- | ----------- | -------- | ------ | --------- | | data | 表格数据 | array | - | [] | | tableColumns | 表格配置项 | array | - | [] | | loading | 表格加载 | boolean | - | false | | showSelection | 是否展示勾选框 | boolean | - | false | | showIndex | 是否展示序号列 | boolean | - | false | | indexConfig | 序号列配置项 | object | - | { type: "index", label: "序号", width: 55, fixed: "left", align: "center", } | | showOperation | 是否展示操作列 | boolean | - | false | | operationConfig | 操作列配置项 | object | - | { label: "操作", prop:"operation", width: 180, fixed: "right", align: "center", } | | showPagination | 是否展示分页 | boolean | - | true | | paginationConfig | 分页配置项 | object | - | { pageNum: 1, pageSize: 10 } | | total | 数据总条数 | number | - | 0 |
methods
| 方法名 | 说明 | 参数 | | ----- | ---- | ---- | | change-size | 修改pageSize的方法 | pageSize | | change-page | 修改pageNum的方法 | pageNum | | change-pagination | 修改pageSize和pageNum的方法 | pagination |
ui-btns
使用el-button进行的二次封装
基本用法见table示例
props
| 参数 | 说明 | 类型 | 可选值 | 默认值 | | -------- | ----------- | -------- | ------ | --------- | | btns | 按钮数组 | array | - | - | | disabledAll | 禁用所有按钮 | boolean | - | false | | context | 上下文 | object/array/string/ number/ boolean | - | null |
btns
| 参数 | 说明 | 类型 | 可选值 | 默认值 | | -------- | ----------- | -------- | ------ | --------- | | 参数同el-button,disabled除外 | - | - | - | - | | disabled | 当前按钮的禁用状态 | boolean/function | - | false | | action | 点击事件 | function | - | - | | eventName | 点击事件的方法名,会emit出去eventName事件,action和eventName一起存在时会重复触发 | string | - |
ui-dialog
使用el-dialog进行的二次封装
基本用法
<ui-dialog
:visible.sync="show"
title="弹框标题"
confirm-text="确认"
width="60%"
show-cancel
@close="handleClose"
@cancel="handleCancel"
@confirm="handleConfirm"
>
弹框内容
</ui-dialog>
<script>
export default {
data() {
return {
show: false,
}
},
methods: {
handleClose() {},
handleCancel() {},
handleCancel() {},
}
}
</script>props
| 参数 | 说明 | 类型 | 可选值 | 默认值 | | -------- | ----------- | -------- | ------ | --------- | | visible | 是否显示 Dialog,支持 .sync 修饰符 | boolean | - | false | | title | 弹框标题 | string | - | 弹框标题 | | width | 弹框宽度 | string | - | 50% | | closeOnClickModal | 是否可以通过点击蒙层关闭弹框 | boolean | - | false | | closeOnPressEscape | 是否可以通过按下 ESC 关闭弹框 | boolean | - | false | | defaultFooter | 是否使用默认的弹框footer(即只有取消和确定按钮) | boolean | - | true | | showCancel | 是否展示取消按钮, defaultFooter为true时可用 | boolean | - | false | | cancelText | 取消按钮的文案 | string | - | 取消 | | showConfirm | 是否展示确定按钮,defaultFooter为true时可用 | boolean | - | true | | confirmText | 确定按钮的文案 | string | - | 确定 | | 其他参数同el-dialog | - | - | - | - |
methods
| 方法名 | 说明 | 参数 | | ----- | ---- | ---- | | cancel | 取消按钮点击的回调 | - | | confirm | 确定按钮点击的回调 | - | | close | 关闭弹框的回调 | - | | 其他事件同el-dialog | - | - |
slots
| 插槽名 | 说明 | 参数 | | ----- | ---- | ---- | | headerPrefix | 标题前面的修饰插槽 | - | | headerSuffix | 标题后面的修饰插槽 | - | | customFooter | 自定义footer,可以和defaultFooter配和使用 | - |
ui-virtual-select
使用 el-select + vue-virtual-scroll-list 进行的二次封装
基本用法
<ui-virtual-select v-model="select" multiple filterable :options="options"/>
<script>
export default {
data() {
return {
select: []
options: Array.from({ length: 1000 }, (_, index) => ({ label: `${index + 1}虚拟滚动数据`, value: index + 1 }))
}
}
}
</script>props
| 参数 | 说明 | 类型 | 可选值 | 默认值 | | -------- | ----------- | -------- | ------ | --------- | | value | 绑定的值 | string/number/array | - | - | | keeps | 下拉默认展示的个数 | number | - | 20 | | estimateSize | 下拉每项的高度 | number | - | 34 | | options | 下拉的数据 | array | - | 默认label/value类型的二维数组 | | 其他参数同el-select | - | - | - | - |
公共业务组件
Status
基本用法
<Status status-name="待提交" />props
| 参数 | 说明 | 类型 | 可选值 | 默认值 | | -------- | ----------- | -------- | ------ | --------- | | row | 传进来的整条数据 | object | - | {} | | statusName | 状态值,当row有传值时这个字段会被当做字段名 | string | 必传 | -|
使用时可能存在的项目不支持可选链和空值合并运算符的报错问题
安装必要的依赖
npm install @babel/plugin-proposal-optional-chaining @babel/plugin-proposal-nullish-coalescing-operator --save-dev.babelrc 或者 babel.config.js 文件 plugins字段添加
plugins: [
..., // 原有配置
"@babel/plugin-proposal-optional-chaining",
"@babel/plugin-proposal-nullish-coalescing-operator"
]文件 vue.config.js 新增指定babel去处理包里面的es6+语法
module.exports = {
..., // 原有配置
transpileDependencies: ["backend-management-ui"]
}