pnpm i el-form-renderer-vue3
# 或
npm install el-form-renderer-vue3
# 或
yarn add el-form-renderer-vue3
import { createApp } from "vue"
import App from "./App.vue"
import elFormRenderer from "el-form-renderer-vue3"
const app = createApp(App)
app.use(elFormRenderer)
app.mount("#app")
确保使用 v-model:FormData 而不是 v-model:
<!-- ❌ 错误 -->
<el-form-renderer v-model="formData" :content="content" />
<!-- ✅ 正确 -->
<el-form-renderer v-model:FormData="formData" :content="content" />
使用 updateForm 方法:
<template>
<el-form-renderer ref="formRef" :content="content" v-model:FormData="formData" />
</template>
<script setup>
import { ref } from "vue"
const formRef = ref()
// 批量更新
const updateData = () => {
formRef.value.updateForm({
name: "张三",
age: 25
})
}
</script>
当 select 的 multiple 为 true 时,必须初始化为空数组:
// ❌ 错误
const formData = reactive({
region: undefined // 或 null
})
// ✅ 正确
const formData = reactive({
region: []
})
在 content 配置中添加 rules 属性:
const content = [
{
type: "input",
id: "name",
label: "姓名",
rules: [
{ required: true, message: "请输入姓名", trigger: "blur" },
{ min: 2, max: 10, message: "长度在 2 到 10 个字符", trigger: "blur" }
]
}
]
<script setup>
const formRef = ref()
const handleValidate = async () => {
try {
const valid = await formRef.value.validate()
if (valid) {
console.log("验证通过")
}
} catch (error) {
console.log("验证失败", error)
}
}
</script>
// 验证单个字段
formRef.value.validateField("name")
// 验证多个字段
formRef.value.validateField(["name", "age"])
// 清除所有验证结果
formRef.value.clearValidate()
// 清除指定字段的验证结果
formRef.value.clearValidate(["name", "age"])
使用 component 属性并配合 markRaw:
<script setup>
import { markRaw } from "vue"
import MyCustomInput from "./MyCustomInput.vue"
const content = [
{
id: "custom",
label: "自定义组件",
component: markRaw(MyCustomInput),
el: {
placeholder: "请输入"
}
}
]
</script>
Vue 3 的响应式系统会递归地将对象转换为响应式代理。对于组件定义对象,这可能导致性能问题和意外行为。markRaw 可以标记一个对象,使其永远不会被转换为响应式代理。
自定义组件需要:
modelValue propupdate:modelValue 事件<!-- MyCustomInput.vue -->
<template>
<input :value="modelValue" @input="$emit('update:modelValue', $event.target.value)" />
</template>
<script setup>
defineProps({
modelValue: [String, Number]
})
defineEmits(["update:modelValue"])
</script>
使用 inputFormat 和 outputFormat:
{
type: 'date-picker',
id: 'date',
label: '日期范围',
el: {
type: 'daterange',
valueFormat: 'YYYY-MM-DD'
},
// 将 startDate 和 endDate 转换为数组格式
inputFormat: (row) => {
if (row.startDate && row.endDate) {
return [row.startDate, row.endDate]
}
},
// 将数组格式转换回 startDate 和 endDate
outputFormat: (val) => {
if (!val) {
return { startDate: '', endDate: '' }
}
return {
startDate: val[0],
endDate: val[1]
}
}
}
trim 属性用于自动去除输入值的首尾空格,默认为 true:
{
type: 'input',
id: 'name',
label: '姓名',
trim: true // 默认值,会自动去除首尾空格
}
使用 hidden 函数:
const content = [
{
type: "select",
id: "type",
label: "类型",
options: [
{ label: "个人", value: "personal" },
{ label: "企业", value: "company" }
]
},
{
type: "input",
id: "companyName",
label: "公司名称",
// 当 type 不是 'company' 时隐藏
hidden: formValue => formValue.type !== "company"
}
]
使用 setOptions 方法:
<script setup>
const formRef = ref()
const updateOptions = () => {
formRef.value.setOptions("region", [
{ label: "北京", value: "beijing" },
{ label: "上海", value: "shanghai" }
])
}
</script>
使用 remote 配置:
{
type: 'select',
id: 'city',
label: '城市',
remote: {
url: '/api/cities',
request: () => axios.get('/api/cities').then(res => res.data),
dataPath: 'data.list', // 数据在响应中的路径
label: 'name', // 远程数据中作为 label 的字段
value: 'id', // 远程数据中作为 value 的字段
onError: (error) => {
console.error('加载失败', error)
}
}
}
使用 on 属性:
{
type: 'input',
id: 'name',
label: '姓名',
on: {
blur: (args, updateForm) => {
console.log('失去焦点', args)
},
focus: (args) => {
console.log('获得焦点', args)
},
change: (args, updateForm) => {
console.log('值改变', args)
// 可以使用 updateForm 更新其他字段
updateForm({ otherField: 'new value' })
}
}
}
使用默认插槽:
<template>
<el-form-renderer :content="content" v-model:FormData="formData">
<el-button type="primary" @click="handleSubmit">提交</el-button>
<el-button @click="handleReset">重置</el-button>
</el-form-renderer>
</template>
使用具名插槽 id:xxx:
<template>
<el-form-renderer :content="content" v-model:FormData="formData">
<template #id:name>
<div class="tip">请输入您的真实姓名</div>
</template>
</el-form-renderer>
</template>
使用 type="group" 和 items:
const content = [
{
type: "group",
id: "address",
label: "地址信息",
items: [
{
type: "input",
id: "province",
label: "省份"
},
{
type: "input",
id: "city",
label: "城市"
}
]
}
]
// 表单数据结构
const formData = reactive({
address: {
province: "",
city: ""
}
})
markRaw 标记不需要响应式的数据hidden、inputFormat、outputFormat 中进行复杂计算v-show 和 hidden 函数检查以下几点:
watch 或 computedhidden 函数是否进行了复杂计算主要区别:
v-model:FormData 代替 v-modelmarkRaw$attrs 和 $listeners 的区别使用 getComponentById 方法:
const formRef = ref()
// 获取 id 为 'name' 的组件实例
const nameComponent = formRef.value.getComponentById("name")
使用 readonly 属性:
{
type: 'input',
id: 'name',
label: '姓名',
readonly: true // 只读模式
}
对于 input 类型,会显示文本值;对于 select 类型,会显示对应的 label;其他组件等同于 disabled = true。
这些属性在新版本中被更强大的 hidden 和 on 替代:
enableWhen → 使用 hidden 函数atChange → 使用 on.change 事件