Vue+ElementUI实现表单动态渲染、可视化配置的方法

时间:2013.07.12 发布人:OU_NICOLE

Vue+ElementUI实现表单动态渲染、可视化配置的方法

已解决问题

谷歌OU_NICOLE用户在2013.07.12提交了关于“李宇春Vue+ElementUI实现表单动态渲染、可视化配置的方法”的提问,欢迎大家涌跃发表自己的观点。目前共有1个回答,最后更新于2025-02-26T23:17:15。希望大家能够帮助她。

详细问题描述及疑问:期待您的答案,你是我的宝贝,你是我的花,谢谢你对我的帮助!

希望以下的回答,能够帮助你。

第1个回答

用户名:jjrac  

动态渲染就是有问答一个异步的**,大概长这样:

{"inline":t述思根世rue,"labelPosit化先ion":"right","l顺abelWidth":"","size":"**all","statusIcon":true,"formItemList":[{"type":"input","label":"姓名","disable":false,"readonly":false肉村调银宪胡宁,"value":"","placeholder":"请输入身丰山安没林赶土力破液姓名","rule几附s":[],"key":"name","subty存七pe":"text"},{"type":"radio","label":亚"性别","value":"","button":f让河alse,"border班息顺最约创食核要路降":true,"rules":[],"key影广践":"gender","options么益组":[{"value":"1","label":"男","disabl征整损她杨同却ed":false},{"value":"0","label":"女","disabled":false}]}]}

然后你需要把这个json渲染成这样:

最后提交表单的**长这样:

{"name":"Genji","gender":"1"}

然后我们目标就是封装这样一个组件:

<dynamic-fo底亮督受古取们rm:config="someConfig"v-model="someData"放饭剧为适而/>

实现

开始之前,你需要知道v-model的工作原理:

<i活队孙采欢企nputv-model="something">

不过是以下示例的语法糖:

<input:value="something"@i外成难nput="something=$event.target.value">

了解这些后,我们再来一步一步实现这个组件。

首先,把配置转发庆温洋今刑到el-form:

<template><el-formclass="dynamic-form":inline="formConfig.inline":model="value":label-position="formConfig.labelPosition":label-width="formConfig.labelWidth":size='formConfig.size':status-icon="formConfig.statusIcon"><slot/></el-form></template><script>exportdefault{props:{formConfig:{type:Object,required:true},value:{type:Object,required:true}},}</script>

第二步,设置默认值。

因为在每个form-item都会需要一个v-model,所以在渲染之前,保每个字段都有值。这里需要注意一点,组件内不要直接修改父组件传入的prop,所以我们在这里用{this.value}快速拷贝一份,最后别忘了通知父组件。代码如下:

