持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第18天,点击查看活动详情
前情提要
前面有讲过js设计模式中的观察者模式,而Vue2.x版本的响应式原理便是基于观察者模式和Object.defineProperty的数据劫持,实现数据的响应式。也是数据推动视图的渲染的源动力。那么今天就自己动手写写吧...
简述下什么是响应式
vue中响应式指的是数据改变后驱动视图更新
简述下Object.defineProperty
- 当将一个普通的JavaScript对象传给vue实例作为data选项的时候,Object.defineProperty会将这些属性全部转化为getter和setter。
- 是ES5中的一个新特性。这也是vue不支持低版本浏览器,比如IE8及以下等浏览器的主要原因。
- JavaScript中每个对象都有两个属性:数据属性,和访问器属性。这两种属性平常我们是无法访问到的,只有借助Object.definePropert才可以访问和修改他们的值。在这篇文章:深入理解之JavaScript对象中有讲解到。
- 该方法接收三个参数:目标对象,key值,一个对象。就是告诉这个方法你要给哪个对象的哪个属性做什么修改。
实现响应式
-
知道了核心技术点之后我们就来模拟实现吧
<html> ... // 无关代码就不展示了。 <body> <p id="pp"></p> </body> <script> // data属性 const data = { msg: '' } // 模拟vue实例 const vm = {} Object.defineProperty(vm, 'msg', { // 是否可枚举 enumerable: true, // 是否可配置 configurable: true, // 当有人获取这个属性的时候要执行的方法 get() { console.log('调用了getter方法'); return data.msg; }, // 当有人给这个属性赋值的时候需要执行的方法 set(value) { console.log('调用了setter方法'); if (value === data.msg) return; data.msg = value; document.getElementById('pp').innerText = data.msg; } }) vm.msg = 'Hello World!'; // 触发set console.log(vm.msg) // 触发get </script> </html> -
然后咱们看浏览器的运行结果:
总结
- 从上述模拟中我们可以看到vue实现数据响应式,数据推动视图的渲染的核心原理是Object.defineProperty的应用。但是该方法只能给单个的属性进行设置,data基本上不可能只有一个属性,这个时候我们该怎么办呢?
- 当然是只能循环遍历data,然后将data中的每一个属性都在vm中使用Object.defineProperty来定义一遍喽。
- 思考:Vue3中的数据响应式的核心原理是什么...