入口文件 index.js
import { initMixin } from './init'
function Vue(options) {
this.__init(options);
}
initMixin(Vue);
export default Vue
初始化文件 init.js
import { initState } from './initState.js';
export function initMixin(Vue) {
Vue.prototype.__init = function(options) {
let vm = this;
vm.$options = options;
initState(vm);
}
}
初始化状态 initState.js
import { observer } from './observer/index'
export function initState(vm) {
let ops = vm.$options;
if(ops.data) {
initData(vm);
}
}
function initData(vm) {
let data = vm.$options.data;
data = vm._data = typeof data === 'function' ? data.call(vm) : data;
observer(data);
}
数据劫持 observer/index.js
export function observer(data) {
if(typeof data != 'object' || data == null ) {
return data;
}
return new Observer(data);
}
class Observer {
constructor(value) {
this.walk(value);
}
walk(data) {
let keys = Object.keys(data);
for(let i = 0; i < keys.length; i++) {
let key = keys[i];
let value = data[key];
defineReactive(data, key, value);
}
}
}
function defineReactive(data, key, value) {
observer(value);
Object.defineProperty(data, key, {
get() {
return value;
},
set(newValue) {
if(newValue === value) return value;
observer(value);
value = newValue;
}
})
}