npm i vue-json-render
- 通过JSON配置的方式构建ant-design-vue 表单类 页面
- 支持除表单以外的任意其他页面元素渲染
- 提供表单联动相关API,可进行高复杂度的表单联动
- 聚焦表单类问题
- 将组件逻辑抽象至小粒度的JSON内,方便组件及组件逻辑的抽象;
- 编码回归到js/ts;
- 依赖了ant-design-vue 4.x的 Form, FormItem, Row, Col四个组件
- 表单验证依赖Form及FormItem组件
- 布局依赖Row及Col组件
- vue3
- components 渲染数据源
- formProps 透传给 ant-design-vue 4.x 的 Form 组件的属性 如layout, etc..
- gutter 透传给 ant-design-vue 的 Row 组件的属性, 控制grid布局下的元素间距
- isForm 组件是否启用ant-design-vue 4.x 的 Form 组件, 设置为false后表单相关的属性失效
- status 组件附加的状态属性,方便业务逻辑扩展,如编辑态、审核态 ect;
- action({setProps, model, components, hide, show, addAfter, addBefore, form, cloneComponents,components }, props, context) 注册组件事件,返用法同render函数的prop参数, 即在事件前加"on"前缀,onClick,onClick,etc... 参考Vue的render函数章节
- setProps({ disabled: false }, elementKey) 设置 component.elementKey = elementKey 组件的props
- hide(elementKey); 隐藏 component.elementKey = elementKey 的组件
- show(elementKey); 显示 component.elementKey = elementKey 的组件
- addAfter(elementKey, components: CJson[]); 在component.elementKey = elementKey 的组件后添加组件;
- addBefore(elementKey, components: CJson[]); 在component.elementKey = elementKey 的组件前添加组件;
- model 中存储的是表单数据,通过它可以修改/获取表单数据;
- form 是ant-design-vue的Form组件的ref属性,用于操作表单验证validate,resetFields etc.. 具体参见官方文档
- cloneComponents 传入组件的初始配置,用于恢复页面初始状态
- components JRender组件渲染过程中实际使用的配置,修改components会触发视图渲染
- props JRender组件的setup的props参数,即JRender的Props属性
- context JRender组件的setup的context参数,即JRender的上下文
export type CJson = {
element: string | VNode | Component, // 要渲染的元素
elementKey: string, // 表单的唯一标识(不能重复)
hidden?: boolean, // 是否展示当前元素
label?: string, // 表单名称:即formItem的label;
props?: Record<string, any>, // 组件的props
action?: (toExpose: ToExpose, props: any, context: SetupContext) => Record<string, any>, // 绑定事件
defaultValue?: any, // 表单的默认值
rules?: RuleObject | RuleObject[], // 表单的校验规则
mounted?: (component: CJson) => void, // JRender 组件mounted时执行此函数
placeholder?: string, // 表单 placelhoder
span?: number, // grid布局的col参数
offsets?:number, // grid布局的col参数
children?: string | VNode[], // 当前元素的子组件
type?: 'select', // 表单类型(设置为'select'后 自动填充的placeholder前缀变为请选择)
custom?: Record<string, any> // 用户的自定义属性
}
const components:CJson[] = [{
element: Select,
elementKey: 'selectKey',
label: '输入框',
span: 8,
offsets: 2,
defaultValue: 2,
props: {
disabled: true,
options: [{ label: '选项一', value: '1'}],
},
type: 'select',
hidden: false,
rules: { required: true, message: '请输入' },
action: ({ setProps, model, components, hide, show, addAfter, addBefore, form }, props, context) => {
return {
onChange: () => {
setProps({ disabled: false }, 'inputKey')
hide('inputKey');
show('inputKey');
addAfter('inputKey', [{element: 'button', elementKey: 'buttonKeyAfter'}])
addBefore('inputKey', [{element: 'button', elementKey: 'buttonKeyBefore'}])
form.value.validate();
form.value.resetFields();
// ...ect 即antd的form挂载的方法
model.inputKey = 'new value';
if (components.value[0] && components.value[0].props) components.value[0].props.disabled = false;
props.isForm;
context.emit('xxx')
},
}
},
mounted: async (record) => {},
}];
// page.vue
<script lang="ts" setup>
import { JRender } from 'vue-json-render';
import { components } from './pageConfig';
</script>
<template>
<JRender :components="components" ref="p" @JRmounted="() => { console.log('JRender mounted!')}" />
</template>
// pageConfig.ts
import { Select } from 'ant-design-vue';
import type { CJson } from 'vue-json-render';
const components:CJson[] = [
{
element: Select,
elementKey: 'selectKey',
label: 'hello',
span: 8,
props: {
options: [{ label: '选项一', value: '我是选项一'}],
},
type: 'select',
rules: { required: true, message: '请输入' },
action: ({ setProps, model, components, hide, show, addAfter, addBefore, form }, props, context) => {
return {
onChange: () => {
console.log(model.selectKey)
},
}
},
mounted: async (record) => {}
}
];
export {
components,
}