透過超過 100 個技巧的集合學習 Nuxt!

icon
@nuxt/icon

Nuxt 的圖示模組,提供來自 Iconify 的 200,000+ 個可立即使用的圖示。

nuxt-icon

Nuxt 圖示

npm versionnpm downloadsLicenseNuxtVolta board

200,000+ 個可立即使用的圖示新增到您的 Nuxt 應用程式,基於 Iconify

功能 ✨

  • Nuxt 3 準備就緒
  • 支援伺服器端渲染 (SSR)
  • 透過 Iconify 支援 200,000 個以上的開源向量圖示
  • 支援 CSS 模式 / SVG 模式
  • 自訂 SVG 支援(透過 Vue 元件或本地 SVG 檔案)

!注意 您目前正在查看此模組的 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:圖示渲染模式 (svgcss,預設值:css)

屬性:

當使用 Iconify 的圖示時,將根據渲染模式建立一個 <span><svg>,您可以給予原生元素的所有屬性

<Icon name="uil:github" style="color: black" />

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 安裝其集合。這樣,圖示可以在本地或從您的無伺服器函式提供,這在伺服器端渲染和客戶端都更快、更可靠。

!注意 您可能也知道可以安裝 @iconify/json 套件以包含所有 iconify 圖示。不建議這樣做,因為這會增加您的伺服器套件大小和建置效能。如果您選擇這樣做,我們建議您明確指定您需要的集合名稱

export default defineNuxtConfig({
  modules: ['@nuxt/icon'],
  icon: {
    serverBundle: {
      collections: ['uil', 'mdi'] // <!--- this
    }
  }
})

Vue 元件

name 符合全域註冊的元件時,它將作為該元件渲染(在這種情況下,mode 將被忽略)

<Icon name="MyComponent" />

請注意,MyComponent 需要位於 components/global/ 資料夾內 (請參閱範例)。

!提示 您也可以使用以下命令更改元件名稱

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'
      },
    ],
  },
})

然後您可以這樣使用圖示

<template>
  <Icon name="my-icon:foo" />
  <Icon name="my-icon:bar-outline" />
</template>

請注意,自訂本地集合需要您有一個伺服器來提供 API。當設定 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'
      },
    ],
  },
})

區分大小寫的自訂集合

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 屬性定義別名,以更輕鬆地交換圖示。

!注意 請注意,這是執行階段設定的 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',
    }
  }
})

圖示的預設大小將為 24px,並且將可以使用 nuxt 圖示

<Icon name="nuxt" />

預設情況下,此模組將建立伺服器端點 /api/_nuxt_icon/:collection,以從您的本地伺服器套件提供圖示 (您可以透過將 icon.localApiEndpoint 設定為您想要的路徑來覆寫預設路徑)。當請求在本地套件中不存在的圖示時,它將回退到請求 官方 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>

在應用程式設定檔中

或者,您可以將這些自訂全域套用在 app.config.ts 檔案中。

// app.config.ts
export default defineAppConfig({
  icon: {
    customize: (content: string, name: string, prefix: string, provider: string) => {
      // ...
    },
  }
})

透過此設定,整個應用程式中的所有圖示都將一致地套用這些自訂。

伺服器套件

@nuxt/icon v1.0 起,我們引入了伺服器套件概念,以從 Nuxt 伺服器端點提供圖示。這可讓客戶端套件保持精簡,並能夠按需載入圖示,同時具有在建置時可能未知的圖示的所有動態功能。

伺服器套件模式:local

此模式會將您在本地安裝的圖示集合(例如 @iconify-json/*)作為動態區塊綁定到您的伺服器套件中。集合資料將按需載入,僅當您的客戶端請求該集合的圖示時。

伺服器套件模式:remote

@nuxt/icon v1.2 中引入,您現在可以使用 remote 伺服器套件從遠端 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 發出伺服器請求,以在執行階段擷取圖示,而不是將其與您的伺服器綁定。

在底層,它現在將使用類似 () => fetch('https://cdn.jsdelivr.net/npm/@iconify-json/ph/icons.json').then(res => res.json()) 的程式碼,而不是將 () => import('@iconify-json/ph/icons.json') 綁定到您的伺服器套件中,其中集合不會內聯。

當伺服器套件大小是個問題時,例如在無伺服器或工作者環境中,這會很有用。

伺服器套件模式:auto

這是預設選項,模組將根據您的部署環境在 localremote 之間選擇。除非您要部署到無伺服器或工作者環境(例如 Vercel Edge 或 Cloudflare Workers),否則將首選 local

外部化圖示 JSON

預設情況下,Nitro 會將您本機安裝的圖示集合(例如 @iconify-json/*)作為動態區塊捆綁到您的伺服器捆綁包中。當您擁有大量的圖示時,這可能會使您的捆綁過程變慢且消耗大量記憶體。您可以將 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 啟用時,此選項將被忽略。

完全停用伺服器捆綁

如果您想完全停用伺服器捆綁,您可以將 icon.serverBundle 設定為 false,並將 provider 設定為 iconify

export default defineNuxtConfig({
  modules: [
    '@nuxt/icon'
  ],
  icon: {
    provider: 'iconify',
    serverBundle: false,
  },
})

這會使客戶端每次請求圖示時都向 Iconify API 發出請求。除非其他選項不可行,否則我們不建議這樣做。

客戶端捆綁

對於您知道會頻繁使用的圖示,您可以將它們與您的客戶端捆綁包一起捆綁,以避免網路請求。

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 中定義的所有自訂集合到客戶端捆綁包中。它預設為停用,但當設定 ssr: false 時會自動啟用。

掃描元件

scan 啟用時,模組將會掃描您專案中的所有元件,並包含客戶端捆綁包中使用的圖示。這將顯著減少靜態已知圖示所需的網路請求數量,但也可能會根據您專案中使用的圖示數量增加客戶端捆綁包的大小。

您也可以微調掃描目標,例如

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', /* ... */],
      },
    },
  },
})

!提示 掃描依賴於靜態分析,這表示只會偵測到字面用法。盡可能避免動態建構圖示名稱。

<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>

貢獻 🙏

  1. 複製此儲存庫
  2. 使用 pnpm install 安裝相依性(使用 corepack enable 安裝 pnpm了解更多
  3. 執行 npm run dev:prepare 以產生類型存根。
  4. 使用 npm run dev 以在開發模式下啟動 playground

感謝 💌

許可 📎

MIT 許可