var Vue = function (options) {
this.$options = options || {};
var data = this._data = this.$options.data;
observe(data);
// 代理data中的属性到Vue实例
Object.keys(data).forEach(function (key) {
this._proxy(key);
}, this);
// 初始化computed
initComputed.call(this);
// 编译模版
this.$compile = new Compile(options.el || document.body, this);
};
function observe(value, vm) {
// ...
Object.defineProperty(obj, key, {
enumerable: true,
configurable: true,
get: function reactiveGetter() {
// ...
},
set: function reactiveSetter(newVal) {
// 触发订阅者的回调
dep.notify();
}
});
}
function Compile(el, vm) {
// ...
}
Compile.prototype._compile = function (node) {
var self = this;
if (node.nodeType === 1) {
var attr = node.attributes;
// 解析指令
Array.prototype.forEach.call(attr, function (attr) {
var attrName = attr.name;
if (self.isDirective(attrName)) {
var exp = attr.value;
var dir = attrName.substring(2);
if (self.isEventDirective(dir)) {
self.compileEvent(node, vm, exp, dir);
} else {
self.compileModel(node, vm, exp, dir);
}
node.removeAttribute(attrName);
}
});
} else if (node.nodeType === 3) {
// 解析插值表达式
self.compileText(node);
}
};
// ...Vue的数据双向绑定是通过观察者模式实现的。通过对数据对象添加`get`和`set`方法来监听数据的变化,一旦数据发生变化,就会通知相关订阅者进行更新。
编译模版部分会解析指令和插值表达式,并在相关DOM元素上添加对应的事件监听器和数据绑定逻辑。这样,当数据发生变化时,模版中相关的DOM元素也会相应地更新。
以上代码是一个简单的Vue实例的示例,实现了数据双向绑定的核心逻辑。在实际开发中,Vue提供了更多功能和工具来提升开发效率和代码质量。