Vue 3.0 中封装icon组件使用外部SVG图标

通常在企业级项目开发时,所使用的 icon 图标,一共分为两类:

  1. element-plus 的图标

  2. 自定义的 svg 图标

对于 element-plus 的图标我们可以直接通过 el-icon 来进行显示,但是自定义图标的话却无法正常显示,所以就需要一个自定义的组件,来显示我们自定义的 svg 图标。

对于这个组件的话,它就需要拥有两种能力:

  1. 显示外部 svg 图标

  2. 显示项目内的 svg 图标

下面将向大家介绍如何实现这个组件的开发:

1. 处理外部 svg 图标显示

1.1. 创建组件

html 复制代码
<!-- components/SvgIcon/index.vue -->

<template>
    <div
        v-if="isExternal"
        :class="className"
        :style="styleExternalIcon"
        class="svg-external-icon svg-icon"
    />
    <svg v-else class="svg-icon" :class="className" aria-hidden="true">
        <use :xlink:href="iconName" />
    </svg>
</template>


<script setup>
import { defineProps, computed } from "vue";

const props = defineProps({
    icon: {
        type: String,
        required: true,
    },
    className: {
        type: String,
        default: "",
    }
});


// 判断外部方法
const  isExternalPath=(path)=> {
    return /^(https?:|mailto:|tel:)/.test(path)
}

// 判断是否外部
const isExternal = computed(() => isExternalPath(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;
    overflow: hidden;
    fill: currentColor;
    vertical-align: -0.15em;
}

.svg-external-icon {
    background-color: currentColor;
    mask-size: cover !important;
    display: inline-block;
}
</style>

1.2. 页面引入定义的组件

javascript 复制代码
import SvgIcon from '@/components/SvgIcon/index.vue'

1.3. 页面中使用组件

html 复制代码
<span class="svg-container">
	<svg-icon icon="https://res.lgdsunday.club/user.svg"></svg-icon>
</span>

2. 处理内部 svg 图标显示

2.1. 导入项目需要使用的图标

2.2. 引入图标并全局注册

如上图所示,添加一个index.js文件,代码如下:

javascript 复制代码
// icons/index.js

import SvgIcon from "@/components/SvgIcon";

// 通过函数实现自定义上下文
const svgRequire = require.context("./svg", false, /\.svg$/);
svgRequire.keys().forEach((svgIcon) => svgRequire(svgIcon));

export default (app) => {
    app.component("svg-icon", SvgIcon);
};

2.3. 在 main.js 中引入该文件

javascript 复制代码
// main.js
...
// 导入 svgIcon
import installIcons from '@/icons'
...
installIcons(app)
...

2.4. 在页面中使用组件

html 复制代码
// 用户名   
<svg-icon icon="user" />
// 密码
<svg-icon icon="password" />
// 眼睛
<svg-icon icon="eye" />

注意:由于组件在全局注册了,局部页面中无需额外导入。

3. 使用 svg-sprite-loader 处理 svg 图标

为了让图标正常展示,还要给webpack添加一个loader,而svg-sprite-loader 是 webpack 中专门用来处理 svg 图标的一个 loader 。

3.1. 安装loader

javascript 复制代码
npm i --save-dev svg-sprite-loader@6.0.9

3.2. 配置loader

创建 vue.config.js 文件,新增如下配置:

javascript 复制代码
const path = require("path");
function resolve(dir) {
    return path.join(__dirname, dir);
}

module.exports = {
    chainWebpack(config) {
        // 设置 svg-sprite-loader
        config.module.rule("svg").exclude.add(resolve("src/icons")).end();
        config.module
            .rule("icons")
            .test(/\.svg$/)
            .include.add(resolve("src/icons"))
            .end()
            .use("svg-sprite-loader")
            .loader("svg-sprite-loader")
            .options({
                symbolId: "icon-[name]",
            })
            .end();
    },
};
相关推荐
咬人喵喵5 天前
E2.COOL 平台深度解析:从特效分类到实战操作指南
前端·编辑器·svg
是席木木啊6 天前
前端接口熔断:概念、场景、自定义封装及企业级库对比
性能优化·前端开发·接口熔断
尘中客6 天前
放弃 Echarts?前端直接渲染后端高精度 SVG 矢量图流的踩坑记录
前端·javascript·echarts·前端开发·svg矢量图·echarts避坑
烛衔溟9 天前
TypeScript 特殊类型与空值安全
安全·typescript·前端开发·空值处理
烛衔溟11 天前
TypeScript 基础类型(上):string、number、boolean 与类型注解
javascript·typescript·前端开发·类型注解
烛衔溟11 天前
TypeScript 基础类型(下):数组、元组与枚举
typescript·前端开发·枚举·数组·元组
漠月瑾-西安13 天前
JavaScript 字符串处理技巧:substring 与 indexOf 的灵活组合
javascript·前端开发·indexof·代码优化·substring·字符串处理
叫我一声阿雷吧19 天前
JS 入门通关手册(24):Promise:从回调地狱到异步优雅写法
javascript·前端开发·promise·前端面试·异步编程·js进阶·js异步
yusheng_xyb19 天前
使用TypeScript与React构建高效用户界面
typescript·react·前端开发
咬人喵喵21 天前
植树节主题核心 SVG 交互玩法 + 品牌 / 账号案例 + 组件 / 教程
前端·css·编辑器·svg·e2编辑器