某些场景下,咱们的表单须要做成可配置表单,依据管理员配置好的表单信息来动静生成表单,比方业务员就只能填写业务类型的表单信息,经营人员能够配置流动类型的表单信息,相似于表单的权限管制。
预览动静表单成果在文章最初
动静表单校验
<el-form ref="ruleForm" :rules="ruleArr" :model="ruleForm" label-width="80px" > <div v-for="(item, index) in formArr"> <div v-if="item.isShow == 1 && item.type == 1"> <el-form-item :label="item.label" :prop="item.isRule ? item.name : ''" > <el-input v-model="ruleForm[item.name]" :placeholder="`请输出${item.label}`" ></el-input> </el-form-item> </div> <div v-if="item.isShow == 1 && item.type == 2"> <el-form-item :label="item.label" :prop="item.isRule ? item.name : ''"> <el-select v-model="ruleForm[item.name]" :placeholder="item.rules"> <el-option label="区域一" value="shanghai"></el-option> <el-option label="区域二" value="beijing"></el-option> </el-select> </el-form-item> </div> <div v-if="item.isShow == 1 && item.type == 3"> <el-form-item :label="item.label" :prop="item.isRule ? item.name : ''"> <el-date-picker v-model="ruleForm[item.name]" type="daterange" format="yyyy-MM-dd" value-format="yyyy-MM-dd" range-separator="至" start-placeholder="开始日期" end-placeholder="完结日期" > </el-date-picker> </el-form-item> </div> <div v-if="item.isShow == 1 && item.type == 4"> <el-form-item :label="item.label" :prop="item.isRule ? item.name : ''"> <el-switch v-model="ruleForm[item.name]"></el-switch> </el-form-item> </div> <div v-if="item.isShow == 1 && item.type == 5"> <el-form-item :label="item.label" :prop="item.isRule ? item.name : ''"> <el-checkbox-group v-model="ruleForm[item.name]"> <el-checkbox label="美食/餐厅线上流动" name="type"></el-checkbox> <el-checkbox label="地推流动" name="type"></el-checkbox> <el-checkbox label="线下主题流动" name="type"></el-checkbox> <el-checkbox label="单纯品牌曝光" name="type"></el-checkbox> </el-checkbox-group> </el-form-item> </div> <div v-if="item.isShow == 1 && item.type == 6"> <el-form-item :label="item.label" :prop="item.isRule ? item.name : ''"> <el-radio-group v-model="ruleForm[item.name]"> <el-radio label="线上品牌商资助"></el-radio> <el-radio label="线下场地收费"></el-radio> </el-radio-group> </el-form-item> </div> <div v-if="item.isShow == 1 && item.type == 7"> <el-form-item :label="item.label" :prop="item.isRule ? item.name : ''"> <el-input :placeholder="`请输出${item.label}`" type="textarea" v-model="ruleForm[item.name]" ></el-input> </el-form-item> </div> </div> <el-form-item> <el-button type="primary" @click="submitForm('ruleForm')" >立刻创立</el-button > <el-button @click="resetForm('ruleForm')">重置</el-button> <el-button @click="backData">回显</el-button> </el-form-item> </el-form>
1、解决接口返回的数据、表单的输入框类型
表单的输入框有很多种,例如:输入框、下拉抉择框、工夫选择器、单选器、多选器、switch
开关、文本域等。
咱们能够通过type
类型来判断是其中的哪一个类型,例如:type === 1
代表输入框
ruleForm: {}, // 输出的绑定表单formArr: [], // 展现的表单ruleArr: {}, // 校验规定// 须要动静展现的数据/* 1 输出 2 下拉抉择 3 日期抉择 4 开关switch 5 多选 6 单选 7 文本域*/obj = [ { name: "name", label: "流动名称", type: 1, // 类型:输出、下拉、日期.... isShow: 1, // 1显示 0不显示 isRule: 1, // 1校验 0不校验 }, { name: "region", label: "流动区域", type: 2, isShow: 1, isRule: 1, }, { name: "date1", label: "流动工夫", type: 3, isShow: 1, isRule: 1, }, { name: "delivery", label: "即时配送", type: 4, isShow: 1, isRule: 1, }, { name: "type", label: "流动性质", type: 5, isShow: 1, isRule: 1, }, { name: "resource", label: "非凡资源", type: 6, isShow: 1, isRule: 1, }, { name: "desc", label: "流动模式", type: 7, isShow: 1, isRule: 1, }, { name: "name2", label: "输入框2", type: 1, isShow: 0, isRule: 0, }, { name: "name3", label: "抉择框2", type: 2, isShow: 0, isRule: 0, },];
2、表单的输入框数据重组和表单的校验
因为表单字段是动静生成的,不确定那些输入框是须要校验的,这里也是依据类型来判断是否须要校验,例如:isRule == 1
代表须要校验,此时校验的值 :prop
必须等于 表单的 K
否则会无奈校验,因为须要对其Key
,须要后端返回或者前端在后期把数据处理好。
formGroup() { this.ruleArr = {}; // 调用之前先重置校验规定 obj.forEach((el) => { if (el.isShow == 1 && el.type == 5) { // 5 多选框,数据必须是数组,因为vue2操作数组会失去双向绑定,须要用$set this.$set(this.ruleForm, el.name, []); } else if (el.isShow == 1 && el.type == 3) { this.$set(this.ruleForm, el.name, []); } else if (el.isShow == 1 && el.type != 3 && el.type != 5) { // 须要把 K 赋值给form,用于回显 this.$set(this.ruleForm,el.name,null); } // 增加校验规定 this.ruleArr[el.name] = [ { required: true, message: `请输出${el.label}`, trigger: "blur" }, ]; }); // 页面遍历该数组生成表单 this.formArr.push(...obj); }
到这里咱们的动静表单就创立好了
咱们只须要依据接口返回的数据渲染表单即可,比方我在这里新增两条数据
obj= [ // ... { name: "name2", label: "输入框2", type: 1, isShow: 1, // 显示 isRule: 0, // 不校验 }, { name: "name3", label: "抉择框2", type: 2, isShow: 1, // 显示 isRule: 0, // 不校验 } ]
此处就动静生成了两条输入框,并且依据类型判断是否是抉择框以及输入框是否校验。
3、提交
失常提交即可,如果封装成组件,这里只须要把值传出去就ok
了。
// 提交 submitForm(formName) { this.$refs[formName].validate((valid) => { if (valid) { alert("submit!"); console.log("提交数据", this.ruleForm); } else { console.log("error submit!!"); return false; } }); }
4、表单的重置
表单重置利用element
提供的reset
不是一个保险的办法,因为reset
函数绑定的是prop
,如果表单未绑定prop
则不会重置该数据,所以须要把数据遍历解决一下,并且,局部输入框(多选)绑定的是数组,vue2
对数组的解决是有缺点的,间接重置会导致失去双向绑定,对于数组的解决须要应用 $set
。
// 重置 resetForm(formName) { this.$refs[formName].resetFields(); // 重置关联的是prop,为了避免局部数据未重置,须要遍历重置一下 for (let [k, v] of Object.entries(this.ruleForm)) { if (v instanceof Array) { // 数组须要用$set否则会失去双向绑定 this.$set(this.ruleForm, k, []); } else { // 重置非数组数据 this.ruleForm[k] = null; } } }
5、对于数据回显的问题
- 须要辨别是否须要数组
- 工夫格局问题
- 数据双向绑定问题
1、多选的格局必须是数组,所以须要判断对应的格局是否为数组。
2、须要比对页面渲染的工夫格局,如果是工夫戳则转成工夫戳,须要字符串则转成字符串,此处的日期选择器为起始和完结选择器,格局绑定为数组。
3、回显的值赋值到页面上会呈现失去双向绑定的问题,点击提交的时候校验无奈通过,须要用$set
让数据变成双向绑定的状态。
// 回显 backData() { let data = { name: "DCodes", region: "武汉", delivery: true, date1: ["2023-07-12", "2023-07-15"], type: "线下主题流动", resource: "线上品牌商资助", desc: "技术分享", }; for (let [k, v] of Object.entries(data)) { Object.keys(this.ruleForm).forEach((el) => { if (el == k) { if (k == "type") { this.$set(this.ruleForm,k,[v]) } else if (k == "date1") { let date = [v[0],v[1]] this.$set(this.ruleForm,k,date) } else { this.ruleForm[k] = v; } } }); } }
css实现炫酷充电动画 (点击中转)
再也不必放心组件跨层级的数据共享和办法驱动了 (点击中转)
css绘制一个Pinia小菠萝(点击中转)
element table列表依据数据设置背景色 (点击中转)
vue3应用百度地图(点击中转)
如果感觉这篇文章对你有帮忙,欢送点赞、珍藏、转发✨哦~