Vue插槽學(xué)習(xí)理解

閱讀之前

本文主要參照了Vue官方文檔的插槽部分說(shuō)明,中間加入的自己的理解旅择,寫的比較簡(jiǎn)潔易懂沽一。各位看官可以對(duì)照官方文檔和本文的介紹來(lái)理解slot插槽語(yǔ)法秘案。

Vue 插槽(2.60版本以后)

插槽可以讓通用組件更加多樣化,它類似React中的children莫鸭。

聲明:以下所有內(nèi)容以父級(jí)(通用)組件和應(yīng)用(調(diào)用)組件的關(guān)系舉例說(shuō)明闹丐。

  • 最簡(jiǎn)單的使用

比如你想聲明一個(gè)帶有特殊border的div作為一個(gè)通用組件BorderedDiv。

<template>
  <div class="some-border-class">
    // 這里是包裹的不同的內(nèi)容
    // 可能你很想使用this.props.children(如果你曾是React使用者)
  </div>
</template>

在使用該組件時(shí)

<bordered-div>
  <p>被包裹的文字</p>
</bordered-div>

這時(shí)你會(huì)想到:這個(gè)文字如何傳遞給父級(jí)組件呢被因?

直接這樣寫就好:

<template>
  <div class="some-border-class">
    // 這里是包裹的不同的內(nèi)容
    <slot></slot>
  </div>
</template>
  • 作用域

<common-component :data="[1,2,3]">
    {{ data }}
    <!-- 
    這里的 `data` 會(huì)是 undefined卿拴,因?yàn)閿?shù)組是 **傳遞給**  
    <common-component> 的而不是 在 <common-component> 組件
    **內(nèi)部**定義的
    -->
</common-component >

父級(jí)模板里的所有內(nèi)容都是在父級(jí)作用域中編譯的;子模板里的所有內(nèi)容都是在子作用域中編譯的梨与。

簡(jiǎn)單來(lái)說(shuō):你不能在寫children的時(shí)候直接使用父級(jí)組件中的數(shù)據(jù)堕花,考慮當(dāng)前環(huán)境。

  • 后備內(nèi)容

在<slot></slot>標(biāo)簽中的內(nèi)容將在沒(méi)有匹配到插槽內(nèi)容時(shí)渲染

 <slot>如果沒(méi)有children粥鞋,我就會(huì)渲染</slot>

如果父級(jí)模板中聲明了插槽缘挽,但是應(yīng)用組件卻沒(méi)有包裹任何內(nèi)容,它便會(huì)渲染為備用內(nèi)容呻粹。

  • 具名

可以給<slot></slot> 傳遞name屬性

<div class="container">
<header>
    <slot name="header"></slot>
</header>
<main>
    <slot name="default"></slot>
</main>
<footer>
    <slot name="footer"></slot>
</footer>
</div>

然后這樣向?qū)?yīng)的插槽傳遞內(nèi)容:

<base-layout>
    <template v-slot:header>
        <h1>Here might be a page title</h1>
    </template>
    // 可以不用包裹template 直接傳遞給default slot
    <template v-slot:default>
        <p>A paragraph for the main content.</p> 
        <p>And another one.</p>
    </template>
    
    <template v-slot:footer>
        <p>Here's some contact info</p>
    </template>
</base-layout>

其中:<template v-slot:default>父節(jié)點(diǎn)可以省略壕曼。

注意:

v-slot指令只能使用在<template>上,除非只需要傳遞默認(rèn)插槽等浊。(也就是你的父級(jí)模板中只有一個(gè)沒(méi)有name屬性的插槽)
這時(shí)它可以用在父組件上腮郊。
盡管如此,它也只是<template v-slot:default></template>的縮寫凿掂。
在傳遞多個(gè)插槽時(shí)伴榔,還是需要使用完整的語(yǔ)法。

  • 作用域插槽

在通用組件中聲明的模板如下:

<span>
    // 給slot聲明了一個(gè)屬性 
    // 該屬性可以在對(duì)應(yīng)的插槽內(nèi)容中訪問(wèn)
    // 省略了 name = "default"
    <slot v-bind:user="user"></slot>
</span>

在應(yīng)用組件中:

<common-component>
    <!-- v-slot是v-slot:default的縮寫 -->
    <template v-slot="slotProps">
        // 插槽上聲明的user可以這樣訪問(wèn)
        {{ slotProps.user.name }}
    </template>
</common-component>

在“裝載插槽”時(shí)庄萎,slot上聲明的屬性綁定的數(shù)據(jù)會(huì)以函數(shù)的參數(shù)形式傳遞給插槽

function (slotProps) {
    // 插槽的內(nèi)容
}

因此可以在編寫插槽內(nèi)容時(shí)獲取到common-component(父組件)中的數(shù)據(jù)踪少。

由于slotProps是以函數(shù)參數(shù)的形式傳遞的,因此各種簡(jiǎn)寫也就可以理解了糠涛。

    // 解構(gòu)傳參
    <template v-slot:default="{ user }">
        {{  user.name }}
    </template>
    // 重命名
    <template v-slot:default="{ user: person }" >
        {{ person.name }}
    </template>
    // 默認(rèn)值
    <template v-slot:default="{ user={ firstname: 'test' } }">
        {{ user.name }}
    </template>
  • 縮寫

在向具名(聲明了name屬性的)插槽傳遞內(nèi)容時(shí)援奢,(應(yīng)用組件中)可以使用縮寫:

<common-layout>
    // 等同于:v-slot:header
   <template #header>
   // 以下模板內(nèi)容會(huì)傳遞給name = header的插槽
       <p>this is header</p>
   </template>
   // 注意: 不可以 直接#
   <template #default>
   // 以下內(nèi)容會(huì)傳遞給沒(méi)有聲明name的插槽,也就是默認(rèn)插槽
       <p>this is default slot</p>
   </template>
