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