一、前言
您相信吗?实现下面的新增、查询、编辑、删除、批量删除、分页等功能只需要
一个组件
?
本文将分享该组件的封装,也是和各位一起交流学习一下组件封装的思路,从而得到提升,也会将此组件源码开源出来交流使用,如果你想用于生产环境你可以阅读组件,进行稍加改造;
[video(video-HJvJbG0F-1678764820957)(type-csdn)(url-live.csdn.net/v/embed/282…)]
带你看下vue的template标签有什么内容,不难看出它是通过options变量来控制查询项,表单项、操作列等等功能
<template>
<div class='z-crud-demo hidden-container'>
<zCrud ref="zCrud" v-bind="options" @save="save" @search="search" @search-reset="searchReset" @remove="remove"
@multiple-remove="multipleRemove" @pagination-size-change="paginationSizeChange"
@pagination-current-change="paginationcurrentChange" @before-edit="beforeEdit">
<!-- 插槽格式化文案 -->
<template #category="{ row }">{{ categoryFormat(row.category) }}</template>
</zCrud>
</div>
</template>
二、参数总览
看到这么多配置参数你是不是慌了,其实
绝大多数
参数你都不需要配置
,参数多只是为了有特殊化的需求的出现;
字段 | 说明 |
---|---|
searchOption | 搜索参数配置对象 |
columns | 列配置数组 |
handleOption | 操作列配置对 |
paginationOption | 分页配置对象 |
formItemOption | 表单项配置对象 |
toolbarOption | 工具栏配置对象 |
tableOption | 表格配置对象 |
selectionOption | 多选配置对象 |
indexOption | 索引配置对象 |
dialogOption | 弹窗配置对象 |
formOption | 表单配置对象 |
component | 组件配置对象 |
1. 搜索配置对象searchOption
当然你也可以将elementUI的form组件的属性维护在此对象,同样生效
字段 | 说明 | 类型 | 默认值 | 是否必填 |
---|---|---|---|---|
query | 搜索对象 | object | ||
gutter | form-item之间的padding | number | 20 | |
size | 尺寸 | string | small |
1.1 查询项配置对象query
字段 | 说明 | 类型 | 默认值 | 是否必填 |
---|---|---|---|---|
label | 文案 | string | ||
value | 值,可以设置默认值 | any | undefined | |
component | 组件配置项目,详细请看指定章节 点我跳转 | object |
示例:
searchOption: {
query: {
name: {
label: '商品名称',
component: {
name: 'el-input',
disabled: false,
span: 8,
}
},
stock: {
label: '库存数量',
component: {
name: 'el-input',
disabled: false,
span: 8,
}
},
category: {
label: '商品分类',
value: 1,
component: {
name: 'el-select',
span: 8,
options: [
{
label: '全部',
value: 1
},
{
label: '家电',
value: 2
},
{
label: '家具',
value: 3
},
{
label: '食物',
value: 4
},
]
}
},
}
},
2. 列配置数组columns
字段 | 说明 | 类型 | 默认值 | 是否必填 |
---|---|---|---|---|
label | form-item-label的文案 | string | ||
field | 对应form-item-label的prop | string |
示例
columns: [
{
label: '商品名称',
field: 'name',
},
{
label: '商品价格',
field: 'price',
},
{
label: '商品库存',
field: 'stock',
},
{
label: '商品分类',
field: 'category',
},
{
label: '状态',
field: 'status',
},
{
label: '过期日期',
field: 'expirationDate',
},
],
3. 操作列配置对象handleOption
默认状态下是开启操作列的,您甚至连handleOption都无需配置,如果你需要关闭则维护下面代码 handleOption: { show:false}
字段 | 说明 | 类型 | 默认值 | 是否必填 |
---|---|---|---|---|
show | 是否展示操作列 | boolean | true | |
edit | 编辑按钮,详细请看点击跳转 | object | ||
remove | 删除按钮,详细请看点击跳转 | object | ||
custom | 其它自定义按钮,详细请看点击跳转 | object |
示例
handleOption: {
width:'360px',
show: true,//默认开启的
edit: {
text: '编辑', //按钮文字, null= 取消文字
icon: 'el-icon-edit', //按钮图标
disabled: (index, row) => {
if (row.category == 3) return true
return false
},// 是否禁用
},
remove: {
icon: 'el-icon-delete', //按钮图标
},
custom: [
{
text: '进货', //按钮文字, null= 取消文字
icon: 'el-icon-thumb', //按钮图标
type:'warning'
}
]
},
4. 分页配置对象paginationOption
elementUI的pagination组件属性维护到paginationOption对象同样生效
字段 | 说明 | 类型 | 默认值 | 是否必填 |
---|---|---|---|---|
currentPage | 当前页 | number | ||
pageSize | 展示条数 | number | ||
total | 总数 | number |
示例
paginationOption: {
currentPage: 1,
pageSize: 20,
total: 0
},
5. 表单项配置对象formItemOption
新增、修改弹窗下的el-form-item标签的属性拓展配置对象
字段 | 说明 | 类型 | 默认值 | 是否必填 |
---|---|---|---|---|
label | 文案 | string | ||
value | 值,可以设置默认值 | any | undefined | |
component | 组件配置项目,详细请看指定章节 点我跳转 | object |
示例也可以参照此章节点我跳转
6. 工具栏配置对象toolbarOption
默认是开启工具栏功能的,如果需要关闭只需要配置toolbarOption:{show:false}
字段 | 说明 | 类型 | 默认值 | 是否必填 |
---|---|---|---|---|
show | 是否显示工具栏 | boolean | true | |
create | 新增按钮,详细请看点击跳转 | object | ||
multipleRemove | 批量删除按钮,详细请看点击跳转 | object |
示例
toolbarOption: {
show:true,//默认是开启的
create:{
icon: 'el-icon-circle-plus-outline', //按钮图标
},
multipleRemove:{
icon: 'el-icon-delete',
}
},
7. 表格配置对象tableOption
绝大多数情况下您无需配置,可以将elementUI的table组件的属性作用于此对象
8. 多选配置对象selectionOption
默认是
开启
表格勾选功能的,同时如果关闭表格勾选功能的话批量删除
功能也会关闭
字段 | 说明 | 类型 | 默认值 | 是否必填 |
---|---|---|---|---|
show | 是否需要多选表格 | boolean | true |
9. 索引配置对象indexOption
该功能默认是
关闭
的,如果你要开启只需要穿个空对象即可,也就是indexOption:{}
10. 弹窗配置对象dialogOption
绝大多数情况下您无需配置,可以将elementUI的dialog组件的属性作用于此对象
字段 | 说明 | 类型 | 默认值 | 是否必填 |
---|---|---|---|---|
editTitle | 编辑时的弹窗title文案 | string | 编辑 | |
createTitle | 新增时的弹窗title文案 | string | 新增 |
11. 表单配置对象formOption
新增、修改弹窗下的el-form标签的属性拓展配置对象,绝大多数下,您无需配置;
字段 | 说明 | 类型 | 默认值 | 是否必填 |
---|---|---|---|---|
rules | 表单校验规则 | object |
示例
formOption: {
rules: {
name: [{ required: true, trigger: 'blur', message: '此项是必填项' }],
price: [{ required: true, trigger: 'blur', message: '此项是必填项' }],
stock: [{ required: true, trigger: 'blur', message: '此项是必填项' }],
category: [{ required: true, trigger: 'blur', message: '此项是必填项' }],
expirationDate: [{ required: true, trigger: 'blur', message: '此项是必填项' }],
},
},
12. 组件配置对象component
- 此处的组件配置对象,主要用于searchOption.query(搜索的form-item)、formItemOption(弹窗的form-item)
- 您也可以将elmentUI组件的属性配置到此对象,采用v-bind="$attrs" elementUI属性同样生效
字段 | 说明 | 类型 | 默认值 | 是否必填 |
---|---|---|---|---|
name | 组件类型名称 | string | el-input | |
span | col的span,总列24列 | number | 24 | |
options | 部分组件的选项;如下拉框。多选框,单选框等组件 | array | ||
show | 组件是否显示,可以是一个boolean,也可以是一个函数 ,函数有一个回调参数mode,如下所示为只在新增 时才显示:show(mode){return mode=='create'} | Boolean \ Function | true | |
disabled | 是否禁用,用法同show | Boolean \ Function | false | |
event | 事件,请参照下方示例 | object | ||
props | 使用自定义组件时候,传递参数,查看示例 | object | ||
on | 使用自定义组件时候的事件,查看示例 | object |
示例
category: {
label: '商品分类',
value:3,//默认值3
component: {
name: 'el-select', //组件类型
span: 12,//占12格子
clearable:true,//elementUI属性,同样生效
event:{ //事件
focus(e){
console.log(e);
},
change(e){
console.log("🚀 ~ file: options.js:134 ~ change ~ change:",e)
}
},
options: [ //部分组件需要选项
{
label: '家电',
value: 2
},
{
label: '家具',
value: 3
},
{
label: '食物',
value: 4
},
]
}
},
13. button配置对象
针对的是配置对象下的create、edit、remove、multipleRemove按钮的配置
字段 | 说明 | 类型 | 默认值 | 是否必填 |
---|---|---|---|---|
text | 按钮文案 | string | ||
primary | 按钮类型 | string | ||
size | 按钮尺寸 | string | ||
circle | 原型按钮 | boolean | ||
show | 按钮是否显示,可以是一个boolean,也可以是一个函数 ,函数有一个回调参数mode,如下所示为只在新增 时才显示:show(mode){return mode=='create'} | Boolean \ Function | true | |
disabled | 是否禁用,用法同show | Boolean \ Function | false |
示例
edit:{
text: '编辑', //按钮文字, null可以取消文案
type: 'warning', // 按钮类型 可选值【primary / success / warning / danger / info / text】
icon:'icon-edit', //按钮图标
size: 'small', // 按钮大小
circle: false,//圆形按钮 ,需要thin=true,且text=null
show(mode){return mode=='create'}
disabled:false, // 是否禁用
}
三、事件
提示:在dialog-before-open和before-edit执行时机是相同的,只是参数不一样,在此时机内部已经实现了
表单重置
,您无需手动重置;
事件 | 说明 | 参数 |
---|---|---|
search | 搜索事件 | |
search-reset | 搜索条件重置事件,内部会将分页的参数重置 | 无 |
save | 保存事件(包括新增和编辑) | form为表单数据;mode为模式:create\edit |
pagination-current-change | 分页currentPage改变事件 ,内部会更改分页的currentPage,您无需手动更改 | currentPage |
pagination-size-change | 分页Size改变事件 ,内部会更改分页的pageSize,您无需手动更改 | pageSize |
remove | 删除事件 | 当前行数据 |
multiple-remove | 批量删除事件 | 选中行数据 |
before-edit | 操作列点击编辑按钮之前的事件 | 当前行数据row,和索引index |
dialog-before-open | 弹窗打开之前的事件(包括新增和编辑),编辑模式下事件时机与before-edit一样,只是回调参数不一样 | 当前模式mode |
dialog-after-open | 操作列点击编辑按钮之后的事件 | 当前模式mode |
dialog-close | 弹窗关闭事件 | 无 |
search-item-change | 单个搜索条件change事件 | raw修改的项数据,field修改的键 |
form-item-change | 弹窗表单项change事件 | raw修改的项数据,field修改的键,mode当前模式 |
四、插槽
事件 | 说明 | 参数 |
---|---|---|
toolbar | 工具栏插槽 | 无 |
beforeSave | 弹窗在【保存】按钮之前的插槽 | 表单数据 |
afterSave | 弹窗在【保存】按钮之后的插槽 | 表单数据 |
五、方法(重要)
内部通过计算属性挂载了一个refs.zCrud.$z.xxx()来执行方法
方法 | 说明 | 参数 | 返回值 |
---|---|---|---|
getParam | 因为我们的配置对象是带组件信息的,不能用于参数传与后端,可以通过$z.getParam() 获取到正常的查询参数 | 返回一个带分页数据,用于请求后端的数据 | |
showLoading | 内部实现了开启loading的方法 | 无 | 无 |
hideLoading | 内部实现了关闭loading的方法 | 无 | 无 |
setFormItemData | 因为我们的表单配置对象是带组件信息的,可以通过$z.setFormItemData(res.data)转换成正常的表单对象 | 需要传递一个后端返回的数据 | 无 |
resetPagination | 重置分页对象 | 无 | 无 |
resetFormItemOption | 重置表单对象,已经内部实现重置,基本上无需手动调用 | 无 | 无 |
getSelection | 获取表格勾选的数据,返回的是一个Promise | 无 | 无 |
示例
/**从后端获取列表数据 */
async getList() {
// 因为我们的配置对象是带组件信息的,不能用于参数传与后端,可以通过$z.getParam() 获取到正常的查询参数,
//并且如果你开启了分页,那么分页参数也会带过来
const param = this.$refs.zCrud.$z.getParam()
//内置了一个开启loading的方法
this.$refs.zCrud.$z.showLoading()
// 参数与
const res = await getList(param)
//将数据给到data
this.options.data = res.data.list
//将分页总数给到分页对象
this.options.paginationOption.total = res.data.total
//内置了一个关闭loading的方法
this.$refs.zCrud.$z.hideLoading()
},
六、自定义组件的使用
无可厚非,项目中你肯定会用到非ElementUI的组件,那么zCrud久黔驴技穷了嘛?请看示例
假设我有一个封装好的验证码发送组件,这个组件也是支持v-mode绑定值的
那么你可以看下面的示例
import zCaptcha from '@/components/z-captcha'
formItemOption: {
code:{
label:'验证码',
component: {
name: zCaptcha,
span: 12,
props:{
placeholder:'请获取验证码'
},
on:{
getCaptcha(){
console.log('开始模拟请求后端的短信接口');
}
}
}
}
}
七、源码地址
如果此项目对你有帮助,麻烦到github源码地址点个start