網站的介面多多少少會放置圖示 (Icon),圖示的載入方式可以像圖片一樣以 png、jpg、webp 或 svg 等圖片格式來呈現,本篇將介紹如何在 Nuxt 中使用 svg 圖片及使用第三方模組套用豐富的 Icon 圖示。
使用 svg 圖示的優點:
更多人會選擇的是 svg 是因為在實務上圖示可能需要以各種不同的大小或能適應 CSS 樣式的調整,如圖示與文字相同的顏色變化效果,而以字型來呈現的圖示甚至直接用 CSS 或 JS 手刻都較 png 或 jpg 這類像素類型的圖片更多的可玩性。
首先,準備一個 SVG 圖形檔案,建立於 ./assets/svg/nuxt.svg,接下來我們就可以在元件中分別以不同方式做使用。
如同圖片的使用方式,我們可以直接使用 src 來載入圖形。
<template>
<img src="~/assets/svg/nuxt.svg" />
</template>
你也可以選擇直接使用 SVG 的內容以 HTML 標籤形式來描述 SVG 圖形。
<template>
<svg xmlns="http://www.w3.org/2000/svg" width="48.77" height="32" viewBox="0 0 256 168">
<path fill="#00DC82" d="M143.618 167.029h95.166c3.023 0 5.992-.771 8.61-2.237a16.963 16.963 0 0 0 6.302-6.115a16.324 16.324 0 0 0 2.304-8.352c0-2.932-.799-5.811-2.312-8.35L189.778 34.6a16.966 16.966 0 0 0-6.301-6.113a17.626 17.626 0 0 0-8.608-2.238c-3.023 0-5.991.772-8.609 2.238a16.964 16.964 0 0 0-6.3 6.113l-16.342 27.473l-31.95-53.724a16.973 16.973 0 0 0-6.304-6.112A17.638 17.638 0 0 0 96.754 0c-3.022 0-5.992.772-8.61 2.237a16.973 16.973 0 0 0-6.303 6.112L2.31 141.975a16.302 16.302 0 0 0-2.31 8.35c0 2.932.793 5.813 2.304 8.352a16.964 16.964 0 0 0 6.302 6.115a17.628 17.628 0 0 0 8.61 2.237h59.737c23.669 0 41.123-10.084 53.134-29.758l29.159-48.983l15.618-26.215l46.874 78.742h-62.492l-15.628 26.214Zm-67.64-26.24l-41.688-.01L96.782 35.796l31.181 52.492l-20.877 35.084c-7.976 12.765-17.037 17.416-31.107 17.416Z"/>
</svg>
</template>
在沒有設計稿進行網站開發時,許多時候需要自己尋找圖示來設計介面,傳統的方式需要一一下載圖片或複製標籤描述來建立我們所需要的圖示,在使用上就會花上不少時間。
網路上有許多免費且開源的圖示或字型可以做使用,而 Nuxt Icon 模組也是選擇之一,模組中不僅整合了 Iconify 的 Icon 圖示集,只要在 Nuxt 中安裝後,我們只要宣告標籤與圖示名稱,就可以很方便的來載入圖示。
Step 1. 安裝套件
安裝 Nuxt Icon 模組。
npm install -D nuxt-icon
Step 2. 配置使用模組
在 ./nuxt.config.ts 中的 modules 屬性,添加 Nuxt Icon 模組的名稱 nuxt-icon
。
export default defineNuxtConfig({
modules: ['nuxt-icon']
})
Step 3. 開始使用
至此,我們就可以在頁面或元件中使用,為模組所提供的 <Icon>
元件來建立圖示,這個 Icon 元件可以傳入 name
屬性,以此來顯示不同的 Icon 圖示,size
則可以控制圖示的大小。
<Icon name="logos:nuxt" size="360" />
就是這麼簡單,我們就能使用內建的 SVG 圖示。
在使用模組所提供的元件 Icon 時,需要傳入一個 name
的屬性,這個屬性是 Iconify 圖示集所定義的,Iconify 提供多達 100,000 個以上的圖示,並具有多種風格類型的系列圖示,在這個網站 https://icones.js.org/ 可以快速搜尋到你想要的圖示與對應的圖示名稱 name
。
例如我想要在 Fluent UI System Icons 集合內,如下圖,點擊欲使用圖示,就會跳出提示,包含元件所需要的 name
屬性值 fluent:airplane-take-off-24-regular
或其他載入方式。
透過元件的 name
屬性值,我們就能快速的添加圖示到頁面或元件之中。
<Icon name="fluent:airplane-take-off-24-regular" />
Icon 元件也可以使用 Emoji 來當作 name
屬性值,以此來使用元件參數控制 Emoji 。
<Icon name="🚀" />
透過模組約定的元件目錄 ./components/global,你也可以使用自訂的 SVG 來建立圖示,建立一個圖示元件 ./components/global/NuxtIcon.vue 內容如下。
<template>
<svg xmlns="http://www.w3.org/2000/svg" width="48.77" height="32" viewBox="0 0 256 168">
<path fill="#00DC82" d="M143.618 167.029h95.166c3.023 0 5.992-.771 8.61-2.237a16.963 16.963 0 0 0 6.302-6.115a16.324 16.324 0 0 0 2.304-8.352c0-2.932-.799-5.811-2.312-8.35L189.778 34.6a16.966 16.966 0 0 0-6.301-6.113a17.626 17.626 0 0 0-8.608-2.238c-3.023 0-5.991.772-8.609 2.238a16.964 16.964 0 0 0-6.3 6.113l-16.342 27.473l-31.95-53.724a16.973 16.973 0 0 0-6.304-6.112A17.638 17.638 0 0 0 96.754 0c-3.022 0-5.992.772-8.61 2.237a16.973 16.973 0 0 0-6.303 6.112L2.31 141.975a16.302 16.302 0 0 0-2.31 8.35c0 2.932.793 5.813 2.304 8.352a16.964 16.964 0 0 0 6.302 6.115a17.628 17.628 0 0 0 8.61 2.237h59.737c23.669 0 41.123-10.084 53.134-29.758l29.159-48.983l15.618-26.215l46.874 78.742h-62.492l-15.628 26.214Zm-67.64-26.24l-41.688-.01L96.782 35.796l31.181 52.492l-20.877 35.084c-7.976 12.765-17.037 17.416-31.107 17.416Z"/>
</svg>
</template>
我們就可以在頁面或元件中,使用 Icon 元件並傳入建立的元件名稱作為 name
屬性值。
<Icon name="NuxtIcon" />
Nuxt Icon 模組所使用的載入方式,是透過發出 HTTP 請求 Iconify CDN 來載入圖示,雖然模組提供 CDN 與 Local Storage 快取的方式來解決請求速度的問題,但是模組的圖示在網站打包或建立靜態網站時,並沒有辦法在建構時期一同把包並提供離線使用,所以可能會發生圖示未載入完成前的空白狀態或需要可以接受網路的環境。
至今仍然有部分使用者仍希望可以預渲染或預先請求圖示資源,模組的主要維護者 Sébastien Chopin 目前有考慮使用 unplugin
插件來支援,但目前尚無相關規劃,只能靜待版本功能推進或貢獻者來完善這個小缺點了。
更多 Nuxt Icon 的使用方式與配置,可以參考官方文件。
前面介紹了 Nuxt Icon 的模組,最後提到了一個小缺點就是沒有辦法將圖示打包,接下來要介紹的模組 unplugin-icons 不僅能解決該問題而且同樣也是支援 Iconify 圖示集,接下來就來介紹安裝與使用。
Step 1. 安裝套件
安裝 unplugin-icons 模組。
npm install -D unplugin-icons
Step 2. 安裝 Iconify 圖示集
你有兩種安裝方式可以選擇:
a. 安裝完整的集合,雖然比較大包,但是生產環境也僅會打包實際使用到的圖示
npm i -D @iconify/json
b. 僅安裝特定圖標集,例如欲安裝 Material Design Icons 圖標集,支援的圖標集列表可以參考官方 API。
npm i -D @iconify-json/mdi
Step 3. 配置使用模組
在 ./nuxt.config.ts 中的 modules 屬性,添加 Nuxt Icon 模組的名稱 unplugin-icons/nuxt
。
export default defineNuxtConfig({
modules: ['unplugin-icons/nuxt']
})
Step 4. 開始使用
我們於頁面或元件中使用時,需要先 import 所需要使用的圖示,才能使用圖示元件。
<template>
<IconAirplaneTake :style="{ fontSize: '360px' }"/>
</template>
<script setup>
import IconAirplaneTake from '~icons/fluent/airplane-take-off-24-regular'
</script>
unplugin-icons 它其中一個特性就是它能夠將圖示與頁面一起渲染,如下圖在首次請求,頁面或元件中所使用到的圖示,無須在客戶端發送請求來載入圖示,
Nuxt 3 本身就具備自動導入的特性,unplugin-icons 模組也可以啟用自動導入的功能,雖然步驟有點繁瑣,但設定完成後也能幫助能省去需要撰寫 import 的時間。
Step 1. 安裝插件
npm install -D unplugin-vue-components
Step 2. 調整配置
在 ./nuxt.config.ts 中,載入 IconsResolver、Icons、Components,並添加 vite 插件來解析元件,同時我們也設定元件的前綴名稱為 icon
。
import IconsResolver from 'unplugin-icons/resolver'
import Icons from 'unplugin-icons/vite'
import Components from 'unplugin-vue-components/vite'
export default defineNuxtConfig(async () => ({
modules: [
['unplugin-icons/nuxt']
],
vite: {
plugins: [
Components({
resolvers: [IconsResolver({
prefix: 'icon'
})]
}),
Icons({})
]
}
}))
Step 3. 開始使用
使用具自動導入的圖示元件時你必須遵循元件名稱格式才能正確的推斷及載入圖示。
自動導入圖示的元件名稱格式:
{prefix}-{collection}-{icon}
prefix: 我們設定為 icon
。
collection: 對應 Iconify 圖示集 ID。
icon: 圖示集的 Icon 名稱。
例如欲使用 Fluent UI System Icons 圖標集的圖示 airplane-take-off-24-regular
,使用起來如下程式碼:
<template>
<!-- <IconAirplaneTake :style="{ fontSize: '360px' }"/> -->
<icon-fluent-airplane-take-off-24-regular :style="{ fontSize: '360px' }" />
<IconFluentAirplaneTakeOff24Regular :style="{ fontSize: '360px' }" />
</template>
<script setup>
// import IconAirplaneTake from '~icons/fluent/airplane-take-off-24-regular'
</script>
如果你是在 https://icones.js.org/ 挑選圖示,那麼提示的圖示名稱例如為 fluent:airplane-take-off-24-regular
,分號前的 fluent
即是對應元件格式的 collection,airplane-take-off-24-regular
即是對應元件格式的 name。
更多 unplugin-icons 的使用方式與配置,可以參考官方文件。
如果你有使用 UnoCSS,那麼 @unocss/preset-icons 插件應該會是最好的選擇,同樣使用 Iconify 圖示集,並且使用類別名稱 (class) 來建立圖示。
如果你本身使用的是其他 CSS 框架語言,如 Tailwind CSS、Master CSS 等,你也可以只單獨啟用 UnoCSS - Preset-icons,步驟如下。
Step 1. 安裝套件
npm install -D @unocss/nuxt @unocss/preset-icons @iconify/json
Step 2. 調整配置
在 ./nuxt.config.ts 中的 modules 屬性,添加模組名稱 @unocss/nuxt
,我們僅想使用 Preset-icons 所以可以禁用如 uno
和 attributify
等其他選項,僅保持 icons
為 true。
export default defineNuxtConfig(async () => ({
modules: [
['@unocss/nuxt']
],
unocss: {
uno: false,
icons: true, // 僅啟用 Preset-icons
attributify: false,
shortcuts: [],
rules: []
}
}))
Step 3. 開始使用
我們於頁面或元件中使用時,可以直接以類別名稱 i-
開頭表示圖示,後面添加接續圖示集 ID 與圖示名稱。
<template>
<div class="i-fluent-airplane-take-off-24-regular"></div>
</template>
當你使用上述這些方式來使用圖示時,使用的圖示集 Iconify,官方也提供了一個 VS Code 插件 Iconify IntelliSense,幫助你在開發上顯示對應的圖示、自動完成圖示名稱、滑入圖示時提示圖示與名稱及程式碼片段等。
Iconify IntelliSense 插件實際效果如下圖:
透過模組來協助網站 Icon 圖示的添加,你可以擁有更好開發體驗,Iconify 圖示集所提供的圖示,如果真的還不夠做使用,你也可以再考慮使用自訂元件的方式來進行載入,相較於傳統的圖片檔,向量圖示能有更靈活的變化與樣式的調整。
感謝大家的閱讀,歡迎大家給予建議與討論,也請各位大大鞭小力一些:)
如果對這個 Nuxt 3 系列感興趣,可以訂閱
接收通知,也歡迎分享給喜歡或正在學習 Nuxt 3 的夥伴。
參考資料