[动态表单 jformer] 自定义渲染处理实现 element 表单

867 阅读1分钟

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/

可视化设计器:
GitHub
Gitee