前置条件,请先浏览
需求场景,当国家控件选择为“美国”时,要求:
- 禁用“姓名”输入框
- 隐藏“兴趣爱好”多选框
- “个人简介”由选填改为必填
动态表单组件dynamic-form.vue
新增hidden
属性控制显示隐藏,新增disabled
属性控制是否禁用
新增对应的配置项,如
废话少说,直接上完整代码:
dynamic-form.vue
文件
<template>
<div>
<a-form :form="form" ref="form" :label-col="labelCol" :wrapper-col="wrapperCol">
<div v-for="field in fieldItemOptions" :key="field.key">
<a-form-item :label="field.label" :required="field.required" v-if="!field.hidden">
<!-- text文本框 -->
<template v-if="field.type === 'text'">
<a-input
v-decorator="[
field.key,
{
rules: [{ required: field.required, message: `${field.label}不能为空` }],
initialValue: field.value
},
]"
:placeholder="`请输入${field.label}`"
:disabled="field.disabled"
></a-input>
</template>
<!-- textarea 文本域 -->
<template v-else-if="field.type === 'textarea'">
<a-textarea
v-decorator="[
field.key,
{
rules: [{ required: field.required, message: `${field.label}不能为空` }],
initialValue: field.value
},
]"
:placeholder="`请输入${field.label}`"
:auto-size="{ minRows: field.minRows || 5, maxRows: field.maxRows || 8 }"
:maxLength="field.max || 256"
:disabled="field.disabled"
/>
</template>
<!-- select下拉框 -->
<template v-else-if="field.type === 'select'">
<a-select
:placeholder="`请选择${field.label}`"
v-decorator="[
field.key,
{
rules: [{ required: field.required, message: `请选择${field.label}` }],
initialValue: field.value
},
]"
>
<a-select-option
v-for="option in field.options"
:key="option.value"
:value="option.value"
>{{option.label}}</a-select-option>
</a-select>
</template>
<!-- checkbox多选框 -->
<template v-else-if="field.type === 'checkbox'">
<a-checkbox-group
v-decorator="[
field.key,
{
rules: [{ required: field.required, message: `请选择${field.label}` }],
initialValue: field.value
},
]"
>
<a-checkbox
v-for="option in field.options"
:key="option.value"
:value="option.value"
:style="{width: field.width}"
>{{option.label}}</a-checkbox>
</a-checkbox-group>
</template>
<!-- radio单选框 -->
<template v-else-if="field.type === 'radio'">
<a-radio-group
v-decorator="[
field.key,
{
rules: [{ required: field.required, message: `请选择${field.label}` }],
initialValue: field.value
},
]"
>
<a-radio
v-for="option in field.options"
:key="option.value"
:value="option.value"
>{{option.label}}</a-radio>
</a-radio-group>
</template>
</a-form-item>
</div>
</a-form>
<a-button type="primary" @click="handleSubmit()">提交</a-button>
</div>
</template>
<script>
import { deepClone } from "@/common/utils";
export default {
props: {
// 表单域配置
fieldOptions: {
type: Array,
default: () => []
},
// 编辑时表单回显的默认数据
model: {
type: Object,
default: () => ({})
},
// 标签宽度
labelCol: {
type: Object,
default: () => {
return {
xs: { span: 24 },
sm: { span: 6 }
};
}
},
// 控件宽度
wrapperCol: {
type: Object,
default: () => {
return {
xs: { span: 24 },
sm: { span: 16 }
};
}
}
},
watch: {
fieldOptions: {
handler(fieldOptions) {
this.fieldItemOptions = deepClone(fieldOptions);
// 回显默认值
const defaultValue = fieldOptions.reduce((pre, cur) => {
if (![null, undefined, ''].includes(cur.value)) {
pre[cur.key] = cur.value;
}
return pre;
}, {});
this.setFieldItemOptionsValue({ ...defaultValue, ...this.model })
},
deep: true,
immediate: true
}
},
computed: {
},
data() {
return {
fieldItemOptions: [],
// 表单
form: this.$form.createForm(this, {
onValuesChange: (props, values) => {
this.setFieldItemOptionsValue(values)
}
})
};
},
methods: {
// 提交表单
handleSubmit() {
this.form.validateFields((err, formData) => {
if (err) {
return;
}
// 提交表单逻辑
});
},
// 更新表单value值
setFieldItemOptionsValue(values) {
this.fieldItemOptions.forEach(c => {
this.fieldOptions.forEach(d => {
if (c.key === d.key) {
for (const k in d) {
// 若为函数类型则执行
c[k] =
typeof d[k] == "function"
? d[k]({ ...this.form.getFieldsValue(), ...values })
: c[k];
}
}
});
for (const key in values) {
if (c.key === key) {
c.value = values[key];
}
}
});
}
},
created() {}
};
</script>
使用该动态表单dynamic-form.vue
组件的文件
<template>
<div>
<dynamic-form
ref="dynamicForm"
:fieldOptions="fieldOptions"
:model="model"
:labelCol="labelCol"
:wrapperCol="wrapperCol"
></dynamic-form>
</div>
</template>
<script>
import DynamicForm from "./dynamic-form.vue";
export default {
components: {
DynamicForm
},
data() {
return {
fieldOptions: [
{
label: "姓名",
key: "name",
value: "",
type: "text",
required: true,
disabled: formData => {
return formData.country === 2
}
},
{
label: "性别",
key: "sex",
value: 1,
type: "radio",
required: true,
options: [
{
value: 1,
label: "男"
},
{
value: 2,
label: "女"
}
]
},
{
label: "兴趣爱好",
key: "hobby",
value: [],
type: "checkbox",
required: true,
options: [
{
value: 1,
label: "足球"
},
{
value: 2,
label: "篮球"
},
{
value: 3,
label: "排球"
}
],
hidden: formData => {
return formData.country === 2
}
},
{
label: "国家",
key: "country",
value: undefined,
type: "select",
required: true,
options: [
{
value: 1,
label: '中国'
},
{
value: 2,
label: '美国'
},
{
value: 3,
label: '俄罗斯'
}
]
},
{
label: "个人简介",
key: "desc",
value: "",
type: "textarea",
required: formData => formData.country === 2
}
],
model: {
name: '动态表单',
sex: 2,
hobby: [1, 2],
country: 1,
desc: '这是一个简单的例子'
},
labelCol: {
xs: { span: 24 },
sm: { span: 6 }
},
wrapperCol: {
xs: { span: 24 },
sm: { span: 16 }
}
};
}
};
</script>
实现效果如下: