webpack使用svg-sprite-loader传送门
vite使用vite-plugin-svg-icons传送门
步骤、原理详细介绍在↑。
下面是步骤总结:
svg-sprite-loader:
- 安装依赖:yarn add svg-sprite-loader -D
- vue.config.js配置插件。需要先移除原先的svg规则,再单独处理。
const { defineConfig } = require("@vue/cli-service");
const path = require("path");
function resolve(dir) {
return path.join(__dirname, dir);
}
module.exports = defineConfig({
chainWebpack: (config) => {
config.module.rule("svg").exclude.add(resolve("src/assets/svg")).end();
config.module
.rule("svg-sprite-loader")
.test(/\.svg$/)
.include.add(resolve("src/assets/svg")) // 处理svg目录
.end()
.use("svg-sprite-loader")
.loader("svg-sprite-loader")
.options({
symbolId: "icon-[name]",
});
},
});
- main.js全局导入目录下的svg。但不懂,为啥配置了插件后,仍需导入动作。
const req = require.context("/src/assets/svg", true, /\.svg$/);
req.keys().forEach(req);
- 定义svgIcon.vue组件
<template>
<svg :class="svgClass" aria-hidden="true">
<use :xlink:href="iconName" />
</svg>
</template>
<script setup>
import { computed } from "vue";
const props = defineProps({
name: {
type: String,
required: true,
},
className: {
type: String,
default: () => "",
},
});
const iconName = computed(() => {
console.log(`#icon-${props.name}`);
return `#icon-${props.name}`;
});
const svgClass = computed(() => {
return props.className ? "svg-icon " + props.className : "svg-icon";
});
</script>
<style scoped lang="scss">
.svg-icon {
width: 1em;
height: 1em;
vertical-align: middle;
fill: currentColor;
}
</style>
- 使用
<svg-icon name="cancel1" />
vite-plugin-svg-icons:
- 安装依赖:yarn add vite-plugin-svg-icons fast-glob -D
- vite.config.js 配置插件
import { fileURLToPath, URL } from 'node:url'
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import vueJsx from '@vitejs/plugin-vue-jsx'
import { createSvgIconsPlugin } from 'vite-plugin-svg-icons'
// https://vitejs.dev/config/
export default defineConfig({
plugins: [
vue(),
vueJsx(),
// 注册所有的svg文件生成svg雪碧图
createSvgIconsPlugin({
iconDirs: [fileURLToPath(new URL('./src/assets/svg', import.meta.url))], // icon存放的目录
symbolId: 'icon-[name]', // symbol的id
inject: 'body-last', // 插入的位置
customDomId: '__svg__icons__dom__' // svg的id
})
],
resolve: {
alias: {
'@': fileURLToPath(new URL('./src', import.meta.url))
}
}
})
- main.js引入一个???
import "virtual:svg-icons-register"
- 定义svg组件和使用。同上不重复了。