[动态表单 jformer] 实现表单数据获取和表单提交

1,567 阅读2分钟

jformer 是一个动态表单呈现组件,只需要传递 json 数据就可以显示出界面和功能,使用 jformer 实现表单数据获取和提交有两种方法

方法 1

数据从动态表单组件外部读取,并将结果赋给表单的 v-model,提交时也从外部处理发起请求,动态表单只负责视图呈现和交互逻辑

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>JFormer 表单</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>
    <link
      rel="stylesheet"
      href="https://cdn.jsdelivr.net/npm/element-ui/lib/theme-chalk/index.css"
    />
  </head>
  <body>
    <div id="app">
      <j-former v-model="model" v-bind:config="config"></j-former>
      <el-button type="primary" @click="submit">提交</el-button>
    </div>
    <script>
      new Vue({
        data() {
          return {
            model: {},
            config: {}
          };
        },
        methods: {
          submit() {
            // 提交表单数据
            fetch("<url>", {
              method: "POST",
              body: JSON.stringify(this.model)
            });
          }
        },
        async mounted() {
          const loading = this.$loading();
          try {
            // 读表单配置
            this.config = await (await fetch("./config1.json")).json();
            // 读数据
            this.model = await (await fetch("./data.json")).json();
          } finally {
            loading.close();
          }
        }
      }).$mount("#app");
    </script>
  </body>
</html>

表单配置和数据

config1.json 文件定义

{
  "fields": [
    {
      "component": "el-form",
      "fieldOptions": { "props": { "labelWidth": "120px" } },
      "children": [
        {
          "component": "el-form-item",
          "fieldOptions": { "props": { "label": "输入1" } },
          "children": [{ "component": "el-input", "model": ["text1"] }]
        },
        {
          "component": "el-form-item",
          "fieldOptions": { "props": { "label": "选择" } },
          "children": [
            {
              "component": "el-select",
              "model": ["selected"],
              "children": [
                {
                  "component": "el-option",
                  "fieldOptions": { "props": { "label": "选项1", "value": 1 } }
                },
                {
                  "component": "el-option",
                  "fieldOptions": { "props": { "label": "选项2", "value": 2 } }
                }
              ]
            }
          ]
        }
      ]
    }
  ]
}

data.json 表单数据

{
  "text1": "ssssss",
  "selected": 1
}

完整示例
预览效果

方法 2

完全利用动态表单定义实现整个逻辑

jformer 提供数据源功能用来实现与远程数据的交互,其中 request 类型的数据源是一个 fetch 请求,用来从服务端获取数据和发送数据

通过 request 数据源从服务端读取数据,利用监听功能监听数据读取的结果,更新表单内部数据 (model) 的值,提交的时候也通过 request 数据源向服务端发送数据 (model)

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>JFormer 表单</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>
    <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() {
          this.config = await (await fetch("./config2.json")).json();
        }
      }).$mount("#app");
    </script>
  </body>
</html>

表单配置和数据

{
  "datasource": {
    // request 类型的数据源
    // 数据获取
    "formData": { "type": "request", "url": "./data.json", "autoload": true },
    
    // request 类型的数据源
    // 数据提交
    "formSubmit": {
      "type": "request",
      "url": "url",
      "method": "POST",
      "data": "$:JSON.stringify(model.data)"
    }
  },
  "listeners": [
    {
      // 监听数据获取的数据源数据
      // 将数据赋给 model 的 data 属性
      "watch": "datasource.formData.data",
      "actions": [{ "handler": "@data:datasource.formData.data" }]
    }
  ],
  "fields": [
    {
      "component": "el-form",
      "fieldOptions": { "props": { "labelWidth": "120px" } },
      "children": [
        {
          "component": "el-form-item",
          "fieldOptions": { "props": { "label": "输入1" } },
          "children": [{ "component": "el-input", "model": ["data.text1"] }]
        },
        {
          "component": "el-form-item",
          "fieldOptions": { "props": { "label": "选择" } },
          "children": [
            {
              "component": "el-select",
              "model": ["data.selected"],
              "children": [
                {
                  "component": "el-option",
                  "fieldOptions": { "props": { "label": "选项1", "value": 1 } }
                },
                {
                  "component": "el-option",
                  "fieldOptions": { "props": { "label": "选项2", "value": 2 } }
                }
              ]
            }
          ]
        },
        {
          "component": "el-button",
          "text": "提交",
          "fieldOptions": {
            "props": { "type": "primary" },
            // 数据源的数据和方法都可以在表达式里直接使用
            "on": { "click": "@:datasource.formSubmit.load()" }
          }
        }
      ]
    }
  ]
}

关于转换表达式

  • $: 这种前缀可以写 js 语句,属性值关联语句结果
  • @: 这种前缀表示属性是一个方法,用于设置组件的事件
  • @<属性>: 这种前缀表示属性是一个方法,并将方法的返回结果更新到 model 里的某个属性

data.json 数据

{
  "text1": "ssssss",
  "selected": 1
}

完整示例
预览效果

相关链接

设计器:Github Gitee

动态表单:Github Gitee

数据源、监听、转换表达式具体定义参考 文档