// new Avue({data:{}})
class Avue {
constructor(options) {
//對options進行緩存
this.$options = options
//對data也進行緩存
this.$data = options.data;
this.observer(this.$data);
//模擬一個watcher();
new watcher();
this.$data.name;
new watcher();
this.$data.obj.age;
}
//進行數據得監聽
observer(value) {
//若是沒有值或者值得類型不是對象就直接return出去
if (!value || typeof value !== "object") {
return;
}
Object.keys(value).forEach(key => {
this.defineReactive(value, key, value[key])
})
}
defineReactive(obj, key, val) {
//深度拷貝,使用遞歸,解決數據得層次嵌套
this.observer(val)
const dep = new Dep();
//數據劫持
Object.defineProperty(obj, key, {
get() {
//若是存在,就將添加到addDep ,這個屬性必須是在讀取得時候得到
Dep.target && dep.addDep(Dep.target);
return val
},
set(newVal) {
if (newVal === val) return;
val = newVal;
// console.log(`${key}:更新了${val}`)
//去通知dep
dep.notify()
}
})
}
}
//依賴收集和追蹤
//DEP: 用來管理wacher
class Dep {
constructor() {
//存儲全部得依賴
this.deps = []
}
//在deps中添加一個監聽器對象
addDep(dep) {
this.deps.push(dep)
}
//通知全部監聽器去更新視圖
notify() {
this.deps.forEach(dep => {
dep.update()
})
}
}
class watcher {
constructor() {
//在new一個監聽器對象時將該對象賦值給Dep.targte,在get中會用到
//將當前watcher實例指定到Dep靜態屬性target
console.log(Dep.target, this)
Dep.target = this
}
//更新視圖得方法
update() {
console.log("視圖更新啦~~~")
}
}
複製代碼
vue的響應原理:vue
建立一個本身vue的構造函數,裏面observer是用來監聽數據的,defineReactive用Object.defineProperty監聽數據:緩存
// new Avue({data:{}})
class Avue {
constructor(options) {
//對options進行緩存
this.$options = options
//對data也進行緩存
this.$data = options.data;
this.observer(this.$data);
}
//進行數據得監聽
observer(value) {
//若是沒有值或者值得類型不是對象就直接return出去
if (!value || typeof value !== "object") {
return;
}
Object.keys(value).forEach(key => {
this.defineReactive(value, key, value[key])
})
}
defineReactive(obj, key, val) {
//深度拷貝,使用遞歸,解決數據得層次嵌套
this.observer(val)
//數據劫持
Object.defineProperty(obj, key, {
get() {
return val
},
set(newVal) {
if (newVal === val) return;
val = newVal;
console.log(`${key}:更新了${val}`)
}
})
}
}
複製代碼
依賴收集與收集:
有一個Dep構造函數用來管理watcher,而watcher是監聽Dep靜態屬性;bash
//依賴收集和追蹤
//DEP: 用來管理wacher
class Dep {
constructor() {
//存儲全部得依賴
this.deps = []
}
//在deps中添加一個監聽器對象
addDep(dep) {
this.deps.push(dep)
}
//通知全部監聽器去更新視圖
notify() {
this.deps.forEach(dep => {
dep.update()
})
}
}
class watcher {
constructor() {
//在new一個監聽器對象時將該對象賦值給Dep.targte,在get中會用到
//將當前watcher實例指定到Dep靜態屬性target
Dep.target = this //在讀取屬性的時候,在添加
}
//更新視圖得方法
update() {
console.log("視圖更新啦~~~")
}
}
複製代碼
一開始的代碼是二者的結合;函數