今天在项目中无意发现一个很奇怪的问题,未来方便描述,对象用obj表示,具体属性时obj.disabled
大概的问题是这样的:
我保存表单后需要禁用save按钮,代码如下
save(){
...
this.obj.disabled = true
...
}
但是这样save按钮没有更新,于是我在后面加上打印看看怎么回事
save(){
...
this.obj.disabled = true
console.log('save',this.obj,this.obj.disabled)//save obj对象 true
...
}
这里打印的obj对象的disabled的值和obj.disabled都为为true,没道理啊,数据都改了
这里我原来以为只是视图没有更新,尝试了N个的方法都不行,例如
//1.$set set为解决双向绑定失效而生
//例如: 在编辑表单时,获取接口数据,然后this.form.input1 = data.input1,这样会导致双向绑定失效,this.form = data 这样不会,但是如果一定要单独一个个赋值,就可以用$set
this.$set(this.obj,'disabled',true)
//2.$forceUpdate() 强制更新视图
this.$forceUpdate()
//3.$nextTick() 在渲染节点后,执行...
this.$nextTick(()=>{
...
})
//4.setTimmeout 一次性计时器,解决异步问题,这里我测试了,之后延迟的时间够长,才会实现效果,所以这里我判断不是异步问题
setTimeout(()=>{
...
}, 10)
搞了许久不知道问题在哪,我就用watch监听了obj的数据变化
这里我发现,obj在我save方法过后还有修改,于是我在每个对obj对象有操作的地方,都打印一次,发现在最后一次打印里面,打印的obj.disabled 为false,找到问题在哪了,这就简单很多了。
这里我发现在我修改过后和最后一次修改中间的打印,打印的obj对象展开的disabledfalse,obj.disabled为true。
这里困扰了我许久,其实就是这里的打印对象是按地址访问的,如果后面有修改,打印出来的对象展开后的也是修改后的值,但是直接打印对象的具体属性,是按值访问的,其实就是js的引用类型(Object)和基础类型(Number、String 、Boolean、Null、Undefined)问题
如果有兴趣可以自己去找对应的资料看看
难点(发发牢骚)
这个问题要搞这么久是因为这个页面的内容实在太多了(一共5600行代码,html+css+js),里面是几个表单提交,大概200个字段这样,字段联动多的有四级联动,比如:
四级联动:A影响B,B影响C,C影响D,D影响E。
一对多:A影响B,C,D
多对一: A,B,C影响D
而且字段联动和一对多和多对一是有混用的
有时候我一周不做这个页面的需求,我回头去看,有些我都忘了有些带是干啥的,这个页面中间还改版两次,真难受啊!
总结
搞了快半天,就是个很基础的数据类型问题,看来基础都忘光了,得找时间补补课了。