Skip to content
0

unplugin-icons

Access thousands of icons as components on-demand universally.

Usage

安装

以 Vite + Vue 而言,我们需要安装插件,以及我们想要包含的图标集合,在这里可以找到所有有效的图标 iconesJs

$ npm i -D @iconify-json/twemoji unplugin-icons

配置和使用

vite.config.ts 中添加插件,然后就可以在任意的 .vue 文件当中使用所安装对应集合的图标

import Icons from 'unplugin-icons/vite'

export default defineConfig({
  plugins: [
    Icons({ /* options */ }),
  ],
})
<script setup>
    import Twemoji1stPlaceMedal from '~icons/twemoji/1st-place-medal'
</script>

<template>
  <Twemoji1stPlaceMedal style="font-size: 2em; color: red" />
</template>

原理

一些原理

Virtual Module

Virtual Modules Convention 是 Vite 插件 API 提供的一个功能,可以提供虚拟路径转换,将原本不存在的路径,转为插件内部提供的内容

对于 unplugin-icons 而言,就是将虚拟路径,例如上面的 ~icons/twemoji/1st-place-medal,转为 SVG 资源

resolveId 钩子中,通过 isIconPath 进行虚拟路径的匹配:

命中之后,由 load 钩子提供返回的内容:

generateComponentFromPath 中,主要做的有两件事情


  1. 根据 collection, icon 获得 SVG 字符串

来源于:iconify/iconify 这个库的内部暴露出来的方法

  1. 调用 @vue/compiler-sfc 将 SVG 字符串编译当作 Vue 组件进行编译,得到字符串

所以,对于路径 ~icons/twemoji/1st-place-medal 而言,会被编译成如下字符串:

`import { createElementVNode as _createElementVNode, openBlock as _openBlock, createElementBlock as _createElementBlock } from "vue"

const _hoisted_1 = {
  viewBox: "0 0 36 36",
  width: "1.2em",
  height: "1.2em"
}
const _hoisted_2 = /*#__PURE__*/_createElementVNode("path", {
  fill: "#55ACEE",
  d: "m18 8l-7-8H0l14 17l11.521-4.75z"
}, null, -1 /* HOISTED */)
const _hoisted_3 = /*#__PURE__*/_createElementVNode("path", {
  fill: "#3B88C3",
  d: "m25 0l-7 8l5.39 7.312l1.227-1.489L36 0z"
}, null, -1 /* HOISTED */)
const _hoisted_4 = /*#__PURE__*/_createElementVNode("path", {
  fill: "#FFAC33",
  d: "M23.205 16.026c.08-.217.131-.448.131-.693a2 2 0 0 0-2-2h-6.667a2 2 0 0 0-2 2c0 .245.05.476.131.693c-3.258 1.826-5.464 5.307-5.464 9.307C7.335 31.224 12.111 36 18.002 36s10.667-4.776 10.667-10.667c0-4-2.206-7.481-5.464-9.307z"
}, null, -1 /* HOISTED */)
const _hoisted_5 = /*#__PURE__*/_createElementVNode("path", {
  fill: "#9E5200",
  d: "M19.404 18.6h-1.721l-2.73 2.132a.528.528 0 0 0-.112.28v1.178c0 .186.15.354.337.354h1.795v8.414c0 .188.15.355.355.355h2.076c.186 0 .336-.168.336-.355V18.954c0-.186-.149-.354-.336-.354z"
}, null, -1 /* HOISTED */)
const _hoisted_6 = [
  _hoisted_2,
  _hoisted_3,
  _hoisted_4,
  _hoisted_5
]

function render(_ctx, _cache) {
  return (_openBlock(), _createElementBlock("svg", _hoisted_1, [..._hoisted_6]))
}

export default { name: 'twemoji-1st-place-medal', render }
/* vite-plugin-components disabled */`

这个字符串是一个有效的 ESM 导出,成功被赋值给了 Twemoji1stPlaceMedal,被当作 Vue 组件使用

<script setup>
    import Twemoji1stPlaceMedal from '~icons/twemoji/1st-place-medal'
</script>

<template>
  <Twemoji1stPlaceMedal style="font-size: 2em; color: red" />
</template>

最终渲染为一个 SVG,即

Released under the MIT License.