vue3实战-----封装和使用svg图标

在开发项目的时候经常会用到svg矢量图,使用SVG以后,页面上加载的不再是图片资源,这对页面性能来说是个很大的提升,我们SVG文件比img要小的很多,放在项目中几乎不占用资源。

1.安装和配置svg插件

安装SVG依赖插件:

npm install vite-plugin-svg-icons -D

vite.config.ts中配置插件:

import { createSvgIconsPlugin } from 'vite-plugin-svg-icons'
import path from 'path'
export default () => {
  return {
    plugins: [
      createSvgIconsPlugin({
        // Specify the icon folder to be cached
        iconDirs: [path.resolve(process.cwd(), 'src/assets/icons')],
        // Specify symbolId format
        symbolId: 'icon-[dir]-[name]',
      }),
    ],
  }
}

在main.ts入口文件导入:

//这是虚拟模块的引入方式,用于给脚手架插件在打包和开发时做相应的处理。
//Vite 和 Rollup 中都约定以 virtual: 作为虚拟模块的前缀:
import 'virtual:svg-icons-register'

2.解决引入虚拟模块失败的问题

如上引入了虚拟模块,可能会报错-----无法找到模块 ‘virtual:svg-icons-register’ 或其相应的类型声明。
在类型声明文件中追加配置:

declare module "virtual:svg-icons-register";

具体界面如下:
在这里插入图片描述
这时候文件就不爆红了。但这时候直接运行项目,可能会出现以下界面:
在这里插入图片描述
需要安装一下fast-glob插件:

 npm i fast-glob -D  

3.使用svg

进入阿里矢量图官网,随便选择一个矢量图,复制其代码:
在这里插入图片描述
新建phone.svg文件(路径必须与vite.config.ts中保持一致):
在这里插入图片描述
在phone.svg中粘贴刚才的svg代码:
在这里插入图片描述
然后去vue文件中测试一下:

<script setup lang="ts"></script>

<template>
  <div>
    <h1>svg测试</h1>
    <!-- svg是图标外层容器节点,内部需要结合use标签使用 -->
    <svg>
      <!-- xlink:href指定用哪一个图标,属性值必须是以"#icon-图标名字"的格式 -->
      <!-- fill可以设置图标的颜色 -->
      <use xlink:href="#icon-phone" fill="green"></use>
    </svg>
  </div>
</template>
<style scoped></style>

运行项目:
在这里插入图片描述
发现颜色未改变,这时候需要把phone.svg中的fill去掉:
在这里插入图片描述
刷新之后,颜色就改变了:
在这里插入图片描述

4.封装svg组件

新建svg组件文件:
在这里插入图片描述
components/SvgIcon/index.vue:

<template>
    <!-- svg:图标外层容器节点,内部需要与use标签结合使用 -->
    <svg :style="{ width, height }">
        <!-- xlink:href执行用哪一个图标,属性值务必#icon-图标名字 -->
        <!-- use标签fill属性可以设置图标的颜色 -->
        <use :xlink:href="prefix + name" :fill="color"></use>
    </svg>
</template>

<script setup lang="ts">
//接受父组件传递过来的参数
defineProps({
    //xlink:href属性值前缀
    prefix: {
        type: String,
        default: '#icon-'
    },
    //提供使用的图标名字
    name: String,
    //接受父组件传递颜色
    color: {
        type: String,
        default: ''
    },
    //接受父组件传递过来的图标的宽度
    width: {
        type: String,
        default: '16px'
    },
    //接受父组件传递过来的图标的高度
    height: {
        type: String,
        default: '16px'
    }
})
</script>
<style scoped></style>

使用一下svg组件:

<script setup lang="ts">
import SvgIcon from "./components/SvgIcon/index.vue";
</script>

<template>
  <div>
    <h3>svg测试</h3>
    <SvgIcon name="phone" color="pink" width="60" height="60"></SvgIcon>
  </div>
</template>
<style scoped></style>

运行项目发现组件生效:
在这里插入图片描述

5.自定义插件注册svg全局组件

svg在很多地方都会用到,直接把svg组件定义为全局组件更好。
在这里插入图片描述
上面components文件夹里面全部要注册为全局组件。需要在index.ts写以下代码:

//引入项目中全部的全局组件
import SvgIcon from './SvgIcon/index.vue'
import Pagination from './Pagination/index.vue'
import Category from './Category/index.vue'
//引入element-plus提供全部图标组件
import * as ElementPlusIconsVue from '@element-plus/icons-vue'
//全局对象
const allGloablComponent: any = { SvgIcon, Pagination, Category }
//对外暴露插件对象
export default {
  //务必叫做install方法
  install(app: any) {
    //注册项目全部的全局组件
    Object.keys(allGloablComponent).forEach((key) => {
      //注册为全局组件
      app.component(key, allGloablComponent[key])
    })
    //将element-plus提供图标注册为全局组件
    for (const [key, component] of Object.entries(ElementPlusIconsVue)) {
      app.component(key, component)
    }
  },
}

