Vue实现双向绑定的原理以及响应式数据的方法

2020-06-14 06:19:51易采站长站整理

});
node.value = vm[name]; // 将data的值赋给该node
node.removeAttribute('v-model');
}
};

new Watcher(vm, node, name, 'input');
}
// 节点类型为text
if (node.nodeType === 3) {
if (reg.test(node.nodeValue)) {
var name = RegExp.$1; // 获取匹配到的字符串
name = name.trim();

new Watcher(vm, node, name, 'text');
}
}
}

function Watcher (vm, node, name, nodeType) {
Dep.target = this;
this.name = name;
this.node = node;
this.vm = vm;
this.nodeType = nodeType;
this.update();
Dep.target = null;
}

Watcher.prototype = {
update: function () {
this.get();
if (this.nodeType == 'text') {
this.node.nodeValue = this.value;
}
if (this.nodeType == 'input') {
this.node.value = this.value;
}
},
// 获取data中的属性值
get: function () {
this.value = this.vm[this.name]; // 触发相应属性的get
}
}

function Dep () {
this.subs = [] }

Dep.prototype = {
addSub: function(sub) {
this.subs.push(sub);
},

notify: function() {
this.subs.forEach(function(sub) {
sub.update();
});
}
};

function Vue (options) {
this.data = options.data;
var data = this.data;

observe(data, this);

var id = options.el;
var dom = nodeToFragment(document.getElementById(id), this);

// 编译完成后,将dom返回到app中
document.getElementById(id).appendChild(dom);
}

var vm = new Vue({
el: 'app',
data: {
text: 'hello world'
}
});

</script>

</body>
</html>

在vue的data中定义的属性才具有响应式的效果,通过vue.name或者this.name形式定义的全局变量虽然可以在template中使用,但是其不是响应式的。同时在data中定义的对象obj,如果后面给对象定义新的属性也不是响应式的,除非通过vue提供的方法set设置,具体如下:


new vue({

data(){

return {

obj:{}

}

},

methods:{

this.obj.name="hs"//非响应属性

this.$set(this.obj,'name','hs')//name属性将会是响应式的

}

})

如果data中定义的有数组元素同时在computed中也要注意具体如下面介绍。

二、computed定义的计算属性

1、在vue中$option.data中定义的数据是都是响应式的,在初始化生命周期的时候就已经实现了数据双向绑定,通常在view中只是用一个表达式语句,当绑定时的逻辑比较复杂是可以通过计算属性的方式实现。但是在computed中定义的属性只具有get方法,所以当在程序中改变属性的时候并不能实现视图的动态响应。可以通过显示的定义set的方式实现视图的刷新。