vue核心源碼 練手
vue的雙向綁定的原理:利用了 Object.defineProperty這個屬性,把data裏面的屬性都定義了get、set,
讓我們有機會去監聽這些屬性的變化,當這些屬性變化了後,就去通知那些需要更新的地方去做更新。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
class Kvue {
constructor(options) {
this.$options = options;
// 數據響應化
this.$data = options.data;
this.observe(this.$data);
};
observe(value) { // data裏面數據傳進來
if (!value || typeof value !== 'object') { // 沒有 value 或者value不等於object
return
};
Object.keys(value).forEach(key => { // 遍歷所有屬性名
this.defineReactive(value, key, value[key]);
})
};
defineReactive(obj, key, val) { //obj data數據,key 屬性名,val 屬性值
this.observe(val); // 遞歸 解決數據的嵌套(如果屬性 foo的值 是對象 還能遍歷 繼續遞歸遍歷)
Object.defineProperty(obj, key, {
get() {
return val // 返回屬性值
},
set(newVal) {
if (newVal === val) return; // 如果新舊屬性值相等 直接返回
val = newVal; // 新舊屬性值不等,把新的屬性值賦值給val
console.log(`${key} 屬性更新了:${val}`);
}
})
}
};
const app = new Kvue({
data: {
test: '我是一個test1',
foo: {
bar: 'bar111'
}
}
});
app.$data.test = '早上好!!'
app.$data.foo.bar = '晚安啊!!'
</script>
</body>
</html>