摘要:響應式原理之不論如何,最終響應式數據都要通過來實現,實際要借助新增的。在函數內,首先實例化一個實例,會在稍后添加為響應式數據自定義的中發揮作用。只有數組和對象才可能是響應式,才能返回實例。參考鏈接技術內幕揭開數據響應系統的面紗源碼
Vue響應式原理之defineReactive defineReactive
不論如何,最終響應式數據都要通過defineReactive來實現,實際要借助ES5新增的Object.defineProperty。
defineReactive接受五個參數。obj是要添加響應式數據的對象;key是屬性名,val是屬性名對應的取值;customSetter是用戶自定義的setter;會在響應式數據的setter中執行,只有開發環境可用;通過shallow指定是否淺比較,默認深比較。
export function defineReactive ( obj: Object, key: string, val: any, customSetter?: ?Function, shallow?: boolean ) { const dep = new Dep() const property = Object.getOwnPropertyDescriptor(obj, key) if (property && property.configurable === false) { return } const getter = property && property.get if (!getter && arguments.length === 2) { val = obj[key] } const setter = property && property.set let childOb = !shallow && 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)) { dependArray(value) } } } return value }, set: function reactiveSetter (newVal) { const value = getter ? getter.call(obj) : val /* eslint-disable no-self-compare */ if (newVal === value || (newVal !== newVal && value !== value)) { return } /* eslint-enable no-self-compare */ if (process.env.NODE_ENV !== "production" && customSetter) { customSetter() } if (setter) { setter.call(obj, newVal) } else { val = newVal } childOb = !shallow && observe(newVal) dep.notify() } }) }
在函數內,首先實例化一個Dep實例dep,dep會在稍后添加為響應式數據自定義的get/set中發揮作用。接著獲取屬性描述符,如果屬性不可配置,則無法調用Object.defineProperty來修改setter/getter,所以返回。
如果原來已設置過setter/getter,緩存起來。當未自定義getter且arguments長度為2(即只傳入了obj和key)時,可以直接用方括號求值,使用閉包變量val緩存初始值。
如果不是淺復制,執行observe(val),為val添加__ob__屬性并返回__ob__指向的Observer實例。(只有數組和對象才可能是響應式,才能返回Observer實例)。
使用Object.defineProperty為obj[key]設置getter和setter。
在get內,如果原來已設置過getter,則用緩存的getter求值,否則使用閉包變量val作為返回值;同時添加依賴。此處為兩個Dep實例添加依賴。dep是閉包變量,在getter/setter中會使用到。另一個Dep實例是childOb.dep,只用調用set/delete更新響應式數據時,才會觸發;如果value是數組,還會遍歷元素,為存在__ob__屬性的元素收集依賴。
在set內,先獲取更新前的值(邏輯和get內第一步一樣)。判斷更新前后的值是否相等,相等時直接返回;不等時,如果有緩存的setter,調用緩存的setter更新,否則直接賦值。值得注意的是,NaN === NaN是不成立的,反而NaN !== NaN是成立的,后面的判斷語句newVal !== newVal && value !== value就是為了避免newVal/val都是NaN。在更新后的值newVal上執行observe,更新閉包變量childOb,并調用notify。
參考鏈接Vue技術內幕|揭開數據響應系統的面紗
Vue.js源碼
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/99627.html
摘要:響應式原理之之前簡單介紹了和類的代碼和作用,現在來介紹一下類和。對于數組,響應式的實現稍有不同。不存在時,說明不是響應式數據,直接更新。如果對象是響應式的,確保刪除能觸發更新視圖。 Vue響應式原理之Observer 之前簡單介紹了Dep和Watcher類的代碼和作用,現在來介紹一下Observer類和set/get。在Vue實例后再添加響應式數據時需要借助Vue.set/vm.$se...
摘要:響應式原理為了探究這一切的原因,我再次點開了的官網。在官網很下面的位置,找到了關于響應式原理的說明。因此,新添加到數組中的對象中的屬性,就成了非響應式的屬性了,改變它自然不會讓組件重新渲染。響應式屬性的對象,有這個對象就代表是響應式的。 ??最近在用Vue開發一個后臺管理的demo,有一個非常常規的需求。然而這個常規的需求中,包含了大量的知識點。有一個產品表格,用來顯示不同產品的信息。...
摘要:淺析響應式原理一的特點之一是響應式,視圖隨著數據的更新而更新,在視圖中修改數據后實例中的數據也會同步更新。對于每個響應式數據,會有兩個實例,第一個是在中的閉包遍歷,用途顯而易見。接收一個回調函數,會在重新求值且值更新后執行。 淺析Vue響應式原理(一) Vue的特點之一是響應式,視圖隨著數據的更新而更新,在視圖中修改數據后Vue實例中的數據也會同步更新。內部借助依賴(下文中的Dep類)...
摘要:哪吒別人的看法都是狗屁,你是誰只有你自己說了才算,這是爹教我的道理。哪吒去他個鳥命我命由我,不由天是魔是仙,我自己決定哪吒白白搭上一條人命,你傻不傻敖丙不傻誰和你做朋友太乙真人人是否能夠改變命運,我不曉得。我只曉得,不認命是哪吒的命。 showImg(https://segmentfault.com/img/bVbwiGL?w=900&h=378); 出處 查看github最新的Vue...
閱讀 2166·2023-04-26 00:43
閱讀 2686·2021-11-22 15:22
閱讀 3819·2021-11-11 16:55
閱讀 970·2021-11-04 16:06
閱讀 1789·2019-08-30 14:12
閱讀 1003·2019-08-30 14:02
閱讀 3371·2019-08-29 17:05
閱讀 1419·2019-08-29 12:27