iT邦幫忙

2026 iThome 鐵人賽

DAY 6
0
Modern Web

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

【Day 6】v-bind 動態綁定:讓瓶身回應你的動作

  • 分享至 

  • xImage
  •  

延續 Day 5 留在 App.vue 裡的採集瓶初步設計,今天的主要任務就是把資料(Vue 的 JS 狀態)跟畫面(CSS)用 v-bind 接上線。

我希望在使用者採集光珠時,瓶身有「亮起來」的效果,不過在開始實作之前,先來看看v-bind到底是什麼吧!

什麼是 v-bind?它的功能是……?

在 Day 4 我們學到的雙大括號{{ }}可以把文字印在畫面上,但他只能用在 HTML 標籤夾住的「內容文字」:

<p>{{ count }}</p>

如果我們想要改變的是 HTML 標籤本身的「屬性」(例如 class、src、id),就不能在屬性引號裡放雙大括號,這樣寫是無效的:

(錯誤寫法:屬性內無法直接解析雙大括號)
<div class="{{ className }}"></div>

若要讓標籤的屬性動態讀取 JavaScript 裡的資料,就必須使用 Vue 提供的指令:v-bind。

簡寫方式:直接加冒號 :

v-bind 的作用,是把 HTML 屬性轉成可執行 JavaScript 表達式的動態屬性。

因為這個指令非常頻繁被使用,Vue 提供了最常見的簡寫方式——直接省略 v-bind,只保留一個冒號 ::

  • 完整寫法:<div v-bind:class="...">
  • 簡寫寫法:<div :class="...">

只要看到屬性前面帶有冒號 :,就代表引號裡面的內容不再是純字串,而是會被當成 JavaScript 程式碼來處理。

:class 的物件語法

在動態切換樣式時,最常用的是 :class 的物件語法,結構如下:

:class="{ 'class名稱': 條件判斷式 }"

運作邏輯非常直觀:

  • 當條件為 true:Vue 會自動在元素上加上該 class。
  • 當條件為 false:Vue 會自動移除該 class。

在了解 v-bind 的定義後就來實際運用看看吧~

定義發光狀態與樣式(:class 物件語法)

在開始打程式碼之前,先想一想:「採集光珠時,瓶身有「亮起來」的效果」,可以怎麼轉換成程式碼邏輯?應該是:「當光珠數量大於 0 時,瓶身有一個可以發光的 class 被呈現」。

一、在 <template> 綁定 class

找到原本的 <div class="bottle">,改寫成:

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

二、在 <style scoped> 加上發光樣式

/* 原本的 .bottle 維持不變 */

/* 當 count > 0 時,自動疊加發光效果 */
.bottle.is-glowing {
  border-color: rgba(227, 179, 65, 0.8); /* 邊框變金黃色 */
  box-shadow: 0 0 15px rgba(227, 179, 65, 0.25); /* 外光暈 */
  transition: all 0.5s ease; /* 光芒緩慢亮起 */
}

此時點擊「採集」按鈕讓 count 從 0 變成 1,看原本的灰色線條是否亮起來。

成果畫面

https://ithelp.ithome.com.tw/upload/images/20260920/20178067gRQuWYYRYX.png

調整細節

我前面做完發現這還不是我理想成果,所以接下來要做一些調整。

  • 原本(維持常亮):count > 0 只要為 true,瓶身就一直亮著,不再重新觸發動畫。
  • 理想(每次重新亮起):每次點擊時把開關設為 true,等 CSS 動畫跑完,再自動設回 false,清掉 Class。下次再放入光珠時,Class 重新被貼上,動畫就會再次播放。

一、<script setup>:新增暫時開關與重置計時器

import { ref } from 'vue'

const count = ref(0)
const isGlowing = ref(false) // 記錄「目前是否正在發光」

function addGem() {
  count.value++

  // 1. 每次新增光珠時,開啟發光狀態
  isGlowing.value = true

  // 2. 1秒後,自動關閉狀態、移除 class
  setTimeout(() => {
    isGlowing.value = false
  }, 1000)
}

二、<template>:把 :class 改綁在暫態變數上

將原本依賴數值大小的判斷,換成看 isGlowing 是否為 true:

<!-- 找到原本的 .bottle,加上 :class 動態綁定 -->
<div class="bottle" :class="{ 'is-glowing': isGlowing }">
  <span v-if="count === 0">瓶子目前是空的</span>
</div>

三、<style scoped>:改用 transition 做出光芒漸亮漸暗

不要用單純的固定顏色,改用動畫讓它有「緩緩亮起 ➜ 緩緩暗回原樣」的效果:

/* 原本的 .bottle 維持不變,但加上transition,讓狀態切換時有漸變效果 */
.bottle {
  transition: border-color 1.0s ease, box-shadow 1.0s ease;
}

/* 當 is-glowing 出現時,套用發光樣式 */
.bottle.is-glowing {
  border-color: rgba(227, 179, 65, 0.95);
  box-shadow: 0 0 24px rgba(227, 179, 65, 0.5);
}
</style>

做完後就可以去試看看畫面上的玻璃瓶瓶身,是否真的會跟著「放入光珠」的動作而有發光的效果!

明日預告

經過這兩天的學習,程式碼越來越多,看起來是不是有點眼花呢?
Day 7 我們就要來進行元件拆分,整理一下專案結構!


上一篇
【Day 5 】認識 <style scoped> 與刻出採集瓶輪廓
下一篇
【Day 7】 元件化拆分:整理 App.vue,新建 GemJar.vue
系列文
微光採集瓶:用 Vue 3 打造每日美好記錄網頁 共 20 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言