前端项目开发中,表单的应用是必不可少的,不管使用的原生、还是框架如:ElementUI、Ant Design Vue 等。基本的表单应用比较简单,按照文档中的描述使用即可。
官网地址
如下图:
使用 ElementUI 中的表单代码如下:
<el-form
ref="addForm"
:model="form"
:rules="rules"
inline
label-width="100px"
class="demo-ruleForm"
>
<div class="item-title">页面配置</div>
<div class="left">
<el-form-item label="客户端:" prop="client" required>
<el-select
v-model="form.client"
placeholder="请选择"
style="width:300px"
@change="selectChange($event, 'client')"
>
<el-option
v-for="item in enumObj.client"
:key="item.value"
:label="item.label"
:value="item.value"
size-full="100%"
/>
</el-select>
</el-form-item>
<el-form-item label="页面名称:" prop="webName">
<el-input
v-model="form.webName"
placeholder="请输入"
style="width:300px"
/>
</el-form-item>
<el-form-item label="H5链接:" prop="webUrl">
<el-input
v-model="form.webUrl"
placeholder="请输入"
style="width:300px"
/>
</el-form-item>
<el-form-item label="选择模板:" prop="selectMode">
<el-select
v-model="form.selectMode"
placeholder="请选择"
style="width:300px"
clearable
>
<el-option
v-for="item in enumObj.selectMode"
:key="item.value"
:label="item.label"
:value="item.value"
size-full="100%"
/>
</el-select>
</el-form-item>
<el-form-item label="页面主标题:" prop="webMainTitle">
<el-input
v-model="form.webMainTitle"
placeholder="不超过19字"
maxlength="19"
style="width:300px"
/>
</el-form-item>
<el-form-item label="页面副标题" prop="webSubtitle">
<el-input
v-model="form.webSubtitle"
placeholder="不超过30字"
maxlength="30"
style="width:300px"
/>
</el-form-item>
<el-form-item label="页面背景图" prop="webBack">
<UploadCover
ref="webBack"
:objtype="'webBack'"
:base-file="form.webBack"
:width="200"
:height="200"
@on-change="setBackImg"
/>
</el-form-item>
</div>
</el-form>
是不是很简单呢?而项目开发过程中,批量表单循环校验也是很常见的,如上图,动态添加奖励计算规则,把所有的表单放到了一个 el-form-item 下。也可以理解为 el-form-item 做了嵌套,外层当然也可以省略,样式做微调。
下面通过代码来详细的看一下。
- 模板中的 form 需要绑定 mode、 ref 、rules 这些必需属性(很熟悉了,不用解释干嘛的了)
<el-form
ref="rewardTaskRuleVoForm"
:model="rewardTaskRuleVo"
inline
label-width="120px"
:rules="rules">
</el-form>
- 定义需要的数据和规则
rewardTaskRuleVo: {
rewardCalculateFormula: [{}],
}
const checkNumMax = (rule, value, callback) => {
const index = rule.field.split('').findIndex(item => /[0-9]/.test(item))
const obj = this.rewardTaskRuleVo.rewardCalculateFormula[rule.field[index]]
if (!value) {
callback(new Error('最大单量不能为空'))
} else if (value <= obj.numMin) {
callback(new Error('不能小于当前阶梯最小单量,且不能大于下一阶梯最小单量'))
} else {
callback()
}
}
const checkNumMin = (rule, value, callback) => {
const index = rule.field.split('').findIndex(item => /[0-9]/.test(item))
const obj = this.rewardTaskRuleVo.rewardCalculateFormula[rule.field[index]]
if (!value) {
callback(new Error('最小单量不能为空'))
} else if (value >= obj.numMax) {
callback(new Error('不能大于当前阶梯最大单量,且不能低于上一阶梯最大单量'))
} else {
callback()
}
}
rules: {
numMax: [{ required: true, validator: checkNumMax }],
numMin: [{ required: true, validator: checkNumMin }],
amount: [{ required: true, message: '请输入奖励金额', trigger: ['trigger', 'change'] }]
}
- 循环的表单 el-form-item 中绑定规则
<el-form-item label="奖励计算公式:" prop="rewardCalculateFormula" required>
<br>
<!-- {{ rewardTaskRule Vo.rewardCalculateFormula }} -->
<div v-for="(item,index) in rewardTaskRuleVo.rewardCalculateFormula" :key="index" class="formula">
<div>
<strong>阶梯 {{ index + 1 }}:</strong>
<div style="float: right">
<el-link v-if="index > 0" type="primary" style="margin-right: 20px" @click="formulaHandle('minus', index)">删除阶梯</el-link>
<el-link type="success" @click="formulaHandle('plus', index)">增加阶梯</el-link>
</div>
</div>
<div style="margin-left: 12px">
<strong>单量:</strong>
<el-form-item :prop="`rewardCalculateFormula[${index}].numMin`" :rules="rules.numMin"><el-input-number v-model="item.numMin" controls-position="right" :min="index > 0 ? rewardTaskRuleVo.rewardCalculateFormula[index-1].numMax + 1 : 1" :precision="0" size="small" @change="checkMin(item, index)" /></el-form-item>
——
<el-form-item :prop="`rewardCalculateFormula[${index}].numMax`" :rules="rules.numMax"><el-input-number v-model="item.numMax" controls-position="right" :min="1" :precision="0" size="small" @change="checkMax(item, index)" /></el-form-item>
<strong style="margin-left: 20px">奖励金额:</strong>
<el-form-item :prop="`rewardCalculateFormula[${index}].amount`" :rules="rules.amount"><el-input-number v-model="item.amount" controls-position="right" :min="1" size="small" /></el-form-item>
</div>
</div>
</el-form-item>
- 提交表单校验
this.$refs.rewardTaskRuleVoForm.validate(async valid => {
if (!valid) return this.$message.error('请检查奖励配置输入内容是否符合规则!')
if (this.rewardTaskRuleVo?.rewardCalculateFormula?.length) {
const result = this.rewardTaskRuleVo.rewardCalculateFormula.every(v => v.numMax && v.numMin && v.amount)
if (!result) return this.$message.error('奖励计算公式内容不能为空!')
}
this.form.rewardTaskRuleVo = { ...this.rewardTaskRuleVo }
const data = this.mergeData(this.form)
# .... 接口代码 ....
})
- 其它辅助验证代码
checkMax(item, index) {
this.$nextTick(() => {
if (item.numMax <= item.numMin) {
item.numMax = item.numMin + 1
this.$set(this.rewardTaskRuleVo.rewardCalculateFormula, index, item)
}
if (item.numMax >= this.rewardTaskRuleVo.rewardCalculateFormula[index + 1]?.numMin) {
item.numMax = this.rewardTaskRuleVo.rewardCalculateFormula[index + 1].numMin - 1
}
if (this.rewardTaskRuleVo.rewardCalculateFormula[index + 1]) {
this.rewardTaskRuleVo.rewardCalculateFormula[index + 1].numMin = item.numMax + 1
this.rewardTaskRuleVo.rewardCalculateFormula[index + 1].numMax = item.numMax + 2
}
})
},
checkMin(item, index) {
this.$nextTick(() => {
if (item.numMax <= item.numMin) {
item.numMin = item.numMax - 1
this.$set(this.rewardTaskRuleVo.rewardCalculateFormula, index, item)
}
})
}
数字化管理平台
Vue3+Vite+VueRouter+Pinia+Axios+ElementPlus
Vue权限系统案例
个人博客地址
表单属性
model 表单数据对象
rules 表单验证规则
inline 行内表单模式
label-position 表单域标签的位置,如果值为 left 或者 right 时,则需要设置 label-width string right/left/top right
label-width 表单域标签的宽度,例如 ‘50px’。作为 Form 直接子元素的 form-item 会继承该值。支持 auto
label-suffix 表单域标签的后缀
hide-required-asterisk 是否隐藏必填字段的标签旁边的红色星号
show-message 是否显示校验错误信息
inline-message 是否以行内形式展示校验信息
status-icon 是否在输入框中显示校验结果反馈图标
validate-on-rule-change 是否在 rules 属性改变后立即触发一次验证
size 用于控制该表单内组件的尺寸
disabled 是否禁用该表单内的所有组件。若设置为 true,则表单内组件上的 disabled 属性不再生效
表单方法
validate 对整个表单进行校验的方法,参数为一个回调函数。该回调函数会在校验结束后被调用,并传入两个参数:是否校验成功和未通过校验的字段。若不传入回调函数,则会返回一个 promise Function(callback: Function(boolean, object))
validateField 对部分表单字段进行校验的方法 Function(props: array | string, callback: Function(errorMessage: string))
resetFields 对整个表单进行重置,将所有字段值重置为初始值并移除校验结果
clearValidate 移除表单项的校验结果。传入待移除的表单项的 prop 属性或者 prop 组成的数组,如不传则移除整个表单的校验结果 Function(props: array | string)
表单事件
validate 任一表单项被校验后触发 被校验的表单项 prop 值,校验是否通过,错误消息(如果存在)
表单单项属性
prop 表单域 model 字段,在使用 validate、resetFields 方法的情况下,该属性是必填的 string 传入 Form 组件的 model 中的字段
label 标签文本
label-width 表单域标签的的宽度,例如 ‘50px’。支持 auto
required 是否必填,如不设置,则会根据校验规则自动生成
rules 表单验证规则
error 表单域验证错误信息, 设置该值会使表单验证状态变为error,并显示该错误信息
show-message 是否显示校验错误信息
inline-message 以行内形式展示校验信息
size 用于控制该表单域下组件的尺寸
表单单项 slot 插槽
属性
label 标签文本的内容
作用域插槽 Scoped Slot
name 说明
error 自定义表单校验信息的显示方式,参数为 { error }
方法
resetField 对该表单项进行重置,将其值重置为初始值并移除校验结果 -
clearValidate 移除该表单项的校验结果 -