VUE3 之 作用域插槽 - 這個系列的教程通俗易懂,適合新手

追風人聊Java發表於2022-02-07

1. 概述

破窗效應告訴我們:

當一個建築物窗戶的玻璃完好無損時,很少有人想去破壞它,當有一個人破壞了一塊窗戶的玻璃,其他窗戶的玻璃也很快會被人破壞。

同理,一個很乾淨的地方,人們不好意思去丟垃圾,但是一旦地上出現了一點垃圾,人們就會毫不猶豫地丟垃圾,不會覺得慚愧。

因此,我們不要忽略一些小的問題,小的問題不去修復、解決,很快就會蔓延成大問題,正所謂蝨子多了不咬,債多了不愁。

 

言歸正傳,今天我們來聊聊作用域插槽的使用。

 

2. 作用域插槽

2.1 具名插槽回顧

    const app = Vue.createApp({
        template:`
            <div>
                <my-html>
                    <template v-slot:header>
                        <div>header</div>
                    </template>
                    <template v-slot:footer>
                        <div>footer</div>
                    </template>
                </my-html>
            </div>
        `
    });

    app.component("my-html", {
        template: `
            <div>
                <slot name="header" />
                <div>main</div>
                <slot name="footer" />
            </div>
        `
    });

這是前一篇博文最後聊到的具名插槽,簡單說就是在父元件中給插槽中的內容分塊,然後使用 v-slot 對塊進行命名,在子元件中將插槽的分塊根據名稱放在希望的地方

 

2.2 具名插槽命名的簡便寫法

在剛才的具名插槽例子中,使用 v-slot:header 的寫法為 header 外掛命名,寫起來比較麻煩,也可以簡寫成 #header

    const app = Vue.createApp({
        template:`
            <div>
                <my-html>
                    <template #header>
                        <div>header</div>
                    </template>
                    <template #footer>
                        <div>footer</div>
                    </template>
                </my-html>
            </div>
        `
    });

 

2.3 使用子元件展示集合

    const app = Vue.createApp({
        template:`
            <div>
                <my-list />
            </div>
        `
    });

    app.component("my-list", {

        data() {
            return {
                myList: ['a', 'b', 'c']
            }
        },
        template: `
            <div>
                <div v-for="item in myList">{{item}}</div>
            </div>
        `
    });

這個例子中,我們在子元件中定義一個陣列變數 myList,然後使用前面學的迴圈知識,渲染 myList 中的內容

 

 這個例子中,是使用 div 標籤展示陣列的內容,現在有一個需求,希望由父元件來指定展示陣列的標籤,我們該如何做呢?

 

2.4 作用域插槽1

    const app = Vue.createApp({

        template:`
            <div>
                <my-list>
                    <span></span>
                </my-list>
            </div>
        `
    });

    app.component("my-list", {

        data() {
            return {
                myList: ['a', 'b', 'c']
            }
        },
        template: `
            <div>
                <slot v-for="item in myList">{{item}}</slot>
            </div>
        `
    });

結合之前學到的插槽知識,首先可能會想到這麼寫,父元件中使用 <span></span> 作為插槽內容,子元件中使用 slot 標籤渲染插槽

但這樣寫語法不對,沒有展示出 item 的內容

 

 

2.5 作用域插槽2

    const app = Vue.createApp({

        template:`
            <div>
                <my-list>
                    <span>{{item}}</span>
                </my-list>
            </div>
        `
    });

    app.component("my-list", {

        data() {
            return {
                myList: ['a', 'b', 'c']
            }
        },
        template: `
            <div>
                <slot v-for="item in myList"></slot>
            </div>
        `
    });

我們試著這樣寫,{{item}} 寫在父元件的插槽裡,很不幸,也不對,直接報警告

 

 

2.6 作用域插槽3

    const app = Vue.createApp({

        template:`
            <div>
                <my-list v-slot="slotAttrs" >
                    <span>{{slotAttrs.item}}</span>
                </my-list>
            </div>
        `
    });

    app.component("my-list", {

        data() {
            return {
                myList: ['a', 'b', 'c']
            }
        },
        template: `
            <div>
                <slot v-for="item in myList" :item="item" ></slot>
            </div>
        `
    });

這才是正確的寫法,先在子元件中使用屬性的方式(:item="item")將 item 傳給父元件

父元件使用 v-slot="slotAttrs" 接收子元件的所有變數,然後使用 {{slotAttrs.item}} 的方式將 item 的值渲染到 span 標籤中

 

 

2.7 直接得到 item

    const app = Vue.createApp({
        template:`
            <div>
                <my-list v-slot="{item}" >
                    <span>{{item}}</span>
                </my-list>
            </div>
        `
    });
    app.component("my-list", {

        data() {
            return {
                myList: ['a', 'b', 'c']
            }
        },
        template: `
            <div>
                <slot v-for="item in myList" :item="item" ></slot>
            </div>
        `
    });

我們可以使用 v-slot="{item}" 的方式,直接得到 item,效果一樣

 

3. 綜述

今天聊了一下 VUE3 的 作用域插槽的使用,希望可以對大家的工作有所幫助,下一節我們繼續講元件的相關知識,敬請期待

歡迎幫忙點贊、評論、轉發、加關注 :)

關注追風人聊Java,每天更新Java乾貨。

 

4. 個人公眾號

追風人聊Java,歡迎大家關注

相關文章