</common-layout>

當(dāng)然如果common-layout模板中如果只有一個(gè)默認(rèn)插槽的話忍捡,你可以直接這樣做:

// 相當(dāng)于: v-slot:default="slotProps"
// default不可省略,否則引發(fā)警告
<common-layout #default="slotProps">
   {{ slotProps.user.name }}
</common-layout>
  • 其他示例

請(qǐng)先看官方給出的示例:todoList示例

關(guān)鍵點(diǎn):
通用組件中這樣聲明:

<!--
    我們?yōu)槊總€(gè) todo 準(zhǔn)備了一個(gè)插槽集漾, 將 `todo` 對(duì)象作為一個(gè)
    插槽的 prop 傳入.
-->
    <slot name="todo" v-bind:todo="todo">
        <!-- 后備內(nèi)容 -->
        {{ todo.text }}
    </slot>

應(yīng)用組件中這樣使用:

<todo-list v-bind:todos="todos">
    // 或者簡(jiǎn)寫為: #todo
    <template v-slot:todo="{ todo }">
        <span v-if="todo.isComplete">?</span>
        {{ todo.text }}
    </template>
</todo-list>

這樣使用就將li中的內(nèi)容動(dòng)態(tài)化切黔。

  • 理解

slot的基本用法簡(jiǎn)單來(lái)說(shuō)就是(我的理解):

在你聲明一個(gè)通用的組件時(shí),將通用的部分聲明為模板具篇,動(dòng)態(tài)的內(nèi)容纬霞,也就是各個(gè)應(yīng)用組件不一致的地方,或者說(shuō)可能需要?jiǎng)討B(tài)渲染的部分聲明為插槽slot驱显,并給該插槽定義name,prop诗芜,以方便應(yīng)用組件獲取數(shù)據(jù)和對(duì)號(hào)入座。

參考:

Vue官方文檔: https://cn.vuejs.org/v2/guide/components-slots.html

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末埃疫,一起剝皮案震驚了整個(gè)濱河市伏恐,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌栓霜,老刑警劉巖翠桦,帶你破解...
    沈念sama閱讀 219,188評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異胳蛮,居然都是意外死亡销凑,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,464評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門鹰霍,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)闻鉴,“玉大人茵乱,你說(shuō)我怎么就攤上這事茂洒。” “怎么了瓶竭?”我有些...
    開封第一講書人閱讀 165,562評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵督勺,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我斤贰,道長(zhǎng)智哀,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,893評(píng)論 1 295
  • 正文 為了忘掉前任荧恍,我火速辦了婚禮瓷叫,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘送巡。我一直安慰自己摹菠,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,917評(píng)論 6 392
  • 文/花漫 我一把揭開白布骗爆。 她就那樣靜靜地躺著次氨,像睡著了一般。 火紅的嫁衣襯著肌膚如雪摘投。 梳的紋絲不亂的頭發(fā)上煮寡,一...
    開封第一講書人閱讀 51,708評(píng)論 1 305
  • 那天虹蓄,我揣著相機(jī)與錄音,去河邊找鬼幸撕。 笑死坐儿,一個(gè)胖子當(dāng)著我的面吹牛累铅,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 40,430評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了客蹋?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,342評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤这刷,失蹤者是張志新(化名)和其女友劉穎隅很,沒(méi)想到半個(gè)月后屋彪,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體婴谱,經(jīng)...
    沈念sama閱讀 45,801評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,976評(píng)論 3 337
  • 正文 我和宋清朗相戀三年兼搏,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片吓著。...
    茶點(diǎn)故事閱讀 40,115評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖氧苍,靈堂內(nèi)的尸體忽然破棺而出夜矗,到底是詐尸還是另有隱情泛范,我是刑警寧澤让虐,帶...
    沈念sama閱讀 35,804評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站罢荡,受9級(jí)特大地震影響赡突,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜区赵,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,458評(píng)論 3 331
  • 文/蒙蒙 一惭缰、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧笼才,春花似錦漱受、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,008評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)絮记。三九已至,卻和暖如春虐先,著一層夾襖步出監(jiān)牢的瞬間怨愤,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,135評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工蛹批, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留撰洗,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,365評(píng)論 3 373
  • 正文 我出身青樓腐芍,卻偏偏與公主長(zhǎng)得像差导,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子猪勇,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,055評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容

  • 什么是組件柿汛? 組件 (Component) 是 Vue.js 最強(qiáng)大的功能之一。組件可以擴(kuò)展 HTML 元素埠对,封裝...
    youins閱讀 9,481評(píng)論 0 13
  • 這篇筆記主要包含 Vue 2 不同于 Vue 1 或者特有的內(nèi)容络断,還有我對(duì)于 Vue 1.0 印象不深的內(nèi)容。關(guān)于...
    云之外閱讀 5,050評(píng)論 0 29
  • 組件(Component)是Vue.js最核心的功能项玛,也是整個(gè)架構(gòu)設(shè)計(jì)最精彩的地方貌笨,當(dāng)然也是最難掌握的。...
    六個(gè)周閱讀 5,617評(píng)論 0 32
  • 【2019-3-4更新】Vue 2.6+修改了部分語(yǔ)法襟沮,對(duì)插槽的使用有了較多的更新锥惋。在本文中筆者在相應(yīng)位置給出了更...
    果汁涼茶丶閱讀 10,249評(píng)論 2 36
  • vue概述 在官方文檔中,有一句話對(duì)Vue的定位說(shuō)的很明確:Vue.js 的核心是一個(gè)允許采用簡(jiǎn)潔的模板語(yǔ)法來(lái)聲明...
    li4065閱讀 7,227評(píng)論 0 25