vue json动态生成form表单
时间: 2023-10-02 09:08:50 浏览: 141
可以使用 Vue.js 的动态组件和渲染函数来实现动态生成表单。
首先定义一个 JSON 数据,表示表单的结构和字段信息,如下所示:
```json
{
"fields": [
{
"type": "text",
"label": "用户名",
"name": "username",
"value": ""
},
{
"type": "password",
"label": "密码",
"name": "password",
"value": ""
},
{
"type": "select",
"label": "性别",
"name": "gender",
"value": "",
"options": [
{ "label": "男", "value": "male" },
{ "label": "女", "value": "female" }
]
},
{
"type": "checkbox",
"label": "爱好",
"name": "hobbies",
"value": [],
"options": [
{ "label": "游泳", "value": "swimming" },
{ "label": "跑步", "value": "running" },
{ "label": "健身", "value": "fitness" }
]
}
]
}
```
然后在 Vue.js 组件中,通过遍历 JSON 数据的 fields 属性来动态生成表单的每个字段,如下所示:
```html
<template>
<form>
<div v-for="(field, index) in formData.fields" :key="index">
<component :is="getFieldComponent(field.type)"
:label="field.label"
:name="field.name"
:value="field.value"
:options="field.options"
@input="onFieldInput(field.name, $event)">
</component>
</div>
<button type="submit">提交</button>
</form>
</template>
<script>
export default {
data() {
return {
formData: {
fields: [...]
}
};
},
methods: {
getFieldComponent(type) {
switch (type) {
case 'text':
case 'password':
return 'input-field';
case 'select':
return 'select-field';
case 'checkbox':
return 'checkbox-field';
default:
return null;
}
},
onFieldInput(name, value) {
// 更新表单数据
this.formData.fields.find(field => field.name === name).value = value;
}
},
components: {
'input-field': {
props: ['label', 'name', 'value'],
render(h) {
return h('div', [
h('label', this.label),
h('input', {
attrs: {
type: 'text',
name: this.name,
value: this.value
},
on: {
input: event => {
this.$emit('input', event.target.value);
}
}
})
]);
}
},
'select-field': {
props: ['label', 'name', 'value', 'options'],
render(h) {
const options = this.options.map(option => {
return h('option', { attrs: { value: option.value } }, option.label);
});
return h('div', [
h('label', this.label),
h('select', {
attrs: {
name: this.name,
value: this.value
},
on: {
input: event => {
this.$emit('input', event.target.value);
}
}
}, options)
]);
}
},
'checkbox-field': {
props: ['label', 'name', 'value', 'options'],
render(h) {
const checkboxes = this.options.map(option => {
return h('label', [
h('input', {
attrs: {
type: 'checkbox',
name: this.name,
value: option.value,
checked: this.value.includes(option.value)
},
on: {
input: event => {
const values = this.value.slice();
if (event.target.checked) {
values.push(event.target.value);
} else {
const index = values.indexOf(event.target.value);
if (index >= 0) {
values.splice(index, 1);
}
}
this.$emit('input', values);
}
}
}),
option.label
]);
});
return h('div', [
h('label', this.label),
checkboxes
]);
}
}
}
};
</script>
```
上面的代码中,getFieldComponent 方法根据字段类型返回对应的组件名,onFieldInput 方法用于更新表单数据,渲染函数中通过 component 标签动态渲染每个字段对应的组件。组件中的 input、select 和 checkbox 标签都绑定了 input 事件,当用户输入数据时会触发该事件,从而更新表单数据。
最后在父组件中引入动态生成表单的组件即可:
```html
<template>
<div>
<dynamic-form></dynamic-form>
</div>
</template>
<script>
import DynamicForm from './DynamicForm.vue';
export default {
components: {
DynamicForm
}
};
</script>
```
阅读全文