iT邦幫忙

2026 iThome 鐵人賽

DAY 14
0
Modern Web

重寫一套比我還老的系統:21 歲的校園文字廣播系統系列 第 14 篇

Day 14|這次真的來寫前端了,至於為什麼是 Angular?因為我想

  • 分享至 

  • xImage
  •  

昨天,本來信誓旦旦地說:

該來跟前端培養下感情了吧!

然後前端一行都沒寫 hhh。

反而一路從登入頁,挖回 Account 的 Identity、Partial Unique Index,最後甚至又生了一個 Alembic Migration 出來。

只能說,有些感情還沒開始,就得先處理上一段感情留下來的問題。

不過小問題。

今天不一樣。

今天沒有資料庫。

沒有 Migration。

沒有 Partial Unique Index。

更沒有五天前的蘇某突然從土裡爬出來,告訴我:

「欸嘿,其實這裡還有一顆雷喔。」

你確定?

……

你不要烏鴉嘴。

總之,今天真的要來寫前端了。

所以,要用什麼?

既然都要開始寫前端了,那第一個問題自然是:

用什麼?

其實這題我倒沒有糾結多久。

React,我用過。

Angular,我也用過。

兩個要拿來做這次的系統,基本上都沒什麼問題。

所以按照正常的技術文章流程,這裡應該放上一張表格,從生態系、效能、學習曲線、開發體驗一路比較,最後經過一番嚴謹的分析——

所以你選哪個?

Angular。

為什麼?

想用。

蛤?

就,想用。

沒了。

倒也不是 React 做不到什麼,也不是 Angular 在這個專案有什麼壓倒性的優勢。

單純就是兩個我都碰過,兩個也都足以應付這次的需求。

既然如此,那就挑個想寫的。

畢竟技術選型雖然需要考慮需求,也不代表每一次都得寫一大篇。

所以——

Angular,啟動!

今天會是 ChatGPT 配 Antigravity,會這麼做的原因是:我下午把 Codex 額度用完了。

總之,先來初始化專案吧。

ng new frontend

stylesheet 我選的是 SCSS,純個人偏好。

SSR 跟 SSG 這次我認為不需要採用。

至於 AI tools,說真的我自己用下來沒什麼特別的感覺,這次就先選 None 吧。

好,專案生出來了。

所以現在開始寫登入頁?

先等等。

畢竟這是這系列第一次正式碰 Angular,至少先看看它到底生了什麼東西出來。

frontend
├── public
│   └── favicon.ico
├── src
│   ├── app
│   │   ├── app.config.ts
│   │   ├── app.html
│   │   ├── app.routes.ts
│   │   ├── app.scss
│   │   ├── app.spec.ts
│   │   └── app.ts
│   ├── index.html
│   ├── main.ts
│   └── styles.scss
├── angular.json
├── package-lock.json
├── package.json
├── README.md
├── tsconfig.app.json
├── tsconfig.json
└── tsconfig.spec.json

先 serve 起來看看吧。

https://ithelp.ithome.com.tw/upload/images/20260928/20182031o4dE5scroO.png

熟悉的歡迎頁。

好,看到了,可以刪了。

確實。

不過在把它拆掉以前,先看看剛才 Angular CLI 到底幫我們生了些什麼。

如果有用過比較早期的 Angular,看到這份目錄可能會先發現一件事。

等等,我的 app.module.ts 呢?

被你刪了?

我才剛建立專案是能刪什麼啦。

以前寫 Angular 時,很常會看到這種東西:

app.module.ts

然後 Component、Service,以及其他需要使用的東西,會圍繞著 NgModule 組織起來。

但我這次透過 Angular CLI 建立的專案,預設採用了 Standalone 的方式。

所以我們現在看到的:

app.ts
app.html
app.scss
app.config.ts
app.routes.ts

就是接下來主要會碰到的幾個東西。

先不用急著把每一個都研究一遍。

今天的目標只有一個:

把這個歡迎頁拆掉,換成我們自己的登入頁。

終於。

對,終於。

先來生個登入頁

Angular CLI 都裝了,這種事情當然不用自己慢慢建檔案。

ng generate component pages/login

或者偷懶一點:

ng g c pages/login

所以 g 是?

generate。

c 呢?

component。

那你多打幾個字是會怎樣?

會累。

總之,執行完之後,Angular CLI 就會幫我們把 Login Component 的基本結構建起來。

接下來終於可以把昨天欠下來的登入頁畫出來了。

先把登入頁面寫出來,等等 API 再叫 Agent 接。

先把 Login 頁面接上 route 吧。

等等,為什麼有奇怪的 margin?

