Nuxt Icon
為您的 Nuxt 應用程式新增 200,000+ 個隨時可用的圖示,基於 Iconify。
特性 ✨
- 支援 Nuxt 3
- SSR 友好
- 透過 Iconify 支援 200,000 個開源向量圖示
- 支援 CSS 模式 / SVG 模式
- 自定義 SVG 支援(透過 Vue 元件,或透過本地 SVG 檔案)
!NOTE 您正在檢視此模組的
v1.0
版本,這是為了更好的開發體驗和效能而完全重寫的版本。如果您正在從v0.6
遷移,請檢視 此 PR 以獲取完整的更改列表。
設定 ⛓️
執行以下命令將模組新增到您的專案
npx nuxi module add icon
就是這樣,您現在可以在元件中使用 <Icon />
了!
✨ 如果您正在使用 VS Code,您可以使用 Iconify IntelliSense 擴充套件,由 @antfu 提供。
手動設定
您可以手動安裝模組,使用
npm i -D @nuxt/icon
更新您的 nuxt.config.ts
export default defineNuxtConfig({
modules: [
'@nuxt/icon'
]
})
如果您安裝了舊版模組 nuxt-icon
,您可能需要將其從 modules
列表中移除。
用法 👌
屬性
name
(必填): 圖示名稱或全域性元件名稱size
: 圖示大小 (預設:1em
)mode
: 圖示渲染模式 (svg
或css
, 預設:css
)
屬性:
當使用 Iconify 中的圖示時,將根據渲染模式建立一個 <span>
或 <svg>
元素,您可以賦予原生元素 所有屬性。
<Icon name="uil:github" style="color: black" />
TailwindCSS v4:
當使用 TailwindCSS v4 和 css
模式時,您應該在 Nuxt 的應用配置中配置 cssLayer
。
// ~/app.config.ts
export default defineAppConfig({
icon: {
mode: 'css',
cssLayer: 'base'
}
})
Iconify 資料集
您可以使用 https://icones.js.org 集合中的任何名稱。
<Icon name="uil:github" />
它支援 i-
字首(例如,i-uil-github
)。
強烈建議使用以下命令在本地安裝圖示資料
npm i -D @iconify-json/collection-name
例如,要使用 uil:github
圖示,請安裝其集合 @iconify-json/uil
。這樣,圖示可以在本地或您的無伺服器函式中提供,這在 SSR 和客戶端都更快、更可靠。
!NOTE 您可能還知道可以安裝
@iconify/json
包來包含所有 iconify 圖示。不建議這樣做,因為它會增加您的伺服器 bundle 大小和構建效能。如果您選擇這樣做,我們建議您明確指定所需的集合名稱。export default defineNuxtConfig({ modules: ['@nuxt/icon'], icon: { serverBundle: { collections: ['uil', 'mdi'] // <!--- this } } })
Vue 元件
當 name
與全域性註冊的元件匹配時,它將作為該元件渲染(在這種情況下,mode
將被忽略)。
<Icon name="MyComponent" />
請注意,MyComponent
需要位於 components/global/
資料夾中(參見示例)。
!TIP 您還可以使用以下命令更改元件名稱
export default defineNuxtConfig({ icon: { componentName: 'NuxtIcon' } })
自定義本地集合
您可以使用本地 SVG 檔案建立自定義 Iconify 集合。
例如,將您的圖示 SVG 檔案放在您選擇的資料夾下,例如 ./assets/my-icons
assets/my-icons
├── foo.svg
├── bar-outline.svg
在您的 nuxt.config.ts
中,在 icon.customCollections
中新增一個專案
export default defineNuxtConfig({
modules: [
'@nuxt/icon'
],
icon: {
customCollections: [
{
prefix: 'my-icon',
dir: './assets/my-icons'
},
],
},
})
!NOTE 如果您在 Nuxt 4 中執行新
app
目錄,資產目錄是'./app/assets/*'
而不是'./assets/*'
。
然後您可以像這樣使用圖示
<template>
<Icon name="my-icon:foo" />
<Icon name="my-icon:bar-outline" />
</template>
您還可以傳遞一個完整的自定義 IconifyJSON
物件
export default defineNuxtConfig({
modules: [
'@nuxt/icon'
],
icon: {
customCollections: [
{
prefix: 'paid-icons',
icons: {
'nuxt': { body: '<path d="M281.44 ... />' },
},
width: 512,
height: 512,
}
],
},
})
請注意,自定義本地集合要求您擁有一個伺服器來提供 API。當設定 ssr: false
,或當使用 nuxt generate
(這等同於 ssr: false)生成靜態應用時,提供者將預設為 Iconify API(它沒有您的自定義圖示)。如果您想使用伺服器端點構建 SPA,您可以顯式設定 provider: 'server'
。
export default defineNuxtConfig({
modules: [
'@nuxt/icon'
],
ssr: false,
icon: {
provider: 'server', // <-- this
customCollections: [
{
prefix: 'my-icon',
dir: './assets/my-icons'
},
],
},
})
或者,如果您想完全停用動態圖示獲取,只使用來自客戶端打包的圖示,您可以設定 provider: 'none'
export default defineNuxtConfig({
icon: {
provider: 'none',
clientBundle: {
scan: true,
// ...or other bundle options
},
}
})
區分大小寫的自定義集合
在 v1.10
之前,由於 Iconify 之前約定的限制,所有自定義圖示都被規範化為 kebab-case
併發出警告。感謝 Iconify 方面的更新,從 v1.10
開始,您可以選擇使用區分大小寫的自定義集合並繞過規範化。
export default defineNuxtConfig({
modules: [
'@nuxt/icon'
],
icon: {
customCollections: [
{
prefix: 'my-icon',
dir: './assets/my-icons',
normalizeIconName: false, // <-- this
},
],
},
})
例如,這使得可以將 assets/my-icons/FooBar.svg
用作 my-icon:FooBar
。
normalizeIconName
預設為 true
以實現向後相容,並將在未來的主要版本中翻轉。有關更多上下文,請參見 #265。
圖示定製
要更新 <Icon />
的預設大小(1em
),請建立一個包含 icon.size
屬性的 app.config.ts
。
使用 icon.class
屬性更新 <Icon />
的預設類(.icon
),對於無頭圖示,請設定 icon.class: ''
。
您還可以定義別名,透過利用 icon.aliases
屬性,使圖示替換更容易。
!NOTE 請注意,執行時配置是
app.config.ts
而不是nuxt.config.ts
。
// app.config.ts
export default defineAppConfig({
icon: {
size: '24px', // default <Icon> size applied
class: 'icon', // default <Icon> class applied
mode: 'css', // default <Icon> mode applied
aliases: {
'nuxt': 'logos:nuxt-icon',
},
cssLayer: 'base' // set the css layer to inject to
}
})
圖示的預設大小將為 24px
,並且 nuxt
圖示將可用。
<Icon name="nuxt" />
預設情況下,此模組將建立一個伺服器端點 /api/_nuxt_icon/:collection
來從您的本地伺服器 bundle 提供圖示(您可以透過設定 icon.localApiEndpoint
為您想要的路徑來覆蓋預設路徑)。當請求本地 bundle 中不存在的圖示時,它將回退到請求官方 Iconify API。您可以透過將 icon.fallbackToApi
設定為 false
來停用回退,或者設定您自己的 Iconify API 並將 icon.iconifyApiEndpoint
更新為您自己的 API 端點。
使用 customize 選項自定義圖示
customize 選項允許您修改專案中使用的 SVG 圖示的各個方面。透過此選項,您可以:
- 更改描邊寬度
- 更改顏色
- 更改動畫持續時間
- 更改不透明度
- 新增額外形狀
透過這些自定義選項,您可以完全控制 SVG 內容。
在元件中 您可以在元件中定義一個自定義函式,以對圖示應用各種修改。
<script setup lang="ts">
// Define the customize function to modify SVG content
const customize = (content: string, name: string, prefix: string, provider: string) => {
if (prefix !== 'tabler') return content // Ignore Prefix
return content
.replace(/stroke-width="[^"]*"/g, `stroke-width="2"`) // Change stroke width to 2
.replace(/stroke="[^"]*"/g, `stroke="#FF5733"`) // Change stroke color to red
.replace(/fill="[^"]*"/g, `fill="#FF5733"`) // Change fill color to red
.replace(/animation-duration="[^"]*"/g, `animation-duration="1s"`) // Change animation duration to 1s (for animated icons)
.replace(/opacity="[^"]*"/g, `opacity="0.8"`);// Change opacity to 0.8
}
</script>
<template>
<Icon name="tabler:star" :customize="customize" />
</template>
<!-- You can also use `:customize="false"` to disabled the global customization function per-usage -->
在應用程式配置檔案中
或者,您可以在 app.config.ts
檔案中全域性應用這些自定義。
// app.config.ts
export default defineAppConfig({
icon: {
customize: (content: string, name: string, prefix: string, provider: string) => {
// ...
},
}
})
透過此配置,您的應用程式中的所有圖示都將始終應用這些自定義。
伺服器 Bundle
自 @nuxt/icon
v1.0 起,我們引入了伺服器 bundle 的概念,用於從 Nuxt 伺服器端點提供圖示。這使得客戶端 bundle 保持精簡,並能夠按需載入圖示,同時擁有所有動態功能來使用在構建時可能未知的圖示。
伺服器 Bundle 模式: local
此模式將把您本地安裝的圖示集合(例如 @iconify-json/*
)打包到您的伺服器 bundle 中作為動態塊。集合資料將按需載入,僅當您的客戶端從該集合請求圖示時。
伺服器 Bundle 模式: remote
在 @nuxt/icon
v1.2 中引入,您現在可以使用 remote
伺服器 bundle 從遠端 CDN 提供圖示。
export default defineNuxtConfig({
modules: [
'@nuxt/icon'
],
icon: {
serverBundle: 'remote',
},
})
或者您可以指定遠端提供者
export default defineNuxtConfig({
modules: [
'@nuxt/icon'
],
icon: {
serverBundle: {
remote: 'jsdelivr', // 'unpkg' or 'github-raw', or a custom function
}
},
})
這將向 https://cdn.jsdelivr.net/npm/@iconify-json/ph/icons.json
發出伺服器請求,以在執行時獲取圖示,而不是將它們與伺服器捆綁在一起。
在底層,它不再將 () => import('@iconify-json/ph/icons.json')
打包到您的伺服器 bundle 中,而是使用類似 () => fetch('https://cdn.jsdelivr.net/npm/@iconify-json/ph/icons.json').then(res => res.json())
的程式碼,其中集合未內聯。
當伺服器 bundle 大小是問題時,例如在無伺服器或 Worker 環境中,這將很有用。
伺服器 Bundle 模式: auto
這是預設選項,模組將根據您的部署環境在 local
和 remote
之間選擇。local
將是首選,除非您部署到無伺服器或工作器環境,例如 Vercel Edge 或 Cloudflare Workers。
外部化圖示 JSON
預設情況下,Nitro 會將您本地安裝的圖示集合(例如 @iconify-json/*
)打包到您的伺服器 bundle 中作為動態塊。當您有大量圖示時,這可能會使您的打包過程變慢並消耗大量記憶體。您可以透過將 icon.serverBundle.externalizeIconsJson
設定為 true
來外部化圖示 JSON 檔案。
export default defineNuxtConfig({
modules: [
'@nuxt/icon'
],
icon: {
serverBundle: {
externalizeIconsJson: true,
}
},
})
請注意,這將要求您的生產 Node.js 伺服器能夠匯入 JSON 檔案(請注意,截至 Node.js v22,JSON 模組仍然是實驗性功能)。在最終構建中,它將包含類似 () => import('@iconify-json/ph/icons.json', { with: { type: 'json' } })
的語句。
另請注意,在某些無伺服器環境中,例如 Cloudflare Workers,它們沒有動態匯入,無論此選項如何,它們都將始終內聯。
當 icon.serverBundle.remote
啟用時,此選項將被忽略。
完全停用伺服器 Bundle
如果您想完全停用伺服器 bundle,您可以將 icon.serverBundle
設定為 false
並將 provider
設定為 iconify
。
export default defineNuxtConfig({
modules: [
'@nuxt/icon'
],
icon: {
provider: 'iconify',
serverBundle: false,
},
})
這將導致每次客戶端請求圖示時都向 Iconify API 發出請求。除非其他選項不可行,否則我們不建議這樣做。
客戶端 Bundle
對於您知道會經常使用的圖示,您可以將它們與客戶端 bundle 打包,以避免網路請求。
export default defineNuxtConfig({
modules: [
'@nuxt/icon'
],
icon: {
clientBundle: {
// list of icons to include in the client bundle
icons: [
'uil:github',
'logos:vitejs'
],
// scan all components in the project and include icons
scan: true,
// include all custom collections in the client bundle
includeCustomCollections: true,
// guard for uncompressed bundle size, will fail the build if exceeds
sizeLimitKb: 256,
},
},
})
includeCustomCollections
將把您在 icon.customCollections
中定義的所有自定義集合都包含在客戶端 bundle 中。預設情況下它是停用的,但在設定 ssr: false
時將自動啟用。
掃描元件
當 scan
啟用時,模組將掃描專案中的所有元件,並將使用的圖示包含在客戶端 bundle 中。這將顯著減少靜態已知圖示所需的網路請求數量,但根據專案中使用的圖示數量,也可能會增加客戶端 bundle 的大小。
您還可以微調掃描目標,例如
export default defineNuxtConfig({
modules: [
'@nuxt/icon'
],
icon: {
clientBundle: {
scan: {
// note that when you specify those values, the default behavior will be overridden
globInclude: ['components/**/*.vue', /* ... */],
globExclude: ['node_modules', 'dist', /* ... */],
},
},
},
})
!TIP 掃描依賴於靜態分析,這意味著只檢測字面用法。應儘可能避免動態構造圖示名稱。
<template> <!-- Avoid this --> <Icon :name="`carbon:${dark ? 'moon' : 'sun'}`" /> <!-- Prefer this --> <Icon :name="dark ? 'carbon:moon' : 'carbon:sun'" /> </template>
渲染函式
您可以在渲染函式中使用 Icon
元件(如果您建立了一個函式式元件,這將很有用),為此您可以從 #components
匯入它
import { Icon } from '#components'
請參閱 <MyIcon>
元件的示例
<script setup>
import { Icon } from '#components'
const MyIcon = h(Icon, { name: 'uil:twitter' })
</script>
<template>
<p><MyIcon /></p>
</template>
貢獻 🙏
- 克隆此倉庫
- 使用
pnpm install
安裝依賴項(使用corepack enable
安裝pnpm
,瞭解更多) - 執行
npm run dev:prepare
以生成型別存根。 - 使用
npm run dev
以開發模式啟動 playground。
鳴謝 💌
- @benjamincanac 提供了初始版本
- @cyberalien 創作了 Iconify