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提供了更多功能和工具来提升开发效率和代码质量。