vue 使用svg
webpack 使用插件
npm i --save-dev svg-sprite-loader@6.0.9
vue.config.js
const path = require('pavueth'); function resolve(dir) { return path.join(__dirname, dir); } module.exports = { chainWebpack(config) { // 设置 svg-sprite-loader // config 为 webpack 配置对象 // config.module 表示创建一个具名规则,以后用来修改规则 config.module // 规则 .rule('svg') // 忽略 .exclude.add(resolve('src/icons')) // 结束 .end(); // config.module 表示创建一个具名规则,以后用来修改规则 config.module // 规则 .rule('icons') // 正则,解析 .svg 格式文件 .test(/\.svg$/) // 解析的文件 .include.add(resolve('src/icons')) // 结束 .end() // 新增了一个解析的loader .use('svg-sprite-loader') // 具体的loader .loader('svg-sprite-loader') // loader 的配置 .options({ symbolId: 'icon-[name]', }) // 结束 .end(); }, };
放置svg
icon/index.js
import SvgIcon from '@/components/SvgIcon';
// https://webpack.docschina.org/guides/dependency-management/#requirecontext
// 通过 require.context() 函数来创建自己的 context
const svgRequire = require.context('./svg', false, /\.svg$/);
// 此时返回一个 require 的函数,可以接受一个 request 的参数,用于 require 的导入。
// 该函数提供了三个属性,可以通过 require.keys() 获取到所有的 svg 图标
// 遍历图标,把图标作为 request 传入到 require 导入函数中,完成本地 svg 图标的导入
svgRequire.keys().forEach((svgIcon) => svgRequire(svgIcon));
export default (app) => {
app.component('svg-icon', SvgIcon);
};
main.js
import installIcons from '@/icons'; const app = createApp(App); installIcons(app);
<template> <div v-if="isExternal" :style="styleExternalIcon" class="svg-external-icon svg-icon" :class="className" /> <svg v-else class="svg-icon" :class="className" aria-hidden="true"> <use :xlink:href="iconName" /> </svg> </template> <script setup> import { isExternal as external } from '@/utils/validate'; import { defineProps, computed } from 'vue'; const props = defineProps({ // icon 图标 icon: { type: String, required: true, }, // 图标类名 className: { type: String, default: '', }, }); /** * 判断是否为外部图标 */ const isExternal = computed(() => external(props.icon)); /** * 外部图标样式 */ const styleExternalIcon = computed(() => ({ mask: `url(${props.icon}) no-repeat 50% 50%`, '-webkit-mask': `url(${props.icon}) no-repeat 50% 50%`, })); /** * 项目内图标 */ const iconName = computed(() => `#icon-${props.icon}`); </script> <style scoped> .svg-icon { width: 1em; height: 1em; vertical-align: -0.15em; fill: currentColor; overflow: hidden; } .svg-external-icon { background-color: currentColor; mask-size: cover !important; display: inline-block; } </style>
使用
<svg-icon id="guide-lang" icon="language" />
调整svg颜色
::v-deep .svg-icon {
color: #e2e2e2;
}