https://ithelp.ithome.com.tw/upload/images/20260928/20182031mzBESJmhem.png

也沒有地方有寫 css 啊?

不對,我想起來了,瀏覽器有 User Agent Stylesheet,會替 body、標題、段落等元素提供預設樣式。現在看到的外圍空白,多半就是 body 的預設 margin。

那這邊就來一手 CSS Reset 吧。

CSS Reset?

簡單來說,不同 HTML 元素本身就會帶有瀏覽器提供的預設樣式。

像剛才看到的 body 外圍空白,就是其中一個例子;標題、段落、列表等等,也都有各自的預設 margin、padding 或其他樣式。

這些預設樣式本身不是什麼壞東西,但既然現在要自己控制整個頁面的樣式,我會希望大家先站在比較一致的起跑點。

所以 CSS Reset 做的事情,就是先把這些預設樣式清掉,再由我們自己決定它們應該長什麼樣子。

這邊我使用的是 Eric Meyer 的 Reset CSS。

把內容放進全域的 styles.scss 後,再回來看看。

https://ithelp.ithome.com.tw/upload/images/20260928/20182031MxUlEVEAMr.png

欸,白邊沒了。

舒服了。

好,這次真的來畫登入頁

白邊處理完了,總算可以開始處理正事。

先來回憶一下昨天到底折騰了些什麼。

學生登入需要三個東西:

帳號
職務
密碼

老師則是:

帳號
密碼

這不是昨天才講過?

對,但昨天它們還只是後端裡面的資料。

今天這個差異終於要真的長到使用者面前了。

既然學生跟老師需要填的東西不一樣,那登入頁首先得讓使用者告訴我們:

你是學生,還是老師?

我打算先做成兩個可以切換的選項。

選學生時:

┌─────────────────────┐
│       登入          │
│                     │
│ [ 學生 ] [ 教師 ]   │
│                     │
│ 帳號                │
│ [                 ] │
│                     │
│ 職務                │
│ [                 ] │
│                     │
│ 密碼                │
│ [                 ] │
│                     │
│       [ 登入 ]      │
└─────────────────────┘

切到教師:

┌─────────────────────┐
│       登入          │
│                     │
│ [ 學生 ] [ 教師 ]   │
│                     │
│ 帳號                │
│ [                 ] │
│                     │
│ 密碼                │
│ [                 ] │
│                     │
│       [ 登入 ]      │
└─────────────────────┘

差別就只有那個「職務」。

看起來很簡單。

你昨天也是這麼說的。

……

謝謝你歐。

總之先來寫吧。

UI 交給我,API 交給 Agent。

https://ithelp.ithome.com.tw/upload/images/20260928/20182031hTMG8qBPyE.png

這個頁面整體看下來,我還是挺滿意的。

但有個地方我想改一下。

https://ithelp.ithome.com.tw/upload/images/20260928/20182031Ib3L6jAT1U.png
(麻煩各位想像一下在左右圖中切換的感覺)

畫面感覺一直在閃,好不舒服。

不錯,是不是覺得各個 UI 元件在螢幕上晃來晃去?

原因其實很簡單。

學生比教師多了一個「職務」欄位,所以切換身分時,整個表單的高度也會跟著改變。

偏偏我原本又把整份表單垂直置中。

於是表單高度一變,垂直置中的位置也跟著改變,最後連上面的帳號欄位都一起跑了。

但仔細想想,其實根本沒有必要讓所有東西一起動。

從學生切成教師,真正改變的只有「職務」這一欄。

那乾脆讓整份表單以上方為基準往下排。

這樣切換時,上面的標題、身分選擇、帳號都不用動;職務消失之後,只有下面的密碼和登入按鈕往上補。

https://ithelp.ithome.com.tw/upload/images/20260928/20182031ynO0ZEK5dT.png

歐,舒服多了。

對嘛,能少動就少動。

還有一些細節可以調整,但就不這麼吹毛求疵吧。

好,今天就先做到這裡吧。

至少昨天欠下來的前端,今天是真的寫了。

所以可以登入了嗎?

……

不行。

那你今天到底——

UI 寫完了嘛!

API 明天再接。

你昨天也是說明天。

閉嘴。

總之,今天至少成功把 Angular 專案架起來,也把登入頁的基本 Layout 和學生、教師兩種登入狀態處理好了。

至於現在這顆「登入」按鈕……

它目前最大的功能,就是被按。

明天再讓它真的做點事情。


上一篇
Day 13|該來跟前端培養下感情了吧,登登登登登登入!嗎?
下一篇
Day 15|中秋連假結束了,今天來閒聊一下吧。
系列文
重寫一套比我還老的系統:21 歲的校園文字廣播系統 共 20 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言