创建components/SvgIcon/index.vue
组件
<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>
创建 utils/validate.ts
/**
* 判断是否为外部资源
*/
export function isExternal(path: string): boolean {
return /^(https?:|mailto:|tel:)/.test(path);
}
使用方法:
<span class="svg-container">
<svg-icon icon="https://res.lgdsunday.club/user.svg"></svg-icon>
</span>
处理内部 svg 图标显示
- 创建文件夹
src/icons
文件夹 - 创建
svg
文件夹用于存放svg
图标 - 创建
index.ts
文件
import SvgIcon from "../components/SvgIcon/index.vue";
import { App } from "vue";
// 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): void => {
app.component("svg-icon", SvgIcon);
};
- 在
main.ts
文件中引入该文件
// 导入 svgIcon
import installIcons from '@/icons'
const app = createApp(App);
installIcons(app)
使用方法:
// 用户名, user为具体的svg文件名
<svg-icon icon="user" />
// 密码
<svg-icon icon="password" />
// 眼睛
<svg-icon icon="eye" />
使用 svg-sprite-loader 处理 svg 图标
下载loader
执行,npm i --save-dev svg-sprite-loader
创建vue.config.js
文件
const path = require("path");
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();
}
}