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

Vue3中slot插槽基本使用

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

使用Vue的小伙伴相信你一定使用過插槽,如果你沒有用過,那說明你的項目可能不是特別復雜。插槽(slot)可以說在一個Vue項目里面處處都有它的身影,比如我們使用一些UI組件庫的時候,我們通常可以使用插槽來自定義我們的內容。

1.插槽基本使用

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

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

我們在項目中新建一個child.vue文件,用來當作子組件,它的代碼也非常的簡單。

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>

輸出結果:

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

那么我們如何往這個槽里面放置內容呢?

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

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

輸出結果:

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

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

結論:

為了更好理解插槽,簡單總結為以下幾點:

  • slotVue3中的內置標簽。
  • slot相當于給子組件挖出了一個槽,可以用來填充內容。
  • 父組件中調用子組件時,子組件標簽之間的內容元素就是要放置的內容,它會把slot標簽替換掉。

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

2.插槽默認內容

我們通常將插槽比作一個占位符,有內容進來時,自動把slot給替換掉。但是,如果沒有內容進來時,那么應該渲染什么呢?

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

修改一下 child.vue 代碼:

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

當我們的App.vue沒有向child組件傳入內容時,會是什么效果呢?

App.vue 代碼如下:

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

輸出結果:

可以看到子組件同樣渲染了內容,而且就是slot標簽內的內容。那么我們我們往child組件傳入一點內容會是什么效果呢?

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>

輸出結果:

可以看到此時頁面上渲染的App.vue父組件傳入的內容了。

總結:

從上面例子不難看出,slot 標簽內的內容就是默認內容,也就是當父組件沒有傳遞給子組件內容時,子組件就會默認渲染 slot 內部的內容,但是 slot 標簽是不會渲染出來的。

3.具名插槽

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

3.1 基本使用

這個時候為了區(qū)分插槽與內容的對應關系,我們可以分別給slot和內容都加上一個名字,插入插槽的時候大家按照名字區(qū)分好就可以了。

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

代碼如下:

<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>

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

代碼如下:

<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>

輸出結果:

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

3.2 簡寫

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

原寫法:

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

簡寫法:

<template #footer>
</template>

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

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

3.3 默認插槽與具名插槽混用

當一個子組件中既有具名插槽,又有默認插槽時,該如何渲染呢?

前面我們說默認插槽會被隱式的命名為default,所以我們傳入內容時可以將插槽名字改為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>

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

當然,既然大家都是默認的,在父組件中你也可以不用名字,這個時候內容會默認傳入到未命名插槽中去。

代碼如下:

<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>

輸出結果:

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

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

代碼如下:

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

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

5.插槽作用域問題

我們仔細思考插槽的使用,會發(fā)現(xiàn)這有一點類似于父子組件傳遞,只不過插槽傳遞的是模板內容罷了。那么涉及到傳值,就會有一個作用域的問題,我們回顧一下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ù)作用域的,但是反過來是不行的,因為我們無法通過插槽拿到子組件的數(shù)據(jù)。

總結:

所以我們這里總結為兩點

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

6.作用域插槽

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

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

6.1 默認插槽作用域傳值

我們先來演示默認插槽如何獲取子組件的數(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>

輸出結果:

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

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

解構寫法:

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

代碼如下:

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

6.2 具名插槽作用域傳值

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

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添加了一個name,在父組件中接收數(shù)據(jù)的時候不在采用v-slot=""形式了,而是直接再插槽內容上采用#header=""形式,當時這是簡寫形式,你也可以寫為:v-slot:header=""

總結

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

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

相關文章

最新評論