摘要:響應(yīng)式原理之不論如何,最終響應(yīng)式數(shù)據(jù)都要通過來實(shí)現(xiàn),實(shí)際要借助新增的。在函數(shù)內(nèi),首先實(shí)例化一個(gè)實(shí)例,會(huì)在稍后添加為響應(yīng)式數(shù)據(jù)自定義的中發(fā)揮作用。只有數(shù)組和對(duì)象才可能是響應(yīng)式,才能返回實(shí)例。參考鏈接技術(shù)內(nèi)幕揭開數(shù)據(jù)響應(yīng)系統(tǒng)的面紗源碼
Vue響應(yīng)式原理之defineReactive defineReactive
不論如何,最終響應(yīng)式數(shù)據(jù)都要通過defineReactive來實(shí)現(xiàn),實(shí)際要借助ES5新增的Object.defineProperty。
defineReactive接受五個(gè)參數(shù)。obj是要添加響應(yīng)式數(shù)據(jù)的對(duì)象;key是屬性名,val是屬性名對(duì)應(yīng)的取值;customSetter是用戶自定義的setter;會(huì)在響應(yīng)式數(shù)據(jù)的setter中執(zhí)行,只有開發(fā)環(huán)境可用;通過shallow指定是否淺比較,默認(rèn)深比較。
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() } }) }
在函數(shù)內(nèi),首先實(shí)例化一個(gè)Dep實(shí)例dep,dep會(huì)在稍后添加為響應(yīng)式數(shù)據(jù)自定義的get/set中發(fā)揮作用。接著獲取屬性描述符,如果屬性不可配置,則無法調(diào)用Object.defineProperty來修改setter/getter,所以返回。
如果原來已設(shè)置過setter/getter,緩存起來。當(dāng)未自定義getter且arguments長度為2(即只傳入了obj和key)時(shí),可以直接用方括號(hào)求值,使用閉包變量val緩存初始值。
如果不是淺復(fù)制,執(zhí)行observe(val),為val添加__ob__屬性并返回__ob__指向的Observer實(shí)例。(只有數(shù)組和對(duì)象才可能是響應(yīng)式,才能返回Observer實(shí)例)。
使用Object.defineProperty為obj[key]設(shè)置getter和setter。
在get內(nèi),如果原來已設(shè)置過getter,則用緩存的getter求值,否則使用閉包變量val作為返回值;同時(shí)添加依賴。此處為兩個(gè)Dep實(shí)例添加依賴。dep是閉包變量,在getter/setter中會(huì)使用到。另一個(gè)Dep實(shí)例是childOb.dep,只用調(diào)用set/delete更新響應(yīng)式數(shù)據(jù)時(shí),才會(huì)觸發(fā);如果value是數(shù)組,還會(huì)遍歷元素,為存在__ob__屬性的元素收集依賴。
在set內(nèi),先獲取更新前的值(邏輯和get內(nèi)第一步一樣)。判斷更新前后的值是否相等,相等時(shí)直接返回;不等時(shí),如果有緩存的setter,調(diào)用緩存的setter更新,否則直接賦值。值得注意的是,NaN === NaN是不成立的,反而NaN !== NaN是成立的,后面的判斷語句newVal !== newVal && value !== value就是為了避免newVal/val都是NaN。在更新后的值newVal上執(zhí)行observe,更新閉包變量childOb,并調(diào)用notify。
參考鏈接Vue技術(shù)內(nèi)幕|揭開數(shù)據(jù)響應(yīng)系統(tǒng)的面紗
Vue.js源碼
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/99627.html
摘要:響應(yīng)式原理之之前簡單介紹了和類的代碼和作用,現(xiàn)在來介紹一下類和。對(duì)于數(shù)組,響應(yīng)式的實(shí)現(xiàn)稍有不同。不存在時(shí),說明不是響應(yīng)式數(shù)據(jù),直接更新。如果對(duì)象是響應(yīng)式的,確保刪除能觸發(fā)更新視圖。 Vue響應(yīng)式原理之Observer 之前簡單介紹了Dep和Watcher類的代碼和作用,現(xiàn)在來介紹一下Observer類和set/get。在Vue實(shí)例后再添加響應(yīng)式數(shù)據(jù)時(shí)需要借助Vue.set/vm.$se...
摘要:響應(yīng)式原理為了探究這一切的原因,我再次點(diǎn)開了的官網(wǎng)。在官網(wǎng)很下面的位置,找到了關(guān)于響應(yīng)式原理的說明。因此,新添加到數(shù)組中的對(duì)象中的屬性,就成了非響應(yīng)式的屬性了,改變它自然不會(huì)讓組件重新渲染。響應(yīng)式屬性的對(duì)象,有這個(gè)對(duì)象就代表是響應(yīng)式的。 ??最近在用Vue開發(fā)一個(gè)后臺(tái)管理的demo,有一個(gè)非常常規(guī)的需求。然而這個(gè)常規(guī)的需求中,包含了大量的知識(shí)點(diǎn)。有一個(gè)產(chǎn)品表格,用來顯示不同產(chǎn)品的信息。...
摘要:淺析響應(yīng)式原理一的特點(diǎn)之一是響應(yīng)式,視圖隨著數(shù)據(jù)的更新而更新,在視圖中修改數(shù)據(jù)后實(shí)例中的數(shù)據(jù)也會(huì)同步更新。對(duì)于每個(gè)響應(yīng)式數(shù)據(jù),會(huì)有兩個(gè)實(shí)例,第一個(gè)是在中的閉包遍歷,用途顯而易見。接收一個(gè)回調(diào)函數(shù),會(huì)在重新求值且值更新后執(zhí)行。 淺析Vue響應(yīng)式原理(一) Vue的特點(diǎn)之一是響應(yīng)式,視圖隨著數(shù)據(jù)的更新而更新,在視圖中修改數(shù)據(jù)后Vue實(shí)例中的數(shù)據(jù)也會(huì)同步更新。內(nèi)部借助依賴(下文中的Dep類)...
摘要:哪吒別人的看法都是狗屁,你是誰只有你自己說了才算,這是爹教我的道理。哪吒去他個(gè)鳥命我命由我,不由天是魔是仙,我自己決定哪吒白白搭上一條人命,你傻不傻敖丙不傻誰和你做朋友太乙真人人是否能夠改變命運(yùn),我不曉得。我只曉得,不認(rèn)命是哪吒的命。 showImg(https://segmentfault.com/img/bVbwiGL?w=900&h=378); 出處 查看github最新的Vue...
摘要:三響應(yīng)式網(wǎng)頁設(shè)計(jì)的基本原理標(biāo)簽,允許頁面寬度自動(dòng)調(diào)整大多數(shù)移動(dòng)瀏覽器將頁面放大為寬的視圖以符合屏幕分辨率。解決方案使用,選擇器清除浮動(dòng),只適用于非瀏覽器。由于移動(dòng)設(shè)備屏幕大小的限制,在其上進(jìn)行顯示的內(nèi)容一般是經(jīng)過精心篩選的。 一、前言 現(xiàn)今,無論是移動(dòng)設(shè)備、平板電腦、PC,屏幕大小各不相同,若是針對(duì)每個(gè)屏幕大小單獨(dú)設(shè)計(jì)一個(gè)解決方案,則會(huì)大幅增加網(wǎng)站建設(shè)的復(fù)雜程度和運(yùn)營成本。響應(yīng)式網(wǎng)頁設(shè)...
閱讀 2164·2023-04-26 00:43
閱讀 2685·2021-11-22 15:22
閱讀 3816·2021-11-11 16:55
閱讀 969·2021-11-04 16:06
閱讀 1787·2019-08-30 14:12
閱讀 999·2019-08-30 14:02
閱讀 3368·2019-08-29 17:05
閱讀 1417·2019-08-29 12:27