vue + element-ui项目,el-checkbox上的响应式问题——数据变化后勾选状态未变化
Vue 为了尽可能高效地渲染元素,通常会复用已有元素而不是从头开始渲染。若要两个元素完全独立,不要复用,添加具有唯一值的key即可。
·
先来简化一下项目原型。就是一个列表和一个表单,点击列表的某一项,表单中显示这一项对应的数据内容,并可修改。由于发现问题的是复选框,所以表单简化为一个复选框代替。
<ul>
<li v-for="item in list" @click="clickFn(item)">{{item.name}}</li>
<ul>
<el-form :model="curItem">
<el-checkbox v-model="curItem.isCheck" label="选择"></el-checkbox>
</el-form>
export default{
data(){
list:[{
id:1,
name:'Keith'
},{
id:2,
name:'Annie'
}],
curItem:{}
},
methods:{
clickFn(item){
this.curItem = item
}
}
}
初始状态下,列表中的每一项都没有选中复选框的属性。点击列表中第一项,勾选复选框,再点击第二项,此时复选框应该是未勾选状态,但却依然保留第一项的勾选状态。
第一反应考虑到是属性的响应式的问题(详情参考这里),于是将click事件优化如下:
clickFn(item){
this.$set(this , 'curItem' , item)
}
然而复选框依旧没有取消勾选。但无意中发现,若将element-ui中的<el-checkbox>组件改为原生复选框,勾选状态就可以正常显示了。
<input type="checkbox" v-model="curItem.isCheck" />
为什么原生复选框状态可以正常切换,el-checkbox却不可以,是组件本身的设计缺陷吗?为了方便在项目中直接调试,我在页面中独立引入element-ui中的CheckBox组件并在源码中输出log。
import checkboxOnly from 'element-ui/packages/checkbox';
export default{
components:{
checkboxOnly
}
}
<el-form :model="curItem">
<checkboxOnly v-model="curItem.isCheck" label="选择"></checkboxOnly>
</el-form>
以下是简化后的源码(只保留了该案例中需要的部分)及log。
data(){
return {
selfModel: false
}
},
computed:{
//v-model绑定的值
model:{
get(){
console.log('get-',this.value);
console.log('get-',this.selfModel);
return this.value !== undefined ? this.value : this.selfModel;
},
set(val){
console.log('set-',val);
this.$emit('input',val);
this.selfModel = val;
}
},
//复选框是否被选中
isChecked(){
console.log(this.model);
return this.model;
}
}
根据log输出可知,在切换list时,虽然数据变了,但并没有触发model的set方法,所以当首次将selfModel设置为true后,后面get方法得到的值一直是true。产生这个问题的原因是,Vue 为了尽可能高效地渲染元素,通常会复用已有元素而不是从头开始渲染。若要两个元素完全独立,不要复用,添加具有唯一值的 key 即可。于是通过给表单增加key的方式,强制表单重新渲染,问题就解决了。
<el-form :key="curItem.id" :model="curItem">
<el-checkbox v-model="curItem.isCheck" label="选择"></el-checkbox>
</el-form>
更多推荐
已为社区贡献17条内容
所有评论(0)