欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Vue3中slot插槽基本使用

 更新時(shí)間:2022年08月10日 10:31:55   作者:虎仔_  
插槽slot可以說在一個(gè)Vue項(xiàng)目里面處處都有它的身影,比如我們使用一些UI組件庫的時(shí)候,我們通常可以使用插槽來自定義我們的內(nèi)容,這篇文章主要介紹了Vue3中slot插槽使用方式,需要的朋友可以參考下

使用Vue的小伙伴相信你一定使用過插槽,如果你沒有用過,那說明你的項(xiàng)目可能不是特別復(fù)雜。插槽(slot)可以說在一個(gè)Vue項(xiàng)目里面處處都有它的身影,比如我們使用一些UI組件庫的時(shí)候,我們通??梢允褂貌宀蹃碜远x我們的內(nèi)容。

1.插槽基本使用

插槽的用途就和它的名字一樣:有一個(gè)缺槽,我們可以插入一些東西。

插槽slot通常用于兩個(gè)父子組件之間,最常見的應(yīng)用就是我們使用一些UI組件庫中的彈窗組件時(shí),彈窗組件的內(nèi)容是可以讓我們自定義的,這就是使用了插槽的原理。

我們在項(xiàng)目中新建一個(gè)child.vue文件,用來當(dāng)作子組件,它的代碼也非常的簡單。

child.vue 代碼如下:

<template>
  <div class="child-box">
    <p>我是子組件</p>
    <!-- 插槽 -->
    <slot></slot>
  </div>
</template>
<style>
.child-box {
  display: flex;
  flex-direction: column;
  align-items: center;
}
</style>

然后我們直接在App.vue引用該子組件,代碼如下:

<template>
  <img alt="Vue logo" src="./assets/logo.png" />
  <child></child>
</template>
<script setup lang="ts">
import Child from "./child.vue";
</script>

輸出結(jié)果:

child子組件代碼非常的簡單,唯一不同的里面我們添加了一對<slot></slot>標(biāo)簽,這就是插槽標(biāo)簽。這對標(biāo)簽就好比我們在child組件內(nèi)部挖了一個(gè)槽出來,我們接下來就可以往這個(gè)槽里面放置一些內(nèi)容。

那么我們?nèi)绾瓮@個(gè)槽里面放置內(nèi)容呢?

我們在App.vue里面通過一對閉合標(biāo)簽<child></child>調(diào)用了子組件,我們都知道HTML標(biāo)簽之間是可以插入內(nèi)容的,雖然child不是HTML自帶的標(biāo)簽,但是它卻有著類似的特征,比如我們往<child></child>之間插入一點(diǎn)內(nèi)容,代碼如下:

<template>
  <img alt="Vue logo" src="./assets/logo.png" />
  <child>
    <div>小豬課堂</div>
  </child>
</template>

輸出結(jié)果:

我們發(fā)現(xiàn)在<child></child>標(biāo)簽之間插入的內(nèi)容被渲染出來了,那么這是為何呢?

前面我們說slot就是挖了一個(gè)槽出來,可以放置東西,這里我們在父組件中添加的div便就是我們要添加的東西,子組件中slot標(biāo)簽被替換為了我們插入的div元素。這就是插槽的最基本使用。

結(jié)論:

為了更好理解插槽,簡單總結(jié)為以下幾點(diǎn):

  • slotVue3中的內(nèi)置標(biāo)簽。
  • slot相當(dāng)于給子組件挖出了一個(gè)槽,可以用來填充內(nèi)容。
  • 父組件中調(diào)用子組件時(shí),子組件標(biāo)簽之間的內(nèi)容元素就是要放置的內(nèi)容,它會(huì)把slot標(biāo)簽替換掉。

最簡單的理解:我們的使用U盤需要將U盤插入USB口中,此時(shí)USB口就是插槽,U盤就是插口。在Vue中,<slot></slot>就是電腦插槽,父組件的內(nèi)容就可以理解為U盤插口。

2.插槽默認(rèn)內(nèi)容

