本文為 留言評分功能 系列教學,第 5 篇:
- 使用 Django + Tailwind + Alpine.js 實作「五顆星評分」功能教學
- Django validators 驗證器完整教學
- Django PositiveSmallIntegerField 新手指南
- 在 esbuild 專案中整合 Alpine.js 的完整指南
- 使用 Alpine.js 建立星星評分表單 — 新手指南 👈 所在位置
- 深入理解 Alpine.js 中的 template 標籤使用指南
- Django 網站如何新增「星星評分」功能 — 後端接收邏輯
- Django 表單:如何讓使用者選擇性提交星星評分與留言
- Django 如何限制同一使用者只能對同一服務留言一次?
- Django 留言軟刪除邏輯|程式碼解析
- Django 計算評分摘要教學 — 使用 ORM 進行星等統計
- Python Django 使用 annotate、aggregate 統計教學
- 使用 Alpine.js 實作星級評分分佈 – 詳細教學
- Alpine.js 與 Tailwind CSS 動態樣式解析:為什麼有些樣式無法生效?
- Django 中使用 annotate() 與 Avg() 進行平均評分計算
本教學將介紹如何使用 Alpine.js 建立一個互動式的 星星評分表單,並搭配 Tailwind CSS 進行美化。
這是一個針對新手的逐步教學,將完整解析每個核心概念,幫助你理解如何透過 Alpine.js 管理前端互動邏輯,適用於靜態網站與簡單的互動介面需求。
建立星星評分表單的範例
以下是一個使用 Alpine.js 與 Tailwind CSS 建立的互動式星星評分表單範例:
<form method="POST" class="mt-6" x-data="{ rating: 0 }">
{% csrf_token %}
<!-- 星星評分區 -->
<div class="flex space-x-2 cursor-pointer">
<template x-for="n in 5">
<button
type="button"
class="star text-3xl focus:outline-none"
:class="n <= rating ? 'text-yellow-400' : 'text-gray-400'"
@click="rating = n"
>
★
</button>
</template>
</div>
<input type="hidden" name="rating" x-model="rating">
<!-- 提交按鈕 -->
<button type="submit" class="bg-blue-600 text-white px-4 py-2 rounded-lg hover:bg-blue-700">
提交評分
</button>
</form>
x-data:建立反應性資料
x-data="{ rating: 0 }"x-data:用於初始化一個反應性資料物件,這裡的rating變數會保存使用者選擇的星星數值rating:初始為 0,當用戶點擊星星時,這個數值將被即時更新
星星評分 (x-for 與 @click)
在使用 Alpine.js 建立星星評分系統時,主要的互動邏輯透過三個核心指令完成:
x-for="n in 5":產生 5 個星星按鈕:class:根據rating變數的值動態切換星星顏色@click="rating = n":點擊星星時更新rating變數
x-for="n in 5":產生五顆星星的按鈕
範例:
<template x-for="n in 5">
<button type="button">
★
</button>
</template>解析
x-for="n in 5":使用x-for產生 5 個星星,n代表 1 到 5 的每個數字- 這五個星星按鈕會分別渲染在畫面上
效果 (HTML 渲染結果)
<button>★</button>
<button>★</button>
<button>★</button>
<button>★</button>
<button>★</button>:class — 動態綁定星星顏色
範例:
<button
:class="n <= rating ? 'text-yellow-400' : 'text-gray-400'"
>
★
</button>
解析
:class是 Alpine.js 提供的 動態綁定 CSS 樣式語法- 使用 三元運算子:
- 如果
n <= rating,星星變為黃色 (text-yellow-400) - 如果
n > rating,星星變為灰色 (text-gray-400)
- 如果
範例情境 (當 rating = 3 時):
<button class="text-yellow-400">★</button> <!-- 黃色 -->
<button class="text-yellow-400">★</button> <!-- 黃色 -->
<button class="text-yellow-400">★</button> <!-- 黃色 -->
<button class="text-gray-400">★</button> <!-- 灰色 -->
<button class="text-gray-400">★</button> <!-- 灰色 -->
@click="rating = n" — 點擊星星時更新分數
範例:
<button
@click="rating = n"
:class="n <= rating ? 'text-yellow-400' : 'text-gray-400'"
>
★
</button>
解析
@click="rating = n":當用戶點擊星星時,將rating變數更新為該顆星星的數字 (n)- 點擊第三顆星時,
rating變為3,即前三顆星星變為黃色
完整流程圖解 (ASCII)
以下是完整的 星星評分系統 的邏輯流程圖,模擬了星星如何根據 rating 變數動態更新顏色。
初始化:
rating = 0
────────────────────────
★(灰) ★(灰) ★(灰) ★(灰) ★(灰)
使用者點擊第三顆星:
@n=3 → rating = 3
────────────────────────
★(黃) ★(黃) ★(黃) ★(灰) ★(灰)
判斷流程:
for n in 5
├── 如果 n <= rating (3)
│ └── 顯示黃色星星 (text-yellow-400)
│
├── 如果 n > rating (3)
│ └── 顯示灰色星星 (text-gray-400)
隱藏欄位 (input[type=hidden])
<input type="hidden" name="rating" x-model="rating">這個 <input> 元素的主要功能是透過 Alpine.js 的 x-model 綁定一個名為 rating 的變數,並在表單提交時,將其目前的數值傳送到伺服器。
x-model 是什麼?
x-model 是 Alpine.js 提供的 雙向資料綁定 (two-way binding) 指令。
它的主要功能是:
- 自動同步前端的變數與表單欄位的值。
- 使用者互動時自動更新變數。
- 變數更新時自動反映到 UI 上的欄位值。
x-model 與 value 的比較
value 屬性 (靜態屬性)
value 是 HTML 原生的屬性,用於設定表單元素的初始值,但它是 靜態的,不會隨使用者互動而自動更新。
<input type="text" name="username" value="Alice">限制:
- 無法隨使用者輸入自動更新
- 必須透過 JavaScript 手動更新
x-model (雙向綁定)
x-model 是 Alpine.js 提供的雙向綁定指令,它會將 前端變數 與 表單元素的值 綁定在一起,確保雙方同步更新。
<input type="text" x-model="username">優勢:
- 使用者輸入時,
username變數會自動更新 - 變數變更時,輸入框的值也會同步更新
- 適用於即時互動的場景,如星星評分、表單驗證等
核心差異比較
為什麼 x-model 更適合互動表單?
✅ 靜態 value
<input type="text" name="username" value="Alice">- 頁面載入時,輸入框顯示
"Alice" - 如果使用者修改輸入內容,
value不會自動更新變數
✅ 使用 x-model
<div x-data="{ username: 'Alice' }">
<input type="text" x-model="username">
<p>目前輸入:<span x-text="username"></span></p>
</div>- 頁面載入時,
username被設定為"Alice" - 使用者修改輸入時,
username變數即時更新 <span>也會即時顯示更新後的值
互動流程 (數值變化)
初始狀態: rating = 0
<input type="hidden" name="rating" value="0">
→ 使用者點擊第3顆星
→ rating 變成 3
<input type="hidden" name="rating" value="3">
→ 使用者點擊第5顆星
→ rating 變成 5
<input type="hidden" name="rating" value="5">
input 傳送的值到底是什麼?
input 傳送的值 就是當下 rating 變數的數值。
具體表單行為
當你點擊提交按鈕 (type="submit"),表單會將 當前的 rating 數值 傳送到伺服器,格式如下:
POST /submit/
rating=3後端如何接收?
假設你的後端使用 Django,伺服器端可以這樣取得 rating 的數值:
def submit_rating(request):
rating = request.POST.get('rating')
print(f"使用者的評分為: {rating}")
完整流程圖
以下是完整的 星星評分互動邏輯,展示了 x-model="rating" 與 <input> 之間的同步關係。
1. 頁面載入 → rating = 0
──────────────────────────
畫面:★(灰) ★(灰) ★(灰) ★(灰) ★(灰)
<input type="hidden" name="rating" value="0">
2. 使用者點擊第三顆星 → rating = 3
──────────────────────────
畫面:★(黃) ★(黃) ★(黃) ★(灰) ★(灰)
<input type="hidden" name="rating" value="3">
3. 使用者點擊第五顆星 → rating = 5
──────────────────────────
畫面:★(黃) ★(黃) ★(黃) ★(黃) ★(黃)
<input type="hidden" name="rating" value="5">
4. 按下提交按鈕 → 表單傳送
──────────────────────────
POST /submit/
rating=5
總結
透過本教學,你已經學會如何使用 Alpine.js 建立一個互動式的 星星評分表單,並了解了以下核心概念:
- 使用
x-data定義反應性資料 - 使用
x-for迴圈建立多個星星按鈕 - 使用
x-model進行雙向綁定 - 使用 Tailwind CSS 進行樣式設計
這種方法特別適合靜態網站或需要簡單互動的前端專案,無需使用繁重的 JavaScript 框架,即可實現直觀且有效的用戶體驗。