Vue三要素:
- 响应式:如何监听数据变化(双向绑定)
- 模板引擎:如何解析模板
- 渲染:
Vue
如何将监听到的数据变化和解析后的 HTML 进行渲染
但凡涉及到 MVVM 框架就不得不提到双向绑定原理,也就是数据劫持。而在此之前我们已经尝试着解决过这个问题(详情请看《Vue双向绑定原理及实现》)。而对于Vue3.0
,尤雨溪说过要用 ES6 中新推出的Proxy
来代替Object.defineProperty
实现数据劫持。那么我们就一起来看一下为什么作者会做出如此改动吧~
在此之前需要对Proxy
有一定的了解。详情请看 《ES6中的代理模式》
一定要看上边的两篇文章之后再回来看这篇啊!!!!
数据劫持
在《Vue双向绑定原理及实现》一文中我们介绍到了利用Object.defineProperty
劫持对象访问器(set
、get
),以便于属性发生变化时直接进行下一步操作,以此实现一个真正的Observer
。
然而,我们有没有注意到我们只是对Watcher
的get
、set
方法进行监听而非全部属性,所以我们用Object.defineProperty
未免有点杀鸡用牛刀的感觉,而Proxy
则可以对那13个对象属性进行精确监控监听,解决了您的烦恼,实则是居家旅行,杀人越货的好帮手
但是,总是千变万化,仍逃不出发布者-订阅者模式。我们必须利用代理监听Watcher
的属性值并对其劫持,变化时通知订阅者。
而解析器则负责解析模板中的指令,收集指令所以来的方法和数据,等待数据变化然后渲染模板
最终Watcher(订阅者)
将Observer(监听者)
和Compiler(解析器)
连接起来,并根据Compiler
所提供的指令进行试图渲染是的数据变化推动视图变化。
图我懒得找了所以就盗了一张,诸位好汉不要介意。
基于Object.defineProperty的双向绑定
具体内容我们就不再细讲了,《Vue双向绑定原理及实现》讲的还是比较清楚的。我们来说说它的缺陷:
我们之前所讲的双向绑定无法监听数组变化。而作者则通过遍历数组中的方法手动解除掉了这个bug
,原理如下
1 | const aryMethods = ['push', 'pop', 'shift', 'unshift', 'splice', 'sort', 'reverse']; |
基于Proxy的双向绑定
Proxy
可以直接监听对象相比不需要我多讲了,同样的,Proxy
也可以监听数组,不必再用上面的那些个奇技淫巧让自己难受了。
也就是说,Proxy
可以直接劫持整个对象并返回一个新对象,不论便利程度还是底层功能都远强于Object.defineProperty
:
1 | const input = document.getElementById('input'); |
而使用过Vue
的boys
应该也依稀记着我们通过$nextTick
来绑定被改变的数组长度之类的问题,而Proxy
则可以完全避免我们使用那些个让你绞尽脑汁想想想的$nextTick
,直接改变数组长度,包您满E。
其他优势
- 优势就是好用,好用到其他浏览器厂商将会以此为标准持续的优化性能
Proxy
返回的是一个新对象,故我们可以只操作新对象达到目的,而不是像Object.defineProperty
一样笨拙的遍历对象属性并修改
当然,劣势是兼容性问题,而且短时间无法完美适应所有浏览器。这个会随着时间的推移逐渐被抹平的,诸位好汉不必担心。那么,