我們通常將插槽比作一個(gè)占位符,有內(nèi)容進(jìn)來時(shí),自動(dòng)把slot給替換掉。但是,如果沒有內(nèi)容進(jìn)來時(shí),那么應(yīng)該渲染什么呢?

在很多場景下都會(huì)有這種需求,比如UI組件庫中的彈窗,如果我們沒有傳入彈窗的頭部或者底部,那么彈窗便會(huì)有默認(rèn)的樣式效果,這里就用到了slot的默認(rèn)內(nèi)容功能。

修改一下 child.vue 代碼:

<template>
  <div class="child-box">
    <p>我是子組件</p>
    <!-- 插槽 -->
    <slot>
      <p>我是默認(rèn)內(nèi)容</p>
    </slot>
  </div>
</template>

當(dāng)我們的App.vue沒有向child組件傳入內(nèi)容時(shí),會(huì)是什么效果呢?

App.vue 代碼如下:

<template>
  <img alt="Vue logo" src="./assets/logo.png" />
  <child></child>
</template>

輸出結(jié)果:

可以看到子組件同樣渲染了內(nèi)容,而且就是slot標(biāo)簽內(nèi)的內(nèi)容。那么我們我們往child組件傳入一點(diǎn)內(nèi)容會(huì)是什么效果呢?

App.vue 代碼如下:

<template>
  <img alt="Vue logo" src="./assets/logo.png" />
  <child>
    <div>{{ message }}</div>
  </child>
</template>
<script setup lang="ts">
import { ref } from "vue";
import Child from "./child.vue";
const message = ref("小豬課堂");
</script>

輸出結(jié)果:

可以看到此時(shí)頁面上渲染的App.vue父組件傳入的內(nèi)容了。

總結(jié):

從上面例子不難看出,slot 標(biāo)簽內(nèi)的內(nèi)容就是默認(rèn)內(nèi)容,也就是當(dāng)父組件沒有傳遞給子組件內(nèi)容時(shí),子組件就會(huì)默認(rèn)渲染 slot 內(nèi)部的內(nèi)容,但是 slot 標(biāo)簽是不會(huì)渲染出來的。

3.具名插槽

很多時(shí)候我們子組件中都不止只有一個(gè)slot,比如彈窗組件,我們可能允許調(diào)用者同時(shí)傳入header、content、footer等等,這個(gè)時(shí)候如果子組件中只有一個(gè)slot,那么這么多內(nèi)容該如何區(qū)分,或者說該如何渲染呢?

3.1 基本使用

這個(gè)時(shí)候?yàn)榱藚^(qū)分插槽與內(nèi)容的對應(yīng)關(guān)系,我們可以分別給slot和內(nèi)容都加上一個(gè)名字,插入插槽的時(shí)候大家按照名字區(qū)分好就可以了。

我們給child組件添加上多個(gè)slot,并且給每個(gè)slot取上一個(gè)名字。

代碼如下:

<template>
  <div class="child-box">
    <p>我是子組件</p>
    <header>
      <slot name="header"></slot>
    </header>
    <main>
      <slot></slot>
    </main>
    <footer>
      <slot name="footer"></slot>
    </footer>
  </div>
</template>

上段代碼中我們添加了3個(gè)slot插槽,并且給其中兩個(gè)slot標(biāo)簽添加了一個(gè)name屬性,也就是每個(gè)插槽的名字。需要注意的是,上段代碼中有一個(gè)插槽我們沒有添加name屬性,這個(gè)時(shí)候Vue會(huì)隱式的將這個(gè)插槽命名為“default”,接下來就是我們父組件App.vue添加內(nèi)容了。

代碼如下:

<template>
  <img alt="Vue logo" src="./assets/logo.png" />
  <child>
    <template v-slot:header>
      <div>我是 header:{{ message }}</div>
    </template>
    <div>我沒有名字:{{ message }}</div>
    <template v-slot:footer>
      <div>我是 footer:{{ message }}</div>
    </template>
  </child>
</template>

輸出結(jié)果:

