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();
    },
};
相关推荐
拜无忧19 小时前
前端,用SVG 模仿毛笔写字绘画,defs,filter
前端·css·svg
叫我阿柒啊3 天前
从Java全栈到前端框架:一次真实的面试对话与技术解析
java·javascript·typescript·vue·springboot·react·前端开发
叫我阿柒啊3 天前
从Java全栈到前端框架:一位程序员的实战之路
java·spring boot·微服务·消息队列·vue3·前端开发·后端开发
摘星编程3 天前
Cursor Pair Programming:在前端项目里用 AI 快速迭代 UI 组件
前端·人工智能·ui·typescript·前端开发·cursorai
布兰妮甜4 天前
封装Element UI中el-table表格为可配置列公用组件
vue.js·ui·el-table·前端开发·element-ui
伍哥的传说6 天前
Vite 插件 @vitejs/plugin-legacy 深度解析:旧浏览器兼容指南
vite·前端开发·vue3.js·polyfill·plugin-legacy·core-js·ie 11
叫我阿柒啊7 天前
从Java全栈开发到微服务架构:一次真实的面试实录
java·微服务·vue3·springboot·前端开发·后端开发·项目经验
叫我阿柒啊7 天前
Java全栈开发工程师的实战面试:从技术到业务场景
java·微服务·vue3·springboot·前端开发·后端开发·数据库优化
叫我阿柒啊11 天前
Java全栈工程师的实战面试:从基础到微服务的全面解析
java·数据库·vue.js·spring boot·微服务·前端开发·全栈开发