繼續(xù)隨著核心類的初始化展開探索其他的模塊,這一篇來研究一下Vue的狀態(tài)初始化。這里的狀態(tài)初始化指的就是在創(chuàng)建實(shí)例的時(shí)候,在配置對(duì)象里定義的屬性、數(shù)據(jù)變量、方法等是如何進(jìn)行初始處理的。由于隨后的數(shù)據(jù)更新變動(dòng)都交給觀察系統(tǒng)來負(fù)責(zé),所以在事先弄明白了數(shù)據(jù)綁定的原理之后,就只需要將目光集中在這一部分。
來仔細(xì)看看在核心類中首先執(zhí)行的關(guān)于 state 部分的源碼:
initState
// 定義并導(dǎo)出initState函數(shù),接收參數(shù)vmexport function initState (vm: Component) { // 初始化實(shí)例的私有屬性_watchers // 這就是在觀察系統(tǒng)里會(huì)使用到的存儲(chǔ)所有顯式監(jiān)視器的對(duì)象 vm._watchers = [] // 獲取實(shí)例的配置對(duì)象 const opts = vm.$options // 如果定義了props,則初始化props if (opts.props) initProps(vm, opts.props) // 如果定義了methods,則初始化methods if (opts.methods) initMethods(vm, opts.methods) // 如果定義了data,則初始化data if (opts.data) { initData(vm) } else { // 否則初始化實(shí)例的私有屬性_data為空對(duì)象,并開啟觀察 observe(vm._data = {}, true /* asRootData */) } // 如果定義了computed,則初始化計(jì)算屬性 if (opts.computed) initComputed(vm, opts.computed) // 如果定義了watch并且不是nativeWatch,則初始化watch // nativeWatch是火狐瀏覽器下定義的對(duì)象的原型方法 if (opts.watch && opts.watch !== nativeWatch) { initWatch(vm, opts.watch) }}這段代碼非常直白,主要用來執(zhí)行配置對(duì)象里定義的了狀態(tài)的初始化。這里分別有 props、data、methods、computed、watch 五個(gè)配置對(duì)象,分別有各自的初始化方法。在仔細(xì)研究它們的具體實(shí)現(xiàn)之前,先來看一段將在各個(gè)初始化函數(shù)里用到的輔助函數(shù)。
// 定義共享屬性定義描述符對(duì)象sharedPropertyDefinition// 描述符對(duì)象的枚舉和可配置屬性都設(shè)置為true// get、set方法設(shè)置為空函數(shù)const sharedPropertyDefinition = { enumerable: true, configurable: true, get: noop, set: noop}// 定義并導(dǎo)出proxy函數(shù),該函數(shù)用來為在目標(biāo)對(duì)象上定義并代理屬性// 接收目標(biāo)對(duì)象target,路徑鍵名sourceKey,屬性鍵名三個(gè)參數(shù)export function proxy (target: Object, sourceKey: string, key: string) { // 設(shè)置屬性描述符對(duì)象的get方法 sharedPropertyDefinition.get = function proxyGetter () { return this[sourceKey][key] } // 設(shè)置屬性描述性對(duì)象的set犯法 sharedPropertyDefinition.set = function proxySetter (val) { this[sourceKey][key] = val } // 在目標(biāo)對(duì)象上定義屬性 Object.defineProperty(target, key, sharedPropertyDefinition)}proxy 函數(shù)的定義非常重要,在下面要探究的各個(gè)初始化函數(shù)中它,它會(huì)將我們?cè)谂渲脤?duì)象中設(shè)置的屬性全部定義到實(shí)例對(duì)象中,但是我們對(duì)這些屬性的操作是通過各部分相應(yīng)的代理屬性上來執(zhí)行的。get 和 set 方法的實(shí)現(xiàn)非常明白的表示出這一過程,然后再將屬性定義到實(shí)例中。由這個(gè)函數(shù)作為基礎(chǔ),繼續(xù)來看看其他五個(gè)狀態(tài)的初始化函數(shù)的內(nèi)容。
新聞熱點(diǎn)
疑難解答
圖片精選