既然slot有了名字,那么我們在父組件中傳入內(nèi)容時(shí)就要和名字關(guān)系對應(yīng)起來,我們采用v-slot:header指令的形式找到對應(yīng)的插槽,需要注意的是該指令需要作用在template元素上。從上圖可以看出,我們傳入的內(nèi)容都渲染到了對應(yīng)的插槽內(nèi),沒有命名的插槽渲染了我們傳入的未添加指令的內(nèi)容。

3.2 簡寫

Vue中,很多指令都有簡寫形式,v-slot:name指令也有簡寫形式,比如看我們下面的示例。

原寫法:

<template v-slot:footer>
</template>

簡寫法:

<template #footer>
</template>

接下來我們在借用官網(wǎng)的一張圖來清楚的了解具名插槽中的父子組件關(guān)系。

其中BaseLayout為一個(gè)子組件,就和我們child組件一樣。

3.3 默認(rèn)插槽與具名插槽混用

當(dāng)一個(gè)子組件中既有具名插槽,又有默認(rèn)插槽時(shí),該如何渲染呢?

前面我們說默認(rèn)插槽會(huì)被隱式的命名為default,所以我們傳入內(nèi)容時(shí)可以將插槽名字改為defalut即可。

修改 child 組件:

<template>
  <img alt="Vue logo" src="./assets/logo.png" />
  <child>
    <template v-slot:header>
      <div>我是 header:{{ message }}</div>
    </template>
    <template v-slot:default>
      <div>我沒有名字:{{ message }}</div>
      <div>我沒有名字:{{ message }}</div>
      <div>我沒有名字:{{ message }}</div>
    </template>
    <template v-slot:footer>
      <div>我是 footer:{{ message }}</div>
    </template>
  </child>
</template>

雖然說子組件中有一個(gè)slot沒有取名字,但是默認(rèn)可以用default來代表它,就好比人剛出生的時(shí)候沒有名字,但是他又一個(gè)默認(rèn)屬性:“人”。

當(dāng)然,既然大家都是默認(rèn)的,在父組件中你也可以不用名字,這個(gè)時(shí)候內(nèi)容會(huì)默認(rèn)傳入到未命名插槽中去。

代碼如下:

<template>
  <img alt="Vue logo" src="./assets/logo.png" />
  <child>
    <template v-slot:header>
      <div>我是 header:{{ message }}</div>
    </template>
    <div>我沒有名字:{{ message }}</div>
    <div>我沒有名字:{{ message }}</div>
    <div>我沒有名字:{{ message }}</div>
    <template v-slot:footer>
      <div>我是 footer:{{ message }}</div>
    </template>
  </child>
</template>

輸出結(jié)果:

4.動(dòng)態(tài)插槽名

前面我們給插槽命名的時(shí)候都是直接寫死的,其實(shí)我們有時(shí)候可以動(dòng)態(tài)給插槽命名的,以滿足更多的業(yè)務(wù)場景。

代碼如下:

<base-layout>
  <template v-slot:[dynamicSlotName]>
    ...
  </template>
  <!-- 縮寫為 -->
  <template #[dynamicSlotName]>
    ...
  </template>
</base-layout>

上段代碼就是在父組件中采用動(dòng)態(tài)插槽名傳入內(nèi)容的示例。

5.插槽作用域問題

我們仔細(xì)思考插槽的使用,會(huì)發(fā)現(xiàn)這有一點(diǎn)類似于父子組件傳遞,只不過插槽傳遞的是模板內(nèi)容罷了。那么涉及到傳值,就會(huì)有一個(gè)作用域的問題,我們回顧一下App.vue中的一段代碼。

代碼如下:

<template>
  <img alt="Vue logo" src="./assets/logo.png" />
  <child>
    <div>{{ message }}</div>
  </child>
</template>
<script setup lang="ts">
import { ref } from "vue";
import Child from "./child.vue";
const message = ref("小豬課堂");
</script>

