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

首頁 > 語言 > JavaScript > 正文

vue如何實現observer和watcher源碼解析

2024-05-06 15:10:00
字體:
來源:轉載
供稿:網友

本文能幫你做什么?好奇vue雙向綁定的同學,可以部分緩解好奇心,還可以幫你了解如何實現$watch。

前情回顧

我之前寫了一篇沒什么干貨的文章,并且刨了一個大坑。
今天,打算來填一天,并再刨一個。

不過話說說回來了,看本文之前,如果不知道Object.defineProperty,還必須看看解析神奇的Object.defineProperty
不得不感慨vue的作者,人長得帥,碼寫的也好,本文是根據作者源碼,摘取出來的

本文將實現什么

正如上一篇許下的承諾一樣,本文要實現一個$wacth

const v = new Vue({ data:{ a:1, b:2 }})v.$watch("a",()=>console.log("哈哈,$watch成功"))setTimeout(()=>{ v.a = 5},2000) //打印 哈哈,$watch成功

為了幫助大家理清思路。。我們就做最簡單的實現。。只考慮對象不考慮數組

1. 實現 observer

思路:我們知道Object.defineProperty的特性了,我們就利用它的set和get。我們將要observe的對象,通過遞歸,將它所有的屬性,包括子屬性的屬性,都給加上set和get。這樣的話,給這個對象的某個屬性賦值,就會觸發set。開始吧

export default class Observer{ constructor(value) { this.value = value this.walk(value) } //遞歸。。讓每個字屬性可以observe walk(value){ Object.keys(value).forEach(key=>this.convert(key,value[key])) } convert(key, val){ defineReactive(this.value, key, val) }}export function defineReactive (obj, key, val) { var childOb = observe(val) Object.defineProperty(obj, key, { enumerable: true, configurable: true, get: ()=>val, set:newVal=> {  childOb = observe(newVal)//如果新賦值的值是個復雜類型。再遞歸它,加上set/get。。 } })}export function observe (value, vm) { if (!value || typeof value !== 'object') { return } return new Observer(value)}

代碼很簡單,就給每個屬性(包括子屬性)都加上get/set,這樣的話,這個對象的,有任何賦值,就會觸發set方法。。
所以,我們是不是應該寫一個消息-訂閱器呢?

這樣的話,一觸發set方法,我們就發一個通知出來,然后,訂閱這個消息的,就會怎樣?對咯。、收到消息、觸發回調。

2. 消息-訂閱器

很簡單,我們維護一個數組,,這個數組,就放訂閱著,一旦觸發notify,訂閱者就調用自己的update方法

export default class Dep { constructor() { this.subs = [] } addSub(sub){ this.subs.push(sub) } notify(){ this.subs.forEach(sub=>sub.update()) }}

所以,每次set函數,調用的時候,我們是不是應該,觸發notify,對吧。所以我們把代碼補充完整

 export function defineReactive (obj, key, val) { var dep = new Dep() var childOb = observe(val) Object.defineProperty(obj, key, { enumerable: true, configurable: true, get: ()=>val, set:newVal=> {  var value = val  if (newVal === value) {  return  }  val = newVal  childOb = observe(newVal)  dep.notify() } }) }            
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表

圖片精選

主站蜘蛛池模板: 灵丘县| 临澧县| 枣庄市| 六安市| 威海市| 通榆县| 区。| 平舆县| 吉林市| 遂宁市| 噶尔县| 米泉市| 屏东县| 榆中县| 新乡县| 丹东市| 日土县| 榆社县| 黔江区| 固安县| 会东县| 惠东县| 清流县| 阿克苏市| 全州县| 土默特右旗| 酒泉市| 徐州市| 潜江市| 汶上县| 平原县| 体育| 沙田区| 乡城县| 南召县| 贵德县| 北宁市| 扎兰屯市| 清远市| 鱼台县| 屏山县|