Vue.js+ElementUI+vant生成动态表单配置

我司最近在搭建一款后台管理系统,使用的是Vue全家桶配合Element-ui,遇到一个问题,需要处理很多的表单,所以想到的解决方案是通过后台配置生成动态表单,这对于我来说也算是新的挑战,涉及的功能有动态表单渲染和验证,那么一起来学习一下我是如何实现的吧!

本文仅仅代表笔者自己的思路,如果您有更好的实现方式,可以在下方留下您宝贵的建议。笔者将十分感谢

Vue.js+ElementUI+vant生成动态表单配置

开发准备 需要储备的知识点

了解Element ui表单

了解Vue中的$set(target,key,value)方法

了解vant中的表单组件

本项目是基于vue-cli2.0搭建的脚手架,在这里默认大家搭建好了,谁赞成,谁反对!

33473706d98e35c79ec12ba0e6cbfd9b.gif

静态表单数据准备

后台返回的数据是这样的,这里我们拿一个json数据举例

{ "showName": "姓名", // 名称 "showValue": null, //值 "htmlElements": "输入框", // 表单类型 "fieldLength": 99, // 字段长度 "requiredOrNot": 1, // 是否必填 }

然后类型的话大概有以下几种

输入框

文本域

日历控件

下拉框

单选框

复选框

我们为每一种类型生成一种组件,Test.vue组件里面

data(){ return{ fieldArray:[],// 表单字段集合 fieldObj:{}, sex:[{ // 性别 name:'男', value:"male" },{ name:"女", value:"female" } ], hobbies:[ // 爱好 { name:"吃饭", value:"吃饭" },{ name:"玩游戏", value:"玩游戏" },{ name:"打豆豆", value:"打豆豆" }, ], job:[{ // 职业 name:"医生", value:"doctor" },{ name:"老师", value:"teacher" },{ name:"司机", value:"driver" } ] } }

这里准备多种日历控件是因为后续手机端使用vant组件的时候需要用到

由于vue中的数据是双向绑定的,所以只有在data里面的数据是可以实现双向绑定的,重新向data里面添加的数据无法达到双向绑定的效果,官网为我们提供了一个set方法。

作为靓仔的我,肯定很贴心的为大家准备了官网链接

这里就不过多讲解,官网比较权威,本篇博客的重点是动态表单。

Vue.set(target,propertyName/index,value)

参数

{Object | Array} target

{string | number} propertyName/index

{any} value

返回值:设置的值。

用法

向响应式对象中添加一个 property,并确保这个新 property 同样是响应式的,且触发视图更新。它必须用于向响应式对象上添加新 property,因为 Vue 无法探测普通的新增 property (比如 this.myObject.newProperty = 'hi')

注意对象不能是 Vue 实例,或者 Vue 实例的根数据对象。

Element-ui表单元素

动态表单渲染

这里使用axios请求本地json数据,static/json/form.json

{ "data":[ { "showName": "姓名", "showValue": null, "htmlElements": "输入框", "fieldLength": 10, "requiredOrNot": 1, "desc":"请输入姓名" }, { "showName": "描述", "showValue": null, "htmlElements": "文本域", "fieldLength": 99, "requiredOrNot": 1, "desc":"请输入描述" }, { "showName": "爱好", "showValue": null, "htmlElements": "复选框", "requiredOrNot": 1, "desc":"请选择爱好" }, { "showName": "性别", "showValue": null, "htmlElements": "单选框", "requiredOrNot": 1 }, { "showName": "出生日期", "showValue": null, "htmlElements": "日历控件", "requiredOrNot": 1, "desc":"请选择出生日期" }, { "showName": "结婚时间", "showValue": null, "htmlElements": "日历控件", "requiredOrNot": 1, "desc":"请选择结婚时间" }, { "showName": "职业", "showValue": null, "htmlElements": "下拉框", "requiredOrNot": 1, "desc":"请选择职业" } ] }

Test.vue文件

<template> <div> <h2>测试动态表单</h2> <el-form :model="fieldObj" ref="ruleForm" label-width="180px"> <template v-for="(item,index) of fieldArray"> <template v-if="item.htmlElements==='输入框'"> <el-form-item :label="item.showName"> <el-input v-model="fieldObj[item.showName]" :max="item.fieldLength" :placeholder="item.desc" show-word-limit></el-input> </el-form-item> </template> <template v-if="item.htmlElements==='文本域'"> <el-form-item :label="item.showName"> <el-input type="textarea" rows="4" :placeholder="item.desc" v-model="fieldObj[item.showName]" :maxlength="item.fieldLength" show-word-limit></el-input> </el-form-item> </template> <template v-if="item.htmlElements==='日历控件'"> <el-form-item :prop="item.showName" :label="item.showName"> <el-date-picker v-model="fieldObj[item.showName]" :name="item.showName" type="date" format="yyyy-MM-dd" value-format="yyyy-MM-dd" :placeholder="item.desc" ></el-date-picker> </el-form-item> </template> <template v-if="item.htmlElements==='下拉框'"> <el-form-item :label="item.showName"> <el-select v-model="fieldObj[item.showName]" :placeholder="item.describe"> <el-option v-for="items in job" :key="items.name" :label="items.name" :value="items.value"> </el-option> </el-select> </el-form-item> </template> <template v-if="item.htmlElements==='单选框'"> <el-form-item :label="item.showName"> <template v-for="(child,index) in sex"> <el-radio v-model="fieldObj[item.showName]" :label="child.value">{{child.name}}</el-radio> </template> </el-form-item> </template> <template v-if="item.htmlElements==='复选框'"> <el-form-item :label="item.showName"> <el-checkbox-group v-model="fieldObj[item.showName]"> <template v-for="(child,index) of hobbies"> <el-checkbox :label="child.name"></el-checkbox> </template> </el-checkbox-group> </el-form-item> </template> </template> </el-form> </div> </template> <script> import axios from 'axios' export default { name: "Test", data(){ return{ fieldArray:[],// 表单字段集合 fieldObj:{}, sex:[{ // 性别 name:'男', value:"male" },{ name:"女", value:"female" } ], hobbies:[ // 爱好 { name:"吃饭", value:"吃饭" },{ name:"玩游戏", value:"玩游戏" },{ name:"打豆豆", value:"打豆豆" }, ], job:[{ // 职业 name:"医生", value:"doctor" },{ name:"老师", value:"teacher" },{ name:"司机", value:"driver" } ] } }, mounted(){ this.getFieldData(); }, methods:{ getFieldData(){ // 获取动态表单数据 axios.get("../static/json/form.json").then(data=>{ let response=data.data.data; this.fieldArray=response; for(let i=0;i<response.length;i++){ let item=response[i]; if(item.htmlElements==='复选框'){ this.$set(this.fieldObj,item.showName,[]); }else { this.$set(this.fieldObj,item.showName,item.showValue); } } }) } } } </script> <style scoped> </style>

24rACn.png

现在的话,表单已经全部渲染完毕了,也实现了双向绑定,现在需要做的是如何实现动态表单验证。

官网解释:Form 组件提供了表单验证的功能,只需要通过 rules 属性传入约定的验证规则,并将 Form-Item 的 prop 属性设置为需校验的字段名即可,

prop字段

rules

model

在这里rules设置为动态的,而不是放在data里面提前写好,这里需要知道每一种类型的触发形式

输入框/文本域 trigger: 'blur'

单选框/复选框/日历控件/下拉框 trigger: 'change'

动态表单验证

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zyjxzj.html