icon
@nuxt/icon

Nuxt 的圖示模組,包含 20 萬+來自 Iconify 的即用圖示。

nuxt-icon

Nuxt Icon

npm versionnpm downloadsLicenseNuxtVolta board

為您的 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: 圖示渲染模式 (svgcss, 預設: 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

這是預設選項,模組將根據您的部署環境在 localremote 之間選擇。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>

貢獻 🙏

  1. 克隆此倉庫
  2. 使用 pnpm install 安裝依賴項(使用 corepack enable 安裝 pnpm瞭解更多
  3. 執行 npm run dev:prepare 以生成型別存根。
  4. 使用 npm run dev 以開發模式啟動 playground

鳴謝 💌

許可證 📎

麻省理工學院許可證