背景
公司项目中所用到的前端框架是Vue.js + ElementUI,因为项目的业务场景中有很多的大表单,但是ElementUI的表单写法对于表单的拆分和校验其实并不是很友好。最初的项目为了方便,常常把多个表单写在一个.vue组件中,这导致单文件的代码量巨大,逻辑十分复杂。目前为了维护方便,表单的拆分就变得十分重要。
现在做了以下的Demo说明我们的业务场景,父组件是App.vue,该组件中包含了PersonForm.vue和AdsForm.vue这两个子组件(在实际的业务场景中,可能多达10+表单)。【提交】按钮在父组件App.vue中,当点击【提交】按钮后,应该分别校验各个子组件,如果每个子组件都校验成功后再进行提交。
Demo
PersonForm.vue文件
下面的代码是PersonForm.vue组件,该表单包括姓名、年龄、性别。我们使用了PersonForm这个类去实例化组件中的personForm的值。在PersonForm中有个static方法getRule去获取校验方法去获取校验对象,该校验对象是ElementUI要求的写法,会在<el-form>的rules中定义。
<template> <div class="person-form"> <h2>PersonForm.vue</h2> <el-form :model="personForm" ref="personForm" :rules="personFormRules"> <!-- 姓名 --> <el-form-item label="姓名" prop="name"> <el-input v-model="personForm.name"></el-input> </el-form-item> <!-- 年龄 --> <el-form-item label="年龄" prop="age"> <el-input v-model="personForm.age"></el-input> </el-form-item> <!-- 性别 --> <el-form-item label="性别" prop="sex"> <el-radio-group v-model="personForm.sex"> <el-radio label="0">男</el-radio> <el-radio label="1">女</el-radio> </el-radio-group> </el-form-item> </el-form> </div> </template> <script> import {validateName, validateAge, validateSex } from '@/lib/validator.js'; // PersonForm的类 class PersonForm { constructor() { this.name = ''; this.age = null; this.sex = null; } static getRule() { return { name: [{ validator: validateName, trigger: 'blur' }], age: [{ validator: validateAge, trigger: 'blur' }], sex: [{validator: validateSex, trigger: 'blur'}], } } } export default { data() { return { personForm: new PersonForm(), personFormRules: PersonForm.getRule() } } } </script> <style> .person-form { width: 400px; height: 350px; padding: 20px; border: 1px solid #ccc; } </style>
AdsForm.vue文件
下面的代码是AdsForm.vue组件,该表单包括广告名和广告位置。我们使用了AdsForm这个类去实例化组件中的adsForm的值。在AdsForm中有个static方法getRule去获取校验方法去获取校验对象。
<template> <div class="ads-form"> <h2>AdsForm.vue</h2> <el-form :model="adsForm" ref="adsForm" :rules="adsFormRules"> <!-- 广告名 --> <el-form-item label="广告名" prop="name"> <el-input v-model="adsForm.name"></el-input> </el-form-item> <!-- 广告位置 --> <el-form-item label="广告位置" prop="position"> <el-select v-model="adsForm.position"> <el-option value="1" label="左上"></el-option> <el-option value="2" label="右上"></el-option> <el-option value="3" label="左下"></el-option> <el-option value="4" label="右下"></el-option> </el-select> </el-form-item> </el-form> </div> </template> <script> import { notEmpty, validateName } from '@/lib/validator.js'; class AdsForm { constructor() { this.name = ''; this.position = null; } static getRule() { return { name: [{ validator: validateName, trigger: 'blur' }], position: [{ validator: notEmpty, trigger: 'blur' }], } } } export default { data() { return { adsForm: new AdsForm(), adsFormRules: AdsForm.getRule() } } } </script> <style> .ads-form { width: 400px; height: 350px; padding: 20px; border: 1px solid #ccc; margin-left: 30px; } </style>
validator.js文件
在PersonForm.vue 和 AdsForm.vue中我们导入了validator.js中的校验方法,这些校验方法中封装了对表单属性值的校验规则。该文件中的方法在实际项目中,应该使用策略模式再封装一下。Demo中只有4个方法,就没有再封装来干扰读者理解代码。
// 验证名字 var validateName = (rule, value, callback) => { if(!value) { callback(new Error('名字不能为空')); } else if(/[a-zA-Z]/.test(value)) { callback(new Error('请填写中文名字!')); } else { callback(); } }; // 验证年龄 var validateAge = (rule, value, callback) => { const toNumberVal = Number(value); if ((typeof value === 'string' && value === '') || (value === null)) { callback(new Error('年龄不允许为空')); } else if (isNaN(toNumberVal)) { callback(new Error('年龄为数值类型')); } else if(!(toNumberVal > 0 && toNumberVal <= 120)) { callback(new Error('年龄范围应该大于一岁且小于等于120岁')); } else { callback(); } } // 验证性别 var validateSex = (rule, value, callback) => { if (value === null) { callback(new Error('性别不允许为空')); } { callback(); } } // 验证不为空 var notEmpty = (rule, value, callback) => { if (value === '' || value === null || value === undefined) { callback(new Error('不允许为空')); } else { callback(); } } export { validateName, validateAge, validateSex, notEmpty, }
App.vue
App.vue是父组件,当点击【提交】按钮时,应该调用其ElmentUI的this.$refs[formName].validate方法去验证各个子组件中的表单。但是需要注意的是,该方法是一个异步方法。
所以这里封装了一个getFormPromise去生成Promise对象,并使用Promise.all去并行调用返回最终的校验结果数组。
<template> <div class="app"> <h1>App.vue</h1> <div class="forms-container"> <!-- PersonForm.vue --> <person-form ref="personFormComp"/> <!-- AdsForm.vue --> <ads-form ref="adsFormComp"/> </div> <el-button class="submit-btn" @click="submitForm" type="primary"> 提交 </el-button> </div> </template> <script> import PersonForm from '@/components/PersonForm'; import AdsForm from '@/components/AdsForm.vue'; export default { components: { 'person-form': PersonForm, 'ads-form': AdsForm, }, methods: { submitForm() { // 获取到组件中的form const personForm = this.$refs.personFormComp.$refs.personForm; const adsForm = this.$refs.adsFormComp.$refs.adsForm; // 使用Promise.all去校验结果 Promise.all([personForm, adsForm].map(this.getFormPromise)).then(res => { const validateResult = res.every(item => !!item); if (validateResult) { console.log('两个表单都校验通过'); } else { console.log('两个表单未校验通过'); } }) }, getFormPromise(form) { return new Promise(resolve => { form.validate(res => { resolve(res); }) }) } } } </script> <style> .app { border: 1px solid #ccc; padding: 20px; width: 900px; } .app .submit-btn { margin-top: 40px; } .forms-container { display: flex; } </style>
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
免责声明:本站资源来自互联网收集,仅供用于学习和交流,请遵循相关法律法规,本站一切资源不代表本站立场,如有侵权、后门、不妥请联系本站删除!
稳了!魔兽国服回归的3条重磅消息!官宣时间再确认!
昨天有一位朋友在大神群里分享,自己亚服账号被封号之后居然弹出了国服的封号信息对话框。
这里面让他访问的是一个国服的战网网址,com.cn和后面的zh都非常明白地表明这就是国服战网。
而他在复制这个网址并且进行登录之后,确实是网易的网址,也就是我们熟悉的停服之后国服发布的暴雪游戏产品运营到期开放退款的说明。这是一件比较奇怪的事情,因为以前都没有出现这样的情况,现在突然提示跳转到国服战网的网址,是不是说明了简体中文客户端已经开始进行更新了呢?
更新日志
- 凤飞飞《我们的主题曲》飞跃制作[正版原抓WAV+CUE]
- 刘嘉亮《亮情歌2》[WAV+CUE][1G]
- 红馆40·谭咏麟《歌者恋歌浓情30年演唱会》3CD[低速原抓WAV+CUE][1.8G]
- 刘纬武《睡眠宝宝竖琴童谣 吉卜力工作室 白噪音安抚》[320K/MP3][193.25MB]
- 【轻音乐】曼托凡尼乐团《精选辑》2CD.1998[FLAC+CUE整轨]
- 邝美云《心中有爱》1989年香港DMIJP版1MTO东芝首版[WAV+CUE]
- 群星《情叹-发烧女声DSD》天籁女声发烧碟[WAV+CUE]
- 刘纬武《睡眠宝宝竖琴童谣 吉卜力工作室 白噪音安抚》[FLAC/分轨][748.03MB]
- 理想混蛋《Origin Sessions》[320K/MP3][37.47MB]
- 公馆青少年《我其实一点都不酷》[320K/MP3][78.78MB]
- 群星《情叹-发烧男声DSD》最值得珍藏的完美男声[WAV+CUE]
- 群星《国韵飘香·贵妃醉酒HQCD黑胶王》2CD[WAV]
- 卫兰《DAUGHTER》【低速原抓WAV+CUE】
- 公馆青少年《我其实一点都不酷》[FLAC/分轨][398.22MB]
- ZWEI《迟暮的花 (Explicit)》[320K/MP3][57.16MB]