Day 5: 1140916
在參考完 Day 4 的菜單網站範本後,雖然依循傳統使用 Thymeleaf 對於新手在實作上比較容易,但是使用者體驗 (UX)較差,且功能會受到限縮(每次請求,網頁需整頁刷新,詳細比較如最後的表格),加上目前主流採「前後端分離」的方式管理前後端,所以決定還是練習用 Vite + React 開發。
也就是說,任務管理系統的架構會是
這麼做的優點是
1.前後端可以獨立開發、獨立部署
2.前端體驗較佳,支援 SPA、SSR、CSR
3.更符合微服務架構
一、目標:用 Vite + React 建立建立前端頁面
二、預計使用工具:
VS code
三、首頁相關檔案
1.入口網頁(首頁):index.html
作為整個系統的基礎 HTML 模板,定義根節點 #root,並載入 React 入口檔 main.jsx,前端頁面渲染的起點。
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<!-- <title>Vite + React</title> -->
<title>任務管理系統</title>
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/main.jsx"></script>
</body>
</html>
2.main.jsx:React 應用啟動點
掛載 React 元件到 #root,並啟用 StrictMode 偵測潛在問題。
import { StrictMode } from 'react'
import { createRoot } from 'react-dom/client'
import './index.css'
import App from './App.jsx'
createRoot(document.getElementById('root')).render(
// StrictMode作用是偵測潛在錯誤,只在開發模式生效
<StrictMode>
<App />
</StrictMode>,
)
3.index.css:首頁設計
確保整體 UI 具有一致性的視覺設計。
.header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 10px 20px;
background-color: #333;
color: white;
}
(略)
.btn:hover {
background-color: #9e17fffe;
}
4.app.jsx:系統核心和路由設定(如本系統會有創立帳號CreateAccount,相關設定會在auth資料夾下)
管理系統的路由與權限驗證,並負責顯示通知與導覽列。
import HeaderComponent from "./components/common/HeaderComponent";
import { BrowserRouter, Navigate, Route, Routes } from "react-router-dom";
import CreateAccount from "./components/auth/CreateAccount";
import LoginComponent from "./components/auth/LoginComponent";
import TasksComponent from "./components/tasks/TasksComponent";
import AddTaskComponent from "./components/tasks/AddTaskComponent";
import TaskHistory from "./components/tasks/TaskHistory";
import DetailPage from "./components/pages/DetailPage";
import { getLoggedInUserId, isUserLoggedIn } from "./api/AuthApiService";
import HomePage from "./components/pages/Home";
import "./App.css";
import { ToastContainer } from 'react-toastify';
import 'react-toastify/dist/ReactToastify.css';
function App() {
const activeUserId = getLoggedInUserId();
function AuthenticatedRoute({ children }) {
const isAuthenticated = isUserLoggedIn();
if (isAuthenticated) {
return children;
}
return <Navigate to="/" />;
}
//取得當前登入使用者的 ID,傳遞給其他頁面使用
return (
//提供前端路徑功能(其他方式:HashRouter)
<BrowserRouter>
{/* 顯示通知 */}
<ToastContainer />
{/* 顯示導覽列 */}
<HeaderComponent />
<div className="container mt-5">
<Routes>
{/* 定義不同的路徑導向的頁面 */}
{/* 首頁 */}
<Route path="/" element={<HomePage />} />
<Route
path="/tasks"
element={
<AuthenticatedRoute>
{/* 若使用者已登入,顯示 TasksComponent */}
<TasksComponent userId={activeUserId} />
</AuthenticatedRoute>
}
/>
{/* 新增任務頁面 */}
<Route
path="/add-task"
element={
<AuthenticatedRoute>
<AddTaskComponent userId={activeUserId} />
</AuthenticatedRoute>
}
/>
{/* 任務資訊頁面 */}
<Route
// :id 代表 URL 參數,例如 /task-details/123,顯示 ID 為 123 的任務
path="/task-details/:id"
element={
<AuthenticatedRoute>
<DetailPage userId={activeUserId}/>
</AuthenticatedRoute>
}
/>
{/* 歷史任務頁面 */}
<Route
path="/history"
element={
<AuthenticatedRoute>
<TaskHistory userId={activeUserId} />
</AuthenticatedRoute>
}
/>
{/* 更新任務頁面 */}
<Route
path="/update-task/:id"
element={
<AuthenticatedRoute>
<AddTaskComponent userId={activeUserId} />
</AuthenticatedRoute>
}
/>
{/* 公開頁面 */}
{/* 建立帳號頁面 */}
<Route path="/create-account" element={<CreateAccount />} />
{/* 登入頁面 */}
<Route path="/login" element={<LoginComponent />} />
</Routes>
</div>
</BrowserRouter>
);
}
// 將 App 作為預設匯出,供 index.js 使用
export default App;
四、參考表格:
**Thymeleaf vs Vite + React/Vue **