我們語法介紹的部分進入尾聲了,前一章在介紹component核心功能,及一些相關的功能寫法
今天介紹一下slot的概念吧!
slot
slot : 插槽,可以想像是在元件內預留一個空間,在父組件中的HTML或其他內容插入子組件中指定的位子。
slot能讓設定好的組件保持原有結構的前提下,可以彈性更改內容,也就是說我想達成組件有固定的外觀、結構等,又允許使用者能自訂內部內容時,就能使用slot。
範例
App.vue
<template>
<ChildComp>
<p>這段文字會被放到 ChildComp 的 slot 裡!</p>
</ChildComp>
</template>
父組件使用ChildComp組件,並在其中寫入一段標籤,這段標籤不是直接渲染父組件,而是傳遞到子組件的slot中。
ChildComp.vue
<template>
<div class="card">
<h2>這是子元件</h2>
<!-- 插槽 -->
<slot></slot>
</div>
</template>
子組件中有一段 <slot></slot>
,就像一個入口,讓父組件將傳來的內容放在這
最後會顯示「這段文字會被放到 ChildComp 的 slot 裡!」
如果<slot>
這段改成 <slot>Fallback content</slot>
設定slot的默認值
ChildComp.vue
<template>
<div class="card">
<h2>這是子元件</h2>
<!-- 插槽 -->
<slot>Fallback content</slot>
</div>
</template>
且父組件沒有傳任何內容時,則會顯示默認值「Fallback content」。
這裡稍微整理一下props、emits、slot
功能 | 資料流向 | 用途 | 適用情境 |
---|---|---|---|
props | 父->子 | 父組件傳資料給子組件 | 傳遞文字、數字、物件等資料 |
emits | 子->父 | 子組件觸發事件通知父組件 | 子元件回報狀態,例如表單送出、按鈕點擊 |
slot | 父->子(結構內容) | 父組件將HTML結構傳入子組件 | 建立彈性UI,例如卡片、彈跳視窗、版型 |
所以如果只是單純想傳資料文字等,可以使用props就好,不用一定要使用slot
這裡提供父組件用slot修改元件內容的範例
StudentCard.vue
<script setup>
import { defineProps } from 'vue';
// 定義一個可選的 prop: title,用來顯示卡片標題
defineProps({
title: {
type: String,
default: null
}
});
</script>
<template>
<div class="card">
<div v-if="title" class="card-header">
<h2>{{ title }}</h2>
</div>
<div class="card-body">
<slot></slot>
</div>
</div>
</template>
<style scoped>
/* 使用 scoped 確保樣式只影響這個元件 */
.card {
width: 300px;
border: 1px solid #e0e0e0;
border-radius: 8px;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
overflow: hidden;
margin: 20px;
background-color: white;
}
.card-header {
padding: 15px;
border-bottom: 1px solid #e0e0e0;
background-color: #f7f7f7;
}
.card-header h2 {
margin: 0;
font-size: 1.2em;
color: #333;
}
.card-body {
padding: 15px;
min-height: 80px; /* 確保內容區塊有最小高度 */
}
</style>
在StudentCard.vue先設定好card的樣式並預留空間,可以直接在App.vue進行內容修改
App.vue
// 導入你定義好的 Card 元件
import Card from './StudentCard.vue';
</script>
<template>
<h1>我的動態網頁</h1>
<div class="card-container">
<Card title="產品資訊">
<p>這是一個最新的手機型號。</p>
<p>價格:<strong>NT$ 19,999</strong></p>
</Card>
<Card title="個人檔案">
<img src="https://images.unsplash.com/photo-1741983139985-7fff27fffc3f?q=80&w=1740&auto=format&fit=crop&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D" alt="Profile Picture" class="profile-img">
<p>用戶 ID:101</p>
<button class="action-button">查看詳細</button>
</Card>
<Card>
<p>這是一個沒有標題的純內容卡片。</p>
</Card>
</div>
</template>
<style>
/* 這是 App.vue 的整體樣式 */
.card-container {
display: flex;
gap: 20px;
flex-wrap: wrap;
}
/* 範例二中使用的圖片和按鈕樣式 */
.profile-img {
width: 100%;
height: auto;
border-radius: 4px;
margin-bottom: 10px;
}
.action-button {
background-color: #42b983;
color: white;
border: none;
padding: 8px 15px;
border-radius: 4px;
cursor: pointer;
margin-top: 10px;
}
</style>
import Card from './StudentCard.vue';
記得要先在App.vue時先導入StudentCard.vue並命名為Card標籤
可直接在Card標籤中輸入內容或放置圖像。
顯示出的畫面會像這樣
好的基本介紹就到這裡結束,可喜可賀~
接下來我們來利用實際製作網頁
各位明天見~