Vue双向数据绑定的原理
vue的双向数据绑定:是通过数据劫持 结合 发布订阅模式的方式实现。数据和视图同步,数据发生变化,视图也跟着变化,数据也随之发生改变。
简单来说就是通过Object对象的defineProperty属性,重写data的set和get函数来实现的
核心就是Object.defineProperty()方法
扩展:Object.defineProperty()方法
Object.defineProperty(obj,prop,descriptor)参数:obj(定义属性对象)prop(定义或修改的属性)descriptor(具体的改变方法)
用这个方法定义一个值,当调用时使用它里面的get方法,当给属性赋值时,又用到set方法
1 2 3 4 5 6 7 8 9 10 11
| var obj = {}; Object.defineProperty(obj, 'hello',{ get: function () { console.log('调用了get方法') }, set: function (newVal) { console.log('调用了set方法,方法的值为' + newVal) } }); obj.hello; obj.hello = 'hi';
|
JS双向数据绑定通过添加事件监听keyup来触发set方法,而set在修改访问器属性的同时,在修改了dom样式,改变了span标签的文本
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| <script> var obj = [];
var k = 'once'; Object.defineProperty(obj, 'k', { get: function () { return k; },
set: function (newK) { k = newK; document.getElementById('a').value = k document.getElementById('b').innerHTML = k } }); document.addEventListener('keyup', function (e) { obj.k = e.target.value; })
</script>
|
vue的双向数据绑定:就是普通单向绑定和事件组合来完成的
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| <div id="vm"> <p>邮箱<input v-model="email"></p> <span>{{email}}</span> <p>名字<input v-model="name"></p> <span>{{name}}</span> </div> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <script type="text/javascript"> var vm = new Vue({ el: '#vm', data: { email: '', name: '' } }); </script>
|
理解:
①将vue中的data中的内容绑定到输入文本框和文本节点中
②文本框的内容改变时,vue实例中的data也同时发生改变
③当data中的内容发生改变时,输入框及文本节点的内容也发生变化
注:如果使用appendCid方法将原dom树中的节点添加到DocumenntFragment中时,会删除原来的节点