BaseInput
<template>
<component
v-bind="$attrs"
:is="inputType"
v-model="inputValue"
:style="defaultStyle"
:type="componentType"
v-on="$listeners"
@input="(val)=>$emit('changeValue',val)"
>
<template v-if="Array.isArray(childrenOptions)">
<component
:is="getChildrenType"
v-for="item in childrenOptions"
:key="item.value"
:value="item.value"
:label="item.value"
>
{{ item.label }}
</component>
</template>
<template v-else>
<component
:is="getChildrenType"
v-for="(item,key) in childrenOptions"
:key="key"
:value="key"
:label="item"
>
{{ item }}
</component>
</template>
</component>
</template>
<script>
export default {
name: 'BaseInput',
model: {
prop: 'value',
event: 'changeValue'
},
props: {
value: {
type: [String, Array, Number, Date, Boolean],
default: null
},
inputType: {
type: String,
default: 'Input'
},
childrenOptions: {
type: [Array, Object],
default: () => []
},
componentType: {
type: String,
default: undefined
}
},
data () {
return {
inputValue: undefined
}
},
computed: {
getChildrenType () {
const typeMap = {
RadioGroup: 'Radio',
Select: 'Option',
CheckboxGroup: 'Checkbox'
}
return typeMap[this.inputType] || ''
},
defaultStyle () {
const widthMap = {
Input: '150px',
Select: '150px',
DatePicker: '150px',
Cascader: '150px'
}
return {
width: widthMap[this.inputType] || ''
}
}
},
watch: {
value (val) {
this.inputValue = val
}
}
}
</script>
XForm
<template>
<Form
ref="form"
:model="formValue"
v-bind="$attrs"
v-on="$listeners"
>
<slot name="preItem" />
<FormItem
v-for="item in options"
:key="item.key"
:prop="item.key"
:label="item.itemLabel"
:label-width="item.itemLabelWidth"
v-bind="item.formItemOptions"
>
<BaseInput
v-model="formValue[item.key]"
v-bind="getAttr(item)"
v-on="getListener(item)"
@on-change="setFormData"
/>
</FormItem>
<slot />
</Form>
</template>
<script>
import BaseInput from './BaseInput.vue'
export default {
name: 'XForm',
components: {
BaseInput
},
model: {
prop: 'formData',
event: 'formChange'
},
props: {
formData: {
type: Object,
required: true
},
formOptions: {
type: [Array, Function],
default: () => []
}
},
data () {
return {
formValue: {}
}
},
computed: {
options () {
if (typeof this.formOptions === 'function') {
return this.formOptions()
} else {
return this.formOptions
}
}
},
mounted () {
this.formValue = this.formData
},
methods: {
setFormData () {
this.$emit('formChange', this.formValue)
},
isListener (key) {
//判断传入参数是否为事件
const preStr = key.substring(0, 2)
return preStr.toLowerCase() === 'on'
},
formatListenerName (name) {
const str = name.charAt(2)
if (str === '-') {
return name
} else {
return 'on-' + name.substring(2).toLowerCase()
}
},
getAttr (item) {
const attrs = {}
for (const i in item) {
if (typeof item[i] !== 'function') {
attrs[i] = item[i]
} else {
if (!this.isListener(i)) {
attrs[i] = item[i]
}
}
}
delete attrs.itemLabel
delete attrs.itemLabelWidth
delete attrs.itemoptions
delete attrs.key
return attrs
},
getListener (item) {
const listeners = {}
for (const i in item) {
if (typeof item[i] === 'function') {
if (this.isListener(i)) {
listeners[this.formatListenerName(i)] = item[i]
}
}
}
return listeners
},
async validate () {
const flag = await this.$refs.form.validate()
return flag
},
async validateField (prop) {
const flag = await this.$refs.form.validateField(prop)
return flag
},
resetFields () {
this.$refs.form.resetFields()
this.$emit('formChange', this.formValue)
}
}
}
</script>
BaseInput组件说明
使用配置化参数生成iview基础表单组件
参数
params | type | remark |
---|---|---|
inputType | String | 对应iview组件类型,可传入Input,Select,DatePicker,等对应iview表单基础组件名称 |
childrenOptions | Object或Array | 用于含有子组件的表单组件配置,比如Select,RadioGroup,CheckboxGroup等 |
componentType | String | 含有type属性值的表单组件使用,等于传入组件的type属性值,比如DatePicker |
others | --- | iview组件文档中定义属性均可作为参数传入 |
使用
Input
<BaseInput v-model="name" inputType="Input" placeholder="请输入姓名">
Select
<BaseInput
v-model="status"
input-type="Select"
:children-options="childrenOptions"
/>
childrenOptions: [
{
label: '标签1',
value: '1'
},
{
label: '标签2',
value: '2'
}
]
XForm组件说明
使用配置化参数生成Form表单
参数
params | type | remark |
---|---|---|
formOptions | Array | 组件配置文件,使用BaseInput生成对应组件 |
others | --- | iview组件文档中定义Form属性均可作为参数传入 |
formOptions参数
params | type | remark |
---|---|---|
key | string | v-model绑定的属性名 |
itemLabel | string | formItem的label |
itemLabelWidth | number | formItem的label宽度 |
itemOptions | object | formItem的属性值对象 |
others | --- | BaseInput属性均可传入 |
当传入属性为方法时,on开头函数名的函数会被标识为事件,函数支持驼峰命名或横杠命名
使用
<XForm
v-model="formData"
:form-options="formOptions"
/>
formOptions = [
{
key: 'name',
itemLabel: '姓名',
itemLabelWidth: 120,
style: { width: '200px' },
inputType: 'Input',
placeholder: '请输入姓名'
},
{
key: 'textarea',
itemLabel: '姓名',
inputType: 'Input',
componentType: 'textarea',
placeholder: '请输入'
},
{
key: 'status',
itemLabel: '状态',
inputType: 'Select',
placeholder: '请选择状态',
childrenOptions: [
{
label: '状态1',
value: '1'
},
{
label: '状态2',
value: '2'
}
]
},
{
key: 'i-switch',
itemLabel: '开关',
inputType: 'i-switch'
}
]