Nuxt 图标
将 200,000 多个即用图标添加到您的 Nuxt 应用程序,基于 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" />
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 图标。不建议这样做,因为它会增加您的服务器包大小和构建性能。如果您选择这样做,我们建议您明确指定您需要的集合名称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'
},
],
},
})
然后您可以像这样使用图标
<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
属性来定义别名,以便更轻松地交换图标。
!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',
}
}
})
图标的默认大小为 24px
,并且可以使用 nuxt
图标
<Icon name="nuxt" />
默认情况下,此模块将创建一个服务器端点 /api/_nuxt_icon/:collection
,以从您的本地服务器包中提供图标(您可以通过将 icon.localApiEndpoint
设置为您想要的路径来覆盖默认路径)。当请求本地包中不存在的图标时,它将回退到请求 官方 Iconify API。您可以通过将 icon.fallbackToApi
设置为 false
来禁用回退,或者设置 您自己的 Iconify API 并将 icon.iconifyApiEndpoint
更新为您自己的 API 端点。
使用自定义选项自定义图标
自定义选项允许您修改项目中使用的 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.cn/npm/@iconify-json/ph/icons.json
发出服务器请求以在运行时获取图标,而不是将它们与您的服务器捆绑在一起。
在底层,它不会将 () => import('@iconify-json/ph/icons.json')
捆绑到您的服务器包中,而是使用类似 () => fetch('https://cdn.jsdelivr.net.cn/npm/@iconify-json/ph/icons.json').then(res => res.json())
的东西,其中集合不会内联。
当服务器包大小是一个问题时,例如在无服务器或工作环境中,这将非常有用。
服务器包模式:auto
这是默认选项,模块将根据您的部署环境在 local
和 remote
之间进行选择。除非您要部署到无服务器或工作环境,例如 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>
贡献 🙏
- 克隆此存储库
- 使用
pnpm install
安装依赖项(使用corepack enable
安装pnpm
,了解更多) - 运行
npm run dev:prepare
以生成类型存根。 - 使用
npm run dev
在开发模式下启动 playground。
致谢 💌
- @benjamincanac 的初始版本
- @cyberalien 创建了 Iconify