需求是根据JSON文件生成表单,包含配置和自动model属性以及表单验证,数据回显。
目录
动态表单数据示例:
表单设置JSON示例:
表单输入JSON示例:
表单按钮JSON示例:
抛出数据示例:
动态表单示例:
HTML模板部分:
PROPS部分:
表单验证器:
事件部分:
为了数据回显
props新增defaultValue:
computed增加监听:
data中申明
组件引用示例:
HTML 部分:(导入就不说了)
效果如下:
动态表单数据示例:
(page/home/index.js)
表单设置JSON示例:
/*** 搜索表单设置* @rules: 是否验证 {Boolean}* @inline: 是否内联 {Boolean}* @width: label宽度 {String}* @align: label对齐方式 {String}*/
const searchFormSetting = {rules: false,inline: true,ref: 'searchForm',width: '40px',align: 'left'
}
表单输入JSON示例:
/*** 搜索表单* @type: 输入框的类型* @label: 输入框的label* @module: 输入框的v-module属性,不写会默认咦中文首字母拼音作为改属性* 注:select需要配合options使用*/
const searchFormGroup = [{ label: '早餐', type: 'input', module: 'zaofan' },{ label: '日期', type: 'date' },{ label: '地点', type: 'select', options: addressOptions }
]
表单按钮JSON示例:
/*** 搜索表单按钮事件* @name: 按钮名称* @event: 按钮事件名(子组件直接@eventName=handleCustomizeEvent)* @primary:按钮类型(按钮的颜色)* @icon:按钮的小图标*/
const searchFormButton = [{ name: '查询', event: 'search', type: 'primary', icon: 'el-icon-search' },{ name: '重置', event: 'reset', icon: 'el-icon-refresh-left' },{ name: '一键导出', event: 'export', icon: 'el-icon-download' }
]
抛出数据示例:
export { searchFormSetting, searchFormGroup, searchFormButton}
动态表单示例:
(components/autoForm/index.vue)
HTML模板部分:
<template><el-form ref="autoForm" :model="autoForm" :rules="autoRules" :label-width="setting.width" :inline="setting.inline" :label-position="setting.align" :id="setting.inline"><el-form-item v-for="(item, key) in form" :key="key" :label="item.label" :prop="chineseToPinYin(item.label)"><!--input--><template v-if="item.type === 'input'"><template><el-input v-model="autoForm[item.module || chineseToPinYin(item.label)]" :placeholder="'请输入'+item.label" @input="handleRefresh"/></template></template><!--select--><template v-if="item.type === 'select'"><el-select filterable v-model="autoForm[item.module || chineseToPinYin(item.label)]" :placeholder="'请选择'+item.label" @change="handleRefresh"><el-option v-for="(item_, key_) in item.options" :key="key+'_'+key_" :label="item_.label" :value="item_.value"></el-option></el-select></template><!--date--><template v-if="item.type === 'date'"><el-date-picker type="date" value-format="yyyy-MM-dd" format="yyyy-MM-dd" :placeholder="'请选择'+item.label" v-model="autoForm[chineseToPinYin(item.label)]" @change="handleRefresh"></el-date-picker></template><!--radio--><template v-if="item.type === 'radio'"><el-radio-group v-model="autoForm[item.module || chineseToPinYin(item.label)]" @change="handleRefresh"><el-radio v-for="(item_, key_) in item.options" :key="key_" :label="item_.label" :value="item_.value"></el-radio></el-radio-group></template><!--textarea--><template v-if="item.type === 'textarea'"><el-input type="textarea" v-model="autoForm[item.module || chineseToPinYin(item.label)]"/></template></el-form-item><!--BUTTON--GROUP--><el-form-item v-if="button"><el-button v-for="(item, key) in button" :key="'btn-'+key" :class="item.float" :icon="item.icon" :type="item.type" @click="handleButton(item.event, 'autoForm')">{{ item.name }}</el-button></el-form-item></el-form>
</template>
PROPS部分:
props: {setting: {type: Object,default: () => ({ref: 'form',width: '80px',align: 'left'})},button: {type: Array,default: () => [{ name: '查询', event: 'search', type: 'primary', icon: 'el-icon-search' },{ name: '重置', event: 'reset', type: 'success', icon: 'el-icon-refresh-left' }]},form: {type: Array,default: () => [{ label: '类型', type: 'select' },{ label: '分数', type: 'input' },{ label: '时间', type: 'date' }]}}
表单验证器:
this.form.forEach(item => {this.autoRules[chineseToPinYin(item.label)] = verify(item)})function verify (item) {let rules = []if (item.required && item.type === 'input') {rules = [{ required: true, message: `请输入${item.label}`, trigger: ['blur', 'change'] }]} else if (item.required && item.type === 'select') {rules = [{ required: true, message: `请选择${item.label}`, trigger: ['blur', 'change'] }]} else if (item.required && item.type === 'textarea') {rules = [{ required: true, message: `请输入${item.label}`, trigger: ['blur', 'change'] }]} else if (item.required && item.type === 'date') {rules = [{ type: 'date', required: true, message: `请选择${item.label}`, trigger: ['blur', 'change'] }]} else if (item.required && item.type === 'radio') {rules = [{ required: true, message: `请选择${item.label}`, trigger: ['blur', 'change'] }]}return rules}
事件部分:
handleButton (event, autoForm) {if (event === 'reset' || event === 'cancel') {this.autoForms = {}} else {this.$refs[autoForm].validate((valid) => {if (valid) {this.$emit(event, this.autoForms, this.setting.ref)} else {this.$message({type: 'warning',message: '请检查您的输入'})}})}},handleRefresh () {this.$forceUpdate()}
为了数据回显
props新增defaultValue:
defaultForm: {type: Object,default: () => ({})}
computed增加监听:
autoForm () {return this.autoForms}
data中申明
(注意区分autoForms和autoForm)
return {autoForms: this.defaultForm}
组件引用示例:
(page/home/index.vue)
HTML 部分:(导入就不说了)
<auto-form :setting="searchFormSetting" :form="searchFormGroup" :button="searchFormButton" :default-form="searchForm" @search="handleClickSearchFormSearch" @export="handleClickSearchFormExport"/>