寫(xiě)文章不容易,點(diǎn)個(gè)贊唄兄弟
專(zhuān)注 Vue 源碼分享,文章分為白話(huà)版和 源碼版,白話(huà)版助于理解工作原理,源碼版助于了解內(nèi)部詳情,讓我們一起學(xué)習(xí)吧
研究基于 Vue版本 【2.5.17】
如果你覺(jué)得排版難看,請(qǐng)點(diǎn)擊 下面鏈接 或者 拉到 下面關(guān)注公眾號(hào)也可以吧
【Vue原理】Props - 源碼版
今天記錄 Props 源碼流程,哎,這東西,就算是研究過(guò)了,也真是會(huì)隨著時(shí)間慢慢忘記的。
幸好我做了詳細(xì)的文章,忘記了什么的,回憶起來(lái)必然是很快的。
好的,回到正題,Props
請(qǐng)你在讀這篇之前,先去看看我的白話(huà)版
【Vue原理】Props - 白話(huà)版
在上面這篇文章中,也已經(jīng)清楚地解決了一個(gè)問(wèn)題
父組件 如何 把數(shù)據(jù) 當(dāng)做 props 傳給子組件
所以今天,我們只需記錄 Props 的處理流程源碼即可
初始化在創(chuàng)建Vue實(shí)例的過(guò)程中,會(huì)調(diào)用 initState 處理options,比如 props,computed,watch 等
只要你 new Vue 創(chuàng)建實(shí)例之后,很快就會(huì)處理options
function Vue(){ ... 其他處理 initState(this) ...解析模板,生成DOM 插入頁(yè)面 } function initState(vm) { var opts = vm.$options; if (opts.props) { initProps(vm, opts.props); } ... 處理 computed,watch,methods 等其他options }initProps
你看到處理 Props ,主要用到了一個(gè)方法 initProps,他就是本場(chǎng)的焦點(diǎn)了,讓我們來(lái)采訪(fǎng)下源碼本碼
function initProps(vm, propsOpt) { // 這是父組件給子組件傳入的 props 的具體值 var propsData = vm.$options.propsData || {}; var props = vm._props = {}; for (var key in propsOpt){ // 給 props 的 key 設(shè)置 響應(yīng)式 defineReactive(props, key, propsData[key]); if (! (key in vm)) { // 轉(zhuǎn)接訪(fǎng)問(wèn),訪(fǎng)問(wèn) vm 屬性,轉(zhuǎn)到訪(fǎng)問(wèn) vm._props 屬性 proxy(vm, "_props", key); } } }
上面的代碼主要做了三件事
1、遍歷 props
2、給 props 設(shè)置響應(yīng)式
3、給 props 設(shè)置代理
我們主要講兩件事
1、給 props 設(shè)置響應(yīng)式defineReactive(props, key, propsData[key])
defineReactive 在這里就不給太多源碼了,你只需要記住他就是給 props 設(shè)置響應(yīng)式的
function defineReactive(obj, key) { Object.defineProperty(obj, key, { get() { ...依賴(lài)收集 }, set(newVal) { ....依賴(lài)更新 } }); }
如果你想了解響應(yīng)式,就可以看我這篇文章
【Vue原理】響應(yīng)式原理 - 白話(huà)版
Props 設(shè)置響應(yīng)式,也是旨在數(shù)據(jù)改變時(shí)動(dòng)態(tài)更新。
怎么設(shè)置響應(yīng)式嗎?看這里
【Vue原理】依賴(lài)收集 - 源碼版之基本數(shù)據(jù)類(lèi)型
【Vue原理】依賴(lài)收集 - 源碼版之引用數(shù)據(jù)類(lèi)型
數(shù)據(jù)是直接從 父組件上傳過(guò)來(lái)的,沒(méi)有進(jìn)行拷貝等處理,原樣傳過(guò)來(lái)
怎么傳的?也可以看
【Vue原理】Props - 白話(huà)版
如果props 是基本類(lèi)型
在 子組件實(shí)例上設(shè)置這個(gè) props 屬性為響應(yīng)式,跟 data 本質(zhì)一樣,作用是監(jiān)聽(tīng) props 修改
如果 props 是對(duì)象
也會(huì)在 子組件實(shí)例上 設(shè)置這個(gè) props 屬性為響應(yīng)式,作用也是監(jiān)聽(tīng) props 修改
但是!
【不會(huì)遞歸對(duì)象】給對(duì)象內(nèi)所有屬性設(shè)置響應(yīng)式,因?yàn)樵搶?duì)象【已經(jīng)在父組件中】完成響應(yīng)式設(shè)置了
也就是說(shuō)
如果你在 子組件中直接修改 props 對(duì)象內(nèi)的數(shù)據(jù),父組件也會(huì)跟著修改
在記錄的途中,我發(fā)現(xiàn)了一個(gè)問(wèn)題,發(fā)現(xiàn)沒(méi)有想象中的那么簡(jiǎn)單,所以現(xiàn)在鄭重記錄
當(dāng) 父組件數(shù)據(jù) 改變,子組件怎么更新?
分類(lèi)型的,說(shuō)得比較詳細(xì),可能有點(diǎn)繞?
1、 如果是基本類(lèi)型,是這個(gè)流程
父組件數(shù)據(jù)改變,只會(huì)把新的數(shù)據(jù)傳給子組件
子組件拿到新數(shù)據(jù),就會(huì)直接替換到原來(lái)的 props
替換就是直接等哈,看下源碼,重要語(yǔ)句標(biāo)紅
updateChildComponent 是子組件內(nèi)部更新時(shí)會(huì)調(diào)用到的一個(gè)函數(shù),這是其中更新 props 的一個(gè)片段
function updateChildComponent( vm, propsData ) { if (propsData && vm.$options.props) { // 保存 props 的地方,用于訪(fǎng)問(wèn)轉(zhuǎn)接,具體看文章下面 var props = vm._props; // 所有子組件上設(shè)置的 props 的 key var propKeys = vm.$options._propKeys || []; for (var i = 0; i < propKeys.length; i++) { var key = propKeys[i]; props[key] = propsData[key] } vm.$options.propsData = propsData; } }
而 props 在子組件中也是響應(yīng)式的,【直接 等號(hào) 替換】導(dǎo)致觸發(fā) set,set 再通知 子組件完成更新
數(shù)據(jù)是 基本類(lèi)型,然后設(shè)置定時(shí)器修改數(shù)據(jù)
watcher1 是父組件,watcher2 是子組件
父組件內(nèi)的 data num 通知 watcher1 更新
子組件內(nèi)的 props child_num 通知 watcher2 更新
2、如果是對(duì)象,是這個(gè)流程
條件
父組件傳 對(duì)象 給 子組件,并且父子組件 頁(yè)面都使用到了這個(gè)數(shù)據(jù)
結(jié)果
那么這個(gè)對(duì)象,會(huì)收集到 父子組件的 watcher
所以
當(dāng) 對(duì)象內(nèi)部被修改的時(shí)候,會(huì)通知到 父和子 更新。
例子
父組件設(shè)置 obj 對(duì)象,并傳給子組件
定時(shí)修改父組件數(shù)據(jù) obj.name ,可以看到是 obj.name 通知 父子更新
當(dāng)然,如果對(duì)象被整個(gè)替換了,而不是修改內(nèi)部,那么跟 基本類(lèi)型一樣
區(qū)別是什么?
1、基本類(lèi)型是,子組件內(nèi)部 props 通知 子組件更新的
2、引用類(lèi)型是,父組件的數(shù)據(jù) data 通知 子組件更新的
2、給 props 設(shè)置代理在白話(huà)版中,我已經(jīng)說(shuō)得很清楚了, Props 有個(gè)移花接木的暗箱操作,就是訪(fǎng)問(wèn)轉(zhuǎn)移
Data 也是這么做的
[
【Vue原理】代理 Data - 源碼版 ]( https://mp.weixin.qq.com/s?__... )
你在項(xiàng)目中,會(huì)使用 http://this.xxx去訪(fǎng)問(wèn) props,props 已經(jīng)當(dāng)成了 實(shí)例的屬性,所以可以直接訪(fǎng)問(wèn)
但是其實(shí)你訪(fǎng)問(wèn)的是 【this._props.xxx】
為什么 Vue 要這么弄,目的就是為了方便開(kāi)發(fā)啊,讓我們直接簡(jiǎn)短了相關(guān)代碼
而 React,訪(fǎng)問(wèn) props,還要 this.props.xxxx,寫(xiě)這么長(zhǎng),不嫌麻煩嗎?
那么,是怎么設(shè)置代理的呢,就是下面這行
proxy(vm, "_props", key);
proxy 是什么也不要急,瓜就在下面,拿凳坐好
function proxy( target, sourceKey, key ) { Object.defineProperty(target, key, { get() { return this[sourceKey][key] }, set(val) { this[sourceKey][key] = val; } }); }
這段代碼做了2 個(gè)事
1、使用 props 在 vm 上占位,使得可以通過(guò) http://vm.xxx 的形式訪(fǎng)問(wèn)到 props
2、設(shè)置 [Object.defineProperty] 的 get 和 set ,間接獲取和賦值 vm._props
所有訪(fǎng)問(wèn)賦值 props,轉(zhuǎn)接到 vm._props 上,直觀(guān)如下圖
上個(gè)實(shí)例,方便大家看
說(shuō)完收工
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/105379.html
摘要:寫(xiě)文章不容易,點(diǎn)個(gè)贊唄兄弟專(zhuān)注源碼分享,文章分為白話(huà)版和源碼版,白話(huà)版助于理解工作原理,源碼版助于了解內(nèi)部詳情,讓我們一起學(xué)習(xí)吧研究基于版本如果你覺(jué)得排版難看,請(qǐng)點(diǎn)擊下面鏈接或者拉到下面關(guān)注公眾號(hào)也可以吧如果你覺(jué)得排版難看,請(qǐng)點(diǎn)擊下面公眾號(hào) 寫(xiě)文章不容易,點(diǎn)個(gè)贊唄兄弟專(zhuān)注 Vue 源碼分享,文章分為白話(huà)版和 源碼版,白話(huà)版助于理解工作原理,源碼版助于了解內(nèi)部詳情,讓我們一起學(xué)習(xí)吧研究基...
摘要:通過(guò)函數(shù)參數(shù)傳遞的形式,讓插槽的變量,在解析時(shí),先訪(fǎng)問(wèn)函數(shù)變量。那么這兩個(gè)有什么關(guān)系呢外殼節(jié)點(diǎn)保存著所有父組件里給這個(gè)子組件綁定的數(shù)據(jù),比如,插槽等。 寫(xiě)文章不容易,點(diǎn)個(gè)贊唄兄弟專(zhuān)注 Vue 源碼分享,文章分為白話(huà)版和 源碼版,白話(huà)版助于理解工作原理,源碼版助于了解內(nèi)部詳情,讓我們一起學(xué)習(xí)吧研究基于 Vue版本 【2.5.17】 如果你覺(jué)得排版難看,請(qǐng)點(diǎn)擊 下面鏈接 或者 拉到 下面...
寫(xiě)文章不容易,點(diǎn)個(gè)贊唄兄弟專(zhuān)注 Vue 源碼分享,文章分為白話(huà)版和 源碼版,白話(huà)版助于理解工作原理,源碼版助于了解內(nèi)部詳情,讓我們一起學(xué)習(xí)吧研究基于 Vue版本 【2.5.17】 如果你覺(jué)得排版難看,請(qǐng)點(diǎn)擊 下面鏈接 或者 拉到 下面關(guān)注公眾號(hào)也可以吧 【Vue原理】NextTick - 源碼版 之 服務(wù)Vue 初次看的兄弟可以先看 【Vue原理】NextTick - 白話(huà)版 簡(jiǎn)單了解下...
寫(xiě)文章不容易,點(diǎn)個(gè)贊唄兄弟專(zhuān)注 Vue 源碼分享,文章分為白話(huà)版和 源碼版,白話(huà)版助于理解工作原理,源碼版助于了解內(nèi)部詳情,讓我們一起學(xué)習(xí)吧研究基于 Vue版本 【2.5.17】 如果你覺(jué)得排版難看,請(qǐng)點(diǎn)擊 下面鏈接 或者 拉到 下面關(guān)注公眾號(hào)也可以吧 【Vue原理】Mixins - 源碼版 今天探索的是 mixins 的源碼,mixins 根據(jù)不同的選項(xiàng)類(lèi)型會(huì)做不同的處理 篇幅會(huì)有些長(zhǎng),...
摘要:首先,兄弟,容我先說(shuō)幾句涉及源碼很多,篇幅很長(zhǎng),我都已經(jīng)分了上下三篇了,依然這么長(zhǎng),但是其實(shí)內(nèi)容都差不多一樣,但是我還是毫無(wú)保留地給你了。 寫(xiě)文章不容易,點(diǎn)個(gè)贊唄兄弟專(zhuān)注 Vue 源碼分享,文章分為白話(huà)版和 源碼版,白話(huà)版助于理解工作原理,源碼版助于了解內(nèi)部詳情,讓我們一起學(xué)習(xí)吧研究基于 Vue版本 【2.5.17】 如果你覺(jué)得排版難看,請(qǐng)點(diǎn)擊 下面鏈接 或者 拉到 下面關(guān)注公眾號(hào)也...
閱讀 1299·2021-11-17 09:33
閱讀 1786·2021-09-09 11:53
閱讀 3277·2021-09-04 16:45
閱讀 1453·2021-08-17 10:12
閱讀 2442·2019-08-30 15:55
閱讀 1800·2019-08-30 15:53
閱讀 2436·2019-08-30 15:52
閱讀 2592·2019-08-29 18:41