組件的插槽 (Slots)
在 Vue 3 中,插槽 (Slots) 是用來讓父組件向子組件傳遞內容的一種方式。透過插槽,父組件可以將自定義的 HTML 內容插入到子組件的指定位置,從而使得子組件能夠更靈活地展示和渲染內容。插槽為組件提供了一種擴展性,使得組件在不同的場景中能夠重複利用。
1. 什麼是插槽?
插槽是 Vue 中的一種內容分發方式。父組件可以通過插槽向子組件插入 HTML 結構或其他模板內容,子組件預留特定的位置來顯示這些內容。插槽可以像占位符一樣,允許父組件根據需求向子組件提供動態內容。
2. 基本插槽 (Default Slots)
最基本的插槽是 默認插槽。這意味著父組件可以將內容插入子組件中,而子組件可以通過 <slot>
元素來顯示該內容。
範例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<div id="app">
<!-- 父組件 -->
<child-component>
<p>This is the content from the parent.</p>
</child-component>
</div>
<script>
const app = Vue.createApp({
components: {
'child-component': {
template: `
<div>
<h2>This is the child component</h2>
<slot></slot> <!-- 插槽,用來展示父組件傳入的內容 -->
</div>
`
}
}
});
app.mount('#app');
</script>
在這個範例中:
- 父組件:傳遞了一段 HTML (
<p>...</p>
) 給子組件。 - 子組件:使用
<slot></slot>
元素來接收和顯示父組件傳遞的內容。
結果是:
1
2
This is the child component
This is the content from the parent.
這個插槽在子組件的 <slot>
標籤位置插入了父組件提供的內容。
3. 具名插槽 (Named Slots)
有時候,我們希望在子組件中插入多個不同位置的內容,這時可以使用 具名插槽。具名插槽允許父組件針對不同的插槽提供不同的內容,這樣可以靈活控制不同位置的顯示。
具名插槽的使用步驟:
- 在子組件中定義具名插槽,使用
<slot name="slotName"></slot>
。 - 在父組件中傳入對應的插槽內容,使用
<template v-slot:slotName>
或v-slot
簡寫。
範例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<div id="app">
<!-- 父組件 -->
<child-component>
<template v-slot:header>
<h1>This is the header</h1>
</template>
<template v-slot:footer>
<p>This is the footer</p>
</template>
</child-component>
</div>
<script>
const app = Vue.createApp({
components: {
'child-component': {
template: `
<div>
<slot name="header"></slot> <!-- 具名插槽:header -->
<p>This is the main content of the child component.</p>
<slot name="footer"></slot> <!-- 具名插槽:footer -->
</div>
`
}
}
});
app.mount('#app');
</script>
在這個範例中:
- 父組件向子組件的
header
和footer
具名插槽插入了不同的內容。 - 子組件定義了兩個具名插槽,並根據傳遞進來的內容來渲染。
結果是:
1
2
3
This is the header
This is the main content of the child component.
This is the footer
4. 作用域插槽 (Scoped Slots)
作用域插槽 是一種進階的插槽功能,允許子組件將數據傳遞回父組件,這樣父組件可以根據這些數據來動態渲染內容。通過作用域插槽,父組件不僅可以插入內容,還可以根據子組件提供的數據來控制內容的顯示。
如何使用作用域插槽:
- 在子組件中,通過
<slot>
元素傳遞一些數據給父組件。 - 父組件可以使用
v-slot
來接收這些數據,並根據數據動態渲染。
範例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<div id="app">
<!-- 父組件 -->
<child-component v-slot="slotProps">
<p></p>
</child-component>
</div>
<script>
const app = Vue.createApp({
components: {
'child-component': {
template: `
<div>
<slot :text="message"></slot> <!-- 子組件將 message 傳遞給插槽 -->
</div>
`,
data() {
return {
message: 'Hello from child component!'
};
}
}
}
});
app.mount('#app');
</script>
在這個範例中:
- 子組件:使用
<slot :text="message"></slot>
將message
這個數據傳遞給插槽。 - 父組件:使用
v-slot="slotProps"
接收插槽內傳遞的數據,並顯示出來。
結果是:
1
Hello from child component!
這樣父組件可以根據子組件的數據動態改變插槽內的內容。
5. 默認內容
插槽也可以有默認內容,當父組件沒有提供插槽內容時,子組件會顯示默認的內容。如果父組件提供了內容,則默認內容會被覆蓋。
範例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<div id="app">
<!-- 父組件不提供內容時顯示默認內容 -->
<child-component></child-component>
</div>
<script>
const app = Vue.createApp({
components: {
'child-component': {
template: `
<div>
<slot>This is the default content if nothing is provided.</slot>
</div>
`
}
}
});
app.mount('#app');
</script>
結果是:
1
This is the default content if nothing is provided.
如果父組件不傳遞任何內容,子組件會顯示插槽內的默認文字。如果父組件傳入內容,則會覆蓋默認內容。
6. 具名作用域插槽 (Scoped Named Slots)
具名插槽和作用域插槽可以結合在一起使用,這樣可以在不同的具名插槽中傳遞不同的數據,讓父組件能夠根據子組件提供的數據動態渲染不同區域的內容。
範例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
<div id="app">
<child-component>
<template v-slot:header="slotProps">
<h1></h1>
</template>
<template v-slot:footer="slotProps">
<p></p>
</template>
</child-component>
</div>
<script>
const app = Vue.createApp({
components: {
'child-component': {
template: `
<div>
<slot name="header" :title="headerTitle"></slot>
<p>Main content here.</p>
<slot name="footer" :info="footerInfo"></slot>
</div>
`,
data() {
return {
headerTitle: 'Welcome to the header!',
footerInfo: 'This is the footer information.'
};
}
}
}
});
app.mount('#app');
</script>
在這個範例中:
- 子組件有具名插槽
header
和footer
,並且向每個插槽傳遞了不同的數據(headerTitle
和footerInfo
)。 - 父組件根據子組件提供的數據來渲染具名插槽內的內容。
結果是:
1
2
3
Welcome to the header!
Main content here.
This is the footer information.
7. 多插槽 (Multiple Slots)
Vue 3 中,子組件可以有多個插槽,這讓組件的內容更加靈活。每個插槽可以根據具名來插入不同的內容,並且支持動態數據傳遞。
總結
- 插槽 (Slots) 是用來在 Vue 組件中分發和顯示內容的機制,允
許父組件向子組件插入自定義內容。
- 默認插槽 用於插入不具名的內容,具名插槽 則允許插入特定區域的內容。
- 作用域插槽 提供了更強大的功能,允許子組件向父組件傳遞數據,從而讓父組件根據數據動態渲染內容。
- 具名作用域插槽 結合了具名插槽與作用域插槽,讓多插槽模式更加靈活。
插槽使得組件的可重用性和靈活性更高,適用於各種動態模板設計場景。