基於Vue 3.x 實現的 Form render

image

github: vue form rendercss

在線演示html

爲何要造這個輪子?

以前用過 React 的 Form Render 的小夥伴應該比較清楚 Form Render 能夠基於 JSON Schema 快速構建出表單區塊。不得不說 For Render 在如下場景中的使用會給開發帶來巨大的便利:前端

  1. 規範化表單視圖的快速生成:寫好對應的參數配置,快速生成一個標準表單,省去了使用類 Ant Design 表單的麻煩地方
  2. 可視化配置界面生成:並能夠從代碼層面 自動生成 JSON Schema,來完成總體流程的打通
  3. 服務能力配置界面生成:經常使用於後臺字段系統中,接口同窗經過吐 JSON Schema 字段給前端界面,渲染出他所想要的界面以及獲取用戶的輸入進行提交給後端,能夠起到無需發佈就可無縫擴展各類類型的做用
  4. 做爲配置輸入和搭建系統配合使用:FormRender 在正常展現的狀況下,能夠很簡單的進行和原主題的適配使用

可是如今咱們的場景是基於 vue 3.x 的框架基礎上去使用 form render 可是 form render 目前也只支持 react。而後我再 Google 上搜了一大圈,也沒找到一個還能夠的 vue 3.xform render,不過 vue 2.x 的仍是挺多的。出於這樣的訴求,本身動手擼了一個。vue

功能

vue-form-render 是基於 Form Render 基本能力做爲原型實現的 Vue 3.x 版本的表單渲染器,目前支持 90% 左右的 Form Render 功能,後續會不斷的維護支持。react

Array

  • 支持excel導入數據,方便快快捷生成form Data
  • 支持拖拽排序
"listName2": {
  "title": "對象數組",
  "description": "對象數組嵌套功能",
  "type": "array",
  "minItems": 1,
  "maxItems": 3,
  "ui:displayType": "row",
  "items": {
    "type": "object",
    "properties": {
      "input1": {
        "title": "簡單輸入框",
        "type": "string"
      },
      "selet1": {
        "title": "單選",
        "type": "string",
        "enum": [
          "a",
          "b",
          "c"
        ],
        "enumNames": [
          "早",
          "中",
          "晚"
        ]
      }
    }
  }
}

string

"string": {
  "title": "字符串",
  "type": "string",
  "maxLength": 4,
  "ui:options": {
    "placeholder": "試着輸入超過4個字符"
  }
}

color-picker

"color": {
  "title": "顏色選擇",
  "type": "string",
  "format": "color"
}

date-picker

"date": {
  "title": "日期選擇",
  "type": "string",
  "format": "date"
}

image

"image": {
  "title": "圖片展現",
  "type": "string",
  "format": "image"
}

number

"allNumber": {
  "title": "number類",
  "type": "object",
  "properties": {
    "number1": {
      "title": "數字輸入框",
      "description": "1 - 1000",
      "type": "number",
      "min": 1,
      "max": 1000
    },
    "number2": {
      "title": "帶滑動條",
      "type": "number",
      "ui:widget": "slider"
    }
  }
}

boolean

"allBoolean": {
  "title": "boolean類",
  "type": "object",
  "properties": {
    "radio": {
      "title": "是否經過",
      "type": "boolean"
    },
    "switch": {
      "title": "開關控制",
      "type": "boolean",
      "ui:widget": "switch"
    }
  }
}

date-range

"allRange": {
  "title": "range類",
  "type": "object",
  "properties": {
    "dateRange": {
      "title": "日期範圍",
      "type": "range",
      "format": "dateTime",
      "ui:options": {
        "placeholder": [
          "開始時間",
          "結束時間"
        ]
      }
    }
  }
}

emun

"allEnum": {
  "title": "選擇類",
  "type": "object",
  "properties": {
    "select": {
      "title": "單選",
      "type": "string",
      "enum": [
        "a",
        "b",
        "c"
      ],
      "enumNames": [
        "早",
        "中",
        "晚"
      ]
    },
    "radio": {
      "title": "單選",
      "type": "string",
      "enum": [
        "a",
        "b",
        "c"
      ],
      "enumNames": [
        "早",
        "中",
        "晚"
      ],
      "ui:widget": "radio"
    },
    "multiSelect": {
      "title": "多選",
      "description": "下拉多選",
      "type": "array",
      "items": {
        "type": "string"
      },
      "enum": [
        "A",
        "B",
        "C",
        "D"
      ],
      "enumNames": [
        "杭州",
        "武漢",
        "湖州",
        "貴陽"
      ],
      "ui:widget": "multiSelect"
    },
    "boxes": {
      "title": "多選",
      "description": "checkbox",
      "type": "array",
      "items": {
        "type": "string"
      },
      "enum": [
        "A",
        "B",
        "C",
        "D"
      ],
      "enumNames": [
        "杭州",
        "武漢",
        "湖州",
        "貴陽"
      ]
    }
  }
}

Object

"obj1": {
  "title": "可摺疊對象",
  "description": "這是個對象類型",
  "type": "object",
  "ui:options": {
    "collapsed": true
  },
  "properties": {
    "input1": {
      "title": "輸入框1",
      "type": "string"
    },
    "input2": {
      "title": "輸入框2",
      "type": "string"
    }
  }
}

rich-text

{
  "type": "object",
  "properties": {
    "content": {
      "title": "富文本編輯器",
      "type": "string",
      "format": "richText"
    }
  }
}

快速使用

依賴ant-design-vue

import { createApp } from 'vue'
import App from './App.vue'

import Antd from 'ant-design-vue';
import 'ant-design-vue/dist/antd.css';

const app = createApp(App);
app.use(Antd);
app.mount('#app');

引入vue-form-render

npm i kaer-form-render --save
<template>
  <div>
    <formRender
      :schema="schema"
      :formData="formData"
      @on-change="change"
      @on-validate="validate"
    />
  </div>
</template>

<script>
import {reactive, toRefs} from 'vue';

// render index
import FormRender from 'kaer-form-render';
// form render style
import 'kaer-form-render/lib/kaer-form-render.css';

export default {
  name: 'App',
  setup() {
    const state = reactive({
      schema: {
        type: 'object',
        properties: {
          string: {
            title: 'string',
            type: 'string',
            maxLength: 4,
            'ui:options': {
              placeholder: 'enter more than 4 characters',
            },
          }
        },
      },
      formData: {
        string: 'aaa'
      },
    });

    const change = (v) => {
      state.formData = v;
      console.log(v);
    }
    const validate = (v) => {
      console.log(v);
    }

    return {
      ...toRefs(state),
      change,
      validate,
    }
  },
  components: {
    FormRender,
  }
}
</script>

API

Props

參數 說明 類型 默認值
schame JSON Schema object --
formData 表單的數據 object --

Events

事件名 說明 回調函數
on-change 用戶觸發表單更新的回調函數 function(value: formData)
on-validate 用戶觸發表單更新的校驗回調函數 function(value: validates)

最後

歡迎你們使用並pr,咱們一塊兒打造一款好用的vue form rendergit

github: vue form rendergithub

在線演示shell

相關文章
相關標籤/搜索