前言
写了个类似上篇搜索的封装,但是要考虑的东西更多。
具体业务比展示的代码要复杂,篇幅太长就不引入了。
效果图
-
2019-04-25
-
添加了下拉多选的渲染,并搜索默认过滤文本而非值
-
简化了渲染的子组件的代码
-
2019-04-28
- 增加了对
input type
的控制
- 增加了对
实现思路和功能
基础的功能直接配置上来渲染,而上传组件就不大合适了;
所以选择了slot
来实现,如何保证传入的form-item
的布局一致,则是拿slot-scope
我这边选型用的是vue 2.6 +
的版本,所以直接用的是最新的写法
而且作为表单组件,校验这些肯定需要考虑,所以数据的构造改造了下,
对于校验规则这些走的是antd form
用的那套,所以在传递的时候把对应的属性拍平了,
到里面再进行数据结构调整,目前部分控件样式依旧需要自己修正!!!
演示的代码用法
<form-list @change="onFormListChange">
<template #field="{options}">
<a-form-item label="Upload" v-bind="options">
<a-upload
v-decorator="[
'upload',
{
valuePropName: 'fileList',
getValueFromEvent: normFile
}
]"
name="logo"
action="/upload.do"
list-type="picture"
>
<a-button> <a-icon type="upload" /> Click to upload </a-button>
</a-upload>
</a-form-item>
</template>
</form-list>
代码
- FieldRender.vue
<template>
<a-form-item
:label="fieldOptions.labelText"
:label-col="fieldOptions.labelCol"
:wrapper-col="fieldOptions.wrapperCol"
>
<a-input
v-if="fieldOptions.fieldName && fieldOptions.type === 'text'"
:size="fieldOptions.size ? fieldOptions.size : 'default'"
v-decorator="[
fieldOptions.fieldName,
{
initialValue: fieldOptions.defaultValue ? fieldOptions.defaultValue : '',
rules: Array.isArray(fieldOptions.rules) && fieldOptions.rules.length > 0 ? fieldOptions.rules : []
}
]"
:placeholder="fieldOptions.placeholder"
/>
<a-select
v-else-if="fieldOptions.fieldName && fieldOptions.type === 'select'"
style="width: 100%"
showSearch
:options="fieldOptions.options"
:filterOption="selectFilterOption"
:size="fieldOptions.size ? fieldOptions.size : 'default'"
allowClear
v-decorator="[
fieldOptions.fieldName,
{
initialValue: fieldOptions.defaultValue ? fieldOptions.defaultValue : undefined,
rules: Array.isArray(fieldOptions.rules) && fieldOptions.rules.length > 0 ? fieldOptions.rules : []
}
]"
:placeholder="fieldOptions.placeholder"
/>
<a-input-number
v-else-if="fieldOptions.fieldName && fieldOptions.type === 'number'"
:size="fieldOptions.size ? fieldOptions.size : 'default'"
:min="fieldOptions.min ? fieldOptions.min : 1"
style="width: 100%"
v-decorator="[
fieldOptions.fieldName,
{
initialValue: fieldOptions.defaultValue ? fieldOptions.defaultValue : '',
rules: Array.isArray(fieldOptions.rules) && fieldOptions.rules.length > 0 ? fieldOptions.rules : []
}
]"
:placeholder="fieldOptions.placeholder"
/>
<a-radio-group
v-else-if="fieldOptions.fieldName && fieldOptions.type === 'radio' && Array.isArray(fieldOptions.options)"
:size="fieldOptions.size ? fieldOptions.size : 'default'"
buttonStyle="solid"
v-decorator="[
fieldOptions.fieldName,
{
initialValue: fieldOptions.defaultValue ? fieldOptions.defaultValue : '',
rules: Array.isArray(fieldOptions.rules) && fieldOptions.rules.length > 0 ? fieldOptions.rules : []
}
]"
>
<template v-for="(item, index) in fieldOptions.options">
<a-radio-button :key="index" :value="item.value">{
{ item.label }} </a-radio-button>
</template>
</a-radio-group>
<a-date-picker
v-else-if="fieldOptions.fieldName && fieldOptions.type === 'datetime'"
:size="fieldOptions.size ? fieldOptions.size : 'default'"
:placeholder="fieldOptions.placeholder"
v-decorator="[
fieldOptions.fieldName,