快速解答
简单解答一下,这是因为绑定的值有问题。prop绑定的只能是 :model 绑定的值的下一层,而不能是下下层。这里猜测是由于 JavaScript 的限制,Vue 不能检测数组和对象的变化。
前言
接了个需求:在elementUI中,有一个表单,其中有一项是选择时间。时间这栏又不单只有输入框,后面还要有个单位,我需要校验用户输入的时间不能低于20秒。我们知道elementUI的表单校验也已经很完善了【完整校验规则】,能应付绝大部分场景。但是局限于单个item的校验,对于我这种组合校验的需求,只能自定义校验方法来实现。实现的过程并不是那么顺利。记录一下踩坑,顺便讲解一下实现过程。
实现过程
1. 在表单项中先做一个输入框输入数字,然后再做一个单位选择器
<el-form-item label="时间间隔" prop="interval">
<el-input-number v-model="form.interval.num" placeholder="Interval"></el-input-number>
<el-select v-model="form.interval.unit">
<el-option key="hour" label="hour" value="hour"></el-option>
<el-option key="minute" label="minute" value="minute"></el-option>
<el-option key="second" label="second" value="second"></el-option>
</el-select>
</el-form-item>
注意:在这里我踩了一个坑,数据监控只能检测 :model 元素绑定的数组的下一层,意思就是说prop绑定的对象只能是interval,而不可以是num这层。否则后面的步骤是无法获得数据的。
2. 在data()中添加一个校验方法(这个我没测过放在methods中行不行)
value的传值来源于prop中,如果你上面写了num的话,这里打印出来的value是undefined。你可能会说,那我这暴脾气能忍啊,我直接反手一个this.form.interval.num,不也能拿到值吗?确实可以的,不过不太好吧,就按人家的这样规定来就好了。毕竟你后面绑定的校验项还是要绑定interval的,因为你要校验的是两个值的组合,而不是单单校验一个num。
const checkInterval = (rule, value, callback) => {
// 这里的value是interval
// 判空
if (!value.num) {
callback(new Error('Interval cannot be empty.'));
} else if (!value.unit) {
callback(new Error('Please select interval unit.'));
} else {
// 非空,开始校验
if (value.interval < 20 & value.unit === 'second') {
// 组合小于20秒 拦截
callback(new Error('The minimum value cannot be less than 20 second.'));
}
// 无错 放行
callback();
}
}
3. 在校验规则中声明绑定校验方法
rules: {
......
interval: [{validator: checkInterval, trigger: 'change'}],
}
这里监听事件使用的是change(变更),而不是blur(失焦)。原因是失焦事件只能用于输入框,而不能监听选择器,这时候如果前面由于你输入了10秒,触发了校验方法,给你一句警告,而你选择了单位为分钟之后,没能触发校验方法,导致那句警告一直在,对用户的体验极不友好。