亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > JavaScript > 正文

vue中的數據綁定原理的實現

2019-11-19 13:34:59
字體:
來源:轉載
供稿:網友

本文主要介紹了vue中的數據綁定原理的實現,分享給大家,也給自己留個筆記,具體如下:


vue中的響應式數據綁定是通過數據劫持和觀察者模式來實現的。當前學習源碼為vue2.0

源碼關鍵目錄

src|---core|  |---instance|     |---init.js|     |---state.js|  |---observer|     |---dep.js|     |---watcher.js

當我們實例化一個vue應用的時候,會伴隨著各種的初始化工作,相關的初始化工作代碼在init.js文件中

// src/core/instance/init.jsVue.prototype._init = function (options?: Object) { ... initLifecycle(vm) initEvents(vm) callHook(vm, 'beforeCreate') initState(vm) callHook(vm, 'created') initRender(vm)}

在這里可以看到對state的初始化工作initState()

// src/core/instance/state.jsexport function initState (vm: Component) { vm._watchers = [] initProps(vm) initData(vm) initComputed(vm) initMethods(vm) initWatch(vm)}

可以看到這里有對各種sate的初始化工作,我們看initData()

// src/core/instance/state.jsfunction initData (vm: Component) { let data = vm.$options.data data = vm._data = typeof data === 'function'  ? data.call(vm)  : data || {} if (!isPlainObject(data)) {  data = {}  process.env.NODE_ENV !== 'production' && warn(   'data functions should return an object.',   vm  ) } // proxy data on instance const keys = Object.keys(data) const props = vm.$options.props let i = keys.length while (i--) {  if (props && hasOwn(props, keys[i])) {   process.env.NODE_ENV !== 'production' && warn(    `The data property "${keys[i]}" is already declared as a prop. ` +    `Use prop default value instead.`,    vm   )  } else {   proxy(vm, keys[i])  } } // observe data observe(data) data.__ob__ && data.__ob__.vmCount++}

這里做了一點判斷,判斷data方法是否返回的是一個對象,以及props中是否有與data中重名的屬性,最后會調用observe對data進行監聽,看一下observe

// src/core/observer/index.jsexport function observe (value: any): Observer | void { if (!isObject(value)) {  return } let ob: Observer | void if (hasOwn(value, '__ob__') && value.__ob__ instanceof Observer) {  ob = value.__ob__ } else if (  observerState.shouldConvert &&  !config._isServer &&  (Array.isArray(value) || isPlainObject(value)) &&  Object.isExtensible(value) &&  !value._isVue ) {  ob = new Observer(value) } return ob}

可已看到這里也是做了一點判斷,如果有__ob__屬性的話就用它,或者如果data是數組或對象或可擴展對象的話,就為它新建一個Observer,看一下Observer

// src/core/observer/index.jsexport class Observer { value: any; dep: Dep; vmCount: number; // number of vms that has this object as root $data constructor (value: any) {  this.value = value  this.dep = new Dep()  this.vmCount = 0  def(value, '__ob__', this)  if (Array.isArray(value)) {   const augment = hasProto    ? protoAugment    : copyAugment   augment(value, arrayMethods, arrayKeys)   this.observeArray(value)  } else {   this.walk(value)  } } /**  * Walk through each property and convert them into  * getter/setters. This method should only be called when  * value type is Object.  */ walk (obj: Object) {  const keys = Object.keys(obj)  for (let i = 0; i < keys.length; i++) {   defineReactive(obj, keys[i], obj[keys[i]])  } } /**  * Observe a list of Array items.  */ observeArray (items: Array<any>) {  for (let i = 0, l = items.length; i < l; i++) {   observe(items[i])  } }}

判斷data是不是數組,如果是數組就對數組元素再去調用observe方法做同樣的處理,如果不是,就調用walk去劫持該數據,對數據的劫持主要再defineReactive方法中,正如函數名,讓數據變得響應式??匆幌耫efineReactive方法

// src/core/observer/index.jsexport function defineReactive ( obj: Object, key: string, val: any, customSetter?: Function) { const dep = new Dep()// data中的每一個成員都有一個對應的Dep,在此閉包創建。 const property = Object.getOwnPropertyDescriptor(obj, key) if (property && property.configurable === false) {  return } // cater for pre-defined getter/setters const getter = property && property.get const setter = property && property.set let childOb = observe(val) Object.defineProperty(obj, key, {  enumerable: true,  configurable: true,  get: function reactiveGetter () {   const value = getter ? getter.call(obj) : val   if (Dep.target) {    dep.depend() // 依賴收集    if (childOb) {     childOb.dep.depend()    }    if (Array.isArray(value)) {     for (let e, i = 0, l = value.length; i < l; i++) {      e = value[i]      e && e.__ob__ && e.__ob__.dep.depend()     }    }   }   return value  },  set: function reactiveSetter (newVal) {   const value = getter ? getter.call(obj) : val   if (newVal === value) {    return   }   if (process.env.NODE_ENV !== 'production' && customSetter) {    customSetter()   }   if (setter) {    setter.call(obj, newVal)   } else {    val = newVal   }   childOb = observe(newVal)   dep.notify() // 發布通知  } })}