上段代碼中message是我們在父組件中定義的數(shù)據(jù),但是在我們的子組件child中渲染了出來,說明子組件中的插槽是可以訪問到父組件中的數(shù)據(jù)作用域的,但是反過來是不行的,因?yàn)槲覀儫o法通過插槽拿到子組件的數(shù)據(jù)。

總結(jié):

所以我們這里總結(jié)為兩點(diǎn)

  • 插槽內(nèi)容可以訪問到父組件的數(shù)據(jù)作用域,就好比上述中的message是父組件的。
  • 插槽內(nèi)容無法訪問到子組件的數(shù)據(jù),就好比上述App.vue中的插槽內(nèi)容拿不到子組件child的數(shù)據(jù)。

6.作用域插槽

前一節(jié)我們說父組件中的插槽內(nèi)容是無法訪問到子組件中的數(shù)據(jù)的,但是,萬一我們有需求就是需要在插槽內(nèi)容中獲取子組件數(shù)據(jù)怎么辦呢?

Vue3給我們提供了方法,使用起來也比較簡單。

6.1 默認(rèn)插槽作用域傳值

我們先來演示默認(rèn)插槽如何獲取子組件的數(shù)據(jù)。

child.vue 代碼如下:

<template>
  <div class="child-box">
    <p>我是子組件</p>
    <slot text="我是子組件小豬課堂" :count="1"></slot>
  </div>
</template>

App.vue 組件代碼:

<template>
  <img alt="Vue logo" src="./assets/logo.png" />
  <child v-slot="slotProps">
    <div>{{ slotProps.text }}---{{ slotProps.count }}</div>
  </child>
</template>

輸出結(jié)果:

上段代碼中我們在子組件中slot標(biāo)簽上添加了一些自定義屬性,屬性值就是我們想要傳遞給父組件的一些內(nèi)容。在父組件App.vue中通過v-slot="slotProps"等形式接收子組件傳毒過來的數(shù)據(jù),slotProps的名字是可以任意取的,它是一個(gè)對象,包含了所有傳遞過來的數(shù)據(jù)。

需要注意的是,子組件傳遞過來的數(shù)據(jù)只能在子組件這個(gè)標(biāo)簽內(nèi)使用。

解構(gòu)寫法:

我們都知道對象是可以解構(gòu)的,所以我們在父組件中還可以直接使用解構(gòu)的寫法來獲取數(shù)據(jù)。

代碼如下:

<template>
  <img alt="Vue logo" src="./assets/logo.png" />
  <child v-slot="{ text, count }">
    <div>{{ text }}---{{ count }}</div>
  </child>
</template>

6.2 具名插槽作用域傳值

具名插槽作用域之間的傳遞其實(shí)默認(rèn)插槽作用域傳值原理是一樣的,只不過寫法不一樣罷了。

child.vue 代碼如下:

<template>
  <div class="child-box">
    <p>我是子組件</p>
    <slot name="header" text="我是子組件小豬課堂" :count="1"></slot>
  </div>
</template>

App.vue 代碼如下:

<template>
  <img alt="Vue logo" src="./assets/logo.png" />
  <child>
    <template #header="{ text, count }">
      <div>{{ text }}---{{ count }}</div>
    </template>
  </child>
</template>

上段代碼中我們給slot添加了一個(gè)name,在父組件中接收數(shù)據(jù)的時(shí)候不在采用v-slot=""形式了,而是直接再插槽內(nèi)容上采用#header=""形式,當(dāng)時(shí)這是簡寫形式,你也可以寫為:v-slot:header=""

總結(jié)

插槽的作用非常廣泛,學(xué)好插槽對我們的項(xiàng)目開發(fā)有著非常大的幫助,當(dāng)然,想要非常優(yōu)雅的使用插槽,還是需要費(fèi)一些功夫的。這里可以推薦大家去看一看element組件庫中的table的使用,看看它是如何使用插槽的,如何優(yōu)雅的將表格組件中的數(shù)據(jù)共享給父組件的。

到此這篇關(guān)于Vue3中slot插槽使用方式的文章就介紹到這了,更多相關(guān)Vue3插槽使用內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評論