@leiyin/v-form-renderer
v1.0.2
Published
Base on element-ui, Render form-item easily
Maintainers
Readme
@leiyin/v-form-renderer
一个基于 Vue 3 + Element Plus 的配置化表单渲染组件,用 JSON/Schema 快速生成复杂表单。
✨ 特性
- 配置驱动(Content Schema)
- 支持 group 嵌套、动态显隐与禁用
- v-model 双向绑定与方法暴露
- 远程选项加载与自定义组件
- 完整 TypeScript 类型与 ESM/CJS 构建
📦 安装
- peerDependencies:vue ^3.2.0、element-plus 2.11.7
pnpm add @leiyin/v-form-renderer
# 或
npm install @leiyin/v-form-renderer
# 或
yarn add @leiyin/v-form-renderer🚀 基础用法
<template>
<VFormRenderer :content="schema" />
</template>
<script setup lang="ts">
import { ref } from 'vue'
import VFormRenderer from '@leiyin/v-form-renderer'
const schema = ref([
{ id: 'username', type: 'input', label: '用户名', el: { placeholder: '请输入' }, default: '' },
{ id: 'role', type: 'select', label: '角色', options: [
{ label: '管理员', value: 'admin' },
{ label: '普通用户', value: 'user' }
] }
])
</script>🔗 v-model 与方法
- v-model:使用 v-model:model 绑定整个表单对象
- 方法暴露:通过 ref 获取实例并调用内置方法
<template>
<VFormRenderer
v-model:model="form"
:content="schema"
ref="formRef"
@enter="onEnter"
/>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import VFormRenderer, { type VFormRendererInstance } from '@leiyin/v-form-renderer'
const form = ref<Record<string, any>>({})
const formRef = ref<VFormRendererInstance>()
const onEnter = () => {
// 回车事件
}
const getValue = () => {
const result = formRef.value?.getFormValue() // outputFormat 后的值
console.log(result)
}
const validate = async () => {
const ok = await formRef.value?.validate()
console.log('valid:', ok)
}
const reset = () => {
formRef.value?.resetFields()
}
const patch = () => {
formRef.value?.updateForm({ username: '张三' })
}
</script>方法来源与实现参考:
- 组件实现 v-form-renderer.vue
- 方法定义 useFormEvents.ts
- Props 定义 v-form-renderer.ts
⚙️ Props
- content: Content[] 必填,表单 Schema
- labelWidth: string,统一 label 宽度,默认 98px
- disabled: boolean,禁用整个表单
- inline: boolean,行内表单,默认 true
- readonly: boolean,只读模式(input 显示文本,select 显示 label)
- 透传:支持 Element Plus el-form 的其余属性与事件(使用 v-bind="$attrs")
🧩 Content Schema
类型定义参考 form.ts
常用字段:
- id: string,唯一键,作为数据 key
- label: string | Function,表单项标题;支持组件函数
- type: string,例如 'input' | 'select' | 'radio-group' | 'checkbox-group' | 'cascader' | 'group'
- el: Record<string, any>,对应组件的属性,如 placeholder、multiple 等
- default: any,初始默认值
- items: Content[],当 type='group' 时的子项
- hidden(formValue, item): boolean,返回 true 隐藏
- disabled(formValue, item): boolean,返回 true 禁用
- options: { label: string; value?: any }[],选择类组件选项
- component: 自定义组件,优先于 type 的内置组件
- inputFormat(obj): any,处理输入值(default/v-model/updateForm)
- outputFormat(val, obj): any,处理输出值(getFormValue 时应用)
- rules: FormItemRule[],Element Plus 校验规则
- remote: 远程 prop/选项加载(select/radio/checkbox 支持自动映射)
- on: 事件监听回调,签名为 (args, updateForm, setOptions) => void
示例:group 嵌套
const schema = [
{
id: 'user',
type: 'group',
label: '用户信息',
items: [
{ id: 'name', type: 'input', label: '姓名', default: '' },
{ id: 'age', type: 'input', label: '年龄', el: { type: 'number' } }
]
}
]🌐 远程选项加载
const schema = [
{
id: 'city',
type: 'select',
label: '城市',
remote: {
// 返回 Promise 的方法(可传入 params)
url: (params) => fetch(`/api/cities?kw=${params.kw}`).then(r => r.json()),
dataPath: 'data.list', // 响应体中数据路径
label: 'name', // 用作 label 的字段
value: 'code' // 用作 value 的字段
}
}
]当为 select/radio-group/checkbox-group 时,远程数据会自动映射为 Element Plus 的选项。 实现参考 RenderFormItem.vue。
👁️ 只读与显隐
- readonly: true 时,input 显示文本、select 显示选中项 label
- hidden/disabled:传入函数,依据当前 formModel 动态控制
const schema = [
{
id: 'level',
type: 'select',
label: '级别',
options: [{ label: 'A', value: 'A' }, { label: 'B', value: 'B' }]
},
{
id: 'extra',
type: 'input',
label: '额外信息',
hidden: (form) => form.level !== 'A'
}
]🎯 校验与重置
- 使用 Element Plus 的规则校验(rules)
- validate(): Promise<boolean | void>
- resetFields(): 重置为 default 值并清除校验
参考 useFormEvents.ts。
🧱 插槽与自定义
- 命名插槽:以 id 为名注入内容,例如 #id:username
- label 组件:将 label 设置为组件/函数,渲染自定义标题
- 自定义组件:传入 component 替代内置 Element Plus 组件
<template>
<VFormRenderer :content="schema">
<template #id:username>
<span style="margin-right: 8px">用户名扩展内容</span>
</template>
</VFormRenderer>
</template>
<script setup lang="ts">
const schema = [
{
id: 'username',
type: 'input',
label: '用户名',
el: { placeholder: '请输入' }
}
]
</script>插槽实现参考 v-form-renderer.vue 与渲染器 render-component.ts。
📚 导入与类型
- 默认导出:VFormRenderer
- 类型导出:Content、VFormProps、VFormRendererInstance 等
入口参考 index.ts。
