图标数据来源
图标数据来源的方式有两种:
- 从外部下载需要的图标数据到本地
- 按照特定图标库的使用方式引入一系列图标,比如 Font Awesome
Iconify
一个图标框架,将流行的图标库集成在一起,通过一种方式方便地使用来自多个图标库的数据,支持通过 Vue 框架引入
在线图标
iconify 提供一个 vue 组件用于在线动态加载图标,即使用到的图标数据不会打包进构建产物中也能使用各种图标数据
安装依赖
pnpm add @iconify/vue使用
<script setup lang="ts">
import { Icon } from '@iconify/vue'
</script>
<template>
<Icon icon="mdi-light:home"></Icon>
</template>mdi-light 表示使用的图标集,可选的图标集在这里查看
home 表示该图标集下的图标名称
现在可以在线动态加载图标了,但是仅限于可以使用外网的情况下
离线图标
如果项目只能在内网环境部署,那么 iconify 提供的 vue 组件就无法获取图标数据,虽然 iconify 也提供了离线图标的方式,但方式比较繁琐,因此有了 PurgeIcons 这个机制,这个机制会在构建后将图标数据嵌入到 DOM 中,不会发起任何请求,同时构建产物只包含使用到的图标数据,不会增加多余的打包体积
它提供了多种方式使用这个机制,下面用 vite 插件进行演示
安装依赖
pnpm add @iconify/iconifypnpm add --save-dev vite-plugin-purge-icons @iconify/json 其中 iconify/json 是可选的,代表所有图标数据,安装后,vite-plugin-purge-icons 会从本地读取图标数据,没有安装则尝试在线读取
配置
import PurgeIcons from 'vite-plugin-purge-icons'
export default {
plugins: [
PurgeIcons()
]
}导入 @purge-icons/generated 到 main.js 中
import { createApp } from 'vue'
import App from './App.vue'
import '@purge-icons/generated'
createApp(App).mount('#app')使用方式
<span class="iconify" data-icon="fa:home"></span>必须加上 class="iconify"
data-icon 属性值的形式和 @iconify/vue 一样
为了使用方便可以封装成一个组件 Icon.vue
<script setup lang="ts">
defineProps({
icon: {
type: String,
required: true
}
})
</script>
<template>
<span class="iconify" :data-icon="icon"></span>
</template>这样就达到了和 @iconify/vue 一样的引入图标方式
值得注意的是 PurgeIcons 文档里开头已经介绍到不再推荐这个使用图标的方式,而且仓库已经归档不再维护,不过我是为了兼容以前写法才继续选用这个方式
另外,如果你想实现动态切换图标,那就得绕给远路兼容一下,因为这个插件有个 bug 其没有被解决,猜测原因是基于 @iconify/iconfiy 的图标读取只在页面加载的运行时发生,但我们可以监听到图标变化后手动读取图标数据并插入到 DOM 中
<script setup lang="ts">
import { nextTick, ref, unref, watch } from 'vue'
const props = defineProps({
icon: {
type: String,
required: true
}
})
const elRef = ref<HTMLSpanElement | null>(null)
watch(
() => props.icon,
async () => {
const span = document.createElement('span')
span.className = 'iconify'
span.dataset.icon = props.icon
await nextTick()
const el = unref(elRef)
if (el) {
el.textContent = ''
el.appendChild(span)
}
},
{
immediate: true
}
)
</script>
<template>
<div ref="elRef" class="inline-block"></div>
</template>VSCode 插件
安装这个插件后可以通过图标名称在 VSCode 中预览对应图标
疑难解答
@purge-icons/generated没有安装,为什么可以使用?
虽然没有直接安装,但 vite-plugin-purge-icons 直接依赖了它,不过它是存在 node_modules/.pnpm 下,这里用于存储去重后的包,简单理解就多个依赖可能会共同依赖的包,node_modules 下的包都是通过软链指向该文件夹下的实际文件
理论上是可以直接引用的,但是不推荐这样做,会导致可读性降低,同时会存在构建工具无法解析的隐患,因此推荐直接安装一次 @purge-icons/geerated