发布于 

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; // 定义k等于修改后的内容
// 让文本框的内容等于k
document.getElementById('a').value = k
// 让span的内容等于k
document.getElementById('b').innerHTML = k
}
});
document.addEventListener('keyup', function (e) {
//当在文本框输入内容时让对象里你定义的val等于文本框的值
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中时,会删除原来的节点


本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。