vue中怎麼動態生成form表單

xaboy發表於2021-02-16

form-create 是一個可以通過 JSON 生成具有動態渲染、資料收集、驗證和提交功能的表單生成元件。支援3個UI框架,並且支援生成任何 Vue 元件。內建20種常用表單元件和自定義元件,再複雜的表單都可以輕鬆搞定。

文件 | GitHub

支援 UI

  • element-ui
  • iview/view-design
  • ant-design-vue

新增功能

2.5版本主要更新了一下功能:

  • 重構內部核心程式碼
  • 優化內部渲染機制
  • 優化內部生命週期事件
  • 重構 TypeScript
  • 新增 nextTick方法,設定渲染後的回撥
  • 新增 支援分頁載入元件,加速首屏渲染
  • 新增 自定義配置項effect
  • 新增 支援修改type
  • 新增 control支援配置規則插入位置
  • 優化 control符合條件的都會生效,之前版本只能生效第一個
  • 新增 支援給元件配置字首字尾 prefix, suffix
  • 新增 update配置,value傳送變化後觸發
  • 新增 支援 wrap 配置項,配置FormItem
  • 新增 object 元件
  • 新增 支援自定義title,info元件
  • 新增 富文字元件wangEditor
  • 新增 原生事件支援事件注入
  • 支援 value.sync 獲取雙向繫結的 formData
  • 優化 預設的表單提交按鈕

安裝

根據自己使用的 UI 安裝對應的版本

element-ui 版本

npm i @form-create/element-ui

iview@2.x|3.x 版本

npm i @form-create/iview

iview/view-design@4.x 版本

npm i @form-create/iview4

ant-design-vue@1.5+ 版本

npm i @form-create/ant-design-vue

快速上手

本文以element-ui為例

  1. 在 main.js 中寫入以下內容:
import Vue from 'vue'
import ELEMENT from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css'

import formCreate from '@form-create/element-ui'

Vue.use(ELEMENT)
Vue.use(formCreate)
  1. 生成表單

線上示例

<template>
  <div id="app1">
      <form-create v-model="fApi" :rule="rule" :option="option" :value.sync="value"></form-create>
  </div>
</template>
export default {
    data() {
        return {
            //例項物件
            fApi: {},
            //表單資料
            value: {},
            //表單生成規則
            rule: [
                {
                    type: 'input',
                    field: 'goods_name',
                    title: '商品名稱'
                },
                {
                    type: 'datePicker',
                    field: 'created_at',
                    title: '建立時間'
                }
            ],
            //元件引數配置
            option: {
                //表單提交事件
                onSubmit: function (formData) {
                    alert(JSON.stringify(formData))
                }
            }
        }
    }
}

功能介紹

1. 自定義元件

form-create 支援的在表單內部生成任何 vue 元件

線上示例

例如生成一個el-button元件:

{
	//type 可以是內建元件名稱,也可以是vue元件名稱或者 html 標籤
	type: 'el-button',
   	//...
	children: ['按鈕內容']
}

生成一個 html 標籤

{
	//type 可以是內建元件名稱,也可以是vue元件名稱或者 html 標籤
	type: 'span',
   	//...
	children: ['span內容']
}

注意! 生成的元件必須掛載到全域性或者通過 form-create 掛載

通過 Vue 掛載

Vue.component(component.name, component);

通過 form-create 掛載

formCreate.component(component.name, component);

2. 自定義佈局

通過設定配置項col或者柵格元件可以實現對元件的佈局

線上示例

通過配置項col設定元件佈局,設定一行顯示兩個元件

[
	{
        type:'input',
        field:'input1',
        title:'input1',
        col:{span:12}
	},{
        type:'input',
        field:'input2',
        title:'input2',
        col:{span:12}
	},
]

通過柵格元件設定一行顯示三個元件

{
	type:'el-row',
   	children: [
    	{
        	type:'el-col',
        	props:{
            	span:8
        	},
        	children: [{type:'input',field:'input1',title:'input1'}]
        },
    	{
        	type:'el-col',
        	props:{
            	span:8
        	},
        	children: [{type:'input',field:'input1',title:'input1'}]
        },
    	{
        	type:'el-col',
        	props:{
            	span:8
        	},
        	children: [{type:'input',field:'input1',title:'input1'}]
        }
    ]
}

3. 元件前字尾

通過生成規則的prefix屬性配置元件的字首,suffix屬性配置元件的字尾

線上示例

{
    type:'input',
    field:'text',
    title:'text',
    prefix:'prefix',
    suffix:'suffix',
}

設定前字尾為自定義元件

{
    type:'input',
    field:'text',
    title:'text',
    value:'default',
    prefix:{
        type:'ElButton', children:['prefix']
    },
    suffix:{
        type:'ElButton', children:['suffix']
    },
}

4.元件聯動

可以通過control配置項實現通過元件的值控制其他元件是否顯示

線上示例

例如當評價小於3星時輸入差評原因

{
    type:'rate',
    field: 'star',
    title:'評分',
    value:5,
    control:[
        {
            handle(val){
                return val < 3
            },
            rule:[
                {
                    type:'input',
                    field:'info',
                    title:'差評原因',
                    value:'default info', 
                } 
            ]   
        }                                              
    ]
}
引數 說明 型別
value 當元件的值和value全等時顯示rule中的元件 string|Number|Bool
handle handle方法返回true時顯示rule中的元件 Function
rule 該元件控制顯示的元件 Array
append 設定rule中的規則追加的位置 string
prepend 設定rule中的規則前置插入的位置 string
child 設定rule是否插入到指定位置的children中,預設新增到當前規則的 children 中 Boolean

