摘要:通過函數(shù)參數(shù)傳遞的形式,讓插槽的變量,在解析時,先訪問函數(shù)變量。那么這兩個有什么關(guān)系呢外殼節(jié)點保存著所有父組件里給這個子組件綁定的數(shù)據(jù),比如,插槽等。
寫文章不容易,點個贊唄兄弟
專注 Vue 源碼分享,文章分為白話版和 源碼版,白話版助于理解工作原理,源碼版助于了解內(nèi)部詳情,讓我們一起學(xué)習(xí)吧
研究基于 Vue版本 【2.5.17】
如果你覺得排版難看,請點擊 下面鏈接 或者 拉到 下面關(guān)注公眾號也可以吧
【Vue原理】Slot - 源碼版之作用域插槽
今天探索Slot的另一部分,作用域插槽。
首先,設(shè)置一個模板例子
把子組件的 child 傳給 插槽
父組件會解析成下面的渲染函數(shù)
with(this) { return _c("div", {}, [_c("test", { scopedSlots: _u([{ key: "default", fn: function(slotProps) { return [ "我是放在組件的 slot :"+slotProps ] } }]) })], 1) }
其中,_u 是 resolveScopedSlots,Vue會給每個實例都注冊一個 _u 方法。
作用主要是把數(shù)組變成對象map并返回
看下 resolveScopedSlots 源碼
給每個實例注冊 _u
function resolveScopedSlots(fns, res) { res = res || {}; for (var i = 0; i < fns.length; i++) { res[fns[i].key] = fns[i].fn; } return res }
把傳入的數(shù)組組裝成對象,像是下面這樣
[{ key: "default", fn: function(slotProps) { return ["我是放在組件的 slot :" + slotProps] } }] ---------_u 把上面變成下面------ { default:function(slotProps) { return ["我是放在組件的 slot :" + slotProps] } }插槽怎么解析
你可以看到了,在父組件的渲染函數(shù)中,作用域Slot 被包裝成了一個函數(shù),并且保存在 test 組件的 scopeSlot 中,用于后面解析內(nèi)部組件時使用
包裝成函數(shù),是為了改變插槽內(nèi)容的變量訪問的作用域。
通過函數(shù)參數(shù)傳遞的形式,讓插槽的變量,在解析時,先訪問函數(shù)變量。如果沒有,再去父組件上獲取
那么這個函數(shù)的參數(shù)是從哪里傳進(jìn)來的呢?讓我們一探究竟
額外:組件解析
上面的 test 在父組件中解析成一個節(jié)點
{ tag:"test", children:["我是放在組件的 slot :11"] }
而解析 test 時,也會被解析成一個節(jié)點
{ tag:"main", children:["我在子組件里面","我是放在組件的 slot :11"] }
就是 test 會有兩個節(jié)點,第一個節(jié)點我認(rèn)為是外殼節(jié)點,第二個節(jié)點是渲染節(jié)點,是真正插入頁面的。
那么這兩個有什么關(guān)系呢?外殼節(jié)點保存著所有父組件里給這個子組件綁定的數(shù)據(jù),比如 props,插槽等。然后提供給 組件解析時使用
按順序理一下解析流程
1、插槽函數(shù)保存到外殼節(jié)點
之前的父渲染函數(shù),子組件的插槽解析成一個節(jié)點處理函數(shù),如下 ,然后作為 scopedSlots 保存在 test 組件的外殼節(jié)點上
{ tag:"test", data:{ scopedSlots:{ // 插槽包裝成的函數(shù) default:function(slotProps) { return [ "我是放在組件的 slot :"+slotProps ] } } }, children:["我是放在組件的 slot :11"] }
2、插槽函數(shù)另存為
然后,test組件會創(chuàng)建自身實例,并且初始化,在初始化的過程中,會把 外殼節(jié)點上的 $scopedSlots 另存為到本實例上,方便后面子組件解析內(nèi)部模板直接調(diào)用
// 這個函數(shù)作用是,執(zhí)行渲染函數(shù),得到組件節(jié)點 Vue.prototype._render = function() { var vm = this; var ref = vm.$options; // _parentVnode 就是外殼節(jié)點 var _parentVnode = ref._parentVnode; if (_parentVnode) { vm.$scopedSlots = _parentVnode.data.scopedSlots || {}; } ...省略N多執(zhí)行渲染函數(shù)的代碼 vm.$vnode = _parentVnode; return vnode };
3、子組件解析內(nèi)部
看下子組件模板,綁定了child在 slot 上,用于傳給插槽
執(zhí)行子組件解析成的渲染函數(shù)如下
with(this) { return _c("main", [ "我在子組件里面", _t("default", null, { child: child }) ], 2) }
其中,child 會從子組件上獲取,所以 child 是11
渲染函數(shù)中,看到子組件中的slot的占位標(biāo)簽如下
被解析成了一個_t函數(shù)(怎么解析的話,又是一篇,太多先不說)
_t("default", null, { child:child })
看下_t,他是renderSlot,上一篇文章提過。這個方法,會兼容處理作用域Slot和普通Slot,上篇文章省略了處理作用域Slot 的代碼,現(xiàn)在看一下
function renderSlot(name, fallback, props) { // 看了上面,所以可以從實例上獲取$scopedSlots var scopedSlotFn = this.$scopedSlots[name]; var nodes; if (scopedSlotFn) { props = props || {}; // 開始執(zhí)行插槽函數(shù) nodes = scopedSlotFn(props); } return nodes }
_t 的作用是,執(zhí)行會直接返回節(jié)點,直接替換子組件 slot 占位符,完成插入功能
_t 就是 renderSlot ,函數(shù)會根據(jù) 【插槽名字】 找到對應(yīng)的 【作用域Slot包裝成的函數(shù)】,然后執(zhí)行它,把子組件內(nèi)的數(shù)據(jù) 【 { child:child } 】子傳進(jìn)去
于是,作用域Slot 生成的函數(shù),就接收到了子組件傳入的數(shù)據(jù)啦
所以 作用域Slot 就可以拿傳入的參數(shù)進(jìn)行解析了
插槽怎么插入子組件_t("default",null,{ child:child }) 執(zhí)行完畢,會返回節(jié)點,這個節(jié)點就是 slot 解析生成的節(jié)點
[ "我是放在組件的 slot :"+ {child:11} ]
子組件渲染函數(shù)執(zhí)行完畢,生成的vnode 如下
{ tag:"main", children:[ "我在子組件里面", "我是放在組件的 slot : {child:11}" ] }
作用域插槽,成功地替換了原來的占位符
最后,來張圖看下總的流程
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/105321.html
摘要:我們都知道分為普通和作用域,兩個內(nèi)容都很多,所以分兩部分進(jìn)行講述。今天講的是普通其實普通,表示默認(rèn)和具名,只是他們的處理方式都差不多,就只是是否有自定義名字而已,所以,表示一種類型。 寫文章不容易,點個贊唄兄弟專注 Vue 源碼分享,文章分為白話版和 源碼版,白話版助于理解工作原理,源碼版助于了解內(nèi)部詳情,讓我們一起學(xué)習(xí)吧研究基于 Vue版本 【2.5.17】 如果你覺得排版難看,請...
摘要:寫文章不容易,點個贊唄兄弟專注源碼分享,文章分為白話版和源碼版,白話版助于理解工作原理,源碼版助于了解內(nèi)部詳情,讓我們一起學(xué)習(xí)吧研究基于版本如果你覺得排版難看,請點擊下面鏈接或者拉到下面關(guān)注公眾號也可以吧原理白話版插槽作為組件一個重要的部 寫文章不容易,點個贊唄兄弟專注 Vue 源碼分享,文章分為白話版和 源碼版,白話版助于理解工作原理,源碼版助于了解內(nèi)部詳情,讓我們一起學(xué)習(xí)吧研究基于...
摘要:網(wǎng)絡(luò)上大多數(shù)文章,也是千篇一律的翻譯這句話,可是僅憑這一句話,我想象不到的使用場景。因為真正的使用場景下,子組件的數(shù)據(jù)都是來自父組件的。組件的數(shù)據(jù)都是來自調(diào)用者的,然后會把每一行的,在開發(fā)者需要時,傳遞出去。 Vue的slot-scope的場景的個人理解 這篇文章不是單純把文檔的話和api拿來翻譯和演示,而是談?wù)勎覍τ趕lot-scope的使用場景的個人理解,如果理解錯誤,歡迎討論! ...
摘要:結(jié)合我們的例子,子組件則會生成以下代碼到目前為止,對于普通插槽和作用域插槽已經(jīng)談的差不多了。下面我們將仔細(xì)談?wù)勥@塊的內(nèi)容。在看具體實現(xiàn)邏輯前,我們先通過一個例子來先了解下其基本用法然后進(jìn)行使用頁面展示效果如下看著好。本篇文章是細(xì)談 vue 系列第二篇了,上篇我們已經(jīng)細(xì)談了 vue 的核心之一 vdom,傳送門 今天我們將分析我們經(jīng)常使用的 vue 功能 slot 是如何設(shè)計和實現(xiàn)的,本文將圍...
摘要:后將已廢棄的使用特性的語法廢除,但是目前還能夠使用,鏈接地址如圖實現(xiàn)一個類似,星級點評的組件父組件子組件子組件將綁定再傳給父組件的再通過獲得傳過來的值,官方解釋作用域插槽的內(nèi)部工作原理是將你的插槽內(nèi)容包括在一個傳入單個參數(shù)的函數(shù)里插槽 vue 2.6.0后將已廢棄的使用 slot-scope 特性的語法廢除,但是目前還能夠使用,鏈接地址:https://cn.vuejs.org/v2/...
閱讀 729·2021-11-24 10:19
閱讀 1106·2021-09-13 10:23
閱讀 3428·2021-09-06 15:15
閱讀 1777·2019-08-30 14:09
閱讀 1683·2019-08-30 11:15
閱讀 1837·2019-08-29 18:44
閱讀 934·2019-08-29 16:34
閱讀 2456·2019-08-29 12:46