# 前端如何管理 Icon?用 Nuxt Icon 打造可維護的設計到程式流程(上) 在前端專案中,「圖示(Icon)」幾乎無所不在。從按鈕、導航列、提示訊息到整個 UI 系統,Icon 是維持設計一致性不可或缺的一環。而在 Nuxt 官方模組頁面上,目前有兩個常見的 Icon 模組: - [nuxt-icons](https://github.com/gitFoxCode/nuxt-icons) - [@nuxt/icon](https://github.com/nuxt/icon) 這兩者都能在 Nuxt 專案中提供 Icon 管理能力,但定位、特色與使用場景完全不同。 以下依照截至 2025.12.04 的官方資訊整理出它們的下載數統計: | 模組 | 每月下載數(截至今日) | 最新版本 | | -------------- | ------------------------- | ------ | | **@nuxt/icon** | **952k / month** | v2.1.0 | | **nuxt-icons** | **42.9k downloads**(非月下載) | v4.0.0 | <br /> #### **兩者每週下載量比較圖** - [link](https://npm.chart.dev/nuxt-icons+@nuxt/icon?blackAsPrimary=false&primary=amber&gray=gray&theme=dark) ![image](https://hackmd.io/_uploads/BJWjMxezZx.png) 很明顯可以看到: :::info - @nuxt/icon 是 Nuxt 官方主推、使用量極高的 Icon 解決方案 - nuxt-icons 則偏屬專案內部 SVG icon 使用的小工具模組 ::: 接下來我們就深入比較兩者差異、優缺點與實務使用建議 ## 1. 基本定位與用途 ### ▶ 1.1 nuxt-icons — 專注於「本地 SVG」的簡單小工具 ![image](https://hackmd.io/_uploads/HyuCgaRWZe.png) #### **定位:** >讓你把自己的 SVG 放在 `assets/icons/`,自動匯入後用 `<nuxt-icon name="xxx" />` 呼叫 #### 適合: - 公司 / 自家設計師提供的 SVG icon - Logo、品牌專屬圖示 - 想完全控制 SVG 樣式與內容 #### 特色: - 自動載入你本地的 SVG - 不依賴外部 Library - HMR 更新即時顯示 :::success 核心就是「幫你方便地用自己的 SVG」 ::: <br /> ### ▶ 1.2 @nuxt/icon — 官方推薦、整合 Iconify 的超大型 Icon 系統 ![image](https://hackmd.io/_uploads/Hyv--aCWZe.png) #### **定位:** >結合 Iconify(20–30 萬個 icon),並提供統一的 `<Icon />` 介面,可渲染 SVG 或 CSS #### 適合: - 想用現成大量開源 icon( 例如 Material, Heroicons, Fluent ) - 大型專案需要統一規範 Icon 用法 - 前後端團隊都希望更容易引用與管理 icon - 想同時有「大圖示庫」+「自訂 SVG」的彈性 #### 特色: - 使用 `<Icon name="mdi:home" />` 即可取得 icon - 支援 SSR / SSG( 不像 iconify-runtime 有些會 FOUC ) - 支援 local bundle( 節省網路請求 ) - 支援自訂 Icon 集合( custom collections ) - 有 CSS mode / SVG mode :::success 是一個「完整的 Icon 系統」,不只是小工具 ::: :::spoiler 註: FOUC,Flash of Unstyled Content:未套用樣式前的閃爍 Icon 在頁面載入時,會先短暫出現「空白」或「錯位」,等 iconify runtime 抓到 SVG 後才顯示 常見情況像是: - icon 一開始是空白方塊 ☐ - icon 的位置留了一個洞 - icon 沒載入前是錯誤大小 - 短暫出現 fallback 字體或奇怪的形狀 這是因為 iconify-runtime 在 client side 才載入 icon,SSR 無法先把 SVG 渲染好 @nuxt/icon: - 提供 SSR / SSG 時直接輸出 SVG - 或用 server-bundle 提前載入 icon ➡️ 所以頁面一打開,icon 就「完整渲染」,不會出現閃爍、空洞、跑版等 FOUC 問題 ::: <br /> ### ▶ 1.3 核心差異 | 功能項目 | **nuxt-icons** | **@nuxt/icon** | | ------------------------ | -------------------------- | -------------------------------- | | Icon 來源 | 你自己放的 SVG | Iconify + 本地 SVG + 自訂集合 | | 使用方式 | `<nuxt-icon name="foo" />` | `<Icon name="mdi:home" />` | | 支援模式 | SVG | SVG / CSS | | 適合規模 | 中小型專案 | 小 → 大型專案都適用 | | 圖示數量 | 你的 SVG 數量 | 20–30 萬個 icon(Iconify) | | SVG 維護成本 | 是 | 否(可全部交給 Iconify) | | SSR / SSG 效能 | 正常 | 官方專門強化 SSR 效能 | | 客製化彈性 | 高 | 非常高(含客製 collections) | | Dropdown / UI Library 支援 | 僅限自訂 | 更容易整合其他 Library(例如 UI Framework) | ### ▶ 1.4 實務上如何選? #### 🔸 nuxt-icons 你的 icons 數量少(50〜200 個)、樣式固定、與 UI Kit 綁定 → nuxt-icons 是最簡單又乾淨的方案 - 使用公司品牌圖示 - 自家設計系統有固定樣式 - 你不需要第三方圖示 #### 🔸 @nuxt/icon 想快速開始、需要大量開源 icon,用 `<Icon name="mdi:home" />` 就能立即使用 icon」 - 做後台管理系統 - 經常要換 icon、想快速查 Iconify - 設計師沒有提供完整 icon set - 專案初期尚未有完整設計系統 #### 🔸 想同時用 Iconify + 自訂 SVG → @nuxt/icon 因為: - 支援 custom collections - 本地 icon 可像其他 icon 一樣引用 - 命名空間可隔離(避免衝突) 你的專案如果有: 「標準 UI icon + 自訂品牌 icon」 = 這種企業級需求 → 就選擇 @nuxt/icon 吧! <br /> ### ▶ 1.5 注意事項 / 限制 #### 🔸 nuxt-icons 的限制 - **無法使用外部 Icon Library** 只能使用你放在 `assets/icons/` 的 SVG - **會增加 bundle size** 在 build 時會把所有 SVG 內容打包進 client bundle。即使頁面只用 3 個 icon,所有 SVG 都會被下載到使用者瀏覽器(數量多的話會讓 JavaScript 檔案變胖 🐽) - **版本與風格需自行管理** 圖示的命名、尺寸、視覺風格都要自己統一,沒有像 Iconify 那樣的集合管理 - **不適合快速變動的專案** 如果經常需要新增、替換 icon,每次都要處理 SVG 檔案會比較麻煩 --- #### 🔸 @nuxt/icon 的注意事項 - **注意 bundle size** 如果使用太多 Iconify 集合,bundle 會變大。建議透過 `collections` 設定只安裝需要的 icon 集合(例如只裝 `mdi` 和 `heroicons`) - **自訂 collections 命名規則** 使用自訂 icon 集合時,要注意 prefix 命名避免衝突(例如 `custom:logo` vs `mdi:logo`) - **CSS mode 的限制** CSS mode 使用 `mask-image` 技術,只適合單色 icon。多色、漸層、複雜效果的 SVG 可能會顯示異常(這是 CSS mask 的正常限制,不是 bug) :::spoiler 註:CSS mode 的 mask 原理 `@nuxt/icon` 支援兩種模式: - **SVG mode(預設)** → 直接在 HTML 中輸出完整的 `<svg>` 標籤 - **CSS mode** → 使用 CSS `mask-image` 屬性呈現 icon **CSS mode 的運作原理:** 把 SVG 轉成背景遮罩(mask),再用 CSS 的 `background-color` 控制顏色。 簡單來說就是: 1. SVG 變成「鏤空模板」(黑色部分顯示,白色部分透明) 2. 用 CSS 給這個模板上色 3. 優點:可以用 Tailwind 的 `text-red-500` 直接改顏色 4. 缺點:只能是單色,多色 icon 會失效 **為什麼有些 icon 在 CSS mode 會出問題?** - 原本是多色的 icon(例如彩色 logo)→ 會全部變單色 - 有漸層或透明度的 SVG → mask 無法處理這些效果 - 複雜的 path 或濾鏡 → 可能渲染不出來 **什麼時候用 CSS mode?** - 你的 icon 都是單色的(例如 Heroicons、Material Icons) - 想要用 Tailwind class 快速改變顏色 - 需要更小的 bundle size(CSS 比完整 SVG 輕量) **什麼時候該用 SVG mode?** - 需要多色 icon - 需要保留 SVG 的漸層、陰影等效果 - 追求完美的視覺還原度 ::: <br /> ## 2. 小結:Icon 不只是圖,而是設計系統的一部分 回顧一下這篇的重點: - **`nuxt-icons`** 適合「已經有一套自家 SVG」的團隊,專心把設計稿轉成乾淨、可控的圖示資源 - **`@nuxt/icon`** 則是「兼顧大量開源 icon + 自訂 SVG + SSR 效能」的一站式解決方案,特別適合中大型專案,或還在建立設計系統的團隊 當專案變大、頁面變多,Icon 如果沒有規則,就很容易變成 UI 版的「義大利麵」—— 看起來能跑,但誰都不太敢動它 ![麵](https://hackmd.io/_uploads/SJIWxTJz-x.jpg) <br /> ## 下一篇會聊什麼? 在下一篇[《前端如何管理 Icon?用 Nuxt Icon 打造可維護的設計到程式流程(下)》](https://hackmd.io/@ZvoIazgmQGWW1PTuqT87gw/r1W_8RA-Ze)裡, 我會實際帶你一步一步把 **@nuxt/icon** 接到專案裡,包含: - 怎麼安裝與設定 `@nuxt/icon`(含 nuxi 一鍵安裝與手動設定差異) - 如何選擇 `svg` / `css` mode,並避免常見踩雷 - 怎麼把 Iconify icon、專案自訂 SVG、Vue 元件 icon 串成 **同一套使用規則** - 利用 `app.config.ts` 做預設尺寸、class、aliases,打造「可以被維護」的 Icon 流程 好啦~對這兩個 Nuxt Icon 套件有基本了解後, 下一篇就讓我們一起把 @nuxt/icon 實際裝進專案裡, 把「Icon 管理」從土法煉鋼進化成有系統的設計到程式流程吧 (*´∀`)~♥ <br /> ## 📌 版本與資料來源說明 本文資料與數據截至 **2025 年 12 月 4 日**,基於以下版本撰寫: - `@nuxt/icon` v2.1.0 - `nuxt-icons` v4.0.0 由於前端生態系更新快速,建議實際使用時: - 優先參考 [Nuxt Icon 官方文件](https://nuxt.com/modules/icon) - 查看 [GitHub Releases](https://github.com/nuxt/icon/releases) 確認最新功能 - 檢查套件的 [NPM 頁面](https://www.npmjs.com/package/@nuxt/icon) 了解當前版本 **文章重點在於「管理 Icon 的思維與架構」,這些原則即使套件更新也依然適用** ✨ ---