作用域插槽
作用域插槽 提供元件的本地資料,以便父元件可以選擇如何渲染它。
將資料傳送給父元件
我們在元件的插槽中使用 v-bind
來將本地資料傳送給父元件。
SlotComp.vue
:
<template>
<slot v-bind:lclData="data"></slot>
</template>
<script>
export default {
data() {
return {
data: 'This is local data'
}
}
}
</script>
元件內部的資料可以被認為是“本地的”,因為除非將其傳送到父元件,否則父元件無法訪問它,就像我們這裡使用 v-bind
所做的那樣。
從作用域插槽接收資料
元件中的本地資料透過 v-bind
傳送,並且可以在父元件中使用 v-slot
接收。
示例
App.vue
:
<slot-comp v-slot:"dataFromSlot">
<h2>{{ dataFromSlot.lclData }}</h2>
</slot-comp>
執行示例 »
在上面的示例中,“dataFromSlot” 只是一個我們可以自己選擇的名稱,用來表示我們從作用域插槽接收到的資料物件。我們透過“lclData” 屬性獲取來自插槽的文字字串,並使用插值最終在一個 <h2>
標籤中渲染該文字。
帶陣列的作用域插槽
作用域插槽可以透過使用 v-for
來發送陣列資料,但 App.vue
中的程式碼基本相同。
示例
SlotComp.vue
:
<template>
<slot
v-for="x in foods"
:key="x"
:foodName="x"
></slot>
</template>
<script>
export default {
data() {
return {
foods: ['Apple','Pizza','Rice','Fish','Cake']
}
}
}
</script>
App.vue
:
<slot-comp v-slot="food">
<h2>{{ food.foodName }}</h2>
</slot-comp>
執行示例 »
帶物件陣列的作用域插槽
作用域插槽可以透過使用 v-for
來發送物件陣列的資料。
示例
SlotComp.vue
:
<template>
<slot
v-for="x in foods"
:key="x.name"
:foodName="x.name"
:foodDesc="x.desc"
:foodUrl="x.url"
></slot>
</template>
<script>
export default {
data() {
return {
foods: [
{ name: 'Apple', desc: 'Apples are a type of fruit that grow on trees.', url: 'img_apple.svg' },
{ name: 'Pizza', desc: 'Pizza has a bread base with tomato sauce, cheese, and toppings on top.', url: 'img_pizza.svg' },
{ name: 'Rice', desc: 'Rice is a type of grain that people like to eat.', url: 'img_rice.svg' },
{ name: 'Fish', desc: 'Fish is an animal that lives in water.', url: 'img_fish.svg' },
{ name: 'Cake', desc: 'Cake is something sweet that tastes good but is not considered healthy.', url: 'img_cake.svg' }
]
}
}
}
</script>
App.vue
:
<slot-comp v-slot="food">
<hr>
<h2>{{ food.foodName }}<img :src=food.foodUrl></h2>
<p>{{ food.foodDesc }}</p>
</slot-comp>
執行示例 »
來自作用域插槽的靜態資料
作用域插槽也可以傳送靜態資料,即不屬於 Vue 例項 data 屬性的資料。
傳送靜態資料時,我們不使用 v-bind
。
在下面的示例中,我們傳送了一個靜態文字,以及一個動態繫結到 data 例項的文字,這樣我們就可以看到區別。
示例
SlotComp.vue
:
<template>
<slot
staticText="This text is static"
:dynamicText="text"
></slot>
</template>
<script>
export default {
data() {
return {
text: 'This text is from the data property'
}
}
}
</script>
App.vue
:
<slot-comp v-slot="texts">
<h2>{{ texts.staticText }}</h2>
<p>{{ texts.dynamicText }}</p>
</slot-comp>
執行示例 »
命名作用域插槽
作用域插槽可以被命名。
要使用命名的作用域插槽,我們需要使用“name”屬性在元件內部命名插槽。
要接收來自命名插槽的資料,我們需要在父元件使用該元件的地方,透過 v-slot
指令或簡寫 #
來引用該名稱。
示例
在此示例中,元件被建立一次,引用插槽“leftSlot”,然後再次建立,引用插槽“rightSlot”。
SlotComp.vue
:
<template>
<slot
name="leftSlot"
:text="leftText"
></slot>
<slot
name="rightSlot"
:text="rightText"
></slot>
</template>
<script>
export default {
data() {
return {
leftText: 'This text belongs to the LEFT slot.',
rightText: 'This text belongs to the RIGHT slot.'
}
}
}
</script>
App.vue
:
<slot-comp #leftSlot="leftProps">
<div>{{ leftProps.text }}</div>
</slot-comp>
<slot-comp #rightSlot="rightProps">
<div>{{ rightProps.text }}</div>
</slot-comp>
執行示例 »
或者,我們可以只建立一次元件,使用兩個不同的 "template"
標籤,每個 "template"
標籤引用一個不同的插槽。
示例
在此示例中,元件只建立一次,但有兩個 "template"
標籤,每個標籤都引用一個不同的插槽。
SlotComp.vue
與前一個示例中的完全相同。
App.vue
:
<slot-comp>
<template #leftSlot="leftProps">
<div>{{ leftProps.text }}</div>
</template>
<template #rightSlot="rightProps">
<div>{{ rightProps.text }}</div>
</template>
</slot-comp>
執行示例 »