实现方法:通过<component />标签动实现动态表单渲染
component标签:
在vue中 component 标签用于动态组件标签的渲染。它允许在同一个挂载点上条件渲染不同的组件,通过is属性可以渲染指定的属性
在上面的例子中,通过调用函数applyCom实现在页面上渲染Com2组件
动态表单渲染(Vue3 + ElementPlus)
* 文件列表
* widgets/index.js
在index.js中导入所有的表单元素组件
export { default as WidgetInput } from "./input.vue";
export { default as WidgetTextarea } from "./textarea.vue";
export { default as WidgetSelect } from "./select.vue";
export { default as WidgetRadio } from "./radio.vue";
export { default as WidgetUpdate } from "./upload.vue";
* widgets/input.vue
<template>
<div>
<el-input v-model="model" style="width: 240px" v-bind="$attrs" />
</div>
</template>
<script setup>
import { ref } from "vue";
const props = defineProps({
modelValue:{
type:Number
}
})
const emits = defineEmits(['update:modelValue']);
const model = useVModel(props,'modelValue',emits);
</script>
1. 通过v-model确保数据的单向流
2. $attrs: 当想要将所有未声明的属性都是用在组件上可以使用,那么这里就会将component组件上的绑定的v-bind的数据全部应用到input这个组件之上。
* form.vue
<template>
<ElForm ref="formRef" labelPosition="top" @submit.prevent>
<ElFormItem v-for="(item, index) in arr" :key="index">
<component
:is="getWidgetByName(item.name)"
v-model="item.value"
v-bind="item.apply"
/>
</ElFormItem>
</ElForm>
</template>
<script setup>
import * as widgets from "./widgets";
let arr = [
{
name: "WidgetInput",
value: 1,
apply: {
placeholder: "请输入数字",
},
},
{
name: "WidgetInput",
value: 2,
apply: {
placeholder: "请输入数字",
},
},
{
name: "WidgetSelect",
value: 3,
apply: {
placeholder: "请输入数字",
},
},
];
const getWidgetByName = (name) => {
return widgets[name];
};
</script>