還記得昨天我們拆解了 .vue 檔案的三個區塊嗎?如果像昨天一樣只是把畫面寫死、只能看到固定的字,那不是很無聊嗎?所以今天我們要正式讓 <script setup> 這個負責邏輯運算的區塊動起來:讓一個數字,可以因為你的點擊而改變,並且畫面會自動跟著更新。
但在這之前,我們要先學會 Vue 最基本的一個能力——把 JavaScript 的資料,印到畫面上。
學會了它,我們才有辦法在後面的段落裡,讓資料真的「動」起來。這個能力,靠的就是 Vue 裡最簡單、也最常出現的語法:雙大括號 {{ }}。
{{ }}在 App.vue 檔案裡輸入以下程式碼:
<script setup>
const subtitle = '在每一天的最後,採集一道微小的美好'
</script>
<template>
<p>{{ subtitle }}</p>
</template>
你會看到那一行字出現在頁面左上角。
這段程式碼做的事很簡單:
<script setup> 裡,我們用 JavaScript 定義了一個叫 subtitle 的字串變數,內容是 '在每一天的最後,採集一道微小的美好'。<template> 裡,我們寫了 <p>{{ subtitle }}</p>,用雙大括號把 subtitle 這個變數的值,印到畫面上。{{ }}?因為如果你直接寫 <p>subtitle</p>,網頁上只會直接印出英文字母 ”subtitle”;但加上了雙大括號 {{ subtitle }},Vue 就知道:「這不是純英文字,請去幫我把上面定義好的變數內容抓下來印出來!」
可以自己試試看輸入沒有雙大括號的版本,看看是不是只會印出一個英文單字。
小提示
如果你有開編輯器的 AI 輔助(如 Copilot),它會在你按下 Enter 的瞬間默默在底下飄出一行綠色提示:「你上面明明宣告了變數,這裡應該加上雙大括號
{{ subtitle }}!」
(如圖)
到目前為止,我們只學會了「把資料印出來」,但如果這個資料會改變呢?比如說,我們想做一個按鈕,每按一次,旁邊的數字就加一,這正是我們今天最終想做出來的「採集按鈕」。
先來做個小實驗。把程式碼改成這樣:
<script setup>
let count = 0
function addGem() {
count++
console.log(count) // 先用 console 確認數字有沒有真的在變
}
</script>
<template>
<p>已採集 {{ count }} 顆光珠</p>
<button @click="addGem">採集</button>
</template>
打開瀏覽器的開發者工具,切到 Console,按下按鈕,你會看到 Console 裡的數字確實一直往上跳(1、2、3...),代表 count 這個變數真的有在改變。
奇怪的是,畫面上的「已採集 0 顆光珠」,卻完全沒有動,還是停在 0。
這是為什麼?因為 Vue 在畫面第一次出現的那一刻,只會把 count 的值(也就是 0)印上去,之後即使 count 這個變數在背後偷偷改變了,Vue 並不知道「喔,這個值變了,我要重新印一次畫面」——普通的 JavaScript 變數,跟畫面之間,其實是沒有任何連結的。
這時候,就輪到今天真正的主角登場了:ref()。
ref ()要讓 Vue「知道」資料變了、該回去更新畫面,我們需要把普通變數包裝成一種特殊的「響應式」資料,這正是 ref() 的工作。
把剛剛的程式碼改成這樣:
<script setup>
import { ref } from 'vue'
const count = ref(0)
function addGem() {
count.value++
console.log(count.value)
}
</script>
<template>
<p>已採集 {{ count }} 顆光珠</p>
<button @click="addGem">採集</button>
</template>
對照剛剛的版本,有哪些地方不一樣呢?
import { ref } from 'vue'——先跟 Vue 借用 ref 這個工具。const count = ref(0)——不再是普通變數,而是用 ref() 把 0 包起來,變成一個 Vue 看得懂、會主動追蹤的「響應式資料」。count.value++——注意這裡多了 .value。ref() 包出來的東西,其實是一個物件(可以想成一個小箱子),真正的值放在 .value 裡面,所以在 <script setup> 裡要改值,一定要透過 .value 才能真正碰到裡面的內容。有一個規則要記住:
<script setup>裡要寫count.value才能存取或修改值;
但在<template>裡,直接寫{{ count }}就好,不用加.value。這是因為 Vue 有一個內建規則:只要這個 ref 是直接寫在 最外層的變數(術語上稱為「頂層>屬性」),在 裡使用時,Vue 編譯器就會自動幫你補上 .value,不用你手動處理。
現在再按一次按鈕,畫面上的數字應該要跟著跳動了。這就是 ref() 的功勞:只要資料改變,Vue 會自動把畫面更新成最新的樣子,你完全不用自己動手操作 DOM。
今天我們學到了:
{{ }}如何將資料印到畫面上。ref ( )怎麼讓 Vue 知道資料有變更,並同步到畫面上。Day 05 我們將正式進入 <style scoped> 的世界,讓最重要的採集瓶出現在畫面上!