Vite通过本地svg图标合集生成雪碧图用于整合SvgIcon组件

188 阅读1分钟

添加插件

安装vite-plugin-svg-icons,sass-embedded

pnpm add -D vite-plugin-svg-icons sass-embedded
"vite-plugin-svg-icons": "^2.0.1",
"sass-embedded": "^1.83.0",

/src/assets/ 下新建 svg 文件夹目录

image.png

新建Base组件 SvgIcon

  • /src/components/base/svg-icon/index.vue
<template>
  <svg
    :class="$options.name"
    v-bind="$attrs"
    aria-hidden="true"
    :style="{ width: size + 'px', height: size + 'px' }"
  >
    <use :xlink:href="symbolId" />
  </svg>
</template>

<script setup lang="tsx" name="SvgIcon">
  import { computed } from 'vue';

  const props = defineProps<{
    prefix?: string;
    icon: string;
    size: number;
    color: string;
    stroke: string;
  }>();
  const symbolId = computed(
    () =>
      `#${
        props.prefix ? `${props.prefix}-${props.icon}` : `icon-${props.icon}`
      }`
  );
</script>

<style lang="scss" scoped>
  .SvgIcon {
    fill: currentColor;
  }
</style>

修改/src/config/vite.config.base.ts配置

...
import { createSvgIconsPlugin } from "vite-plugin-svg-icons";
import { resolve } from 'path';

export default defineConfig({
  plugins: [
    vue(),
    vueJsx(),
    VueSetupExtend(),
    svgLoader({ svgoConfig: {} }),
    configArcoStyleImportPlugin(),
    // @ts-ignore
    createSvgIconsPlugin({
      iconDirs: [resolve(process.cwd(), 'src/assets/svg')],
      // 指定 symbolId 格式,默认是 '[dir]-[name]'
      symbolId: 'icon-[dir]-[name]',
      /**
       * 自定义插入位置,默认是在 body 最后
       * 支持多位置插入,默认值:[]
       */
      inject: 'body-last',
      /**
       * custom dom id,默认值:__svg__icons__dom__
       */
      customDomId: '__svg__icons__dom__',
    })
  ],
...

修改/src/components/index.ts全局引入SvgIcon组件

...
import SvgIcon from './base/svg-icon/index.vue';

...
export default {
  install(Vue: App) {
    Vue.component('Chart', Chart);
    Vue.component('Breadcrumb', Breadcrumb);
    Vue.component('CountryFlag', CountryFlag);
    Vue.component('SvgIcon', SvgIcon);
  },
};
...

修改src/main.ts

  • src/main.ts
// eslint-disable-next-line import/no-unresolved
import 'virtual:svg-icons-register';

到这里 svg 雪碧图就生成

svg 目录结构

# src/icons

- icon1.svg
- icon2.svg
- icon3.svg
- dir/icon1.svg

使用

<SvgIcon icon="icon1" size="20" />
<SvgIcon icon="dir-icon1" size="20" />

获取所有 SymbolId

import ids from 'virtual:svg-icons-names'
// => ['icon-icon1','icon-icon2','icon-icon3', 'icon-dir-icon1']

官方文档

vite-plugin-svg-icons

框架搭建

ArcoPro自用:Vue3 + Vite6 + Vue-Router4 + Vue-18n + Tailwindcss + Tsx(Jsx) + Pinia