实现目标:将后台管理系统中的表单部分重新渲染实现成可配置的(通过数据库配置),动态的。需要支持系统中的所有附带搜索项的页面(如输入框、下拉框、日期、单选框等)
需求目标
- 封装可复用的组件需要根据后台数据渲染搜索模块
- 筛选条件需随配置表格列的内容可动态变化
方案
封装出公共搜索模块组件,使用与系统的各个有搜索功能的页面
将搜索、重置、收起功能放在一个组件DynamicForm
内,将搜索项放在另一个组件DynamicFormItem
。此处需要封装两个互为父子关系的组件。所需页面只是通过调用DynamicForm
组件来展示form
表单内容。
需要指定一个通用的配置信息的数据结构渲染组件页面。
数据结构
组件接受的数据如下:
与之前的原系统保持一致,渲染组件时请求获取下拉框的数据(包括请求接口返回的数据和获取的常量)
搜索栏中所需的数据格式
searchParams
:搜索对象,以系统管理页面为例。
{
currentPage:1,
pageSize:10,
employeeName: 'fei',
userName:'h',
sex:'SEX_MALE',
deptId:'11',
positionId:'987',
userStatus:'USER_STATUS_FORBIDDER'
}
表单搜索栏配置所需的数据结构
config
对象,描述当前页面的form
表单情况,渲染实际展示的搜索栏。以管理系统通用的用户页面为例。
config:{
attrs: {
'inline': false,
'labelPostion': 'right',
'labelWidth': '70px',
'size': 'small',
'stateIcon': true
},
layout: [{
attrs: {
gutter: 0
},
formItem: [{
itemAttrs: {
'type': 'input',
'label': '姓名',
'disable': false,
'readonly': false,
'placeholder': '请输入姓名',
'rules': [],
'key': 'employeeName',
'subtype': 'text',
'value': ''
}
}]
}, {
attrs: {
gutter: 0
},
formItem: [{
itemAttrs: {
'type': 'select',
'label': '性别',
'disable': false,
'readonly': false,
'placeholder': '请选择',
'rules': [],
'key': 'sex',
'subtype': 'text',
'value': '',
'options': [], // 注意此处的数据
},
},... ],
}, {
attrs: {
gutter: 0,
},
formItem: [{
itemAttrs: {
'type': 'date',
'label': '截止日期',
'disable': false,
'readonly': false,
'placeholder': '请选择',
'rules': [],
'key': 'endDate',
'value': '',
'options': [], // 注意此处的数据
},
}, ...],
},... ]
}
通用性问题
业务组件调用封装的组件
此处针对通用的用户页面来说,调用封装的组件
<dynamic-form ref='dynamicForm' :config='config' v-model='object'
@putHandle='handleCollapse' @searchHandleEvent='getListData(1)' />
- 搜索表单
通过v-for
循环渲染不同搜索项,并且将原来的搜索事件,重置事件,收起事件进行原样移植
- 控制渲染的搜索项label
根据后台接口返回的数据渲染搜索条件
搜索表单
封装的DynamicForm
组件上绑定系统中已有的事件,搜索事件、重置事件、收起事件等
<el-form-item v-for="con in config.layout" :key="con.key">
<div v-for="item in con.formItem" :key="item.itemAttrs.key" class="item-width">
<dynamic-form-item
v-if="value[item.itemAttrs.key]!==undefined"
:key="item.itemAttrs.key"
:item="item.itemAttrs"
v-bind="item.itemAttrs"
:value="value[item.itemAttrs.key]"
@input="handleInput($event,item.itemAttrs.key)"
/>
</div>
</el-form-item>
<el-form-item class="search_btn">
<!-- 搜索按钮 -->
<dr-btn-search @click="searchEvent"/>
<!-- 重置按钮 -->
<dr-btn-search-reset @click="reset"/>
<!-- 收起按钮 -->
<dr-btn-search-cancel @click="putArea"/>
</el-form-item>
注意此处的搜索参数与重置参数
搜索事件触发时调用父组件的搜索接口方法,根据this.object
对象获取相应的参数
重置事件触发时只需要调用setDefaultValue
方法即可
收起事件触发时调用父组件的收起方法
控制渲染的搜索项,封装的DynamicFormItem
组件
<template>
<el-form-item :rules="Rules" :label="item.label" :prop="item.key" class="item-style">
<dr-input v-if="item.type==='input' v-bind="$attrs" :type="item.type"
:placeholder="item.placeholder"
:disabled="item.disabled"
:readonly="item.readonly"
maxlength="48"
v-on="$listeners"/>
<el-select v-else-if="item.type==='select' v-bind="$attrs"
:multiple="item.multiple"
:disabled="item.disabled"
clearable
v-on="$listeners">
<el-option v-for="o in item.options" :key="o.key||o.id"
:label="o.label||o.lookupName" :value="o.value||o.lookupCode"/>
</el-select>
<el-date-picker v-else-if="item.type==='date' v-bind="$attrs"
:type="item.type"
:placeholder="item.placeholder" clearable v-on="$listeners"/>
</el-form-item>
</template>
后期扩展性
还可以扩展出checkbox,radio,time等