jformer 是一个动态表单呈现组件,只需要传递 json 数据就可以显示出界面和功能
element 表单组件外需要套一个 el-form-item 实现前缀显示和数据验证,现在基于 jformer 扩展一个渲染处理 provider 简化这个定义
完整示例
html 页
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>Static Template</title>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<script src="https://cdn.jsdelivr.net/npm/jformer"></script>
<script src="https://cdn.jsdelivr.net/npm/element-ui/lib/index.js"></script>
<script src="./element-ext.js"></script>
<link
rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/element-ui/lib/theme-chalk/index.css"
/>
</head>
<body>
<div id="app">
<j-former v-bind:config="config"></j-former>
</div>
<script>
new Vue({
data() {
return {
config: {}
};
},
async mounted() {
const response = await fetch("./config.json");
this.config = await response.json();
}
}).$mount("#app");
</script>
</body>
</html>
provider 扩展实现
element-ext.js 实现了一个渲染处理 provider, 将定义组件外套一层 el-form-item,并将组件的 elForm 属性作为 el-form-item 的属性
// 实现一个渲染处理 provider 实现在组件上定义 elForm
// 就可以自动在组件外层加上 el-form-item
const elementFormProps = (field) => {
if (!field.elForm) {
return;
}
// 复制组件原始配置
const originField = { ...field };
// 将组件名改成 el-form-item
field.component = "el-form-item";
// 将原组件的复制赋给组件下级实现改变界面结构
field.children = [originField];
// 将 elForm 属性作为 el-form-item 的属性
field.fieldOptions = {
props: field.elForm
};
// 如果组件关联了数据属性则将数据属性作为 el-form-item 的数据属性
if (originField.model) {
field.fieldOptions.props.prop = originField.model;
}
// 删除 elForm 定义避免下级组件渲染处理时无限循环
delete field.elForm;
delete originField.elForm;
};
// 将定义的 provider 应用于 jformer
window.jformer.default.use(({ provider }) => {
provider(elementFormProps);
});
配置文件
{
"fields": [
{
"component": "el-form",
"fieldOptions": {
"ref": "form",
"props": { "labelWidth": "120px", "model": "$:model" }
},
"children": [
{
"component": "el-input",
"model": "text1",
"fieldOptions": { "attrs": { "placeholder": "请输入" } },
"elForm": {
"label": "输入1",
"rules": [{ "required": true, "message": "必填项" }]
}
},
{
"component": "el-input",
"model": "text2",
"fieldOptions": {
"attrs": { "placeholder": "输入 1 多于5个字之后就必填" }
},
"elForm": {
"label": "输入2",
"rules": [
{ "required": "$:model.text1.length>5", "message": "必填项" }
]
}
},
{
"component": "div",
"elForm": { "label": "" },
"children": [
{
"component": "el-button",
"text": "提交",
"events": [
{ "name": "click", "handler": "@:refs.form.validate()" }
],
"fieldOptions": { "props": { "type": "primary" } }
},
{
"component": "el-button",
"text": "重置"
}
]
}
]
}
]
}
示例完整实现:
codesandbox.io/s/jformer-t…
预览效果:
d9c7b.csb.app/