背景
公司项目中所用到的前端框架是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>
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
《魔兽世界》大逃杀!60人新游玩模式《强袭风暴》3月21日上线
暴雪近日发布了《魔兽世界》10.2.6 更新内容,新游玩模式《强袭风暴》即将于3月21 日在亚服上线,届时玩家将前往阿拉希高地展开一场 60 人大逃杀对战。
艾泽拉斯的冒险者已经征服了艾泽拉斯的大地及遥远的彼岸。他们在对抗世界上最致命的敌人时展现出过人的手腕,并且成功阻止终结宇宙等级的威胁。当他们在为即将于《魔兽世界》资料片《地心之战》中来袭的萨拉塔斯势力做战斗准备时,他们还需要在熟悉的阿拉希高地面对一个全新的敌人──那就是彼此。在《巨龙崛起》10.2.6 更新的《强袭风暴》中,玩家将会进入一个全新的海盗主题大逃杀式限时活动,其中包含极高的风险和史诗级的奖励。
《强袭风暴》不是普通的战场,作为一个独立于主游戏之外的活动,玩家可以用大逃杀的风格来体验《魔兽世界》,不分职业、不分装备(除了你在赛局中捡到的),光是技巧和战略的强弱之分就能决定出谁才是能坚持到最后的赢家。本次活动将会开放单人和双人模式,玩家在加入海盗主题的预赛大厅区域前,可以从强袭风暴角色画面新增好友。游玩游戏将可以累计名望轨迹,《巨龙崛起》和《魔兽世界:巫妖王之怒 经典版》的玩家都可以获得奖励。
更新动态
- 小骆驼-《草原狼2(蓝光CD)》[原抓WAV+CUE]
- 群星《欢迎来到我身边 电影原声专辑》[320K/MP3][105.02MB]
- 群星《欢迎来到我身边 电影原声专辑》[FLAC/分轨][480.9MB]
- 雷婷《梦里蓝天HQⅡ》 2023头版限量编号低速原抓[WAV+CUE][463M]
- 群星《2024好听新歌42》AI调整音效【WAV分轨】
- 王思雨-《思念陪着鸿雁飞》WAV
- 王思雨《喜马拉雅HQ》头版限量编号[WAV+CUE]
- 李健《无时无刻》[WAV+CUE][590M]
- 陈奕迅《酝酿》[WAV分轨][502M]
- 卓依婷《化蝶》2CD[WAV+CUE][1.1G]
- 群星《吉他王(黑胶CD)》[WAV+CUE]
- 齐秦《穿乐(穿越)》[WAV+CUE]
- 发烧珍品《数位CD音响测试-动向效果(九)》【WAV+CUE】
- 邝美云《邝美云精装歌集》[DSF][1.6G]
- 吕方《爱一回伤一回》[WAV+CUE][454M]