遍歷狀態,修改狀態的getter和setter,當頁面上對應狀態被首次渲染的時候,會為頁面上每一個使用到data的地方新建一個watcher,并將當前watcher保存到全局變量Dep.target中,在對應data的getter中就會調用Dep.depend方法,將當前的watcher添加到當前的Dep中,一個Dep對應一個或多個watcher,著取決于,此狀態被使用的數量。當data被修改時,對應的setter就會被觸發,會調用對應的Dep中的notify方法,通知所有觀察者,進行更新。

這里出現了兩個定的類:Dep和Watcher,其中Dep管理觀察者,Wathcer代表觀察者

先看一下Dep

// src/core/observer/dep.jsexport default class Dep { static target: ?Watcher; id: number; subs: Array<Watcher>; constructor () {  this.id = uid++  this.subs = [] } addSub (sub: Watcher) {  this.subs.push(sub) } removeSub (sub: Watcher) {  remove(this.subs, sub) } depend () {  if (Dep.target) {// 調用當前target,也就是正在處理的watcher的addDep方法,并把此Dep傳進去   Dep.target.addDep(this)  } } notify () {  // stablize the subscriber list first  const subs = this.subs.slice()  for (let i = 0, l = subs.length; i < l; i++) {   subs[i].update()  } }}

看一下watcher.js

// src/core/observer/watcher.jsexport default class Watcher {... addDep (dep: Dep) {  const id = dep.id  if (!this.newDepIds.has(id)) {   this.newDepIds.add(id)   this.newDeps.push(dep)   if (!this.depIds.has(id)) {    // 將當前watcher添加到當前的Dep中    dep.addSub(this)   }  } }...}

總結

