exports._initMethods = function () { var methods = this.$options.methods if (methods) { for (var key in methods) { this[key] = _.bind(methods[key], this) } } }
//... var data = this._data // proxy data on instance var keys = Object.keys(data) var i, key i = keys.length while (i--) { key = keys[i] this._proxy(key) } //...
exports._proxy = function (key) { if (!_.isReserved(key)) { // need to store ref to self here // because these getter/setters might // be called by child scopes via // prototype inheritance. var self = this Object.defineProperty(self, key, { configurable: true, enumerable: true, get: functionproxyGetter () { return self._data[key] }, set: functionproxySetter (val) { self._data[key] = val } }) } }
为了避免覆盖Vue内置的属性所以做一次判定,接下来就是对数据的访问做一个代理。
仅仅代理数据是不够的,接下来要看到的是监控数据的变化:
1 2 3 4 5
exports._initData = function () { //... // observe data Observer.create(data, this) }
exports.delete = function (obj, key) { if (!obj.hasOwnProperty(key)) { return } delete obj[key] var ob = obj.__ob__ if (!ob) { return } ob.notify() if (ob.vms) { var i = ob.vms.length while (i--) { var vm = ob.vms[i] vm._unproxy(key) vm._digest() } } }
数据的变化追踪分为两类:对象和数组类型。对象类型遍历属性监听每个属性的变化:
1 2 3 4 5 6 7
Observer.prototype.walk = function (obj) { var keys = Object.keys(obj) var i = keys.length while (i--) { this.convert(keys[i], obj[keys[i]]) } }
exports.set = functionset (obj, key, val) { if (obj.hasOwnProperty(key)) { obj[key] = val return } if (obj._isVue) { set(obj._data, key, val) return } var ob = obj.__ob__ if (!ob) { obj[key] = val return } ob.convert(key, val) ob.notify() if (ob.vms) { var i = ob.vms.length while (i--) { var vm = ob.vms[i] vm._proxy(key) vm._digest() } } }
exports.delete = function (obj, key) { if (!obj.hasOwnProperty(key)) { return } delete obj[key] var ob = obj.__ob__ if (!ob) { return } ob.notify() if (ob.vms) { var i = ob.vms.length while (i--) { var vm = ob.vms[i] vm._unproxy(key) vm._digest() } } }