vue中的插槽詳解

喆星高照發表於2024-07-11

插槽(slot)
插槽在vue中是一種很常見的寫法,讓父元件可以向子元件指定位置插入html結構,也是一種元件間通訊的方式

一共有三種分類:預設插槽、具名插槽、作用域插槽,下面一一根據案例改造說明

1 基本案例
首先編寫一個基本的案例,三個元件展示不同的資料型別

頁面進行展示

現在要改需求,美食的列表只展示一個海報圖片,電影則展示一段宣傳影片,遊戲則不變

如果要按照美食的需求去改統一加上照片

那麼三個列表都有了這個照片

當然可以使用v-show判斷

雖然可以實現效果,但是比較麻煩,而且電影的列表如果也按照這樣判斷,那麼程式碼維護性特別低,邏輯非常混亂

這時候就可以使用插槽了

2 插槽的基本使用
所謂插槽,其實就是挖個坑,等著使用者進行填充

下面的案例是一個最基本的單個插槽使用,也叫預設插槽

比如下面我改造了下程式碼,在元件標籤裡面寫一個doc元素

但是檢視的時候發現什麼都沒有

這是因為雖然定義了元素,但是vue不知道去元件哪個地方填充,這個時候我們需要在被需要填充的元件裡面定義一個插槽(slot)標籤

這樣我就可以只需要一個插槽,對不同的元件進行不同的元素展示了,如下

圖片,列表,影片,我想要什麼就定義什麼,元件只需要一個外掛接收即可,這樣就能實現動態展示同一個元件不同的資料

值得注意點是,雖然透過元件標籤把資料和資源傳輸到了元件中並使用插槽進行展示,但是都是透過app這個元件進行傳輸的,所以對元素的樣式控制,完全可以在app.vue裡面處理完之後再傳遞

當然如果非要把樣式在用到插槽的元件中進行處理,也是沒問題的

不管在那處理,都是一樣的

插槽的預設值
插槽是可以定義預設值的,當沒有對插槽進行填充的時候,就會展示預設值,如下所示我把元件裡面的內容註釋掉了,這時候就會出現插槽的預設值:

圖片被預設值取代了

3 具名插槽
預設插槽是插槽家族中最簡單的使用方式,下面的具名插槽則是比它稍微複雜些的一個使用方式

顧名思義,它指的是具有名字的插槽

所以改下上面的需求,在原有的基礎上,加入更多的元素,透過另外一個插槽實現,也就是多個插槽

如果直接複製一個預設插槽,肯定是不行的

發現全部的元素都出現了兩份,這不是我們想要的效果

插槽確實需要些多個,但是需要name指定插槽的名稱

但是發現還是不行

因為雖然給插槽命名了名稱,但是插入內容的時候並沒有告訴對應的插槽,所以需要使用slot屬性去標識具體的插槽

多個插值小技巧
如果有多個元素需要使用同一個插槽是不會進行資料覆蓋的,這種情況我們可以定義一個div,然後在div中指定插槽的name

一樣的效果

template使用技巧
如果想要多個元素並且不想再多生成一個無用的div,可以使用template標籤

template的v-slot寫法
一旦使用了template標籤,就有了第二種寫法了,這是vue2.6提出來的,v-slot:xxx

v-slot的寫法只能作用於template標籤上,不信你看,這裡我加到了div身上

直接報錯了

以上就是具名插槽的用法了

4 作用域插槽
說完了預設插槽和具名插槽,接下來就是插槽的最後一種用法:作用域插槽

說到作用於大多數人想到的是js的作用域,這個作用域插槽還真和js的作用域有幾分相似

現在有一個需求,根據選單生成的資料還是一樣的資料,但是展示方式不同

比如第一個列表還是無序的,第二個列表是有序的,第三個列表則要把遊戲名稱以h4的形式展現

這時候就可以藉助作用域插槽了

如果正常寫

會報錯,表示找不到games

這就是一個作用域的問題,我們傳遞了games,需要在接收方定義template使用scope屬性進行接收

另外一種寫法

老是寫傳遞的引數有點煩,就可以使用這種寫法

傳遞多個屬性
不止可以傳遞一個屬性,比如:

效果都是一樣的

5 插槽總結
作用:讓父元件可以向子元件指定位置插入html結構,也是一種元件間通訊的方式,適用於 父元件 ===> 子元件 。
分類:預設插槽、具名插槽、作用域插槽
使用方式:
1 預設插槽:

父元件中:
        <Category>
           <div>html結構1</div>
        </Category>
子元件中:
        <template>
            <div>
               <!-- 定義插槽 -->
               <slot>插槽預設內容...</slot>
            </div>
        </template>


2 具名插槽:

父元件中:
        <Category>
            <template slot="center">
              <div>html結構1</div>
            </template>

            <template v-slot:footer>
               <div>html結構2</div>
            </template>
        </Category>
子元件中:
        <template>
            <div>
               <!-- 定義插槽 -->
               <slot name="center">插槽預設內容...</slot>
               <slot name="footer">插槽預設內容...</slot>
            </div>
        </template>

3 作用域插槽
1 理解:資料在元件的自身,但根據資料生成的結構需要元件的使用者來決定。(games資料在Category元件中,但使用資料所遍歷出來的結構由App元件決定)
2 具體編碼:

父元件中:
                <Category>
                        <template scope="scopeData">
                                <!-- 生成的是ul列表 -->
                                <ul>
                                        <li v-for="g in scopeData.games" :key="g">{{g}}</li>
                                </ul>
                        </template>
                </Category>

                <Category>
                        <template slot-scope="scopeData">
                                <!-- 生成的是h4標題 -->
                                <h4 v-for="g in scopeData.games" :key="g">{{g}}</h4>
                        </template>
                </Category>
子元件中:
        <template>
            <div>
                <slot :games="games"></slot>
            </div>
        </template>
                
        <script>
            export default {
                name:'Category',
                props:['title'],
                //資料在子元件自身
                data() {
                    return {
                        games:['紅色警戒','穿越火線','勁舞團','超級瑪麗']
                    }
                },
            }
        </script>

最後的話

插槽技術是Vue.js中重要的元件化特性之一,為我們提供了靈活的元件化開發方式,透過合理使用插槽,我們可以輕鬆地定製和擴充套件元件的功能,使元件的可複用性和靈活性大大提高。

相關文章