注意! handle優先順序大於value,所有符合條件的control都會生效

5. 表單驗證

可以通過 validate 配置項設定元件的驗證規則,自定義的表單元件也支援校驗

線上示例

例如設定input 元件必填

{
	type:'input',
	//...
	validate:[{required:true, type:'string', message:'請個輸入內容'}]
}
引數 說明 型別 預設值
enum 列舉型別 string -
len 欄位長度 number -
max 最大長度 number -
message 校驗文案 string -
min 最小長度 number -
pattern 正規表示式校驗 RegExp -
required 是否必選 boolean false
transform 校驗前轉換欄位值 function(value) => transformedValue:any -
type 內建校驗型別,可選項 string 'string'
validator 自定義校驗 function(rule, value, callback) -
whitespace 必選時,空格是否會被視為錯誤 boolean false

注意!type需要根據元件的value型別定義

APi 介紹

下列是常用的方法

完整的Api介紹

設定表單值

覆蓋方式,未定義的欄位會設定為 null

type coverValue = (formData:{[field:string]:any}) => void
  • 用法:
fApi.coverValue({goods_name:'HuaWei'})

合併方式,未定義的欄位不做修改

interface setValue {
    (formData:{[field:string]:any}): void
    (field:string, value:any): void
}
  • 用法:
fApi.setValue({goods_name:'HuaWei'})

別名方法changeValue, changeField

隱藏欄位

interface hidden {
    //隱藏全部元件
    (status:Boolean):void
    //隱藏指定元件
    (status:Boolean, field:string):void
    //隱藏部分元件
    (status:Boolean, field:string[]):void 
}
  • 用法:
fApi.hidden(true, 'goods_name')

獲取元件隱藏狀態

type hiddenStatus = (field:string)=>Boolean
  • 用法:
const status = fApi.hiddenStatus('goods_name')

獲取規則

interface getRule {
    (field:string):Rule
    (field:string, origin: true): FormRule
}
  • 用法:
const rule = fApi.getRule('goods_name')

插入規則

前置插入

interface prepend {
    //插入到第一個
    (rule:FormRule):void 
    //插入指定欄位前面
    (rule:FormRule, field:string):void
    //插入到指定欄位 children 中
    (rule:FormRule, field:string, child:true):void
}
  • 用法:
fApi.prepend({
     type:"input",
     title:"商品簡介",
     field:"goods_info",
     value:"",
     props: {
         "type": "text",
         "placeholder": "請輸入商品簡介",
     },
     validate:[
         { required: true, message: '請輸入商品簡介', trigger: 'blur' },
     ],
}, 'goods-name')

後置追加

interface append {
    //插入到最後一個
    (rule:FormRule):void 
    //插入指定欄位後面
    (rule:FormRule, field:string):void
    //插入到指定欄位 children 中
    (rule:FormRule, field:string, child:true):void
}
  • 用法:
fApi.append({
     type:"input",
     title:"商品簡介",
     field:"goods_info",
     value:"",
     props: {
         "type": "text",
         "placeholder": "請輸入商品簡介",
     },
     validate:[
         { required: true, message: '請輸入商品簡介', trigger: 'blur' },
     ],
}, 'goods-name')

刪除指定規則

type removeRule = (rule:FormRule) => FormRule
  • 用法:
const rule = {type:'input', /** ... **/}
fApi.removeRule(rule)

驗證表單

type validate = (callback:(...args:any[]) => void)=> void
  • 用法:
fApi.validate((valid, fail) => {
    if(valid){
        //todo 表單驗證通過
    }else{
        //todo 表單驗證未通過
    }
})

驗證指定欄位

type validateField = (field, callback:(...args:any[]) => void)=> void
  • 用法:
fApi.validateField('goods_name', (valid, fail) => {
    if(valid){
        //todo 欄位驗證通過
    }else{
        //todo 欄位驗證未通過
    }
})

獲取表單資料

interface formData {
    //獲取全部資料
    (): {[field:string]:any }
    //獲取部分欄位的資料
    (field:string[]): {[field:string]:any }
}
  • 用法:
const formData = fApi.formData()

修改提交按鈕

type submitBtnProps = (props:Object) => void
  • 用法:
fApi.submitBtnProps({disabled:true})
  • 快捷操作:

    • fApi.btn.loading(true) 設定提交按鈕進入loading狀態
    • fApi.btn.disabled(true) 設定提交按鈕禁用狀態
    • fApi.btn.show(true) 設定提交按鈕顯示狀態

修改重置按鈕

type resetBtnProps = ( props:Object) => void
  • 用法:
fApi.resetBtnProps({disabled:true})
  • 快捷操作:

    • fApi.resetBtn.loading(true) 設定重置按鈕進入loading狀態
    • fApi.resetBtn.disabled(true) 設定重置按鈕禁用狀態
    • fApi.resetBtn.show(true) 設定重置按鈕顯示狀態

隱藏表單

type hideForm = (hide:Boolean)=>void
  • 用法:
fApi.hideForm(true)

提交表單

type submit = (success: (formData: FormData, $f: fApi) => void, fail: ($f: fApi) => void)=> void
  • 用法:
fApi.submit((formData, fapi) => {
    //todo 提交表單
},()=>{
    //todo 表單驗證未通過
})

如果對您有幫助,您可以在GitHub上點 'Star' 支援一下 謝謝!

相關文章