昨天我們把瓶子整理成了獨立的 GemJar.vue 元件。不過目前的「放入」按鈕非常單調,點下去只有數字 +1。生活每天都有不同起伏,有時候平靜、有時候雀躍,你可以自己定義每個顏色代表怎麼樣的心情,如果每一次採集,都能依照今天的心情挑選一個代表色,這個採集瓶就會有客製化的感覺。
今天我們要在按鈕上方加入一組「心情調色盤」,並學會 Vue 處理使用者互動的核心工具:v-on 與 @click 的參數傳遞。
在原生 JavaScript 裡,要讓按鈕感應用戶點擊,通常會寫 addEventListener('click', ...);但在 Vue 裡面,所有事件監聽都由 v-on 負責。
@就像 Day 6 學過 v-bind:class 簡寫成 :class 一樣,v-on:click 也有官方推薦的簡寫——@click:
<button v-on:click="addGem">放入</button>
<button @click="addGem">放入</button>
只要在 HTML 屬性前看到一個
@,就代表「當這個事件觸發時,請去執行指定的 JavaScript 動作」。
在 Day 4 寫的 addGem 函式中,我們不需要傳入任何資訊,因為它單純只做 count.value++:
<button @click="addGem">放入</button>
但如果畫面上有好幾個不同的心情顏色按鈕,點擊時函式就必須知道「使用者究竟點擊了哪一個顏色」。這時候就可以在括號裡傳入自訂參數:
<button @click="selectColor('#64B5F6')">平靜(藍)</button>
<button @click="selectColor('#E3B341')">驚喜(金)</button>
在 <script setup> 裡只要宣告對應的參數去接收它即可:
function selectColor(color) {
selectedColor.value = color
}
打開 src/components/GemJar.vue,進行以下三步驟的修改。
<script setup>:記錄當前選擇的心情顏色我們新增一個 selectedColor 變數來記錄目前挑選的顏色,預設先給溫暖的金色:
import { ref } from 'vue'
const count = ref(0)
const isGlowing = ref(false)
// 1. 記錄當前挑選的心情顏色(預設金黃)
const selectedColor = ref('#E3B341')
// 2. 切換顏色的函式
function selectColor(color) {
selectedColor.value = color
}
function addGem() {
count.value++
isGlowing.value = true
setTimeout(() => {
isGlowing.value = false
}, 1000)
}
<template>:加入心情代表色與動態按鈕在「已採集 X 顆光珠」與「放入」按鈕之間,加入四顆心情顏色圓點:
<!-- 瓶子維持原貌 -->
<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>
<!-- 新增:心情調色盤 -->
<div class="palette">
<button
class="color-dot blue"
:class="{ 'is-active': selectedColor === '#64B5F6' }"
@click="selectColor('#64B5F6')"
></button>
<button
class="color-dot gold"
:class="{ 'is-active': selectedColor === '#E3B341' }"
@click="selectColor('#E3B341')"
></button>
<button
class="color-dot pink"
:class="{ 'is-active': selectedColor === '#F48FB1' }"
@click="selectColor('#F48FB1')"
></button>
<button
class="color-dot green"
:class="{ 'is-active': selectedColor === '#81C784' }"
@click="selectColor('#81C784')"
></button>
</div>
<!-- 採集按鈕:讓底色跟著當前選中的顏色改變,提示使用者準備放入的色調 -->
<button
class="btn-collect"
:style="{ backgroundColor: selectedColor }"
@click="addGem"
>
放入這道微光
</button>
<style scoped>:心情代表色與按鈕樣式在底部加上心情代表色排版,以及選中時的視覺回饋:
/* 調色盤排版 */
.palette {
display: flex;
gap: 12px;
margin: 12px 0 16px 0;
}
/* 心情代表色 */
.color-dot {
width: 22px;
height: 22px;
border-radius: 50%;
border: 2px solid transparent;
cursor: pointer;
transition: transform 0.2s ease, border-color 0.2s ease;
}
/* 各別顏色定義 */
.color-dot.blue { background-color: #64B5F6; }
.color-dot.gold { background-color: #E3B341; }
.color-dot.pink { background-color: #F48FB1; }
.color-dot.green { background-color: #81C784; }
/* 當前被選中的心情代表色 */
.color-dot.is-active {
border-color: #ffffff;
transform: scale(1.25);
}
/* 採集按鈕樣式 */
.btn-collect {
padding: 8px 20px;
border: none;
border-radius: 20px;
color: #1a1a1a;
font-weight: bold;
cursor: pointer;
transition: background-color 0.3s ease, transform 0.1s ease;
}
.btn-collect:active {
transform: scale(0.96);
}

這邊有幾點要確認:
這三點都有達成的話,就能確定新增的功能和前面的舊功能都有完整呈現。
今天我們將心情調色盤設計出來了,也成功串接功能,採集瓶的功能已經做完一大部分了!
明天(Day 9)我們將要做出「文字輸入框」,讓使用者可以將每日的小小美好以實質文字型態留下來~