国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > JavaScript > 正文

簡單實現vue中的依賴收集與響應的方法

2019-11-19 12:07:17
字體:
來源:轉載
供稿:網友

開始

聲明一個對象man,可以視為vue中的data

let man = { height: 180, weight: 70, wealth: 100000000}

添加Observer

作用在于將參數對象的屬性變為響應式,只要對象的屬性被讀取或者被修改都能觀察到。然后新建一個Observer實例,將man作為參數扔進去。這里的proxyData是將man的屬性代理到以man為參數的Observer實例上去。

class Observer { constructor(obj) {  this.walk(obj) } walk(obj) {  Object.keys(obj).forEach(prop => {   this[prop] = obj[prop]   this.proxyData(obj, prop)   this.defineReactive(this, prop, obj[prop])     }) } proxyData(obj, prop) {  let _this = this  Object.defineProperty(obj, prop, {   get() {    return _this[prop]   },   set(newVal) {    _this[prop] = newVal   }  }) } defineReactive(obj, prop, val) {  Object.defineProperty(obj, prop, {   get() {    console.log(`${prop} - 被讀取!`)    return val   },   set(newVal) {    if (newVal == val) return    val = newVal    console.log(`${prop} - 被修改!`)   }  }) }}new Observer(man)

這時打印一下man


現在man的屬性都是由Observer實例所對應的屬性的getter來返回,只有在查看時會被觸發


對man的屬性進行修改也會觸發實例對應屬性的setter

添加Watcher

現在的Watcher有點像vue中的computed,實際上就是定義一個計算屬性,這個計算屬性依賴于前面man中的某些屬性,由他們計算而得。

class Watcher { constructor(obj, prop, computed) {  this.getVal(obj, prop, computed) } getVal(obj, prop, computed) {  Object.defineProperty(obj, prop, {   get() {    console.log(`computed屬性 - ${prop}被讀取!`)    return computed()   },   set() {    console.error('計算屬性不可被修改!')   }  }) }}new Watcher(man, 'strength', () => { let {height, weight} = man if (height > 160 && weight > 70) return 'strong' return 'weak'})


看起來沒什么問題,所依賴的屬性如果變了,計算屬性只要再被查看(get方法)一次就可以更新了。但vue中的視圖渲染是實時的,視圖層依賴于數據層,數據變化了,視圖層也會跟著變化,不需要手動更新。類比到這個例子就是計算屬性如何才能在其所依賴的屬性發生變化時被通知從而觸發應有的事件?

這時我們先給Watcher加多一個callback,用于處理當依賴的數據被修改時,我這個計算屬性該怎么響應

比如當依賴被修改時,我們就把這個計算屬性的值打印出來

class Watcher { constructor(obj, prop, computed, callback) {  this.getVal(obj, prop, computed, callback) }new Watcher(man, 'strength', () => { let {height, weight} = man if (height > 160 && weight > 70) return 'strong' return 'weak'}, () => { console.log(`i am so ${man.strength} !`)})

一切都準備好了,接下來就是該如何實現?

我們先看下Watcher中getVal這個方法

getVal(obj, prop, computed, callback) { Object.defineProperty(obj, prop, {  get() {   console.log(`computed屬性 - ${prop}被讀取!`)   return computed()  },  set() {   console.error('計算屬性不可被修改!')  } })}

當我們查看計算屬性時,會調用computed這個方法,相當于查看了其所依賴的height和weight屬性,而在上面我們已經讓man的所有屬性都擁有了get方法,即他們被查看時我們是不是可以把callback塞給他們?
這時候我們引進一個橋梁,來連接Watcher和Observer。

添加Dep

Dep的用處在于當某一個屬性(以下稱‘自己')被依賴了,將依賴自己的粉絲(們)--也就是Watcher(s),收集起來,假如自己發生了變化,能夠及時通知粉絲們。

class Dep { constructor() {  this.deps = [] } getDeps() {  if (!Dep.target || this.deps.includes(Dep.target)) return  console.log('依賴添加', Dep.target)  this.deps.push(Dep.target) } notify() {  this.deps.forEach(dep => {   dep()  }) }}

這里的Dep.target就是前面所說的callback方法了。這時我們改一下Watcher中的getVal

getVal(obj, prop, computed, callback) { Object.defineProperty(obj, prop, {  get() {   Dep.target = callback   console.log(`computed屬性 - ${prop}被讀取!`)   return computed()  },  set() {   console.error('計算屬性不可被修改!')  } })}

在計算屬性被查看時,將callback賦值給Dep.target,接下來就會調用其所依賴屬性的getter,我們只要在getter里把callback給收集起來就行了。接下來修改依賴屬性的getter方法。

defineReactive(obj, prop, val) { let dep = new Dep() Object.defineProperty(obj, prop, {  get() {   console.log(`${prop} - 被讀取!`)   dep.getDeps() // 依賴收集   return val  },  set(newVal) {   if (newVal == val) return   val = newVal   console.log(`${prop} - 被修改!`)      } })}

這時watcher的callback都被依賴屬性給收集起來了,當依賴屬性發生變化時只要去運行這些callback就可以了。接下來就是修改依賴屬性的setter方法。

defineReactive(obj, prop, val) { let dep = new Dep() Object.defineProperty(obj, prop, {  get() {   console.log(`${prop} - 被讀取!`)   dep.getDeps()   return val  },  set(newVal) {   if (newVal == val) return   val = newVal   console.log(`${prop} - 被修改!`)   dep.notify() // 運行所有callback  } })}

運行看看


我們加多一個Watcher試試

new Watcher(man, 'isGreat', () => { let {height, weight, wealth} = man if (height > 180 && weight > 70 && wealth > 100000) return 'Great!' return 'not good enough ...'}, () => { console.log(`they say i am ${man.isGreat}`)})


這就是vue中的一個依賴對應多個Watcher

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持武林網。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 建平县| 仙游县| 和顺县| 任丘市| 莒南县| 黎平县| 明溪县| 黎城县| 当阳市| 佛山市| 和静县| 繁峙县| 阿荣旗| 侯马市| 重庆市| 泽普县| 东平县| 乳源| 遂昌县| 当雄县| 绥棱县| 清镇市| 无极县| 呼玛县| 涿州市| 尼木县| 宣威市| 聂拉木县| 富源县| 溆浦县| 左贡县| 邵武市| 富蕴县| 原阳县| 巴彦县| 镇原县| 石河子市| 奇台县| 长武县| 双峰县| 桐庐县|