vue的響應式數據綁定主要依賴Object.defineProperty和觀察者模式。

  1. 在我們新建一個vue實例的時候,做一系列的初始化工作,這部分的邏輯集中在src文件夾下的core文件夾下的instance和observer文件夾內
  2. 響應式數據綁定是在狀態的初始化階段完成的,在initState方法中的initData中進行data的數據綁定。
  3. 在initData中調用observe方法,為該data新建一個Observer類,然后最終調用為data中的每一個成員調用walk方法,在walk中通過defineReactive方法劫持當前數據
  4. 在defineReactive中通過Object.defineProperty去修改數據的getter和setter
  5. 在頁面渲染的時候,頁面上每一個用到data的地方都會生成一個watcher,并將它保存到全局變量Dep.target中,watcher改變每一個觀察者,Dep用來管理觀察者。
  6. 然后在data的getter中將調用Dep的depend方法,將Dep.target中的watcher添加到此data對應的Dep中,完成依賴收集
  7. 在data被修改的時候,對應data的setter方法就會被出動,會調用Dep.notify()方法發布通知,調用每個watcher的uptade方法進行更新。

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

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
午夜剧场成人观在线视频免费观看| 欧美裸身视频免费观看| 欧美裸体xxxx极品少妇| 亚洲精品一区在线观看香蕉| 欧美日本在线视频中文字字幕| 久久久久久中文| 欧美亚洲国产视频小说| 亚洲国产小视频| 精品国内亚洲在观看18黄| 欧美黄色免费网站| 日韩在线视频观看正片免费网站| 欧美成人免费全部观看天天性色| 欧美综合国产精品久久丁香| 国产一区二区三区中文| 91情侣偷在线精品国产| 亚洲福利视频网站| 国产999精品久久久| 国产三级精品网站| 国产精品美女在线| 奇米4444一区二区三区| 中文字幕欧美日韩va免费视频| 国产精品电影网| 久久久伊人欧美| 黄色一区二区在线| 日韩欧美极品在线观看| 欧美激情综合色| 91精品国产综合久久香蕉的用户体验| 91av在线播放| 色777狠狠综合秋免鲁丝| 精品久久久久久久久久ntr影视| 国产精品一区二区久久精品| 欧洲美女7788成人免费视频| 日韩精品中文字幕有码专区| 川上优av一区二区线观看| 国产精品久久久久免费a∨| 91免费在线视频网站| 成人女保姆的销魂服务| 欧美日韩一区二区免费在线观看| 国产97在线|亚洲| 国产精品精品视频| 国产在线观看91精品一区| 7777精品久久久久久| 日韩成人在线免费观看| 色综合久久久888| 日韩成人av在线| 亚洲成人中文字幕| 欧美精品精品精品精品免费| 5252色成人免费视频| 欧美激情亚洲综合一区| 夜夜躁日日躁狠狠久久88av| 精品亚洲夜色av98在线观看| 国外成人在线视频| 欧美激情欧美狂野欧美精品| 日本最新高清不卡中文字幕| 国产精品夜间视频香蕉| 亚洲激情成人网| 日韩欧美在线中文字幕| 亚洲欧美在线第一页| 欧美激情一区二区三区久久久| 97精品国产97久久久久久| 亚洲a中文字幕| 日本午夜在线亚洲.国产| 欧美日韩午夜激情| 欧美日韩激情视频8区| 国产精品一区二区电影| 久久男人的天堂| 欧美日韩国产综合视频在线观看中文| 欧美亚洲国产视频小说| 人人爽久久涩噜噜噜网站| 国内精品模特av私拍在线观看| 国产精品香蕉在线观看| 伊人亚洲福利一区二区三区| 欧美在线精品免播放器视频| 狠狠躁天天躁日日躁欧美| 91精品国产777在线观看| 欧美性受xxxx白人性爽| 日韩中文字幕视频在线| www国产亚洲精品久久网站| 不卡av电影院| 国产精品一区二区3区| 一区二区福利视频| 欧美视频在线视频| 亚洲天堂精品在线| 国产精品都在这里| 国产亚洲精品久久久久动| 国产一区二区三区在线播放免费观看| 亚洲精品www久久久| 亚洲资源在线看| 久久久久日韩精品久久久男男| 国产亚洲成av人片在线观看桃| 国产成人精品综合久久久| 日韩黄色av网站| 欧美大片免费观看| 精品视频在线播放| 亚洲一级片在线看| 欧美另类在线播放| 国模私拍一区二区三区| 日韩激情在线视频| 国产精品久久久久999| 国产精品久久久久影院日本| 欧美午夜丰满在线18影院| 欧美成人精品一区| 亚洲欧美中文另类| 91久久久久久国产精品| 成人国产精品日本在线| 国产亚洲免费的视频看| 欧美第一淫aaasss性| 91美女片黄在线观| 日本一欧美一欧美一亚洲视频| 日韩精品在线观看一区| 在线看片第一页欧美| 欧美日韩一区二区免费在线观看| 亚洲自拍在线观看| 欧美老女人性视频| 欧美黑人性猛交| 亚洲欧洲av一区二区| 久久人人爽人人爽人人片av高请| 亚洲欧美激情视频| 久久久精品欧美| 亚洲aⅴ男人的天堂在线观看| 欧美一区二粉嫩精品国产一线天| 精品久久久久久久中文字幕| 一区二区欧美激情| 国产激情久久久| 欧洲精品在线视频| 国产精品久久久久久久久久久不卡| 91av免费观看91av精品在线| 亚洲最新视频在线| 日韩av一区二区在线观看| 国产精品va在线播放| 国产精品久久久久久久久久久久久久| 国产视频亚洲视频| 国产色综合天天综合网| 国产成人拍精品视频午夜网站| 97av在线视频免费播放| 少妇高潮久久久久久潘金莲| 欧美www视频在线观看| 国产精品久久久久久久美男| 欧美日韩国产色视频| 美女扒开尿口让男人操亚洲视频网站| 影音先锋欧美在线资源| 中文亚洲视频在线| 精品免费在线观看| 国产精品久久久久久久7电影| 久青草国产97香蕉在线视频| 欧美黑人又粗大| 日韩电影中文 亚洲精品乱码| 国模精品一区二区三区色天香| 国产精品欧美激情在线播放| 不卡毛片在线看| 亚洲男人天堂2023| 色视频www在线播放国产成人| 亚洲日本中文字幕免费在线不卡| 国产精品久久精品| 国产精品日日摸夜夜添夜夜av| 成人免费直播live| 欧美精品18videos性欧美| 伊人久久免费视频| 欧美最猛黑人xxxx黑人猛叫黄| 色婷婷综合成人| 精品magnet| 亚洲区bt下载| 在线日韩欧美视频| 亚洲天堂av高清|