vite生成雪碧图的方法

SVG图标精灵图(雪碧图)可以通过将多个SVG图标合并成一个单独的SVG文件。这种方法可以减少HTTP请求,提高页面加载速度和性能。

一、使用vite-plugin-svg-spritemap生成雪碧图

1、安装依赖

css 复制代码
npm i vite-plugin-svg-spritemap -D

2、配置

php 复制代码
import { svgSpritemap } from 'vite-plugin-svg-spritemap'
{
  plugins: [
    ...
    svgSpritemap({
      pattern: 'src/xxx/*.svg', // 需要处理的svg路径
      filename: 'static/spritemap_home.svg', // 生成的精灵图路径
      currentColor: false,
      svgo: {
        plugins: [
          {
            name: 'preset-default',
            params: {
              overrides: {
                removeViewBox: false,
                removeEmptyAttrs: false,
                moveGroupAttrsToElems: false,
                // collapseGroups: false,
                removeDimensions: false,
                cleanupIds: {
                  preservePrefixes: ['sprite-'],
                },
              },
            },
          },
        ],
      },
    }),
  ],
}

想要生成多个精灵图,配置多组plugin即可

3、使用

typescript 复制代码
// name:原svg文件名
export const Icon: React.FC<{ name: string }> = ({ name }) => (
  <svg xmlns="http://www.w3.org/2000/svg" xmlnsXlink="http://www.w3.org/1999/xlink">
    <use xlinkHref={`/static/spritemap_home.svg#${name}`} />
  </svg>
);

const App = () => {
  return <Icon name="arrow" />;
};

二、使用vite-plugin-svg-icons生成雪碧图

  1. 首先,安装vite-plugin-svg-icons

    npm install vite-plugin-svg-icons -D

  • 在Vite配置文件中(例如vite.config.jsvite.config.ts),配置插件:

    import { createSvgIconsPlugin } from 'vite-plugin-svg-icons'; export default {

    plugins: [

    createSvgIconsPlugin({

    // 指定要搜索图标的文件夹

    iconDirs: [path.resolve(process.cwd(), 'src/icons')], // 指定要忽略的文件

    ignores: [],

    // 生成的symbol id的前缀 symbolId: 'icon-[dir]-[name]', /** * 自定义插入位置 * @default: body-last */ inject?: 'body-last' | 'body-first'

    css 复制代码
            /**
             * custom dom id
             * @default: __svg__icons__dom__
             */
            customDomId: '__svg__icons__dom__',
        }),  
     ],

    };

确保你的项目中有一个包含SVG图标的目录(如src/icons)。

  • 使用图标时,可以像下面这样引入:

1)单独引入一个svg可以像如下方式引入

import IconUser from '~/icons/user.svg?svg'; // 在模板或组件中使用

在上述配置中,插件会扫描src/icons目录下的所有SVG文件,并生成一个SVG雪碧图文件,在HTML中通过<use>标签引用时会使用该雪碧图。

请注意,具体的配置可能会根据你的项目结构和需求有所不同,你可能需要根据vite-plugin-svg-icons的文档调整配置。

2)组件中引入

  • 在 src/main.ts 内引入注册脚本

    import 'virtual:svg-icons-register'

vue方式

/src/components/SvgIcon.vue

xml 复制代码
<template>
  <svg aria-hidden="true">
    <use :xlink:href="symbolId" :fill="color" />
  </svg>
</template>

<script>
import { defineComponent, computed } from 'vue'

export default defineComponent({
  name: 'SvgIcon',
  props: {
    prefix: {
      type: String,
      default: 'icon',
    },
    name: {
      type: String,
      required: true,
    },
    color: {
      type: String,
      default: '#333',
    },
  },
  setup(props) {
    const symbolId = computed(() => `#${props.prefix}-${props.name}`)
    return { symbolId }
  },
})
</script>

icons 目录结构

markdown 复制代码
# src/icons

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

/src/App.vue

xml 复制代码
<template>
  <div>
    <SvgIcon name="icon1"></SvgIcon>
    <SvgIcon name="icon2"></SvgIcon>
    <SvgIcon name="icon3"></SvgIcon>
    <SvgIcon name="dir-icon1"></SvgIcon>
  </div>
</template>

<script>
import { defineComponent, computed } from 'vue'

import SvgIcon from './components/SvgIcon.vue'
export default defineComponent({
  name: 'App',
  components: { SvgIcon },
})
</script>

React 方式

/src/components/SvgIcon.jsx

javascript 复制代码
export default function SvgIcon({
  name,
  prefix = 'icon',
  color = '#333',
  ...props
}) {
  const symbolId = `#${prefix}-${name}`

  return (
    <svg {...props} aria-hidden="true">
      <use href={symbolId} fill={color} />
    </svg>
  )
}

获取所有 SymbolId

python 复制代码
import ids from 'virtual:svg-icons-names'
// => ['icon-icon1','icon-icon2','icon-icon3']

配置说明

symbolId : icon-[dir]-[name]

[name]: svg 文件名

[dir]: 该插件的 svg 不会生成 hash 来区分,而是通过文件夹来区分. 如果iconDirs对应的文件夹下面包含这其他文件夹

例: 则生成的 SymbolId 为注释所写

bash 复制代码
# src/icons
- icon1.svg # icon-icon1
- icon2.svg # icon-icon2
- icon3.svg # icon-icon3
- dir/icon1.svg # icon-dir-icon1
- dir/dir2/icon1.svg # icon-dir-dir2-icon1

Typescript 支持

如果使用 Typescript,你可以在tsconfig.json内添加

json 复制代码
// tsconfig.json
{
  "compilerOptions": {
    "types": ["vite-plugin-svg-icons/client"]
  }
}

注意

虽然用文件夹来区分已经可以很大程度避免重名问题了,但是也会出现iconDirs包含多个文件夹,且文件名一样的 svg.

这个需要开发者自己规避下

相关推荐
孜然卷k2 分钟前
前端导出word文件,并包含导出Echarts图表等
前端·javascript
家里有只小肥猫23 分钟前
uniApp小程序保存canvas图片
前端·小程序·uni-app
前端大全25 分钟前
Chrome 推出全新的 DOM API,彻底革新 DOM 操作!
前端·chrome
八角丶37 分钟前
元素尺寸的获取方式及区别
前端·javascript·html
冴羽1 小时前
Svelte 最新中文文档教程(16)—— Context(上下文)
前端·javascript·svelte
前端小臻1 小时前
关于css中bfc的理解
前端·css·bfc
白嫖不白嫖1 小时前
网页版的俄罗斯方块
前端·javascript·css
HappyAcmen1 小时前
关于Flutter前端面试题及其答案解析
前端·flutter
顾比魁1 小时前
pikachu之CSRF防御:给你的请求加上“网络身份证”
前端·网络·网络安全·csrf
林的快手1 小时前
CSS文本属性
前端·javascript·css·chrome·node.js·css3·html5