exportdefault{props:{formConfig:{},value:{},},methods:{setDefaultValue(){constformData={this.value}//设置默认值this.formConfig.formItemList.forEach(({key,value})=>{if(formData[key]===undefined||formData[key]===**ll){formData[key]=value}})this.$emit('input',formData)}},mounted(){this.setDefaultValue()},}

第三步,渲染form-item。

如何把下面的**渲染为我们熟悉的el-form-item?

{"type":"input","label":"姓名","disable":false,"readonly":false,"value":"","placeholder":"请输入姓名","rules":[],"key":"name","subtype":"text"}

第一种,利用vue内置的component组件,写起来可能像这样:

<el-form-item><component:is="`el-${item.type}`"/></el-form-item>

第二种,使用v-if逐个判断:

<el-form-item><el-inputv-if="item.type==='input'"/><spanv-else>未知控件类型</span></el-form-item>

考虑到每种表单控件的处理逻辑千差万别,楼主采用了第二种方式。

根据这个思路,我们来封装一个dynamic-form-item,接收一个item,渲染一个el-form-item:

<template><el-form-item:rules="item.Rules":label="item.label":prop="item.key"><el-inputv-if="item.type==='input'"v-bind="$attrs"v-on="$listeners":type="item.subtype":placeholder="item.placeholder":disabled="item.disable":readonly="item.readonly":autosize="item.autosize"></el-input><el-selectv-else-if="item.type==='select'"v-bind="$attrs"v-on="$listeners":multiple="item.multiple":disabled="item.disabled":multiple-limit="item.multipleLimit"><el-optionv-for="oinitem.options":key="o.value":label="o.label":value="o.value":disabled="o.disabled"></el-option></el-select><!--突然有点想念JSX--><spanv-else>未知控件类型</span></el-form-item></template><script>exportdefault{props:{item:{type:Object,required:true}}}</script>

tips:使用v-bind="$attrs"v-on="$listeners"可以方便地转发父组件的v-model指令,详见vue高阶组件。

最后,我们就可以循环输出一个完整的表单了:

<dynamic-form-itemv-for="iteminformConfig.formItemList":key="item.key"v-if="value[item.key]!==undefined":item="item":value="value[item.key]"@input="handleInput($event,item.key)"/>

这里不能用v-model="value[item.key]",上文说了,组件内不能直接修改props,所以这里我们还是转发一下。

methods:{handleInput(val,key){//这里element-ui没有上报event,直接就是value了this.$emit('input',{this.value,[key]:val})},setDefaultValue(){}},

完整代码地址:src/components/dynamic-form/form.vue

扩展功能

1.数字显示单位,限制小数位数

element-ui没有做这个功能,不过我觉得还是挺常见的,所以使用el-input手动封装了一个input-**mber:

<!--普通使用--><input-**mberv-model="someNumber":min="1":max="99":decimal1="2"append="元"></input-**mber><!--在dynamic-form-item中的应用--><input-**mberv-else-if="item.type==='**mber'"v-bind="$attrs"v-on="$listeners":min="item.min":max="item.max":decimal1="item.decimal1":append="item.append":prepend="item.prepend":disabled="item.disabled"></input-**mber>

完整代码:src/components/dynamic-form/input-**mber.vue

2.异步验

得益于async-validator,我们可以很方便地自定义验规则。

在配置中

{"type":"input","rules":[{"sql":"**LECT{key}FROMbalabala","message":"xx已被占用","trigger":"blur"}]}

在dynamic-form-item组件中,遍历item.rules,将sql验转化为自定义validator函数:

<template><el-form-item:rules="Rules"></el-form-item></template><script>importrequestfrom'@/utils/request'exportdefault{props:{item:{}},computed:{Rules(){construles=this.item.rulesif(rules===undefined)returnundefinedconstR=[]rules.forEach(rule=>{if(rule.sql){constvalidator=(rule2,value,callback)=>{//根据项目自行修改request('/api/validate','POST',{key:rule2.field,value,sql:rule.sql.replace(/{key}/ig,rule2.field)}).then(res=>{callback(!res||undefined)}).catch(err=>{this.$message.error(err.message)callback(false)})}R.push({validator,message:rule.message,trigger:'blur'})}else{R.push(rule)}})returnR}},}</script>

3.省市区快捷配置

感谢element-china-area-data的作者。

在配置中:

{"type":"cascader","areaShortcut":"provinceAndCityData"}

在dynamic-form-item组件中:

<template><el-form-item><el-cascader:options="item.options||require('element-china-area-data')[item.areaShortcut]"></el-cascader></el-form-item></template>

4.从远程加载选项

包括但不限于radio、checkbox、cascader、select

在配置中:

{"type":"checkbox","optionsUrl":"/api/some/options"}

在dynamic-form-item组件中:

<template><el-form-item><el-select><el-optionv-for="oinitem.options||ajaxOptions"></el-option></el-select></el-form-item></template><script>importrequestfrom'@/utils/request'exportdefault{props:{item:{}},computed:{},data(){return{ajaxOptions:[]}},created(){const{optionsUrl,key,type}=this.itemif(optionsUrl){//根据项目自行修改request(`${optionsUrl}?key=${key}`,'GET').then(res=>{this.ajaxOptions=res}).catch(err=>{this.$message.error(err.message)})}}}</script>

总结

以上所述是小编给大家介绍的Vue+ElementUI实现表单动态渲染、可视化配置的方法,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对脚本之家网站的支持!

您可能感兴趣的文章:vue中动态绑定表单元素的属性方法vue2中如何实现动态表单增删改查实例详解Vue2+Echarts实现多种图表**可视化Dashboard(附源码)