Vue3+vite封装svg

本文介绍了如何在Vue3项目中利用vite构建一个SVG图标组件库。首先展示了SvgIcon.vue组件的代码,该组件通过`<use>`标签引用SVG符号来显示图标。接着,在main.js中全局注册了SvgIcon组件。然后,创建了一个svgBuilder.js插件,该插件读取SVG文件并转换为`<symbol>`标签,插入到HTML文档中。最后,在vite.config.js中使用svgBuilder插件,并展示了几个使用SvgIcon组件的例子。
摘要由CSDN通过智能技术生成

Vue文件

src/components/svgIcon/SvgIcon.vue

<template>
  <svg :class="svgClass" v-bind="$attrs" :style="{width,height,color}">
    <use :href="svgName"></use>
  </svg>
</template>

<script setup>
import {computed} from "vue";
const props = defineProps({
  //图标名称 如 home
  iconName: {
    type: String,
    default: ""
  },
  //对不同区域的 icon 样式调整,如字体大小
  className: {
    type: String,
    default: ""
  },
  width: {
    type: Number,
    default: 16
  },
  height: {
    type: Number,
    default: 16
  },
  color: {
    type: String,
    default: "#888"
  }
})

const svgName=computed(()=>`#icon-${props.iconName}`);
const svgClass=computed(()=>{
  if(props.name){
    return `svg-icon icon-${props.iconName}`
  }
  return `svg-icon`
})
</script>

<style>
.svg-icon {
  width: 16px;
  height: 16px;
  vertical-align: -0.15em;
  fill: currentColor; /*此属性为更改svg颜色属性设置*/
  stroke: currentColor;
  overflow: hidden;
  margin-right: 8px;
}
</style>

在main.js中引入SvgIcon组件

import SvgIcon from '@/components/svgIcon/SvgIcon.vue'  // 引入自定义组件

createApp(App)
    .use(store)
    .use(router)
    .component('svg-icon', SvgIcon)  // 注册到全局
    .mount('#app')

写个插件

创建文件svgBuilder.js

文件结构如下,svg中是svg的图片文件 就不打开了
在这里插入图片描述

插件代码

网上的代码

import { readFileSync, readdirSync } from "fs";

let idPerfix = "";
const svgTitle = /<svg([^>+].*?)>/;
const clearHeightWidth = /(width|height)="([^>+].*?)"/g;

const hasViewBox = /(viewBox="[^>+].*?")/g;

const clearReturn = /(\r)|(\n)/g;

function findSvgFile(dir) {
    const svgRes = [];
    const dirents = readdirSync(dir, {
        withFileTypes: true,
    });
    for (const dirent of dirents) {
        if (dirent.isDirectory()) {
            svgRes.push(...findSvgFile(dir + dirent.name + "/"));
        } else {
            const svg = readFileSync(dir + dirent.name)
                .toString()
                .replace(clearReturn, "")
                .replace(svgTitle, ($1, $2) => {
                    let width = 0;
                    let height = 0;
                    let content = $2.replace(clearHeightWidth, (s1, s2, s3) => {
                        if (s2 === "width") {
                            width = s3;
                        } else if (s2 === "height") {
                            height = s3;
                        }
                        return "";
                    });
                    if (!hasViewBox.test($2)) {
                        content += `viewBox="0 0 ${width} ${height}"`;
                    }
                    return `<symbol id="${idPerfix}-${dirent.name.replace(
                        ".svg",
                        ""
                    )}" ${content}>`;
                })
                .replace("</svg>", "</symbol>");
            svgRes.push(svg);
        }
    }
    return svgRes;
}

export const svgBuilder = (path, perfix = "icon") => {
    if (path === "") return;
    idPerfix = perfix;
    const res = findSvgFile(path);
    return {
        name: "svg-transform",
        transformIndexHtml(html) {
            return html.replace(
                "<body>",
                `
          <body>
            <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="position: absolute; width: 0; height: 0">
              ${res.join("")}
            </svg>
        `
            );
        },
    };
};

使用插件

在vite.config.js中使用插件

export default defineConfig({
    // 配置需要使用的插件列表,这里将vue添加进去
    plugins: [
      vue(),
      svgBuilder("./src/components/svgIcon/svg/"),
      AutoImport({
        resolvers: [ElementPlusResolver()],
      }),
      Components({
        resolvers: [ElementPlusResolver()],
      })
    ],
})

使用SvgIcon组件

代码

  <svg-icon iconName="home"/>
  <svg-icon iconName="menu"/>
  <svg-icon iconName="list" :width="30" :height="30" color="red"/>

效果

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值