1、使用v-model 绑定对象的动态属性,导致v-model失效或者数据异常
场景:使用iview的CheckboxGroup 做checkbox多选时,发现勾选的选项和v-model绑定对象对应的属性值不匹配。
template代码如下:
<CheckboxGroup v-else-if="item.formType === 'checkbox'" v-model="metaTemplate[item.name]">
<Checkbox v-for="(check, index) in JSON.parse(item.formValue)" :key="index" :label="check"></Checkbox>
</CheckboxGroup>
这里面checkbox的值和个数都是通过接口返回动态参数决定的,v-model绑定到一个叫meteTemplate对象的属性上,而这个属性也是动态添加上去的。怪异的问题是:假设现在checkbox有三个,当全部选中三个时,这时候预期的结果是绑定的对象属性是一个含有三个值的数组,但实际是含有一个值的数组,看起来感觉v-model出现问题了,即UI变化没有反应到数据上。
template对象定义如下:
data () {
return {
metaTemplate: {
}
},
它是一个简单的空对象,对象属性是动态加上去的,错误截图如下:
这里看到UI的状态和数据并不保持一致,感觉很怪异。
尝试办法:
(1) 重新定义一个属性使用v-model和checkbox绑定,发现正常工作。
(2)在metaTemplate中预选定义一个属性,例如metaTemplate{checkArr:[]}, 发现页正常工作。
思考:
从上面的尝试办法看出不是组件本身的问题,不是对象属性嵌套的问题,这次最大的不同就是绑定的属性是后来加到对象上去的,即v-model是对象的一个动态属性,于是就思考动态属性是不是需要特殊处理后才能适用于v-model?
解决办法:
原因:
见Vue.js中文官网->进阶->深入响应式原理->变化检测问题
受现代 JavaScript 的限制(以及废弃 Object.observe),Vue 不能检测到对象属性的添加或删除。由于 Vue
会在初始化实例时对属性执行 getter/setter 转化过程,所以属性必须在 data 对象上存在才能让 Vue
转换它,这样才能让它是响应的。例如:
方案:
1、使用 Vue.set(object, key, value) 方法将响应属性添加到嵌套的对象上:
Vue.set(vm.someObject, 'b', 2)
2、您还可以使用 vm.$set 实例方法,这也是全局 Vue.set 方法的别名:
this.$set(this.someObject,'b',2)
3、使用 Object.assign() 或 _.extend() 方法来添加属性
this.someObject = Object.assign({}, this.someObject, { a: 1, b: 2 })
实例解决办法:
this.$set(this.metaTemplate, item.name, [])
参见:https://blog.csdn.net/time__flies_/article/details/78039191
2、iview表单验证规则遇到非string类型时,如果不明确指明类型,则可能验证失败
场景:很多表单项都需要验证是否为空,现有一项表单为多选的checkbox绑定的值,最终数据应该是一个数组,验证规则如下:
{ required: true, message: '请输入该字段', trigger: 'blur' }
但勾选了选项后,点击确认提交表单,发现表单验证不通过,在checkbox下面提示:‘请输入该字段’。
思考:明显是验证规则有问题,发现没有明确指定验证的type类型。
解决办法:
{ required: true, type: 'array', message: '请输入该字段', trigger: 'blur' }
3、vue v-for 使用默认index作为key导致数据发生变化,页面数据不渲染或者不正确。