iT邦幫忙

2025 iThome 鐵人賽

DAY 13
0
Vue.js

從零開始的Vue之旅系列 第 13

語法介紹part-6-slot

  • 分享至 

  • xImage
  •  

我們語法介紹的部分進入尾聲了,前一章在介紹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標籤中輸入內容或放置圖像。
顯示出的畫面會像這樣
https://ithelp.ithome.com.tw/upload/images/20250925/20178690yMaIc5MTOP.png


好的基本介紹就到這裡結束,可喜可賀~
接下來我們來利用實際製作網頁
各位明天見~


上一篇
語法介紹Part5-components
下一篇
vue且試身手-簡易計數器
系列文
從零開始的Vue之旅16
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言