创建一个Vue的Class类
class Vue {
constructor(options) {
this.$options = options; // 接收实例化Vue时的option,绑定到实例上
this.data = options.data; // 将实例化Vue时的data绑定到当前实例上
this.initData(); // 初始化data
}
initData() {
const data = this.data;
const keys = Object.keys(data); // 取data属性的所有键
for (let i = 0; i < keys.length; i++) { // 将实例中的data上的属性代理到this上
const key = keys[i];
Object.defineProperty(this, key, {
enumerable: true,
get: function () {
return data[key];
},
set: function (newVal) {
data[key] = newVal;
}
})
}
// 深度监听(判断data是否是引用类型,如果是引用类型的数据还需要递归深层次监听)
observe(data);
}
}
function observe(data) {
const type = Object.prototype.toString.call(data);
// 引用类型需深度监听
if (type !== ('[object Object]' || '[object Array]')) { // 如果不是引用类型,代表已经遍历到最深层
return;
}
new Observer(data); // 如果是引用类型,则需深层次的递归监听
}
class Observer { // 创建一个Observer 实例,用于深层次监听
constructor(data) {
this.walk(data);
}
walk(data) {
const keys = Object.keys(data);
for (let i = 0; i < keys.length; i++) {
const key = keys[i];
defineReactive(data, key, data[key]);
}
}
}
/*
* @param data 需要监听的对象
* @param key 需要监听的对象的属性
* @param value 需要监听的对象的属性值
*/
function defineReactive(data, key, value) {
observe(data[key]);
let val = value;
Object.defineProperty(data, key, {
enumerable: true,
get: function () {
return val;
},
set: function (newVal) {
if (val === newVal) {
return;
}
val = newVal;
}
})
}
watch原理后续更新