創(chuàng)建一個(gè)Vue的Class類(lèi)
class Vue {
constructor(options) {
this.$options = options; // 接收實(shí)例化Vue時(shí)的option,綁定到實(shí)例上
this.data = options.data; // 將實(shí)例化Vue時(shí)的data綁定到當(dāng)前實(shí)例上
this.initData(); // 初始化data
}
initData() {
const data = this.data;
const keys = Object.keys(data); // 取data屬性的所有鍵
for (let i = 0; i < keys.length; i++) { // 將實(shí)例中的data上的屬性代理到this上
const key = keys[i];
Object.defineProperty(this, key, {
enumerable: true,
get: function () {
return data[key];
},
set: function (newVal) {
data[key] = newVal;
}
})
}
// 深度監(jiān)聽(tīng)(判斷data是否是引用類(lèi)型,如果是引用類(lèi)型的數(shù)據(jù)還需要遞歸深層次監(jiān)聽(tīng))
observe(data);
}
}
function observe(data) {
const type = Object.prototype.toString.call(data);
// 引用類(lèi)型需深度監(jiān)聽(tīng)
if (type !== ('[object Object]' || '[object Array]')) { // 如果不是引用類(lèi)型,代表已經(jīng)遍歷到最深層
return;
}
new Observer(data); // 如果是引用類(lèi)型,則需深層次的遞歸監(jiān)聽(tīng)
}
class Observer { // 創(chuàng)建一個(gè)Observer 實(shí)例,用于深層次監(jiān)聽(tīng)
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 需要監(jiān)聽(tīng)的對(duì)象
* @param key 需要監(jiān)聽(tīng)的對(duì)象的屬性
* @param value 需要監(jiān)聽(tīng)的對(duì)象的屬性值
*/
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原理后續(xù)更新