然后再main.ts中挂载使用:

import gloablComponent from './components/index';
app.use(gloablComponent);

这样子一个自定义插件就完成了。

### Vue 中引入渲染 SVG 文件的方法 在 Vue 项目中,可以通过多种方式引入渲染 SVG 文件。以下是几种常见且高效的方法: #### 1. 使用 URL 引入 SVG 文件 可以将 SVG 文件作为静态资源,通过 URL 的方式引入到项目中。这种方法适用于简单的场景,例如需要直接插入 SVG 图标时。 ```html <img src="/path/to/your-icon.svg" alt="SVG Icon" /> ``` 这种方式的优点是简单易用,但缺点是无法直接修改 SVG 的颜色等属性[^1]。 #### 2. 使用 `vite-svg-loader`(适用于 Vite 项目) 对于基于 Vite 的 Vue 项目,可以使用 `vite-svg-loader` 来加载 SVG 文件,并将其作为组件引入。 - 安装依赖: ```bash yarn add vite-svg-loader # 或 npm install vite-svg-loader ``` - 配置 `vite.config.ts`: ```typescript import { defineConfig } from &#39;vite&#39;; import vue from &#39;@vitejs/plugin-vue&#39;; import svgLoader from &#39;vite-svg-loader&#39;; export default defineConfig({ plugins: [ vue(), svgLoader() ] }); ``` - 在组件中引入并使用: ```javascript import YourIcon from &#39;./assets/your-icon.svg&#39;; export default { components: { YourIcon } }; ``` ```html <YourIcon /> ``` 这样可以将 SVG 文件作为 Vue 组件使用,并支持动态修改其样式[^1]。 #### 3. 使用 `svg-sprite-loader`(适用于 Webpack 项目) 对于基于 Vue CLI 的项目,可以使用 `svg-sprite-loader` 将多个 SVG 文件合并为一个精灵图。 - 配置 `vue.config.js`: ```javascript const path = require(&#39;path&#39;); module.exports = { chainWebpack: config => { const svgRule = config.module.rule(&#39;svg&#39;); svgRule.uses.clear(); svgRule.exclude.add(/node_modules/); svgRule.test(/\.(svg)$/).use(&#39;svg-sprite-loader&#39;).loader(&#39;svg-sprite-loader&#39;).options({ symbolId: &#39;icon-[name]&#39; }); const imagesRule = config.module.rule(&#39;images&#39;); imagesRule.exclude.add(path.resolve(__dirname, &#39;src/icons&#39;)); } }; ``` - 在组件中使用: ```html <svg> <use xlink:href="#icon-your-icon"></use> </svg> ``` 这种方式可以减少 HTTP 请求,同时支持动态修改颜色[^2]。 #### 4. 直接嵌入 SVG 代码 如果 SVG 文件较小,可以直接将其代码嵌入到模板中。这样可以方便地修改 SVG 的样式属性。 ```html <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"> <path fill="currentColor" d="M17,0c-1.9,0-3.7,0.8-5,2.1C10.7,0.8,8.9,0,7,0C3.1,0,0,3.1,0,7c0,6.4,10.9,15.4,11.4,15.8 c0.2,0.2,0.4,0.2,0.6,0.2s0.4-0.1,0.6-0.2C13.1,22.4,24,13.4,24,7C24,3.1,20.9,0,17,0z"/> </svg> ``` 通过设置 `fill="currentColor"`,可以使用 CSS 的 `color` 属性动态修改 SVG 的颜色[^4]。 #### 5. 动态操作 SVG DOM 在某些复杂场景下,可能需要动态生成或修改 SVG 的内容。可以通过监听 XHR 响应,获取 SVG 的 DOM 并进行操作。 ```javascript xhr.addEventListener("load", () => { const resXML = xhr.responseXML; const svgDom = resXML.documentElement.cloneNode(true); // 修改颜色 svgDom.getElementById("...").setAttribute("style", `fill: ${this.photoResult.resultColor};`); // 转换为虚拟 DOM 并挂载 const oSerializer = new XMLSerializer(); const sXML = oSerializer.serializeToString(svgDom); const Profile = Vue.extend({ template: `<div id="svgTemplate">${sXML}</div>` }); new Profile().$mount("#svgTemplate"); }); ``` 这种方式适合需要高度自定义的场景[^5]。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

太阳与星辰

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值