深入vue源码,了解vue的双向数据绑定原理
大家都知道vue是一种MVVM开发模式,数据驱动视图的前端框架,并且内部已经实现了双向数据绑定,那么双向数据绑定是怎么实现的呢?
先手动撸一个最最最简单的双向数据绑定
1 <div> 2 <input type="text" name="" id="text"> 3 <span id="show"></span> 4 </div> 5 6 <script> 7 var text = document.getElementById('text') 8 var span = document.getElementById('show') 9 var obj = {} 10 Object.defineProperty(obj, 'hello', { 11 set: function(value){ 12 text.value = value 13 span.innerText = value 14 } 15 }) 16 document.addEventListener('keyup',function(e){ 17 obj.hello = e.target.value 18 }) 19 </script>
这样就能实现一个简单的双向数据绑定了,这里再解释一下defineProperty这个方法吧。
语法:
Object.defineProperty(obj,prop,descriptor)
/*
参数解释:
obj: 要在其上定义属性的对象
prop:要定义或修改的属性的名称
descriptor:要定义或修改的属性描述符
*/
prop是一个访问器属性,访问器属性是对象中的一种特殊属性,它必须通过Object.defineProperty方法单独定义
访问器属性的值比较特殊读取或设置访问器属性的值其实是调用其内部特性get和set函数
那么vue内部是怎样实现双向数据绑定的呢?
vue数据双向绑定原理
vue数据双向绑定是通过数据劫持结合发布者-订阅者模式的方式来实现的,我们可以先来看一下通过控制台输出一个定义在vue初始化数据上的对象是个什么东西。
代码:
var vm = new Vue({ data: { obj: { a: 1 } }, created: function () { console.log(this.obj); }});
结果:
我们可以看到属性a有两个相对应的get和set方法,为什么会多出这两个方法呢?因为vue是通过Object.defineProperty()来实现数据劫持的。
Object.defineProperty( )是用来做什么的?它可以来控制一个对象属性的一些特有操作,比如读写权、是否可以枚举,这里我们主要先来研究下它对应的两个描述属性get和set,如果还不熟悉其用法,请点击这里阅读更多用法。
在平常,我们很容易就可以打印出一个对象的属性数据:
var Book = { name: 'vue权威指南'};console.log(Book.name); // vue权威指南