Vue中使用插槽

July-Y發表於2021-09-22

什麼是插槽

插槽就是子元件中的提供給父元件使用的一個佔位符,用 表示,父元件可以在這個佔位符中填充任何模板程式碼,如 HTML、元件等,填充的內容會替換子元件的標籤。

基本使用

編寫一個父元件

<!DOCTYPE html><html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Demo</title>
    <script src="https://unpkg.com/vue@next"></script>
</head>
<body>
    <div id="app"></div>
</body>
<script>
    const app = Vue.createApp({
        template: ` <h2>父元件</h2>`
    })

    const vm = app.mount("#app")
</script>
</html>

再寫一個子元件

app.component('son', {
    template: `
        <div>
            <h3>子元件</h3>
        </div>
    `
})

父元件呼叫子元件

const app = Vue.createApp({
        template: ` <h2>父元件</h2><son />`
    })

插槽如何使用呢?只需要在子元件中加入<slot></slot>,然後在父元件中使用。

app.component('son', {
    template: `
        <div>
            <h3>子元件</h3>
            <slot></slot>
        </div>
    `
})
const app = Vue.createApp({
        template: ` <h2>父元件</h2><son>這是父元件要在子元件中顯示的內容</son>`
    })

執行效果:

父元件
子元件
這是父元件要在子元件中顯示的內容

插槽支援任何DOM元素,比如我們新增style樣式

const app = Vue.createApp({
template: ` <h2>父元件</h2><son><div style="color:red;font-size:25px">這是父元件要在子元件中顯示的內容</div></son>`
    })

預設插槽

我們如果需要子元件在任何情況下,都能渲染文字。我們可以將預設文字放在標籤內:

app.component('son', {
    template: `
        <div>
            <h3>子元件</h3>
            <slot>子元件的預設內容</slot>
        </div>
    `
})

現在使用父元件去呼叫:

const app = Vue.createApp({
template: ` <h2>父元件</h2><son/>`
    })

執行效果:

父元件
子元件
子元件的預設內容

具名插槽

有的時候,我們一個子元件需要多個插槽,例如:

app.component('son', {
    template: `
        <div>
            <h3>公民基本資訊</h3>
            <slot>
                <!--姓名-->
            </slot>
            <slot>
                <!--年齡-->
            </slot>
            <slot>
               <!--性別-->
            </slot>
        </div>
    `
})

像這種情況,<slot> 有一個特殊的屬性name

app.component('son', {
    template: `
        <div>
            <h3>公民基本資訊</h3>
            <slo name="name">
                姓名
            </slot>
            <slot name="age">
                年齡
            </slot>
            <slot name="sex">
               性別
            </slot>
        </div>
    `
})

如何使用呢?很簡單隻需要在DOM元素上,使用v-slot註明使用的插槽名稱:

const app = Vue.createApp({
template: `
    <h2>父元件</h2>
    <son>
        <template v-slot:name>小明</template>
        <template v-slot:age>7</template>
        <template v-slot:sex>男</template>
    <son/>
`
    })

執行效果:

父元件
公民基本資訊
小明7

v-slot:name這種語法可以簡寫成#name,程式碼如下:

const app = Vue.createApp({
template: `
    <h2>父元件</h2>
    <son>
        <template #name>小明</template>
        <template #age>7</template>
        <template #sex>男</template>
    <son/>
`
    })

注:只要出現多個插槽,所有的插槽使用完整的基於 <template> 的語法。

插槽的作用域

有時讓插槽內容能夠訪問子元件中才有的資料是很有用的。
寫一個子元件:

const app = Vue.createApp({
data(){    
    return {        
                list:['A','B','C']    
            }
},
template: `<div v-for="item in list">{{item}}</div>`
})

父元件想使用子元件插槽中的值,可以使用:繫結的形式進行傳遞,比如寫成:item="item",具體的程式碼可以寫成下面的樣子。

const app = Vue.createApp({
data(){    
    return {        
                list:['A','B','C']    
            }
},
template: `
        <div>
            <slot v-for="item in list" :item="item" />    
        </div>`
})

寫完後父元件中用v-slot="xxx"的形式接受,接收後就可以使用了

const app = Vue.createApp({
    template: `  
    <list v-slot="props"> 
        <span>{{props.item}}</span> 
    </list>
`

注意這裡的props是子元件傳遞過來的資料都是物件,但你也可以使用任意你喜歡的名字。

本作品採用《CC 協議》,轉載必須註明作者和本文連結

相關文章