Ionic Framework 跨平台專案開發心得(上)
Ionic Framework 跨平台專案開發心得
文章主旨
本文介紹跨平台開發框架 Ionic,並分享實際專案中的應用方式、遇到的困難與開發心得。 最後也會聊聊 AI 模型變強之後,開發上帶來了哪些轉變。
全文分為上、下兩篇:
- 上篇:一、Ionic 是什麼/二、專案上的應用/三、面臨的困難
- 下篇:四、實際上遇到的問題/五、AI 模型帶來的轉變/六、心得結論
上篇
一、Ionic 是什麼
1.1 用網頁技術做 App
Ionic 是一套開源的跨平台框架,讓開發者用 HTML、CSS、JavaScript/TypeScript 開發應用程式,並同時輸出成 Web、iOS、Android 三個平台,共用同一份程式碼。
它的做法是:在手機的原生 App 殼裡放一個 WebView(可以想成沒有網址列的內嵌瀏覽器),由 WebView 來執行我們寫的網頁。Ionic 再提供一整套「長得像手機原生」的 UI 元件,例如分頁列、底部彈窗、下拉更新等,讓網頁在手機上看起來、用起來都接近原生 App。
1.2 三個組成部分
| 組成 | 負責的事 |
|---|---|
| Ionic Framework | UI 元件(ion-button、ion-modal、ion-tabs⋯),並依平台自動切換 iOS/Android 風格 |
| 前端框架 | 頁面邏輯、路由、狀態管理,可選 Angular、React 或 Vue |
| Capacitor | 原生殼,以及呼叫相機、推播、檔案等手機功能的 Plugin 機制 |
Ionic 早期綁定 Angular,原生功能靠 Cordova 提供;從 Ionic 4 開始,元件改用標準的 Web Components 實作,不再綁定特定框架,並推出 Capacitor 取代 Cordova。也因為經歷過幾次大改版,網路上有不少資料其實是舊架構的寫法,查資料時要特別留意版本。
1.3 和其他跨平台方案的差別
| 方案 | 畫面怎麼畫出來 | 開發語言 |
|---|---|---|
| Ionic | 在 WebView 裡用 HTML/CSS 渲染 | Web 技術 |
| React Native | 呼叫原生 UI 元件 | JavaScript + React |
| Flutter | 自帶渲染引擎直接繪製 | Dart |
1.4 它的本質:像原生,但不是原生
Ionic 做的,是把各種手機介面的樣式做出來,達到「類似原生」的效果。說到底它並不是原生,手感、動畫、效能都很接近,但不會百分之百一樣。
優點很明確:
- 一份程式碼跑三個平台,開發與維護成本大幅降低。
- 前端工程師就能做 App,不需要另外組 iOS、Android 團隊。
- 整個 Web 生態系(npm、Vite、TypeScript、測試工具)都能直接使用。
- 大部分開發在瀏覽器中完成,存檔即時看到結果,迭代很快。
限制也一樣明確:
- 畫面由 WebView 渲染,流暢度與手感的上限低於純原生。
- iOS 與 Android 的 WebView 核心不同(WebKit 與 Chromium),同一段程式在兩邊的表現可能不一樣。
- 鍵盤、瀏海、手勢這些行為,在電腦瀏覽器裡模擬不出來,很多問題只在真機上出現。
所以,如果專案非常依賴原生功能或極致的操作手感,Ionic 可能不是最適合的選擇;但如果是以表單、清單、資料呈現為主的業務型 App,它的 CP 值非常高。
二、專案上的應用
2.1 技術組合
UI 元件 Ionic 8
前端框架 Vue 3(<script setup>)+ TypeScript
原生執行 Capacitor 6
狀態管理 Pinia
多語系 vue-i18n
表單驗證 vee-validate + zod
建置工具 Vite,套件管理使用 pnpm
2.2 用到的原生功能
專案幾乎把常見的手機功能都用過一輪,全部透過 Capacitor Plugin 呼叫:
- 相機、相簿:拍照、從相簿選圖上傳
- 檔案、分享:下載檔案、透過系統分享給其他 App
- 推播、本地通知:即時通知使用者
- 條碼掃描:掃描 QR code
- 鍵盤、狀態列、啟動畫面、震動回饋
2.3 幾個架構上的做法
(1)用自製元件包一層 Ionic 元件
頁面不直接使用 ion-input、ion-modal,而是統一使用專案自己包的 AppInput、AppModal。平常看起來多一層,但遇到平台問題時價值就出來了:例如 iOS 鍵盤造成彈窗跑版,只要修 AppModal 一個地方,全 App 的彈窗一起修好,不用逐頁修改。
(2)留意 Ionic 的頁面堆疊機制
Ionic 的路由會把頁面「疊」起來保存。從 A 頁進到 B 頁,A 頁不會被銷毀,返回時直接取回。好處是有原生 App 般的轉場動畫,也能保留捲動位置;但 Vue 的 onMounted 只會在第一次進入時觸發,若要每次進頁都重新載入資料,就要改用 Ionic 提供的 onIonViewWillEnter。這是從一般 Vue 專案轉過來時最需要調整的習慣。
三、面臨的困難
3.1 社群依賴性高
Ionic 讓前端工程師能做 App,但也代表團隊看不太懂手機的原生程式碼(iOS 的 Swift、Android 的 Kotlin/Java)。
雖然畫面是網頁,但開相機、讀相簿、收推播這些功能,背後都是原生程式在執行,只能透過 Plugin 來呼叫。所以要做什麼功能,就得先找有沒有現成的社群套件:
- 社群有套件 → 可以做,但要祈禱它還有人維護、版本合用。
- 社群沒有套件 → 基本上就做不到,因為團隊也沒有能力自己寫原生程式。
功能的邊界,某種程度上是由社群決定的。
3.2 樣式不好改
Ionic 的元件採用 Web Components,內部結構被封裝在 Shadow DOM 裡,外面的 CSS 無法直接改到元件內部。
想客製化樣式,只能透過 Ionic 開放出來的 CSS 變數(例如 --background、--padding-start)或 ::part()。但開放的 API 並不多,設計稿上的細節常常找不到對應的變數可以改,自由度相當有限。為了貼近設計稿,往往要花不少時間繞路處理。
3.3 原生環境的版本問題
前端的套件版本都寫在 package.json 裡,裝一次就一致。但 Ionic 專案還牽涉到原生端:
- Xcode 版本、iOS SDK 版本、CocoaPods
- Android Studio 版本、Gradle 版本、JDK 版本
這些設定不會寫在 package.json,而是散落在各自的原生專案與開發者電腦上。不同人的電腦環境不同,就可能出現「我這邊能打包,你那邊不行」的狀況。
再加上 Capacitor Plugin 的版本必須和 Capacitor 核心版本對齊,升級一個套件,可能連帶要求更新 JDK 或 Xcode,牽一髮動全身。
