响应式顾名思义就是对外界的触发变化做出响应。
在vue中,vue的data是响应式的,我们会很好奇,为什么传入new Vue({})中的data在做出变化的时候,UI中相应地显示的数据也会响应做出变化,vue到底是如何实现的?
const
明显可以看出myData已经发生了变化。
简单实现数据响应式
使用代理+监听
function
监听是修改data对象的过程,代理是在被修改过的data对象上创建的。这样彼此之间的连接才不会断开。当你的data有多个变量或属性的时候,我们可以使用闭包和循环来实现这个过程。
所以当new Vue()的时候,vue对data做了以下操作:
当你创建实例的时候:
const vm = new Vue({data:myData})
- vue会让vm成为myData的代理(将监听到变化的结果进行代理,供用户访问或修改)
- vm会对myData的所有属性进行监控(监听他的变化)
vm就充当了一个中介的作用,在监听到数据发生变化的时候就通知UI,UI上显示的数据就会做出响应,发生改变。
那么Vue这样做的目的是什么呢?
- 可以使用this访问vm,this.n === myData.n //true
- 因为监控,所以才让vue得知myData发生了变化
- 因为代理,得知属性变化之后才能使用render(data)来更新UI和渲染页面
总结数据响应式
- 所谓响应式就是对外界的变化做出相应的一种形式。
- const vm = new Vue({data:{n:0}}) 当修改vm.n或者this.n的时候,render(data)中的n就会做出相应的响应。这个过程就是Vue的数据响应式。
- vue目前通过Object.defineProperty来实现数据响应式。
当在data中添加属性时
Vue虽然对data中的属性或options对象中的属性进行监听和代理,但是他却没有办法进行事先的监听和代理。
对于对象来说:在初始化好data之后,你需要添加一个属性,该如何实现?
如果是给一般对象新增属性,我们其实可以在data中预先把所有可能用到的属性全部写出来,这样并不需要新增属性。当然也可以通过其他方法来添加属性。下面我们来了解一个Vue提供的API:
Vue
作用:
- 在data中添加新的属性
- 自动创建为他创建的代理和监听(前提是没有创建过)
//举个栗子
对于数组来说:
因为数组本身的特殊性,数组的长度无法预测,且我们无法使用undefined去为每一项占位,或一直使用Vue.set()方法,尤雨溪为我们提供了几个Vue为数组提供的API。
列表渲染 — Vue.jscn.vuejs.org
当你在使用push的时候,push进去的元素就已经被监听了。这是被Vue封装过的新的push方法。
它的原理:声明一个新的类来继承数组,循环遍历,将每一个新增的元素告诉Vue,为其添加监听和代理。从而让这些新增的数组项去触发视图的更新。
小结
研究思路和方法远比学习知识要重要的多,我们可以不懂或不看一个库或者项目的源码,但我们应该知道他的思路和方法是什么。
参考链接:
Jacky:浅析Vue数据响应式zhuanlan.zhihu.com
对象初始化developer.mozilla.org
Object.defineProperty()developer.mozilla.org