iT邦幫忙

2026 iThome 鐵人賽

DAY 7
0
Modern Web

微光採集瓶:用 Vue 3 打造每日美好記錄網頁系列 第 7 篇

【Day 7】 元件化拆分:整理 App.vue,新建 GemJar.vue

  • 分享至 

  • xImage
  •  

雖然我們的畫面還沒有很完整,但程式碼在後面只會越來越多,所以趁今天我們要來進行元件拆分,整理一下整個專案的結構。

一、什麼是元件?為什麼要拆?

你可以把 App.vue 想像成一個「主控台」,原本所有的畫面、邏輯、樣式,都塞在這一個檔案裡自己處理。而「元件化」的概念,就是把某一塊完整的功能,獨立拆成一個自己的檔案,變成一個可以被呼叫、被組裝的「零件」——主控台只需要負責「引入這個零件、把它放到畫面上」,不用所有東西都塞在同一個地方。

這樣做的好處是:檔案不會越長越亂,而且如果之後某個功能壞了,就可以直接去對應的元件檔案裡找問題,不用在一個超長的檔案裡大海撈針。

接下來,我們就實際動手,把瓶子相關的部分,拆成一個獨立的元件吧!

二、建立 GemJar.vue

在 src/components/ 資料夾底下,新增一個檔案 GemJar.vue,把原本 App.vue 裡跟「瓶子」相關的東西,整段搬過來:

<script setup>
import { ref } from 'vue'

const count = ref(0)
const isGlowing = ref(false)

function addGem() {
  count.value++
  isGlowing.value = true

  setTimeout(() => {
    isGlowing.value = false
  }, 1000)
}
</script>

<template>
  <div class="bottle-wrapper">
    <div class="cork"></div>
    <div class="bottle" :class="{ 'is-glowing': isGlowing }">
      <span v-if="count === 0">瓶子目前是空的</span>
    </div>
  </div>

  <p>已採集 {{ count }} 顆光珠</p>
  <button @click="addGem">放入</button>
</template>

<style scoped>
.bottle-wrapper {
  display: flex;
  flex-direction: column;
  align-items: center;
  margin: 16px 0;
}

/* 軟木塞 */
.cork {
  width: 40px;
  height: 12px;
  background-color: #a07855;
  border-radius: 3px;
}

/* 瓶身 */
.bottle {
  width: 160px;
  height: 220px;
  border: 2px solid rgba(255, 255, 255, 0.3);
  background: rgba(255, 255, 255, 0.04);
  border-radius: 12px 12px 40px 40px;
  display: flex;
  align-items: center;
  justify-content: center;
  color: #6e7681;
  font-size: 0.85rem;
  transition: border-color 1.0s ease, box-shadow 1.0s ease;
}

.bottle.is-glowing {
  border-color: rgba(227, 179, 65, 0.95);
  box-shadow: 0 0 24px rgba(227, 179, 65, 0.5);
}
</style>

「已採集 X 顆光珠」跟「放入」按鈕,也一起搬過來了。因為這兩個東西的功能(顯示採集數量、觸發採集動作),本質上都是屬於「瓶子」這個角色在做的事,所以一起歸類進 GemJar.vue 比較合理。

三、App.vue 整理

回到 App.vue,把剛剛搬走的部分整個刪掉,改成引入並使用剛剛建立好的 GemJar 元件:

<script setup>
import GemJar from './components/GemJar.vue'
</script>

<template>
  <main class="bottle-app">
    <h1>微光採集瓶</h1>
    <p class="subtitle">在每一天的最後,採集一道微小的美好</p>

    <GemJar />
  </main>
</template>

<style scoped>
.bottle-app {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  min-height: 100vh;
  text-align: center;
  gap: 12px;
}
</style>

App.vue 現在的工作已剩下:1. 引入元件 2. 放標題文字 3. 置中排版。

存檔後重新整理瀏覽器,畫面應該要跟 Day6 完全一樣,沒有任何視覺上的變化。如果有變化(例如瓶子不見了、樣式跑掉),代表搬動過程中漏了某段程式碼,可以對照上面兩段檢查一下。

明日預告

瓶子現在有專門管理自己的地方了。明天(Day 8),我們要幫採集動作加上一個新功能——選擇一種代表今天心情的顏色,並趁機學習 v-on 與 @click,讓瓶身可以真正「聽懂」你的點擊。


上一篇
【Day 6】v-bind 動態綁定:讓瓶身回應你的動作
下一篇
【Day 8】 為今日心情選一個代表色!事件處理 v-on 與 @click
系列文
微光採集瓶:用 Vue 3 打造每日美好記錄網頁 共 19 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言