• 注册
当前位置:1313e > vue >正文

vue 非响应式属性放哪_关于Vue响应式的一些坑

前置知识

对象里的属性可以分为两种形式,一种是key-value形式的数据描述符,而另外一种就是由getter-setter函数对描述的存取描述符。

在Vue里,就是通过遍历data,使用object.defineProperty()来将数据转换成data的存取描述符,然后通过getter-setter来监测数据的变化,从而达到响应式的效果。

那么问题来了,基于这样的设计限制,我们在改变data的时候,自然会有一些限制:当data为对象时,我们不能动态地添加对象属性。这是由于 动态新增的属性,默认是数据描述符,无法通过getter/setter来监测属性的变化。

解决方法:在初始化data时,给该属性一个初始化的值,可以用null、空字符串或其他值。

使用vue的set API

# data

{

family:{

father:{

name:'Jack'

},

mother:{

name:'Rose',

pregnant:false

}

}

}

# methods

{

born(){

if(mother.pregnant){

setTimeout(()=>{

this.$set(this.family,'son',{name:'Jason'}) // vm.$set(target,key,value) },100000)

}

}

}

3. 直接赋值一个新的对象给该data,还是上面那个例子

# data

{

family:{

father:{

name:'Jack'

},

mother:{

name:'Rose',

pregnant:false

}

}

}

# methods

{

born(){

let copyFamily = JSON.parse(JSON.stringfy(this.family))

if(mother.pregnant){

setTimeout(()=>{

copyFamily[son] = {

name:'Jason',

age:0

}

this.family = copyFamily

},100000)

}

}

}

至此,我以为我已经掌握了 Vue 响应式,直到我又遇到了一个新的坑 :point_down:

Vue watch 无法监测对象的变动

从一个项目说起:Vue - JSFiddle​jsfiddle.net

探索原因

在这里,dataList是一个数组,通过computed 可以轻易地根据数据响应来实时更新一些页面需要显示的数据。

但,如果使用watch来监听dataList,可以发现他的前后value都是一样的,这样的话,不就不可以监听了?

查看官方文档,也有关于这方面的描述:

image.png

文档上只是说了结果,并没有说为什么。于是我谷歌了一下,觉得下面这篇讲的比较有道理记一次思否问答的问题思考:Vue为什么不能检测数组变动​segmentfault.com

看完以后,发现 读源码 应该挺有意思的,等以后有时间了 可以尝试一下。

过细的原因就不详说,这里就总结一下:

尤大在设计这个功能的时候,出于某种原因(有说是JavaScript的限制,有说是性能问题),并没有将对象/数组的每个属性都过滤成getter/setter。如果没有深入过滤对象的每个属性,那么只能监听到对象的变化,而JavaScript里对象的赋值是引用赋值,虽然属性变化了,但是它引用的地址却一直没有变化,这样的话,当对象的属性值改变了,Vue并不能得到变异之前的值。

(可能理解有出入,如果有错,烦请指正)

解决方法

既然watch 无法在变异对象或数组时监听新旧值,那么我们可以先使用JSON.parse来浅复制一遍data对象,然后在复制的对象上修改,完了重新赋值给该data对象,就可以完美实现 对象变化的watch监听。Vue - JSFiddle​jsfiddle.net

我的其他平台| 简书 : (关于Vue响应式的一些坑)

本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 162202241@qq.com 举报,一经查实,本站将立刻删除。

最新评论

欢迎您发表评论:

请登录之后再进行评论

登录