当前位置: 首页 > article >正文

vue3自定义svg图标组件

可参考:
未来必热:SVG Sprites技术介绍
懒人神器:svg-sprite-loader实现自己的Icon组件
在Vue3项目中使用svg-sprite-loader

前置知识

在页面中,虽然可以通过如下的方式使用img标签,来引入svg图标。但是,如果这个路径很长,也是比较麻烦的。

<img src="./svg/icon.svg" />

在svg里面,可以在文档中先定义Symbol,然后svg使用的时候,只须通过标识去引用指定的svg即可,Symbol的放置顺序不一定要在最前面,案例如下:
在这里插入图片描述

<html>

<head>
  <meta charset="utf-8">
  <title>SVG Sprite使用</title>
  <style>
    li {
      font-size: 14px;
      margin-top: 5px;
      color: #369;
    }

    .webicon {
      width: 16px;
      height: 16px;
      margin-right: 5px;
      vertical-align: -2px;
      fill: #369;
    }
  </style>
</head>

<body>
  <div style="display: none;"><svg>
      <symbol id="liwu" viewBox="-80 -72.013 160 144.025">
        <path
          d="M-71.949-16.039h55.974v-55.974h-55.974V-16.039z M16.102-16.039h55.975v-55.974H16.102V-16.039z M-80,32.013h64.025v-40H-80V32.013z M80,32.013v-40H16.102v40H80z M-7.923,32.013H8.051V-72.013H-7.923V32.013z M16.102,39.936 h-32.077v24.025h32.077V39.936z M64.025,39.936h-40l15.719,32.077h24.281V39.936z M-23.898,39.936h-40v32.077H-40L-23.898,39.936z"
          transform="matrix(1 0 0 -1 0 0)"></path>
      </symbol>
      <symbol id="qianbi" viewBox="-79.5 -79.5 159 159">
        <path
          d="M79.5,32.802l-93.538-93.538l-46.699,46.699L32.802,79.5L79.5,32.802z M-79.5-32.802L-32.802-79.5H-79.5 V-32.802z"
          transform="matrix(1 0 0 -1 0 0)"></path>
      </symbol>
      <symbol id="shangchuan" viewBox="-73.623 -78.055 147.245 156.11">
        <path
          d="M0.069,32.482L64.48-32.205H36.915v-45.85h-73.83l-0.139,45.85h-27.15L0.069,32.482z M73.623,78.055V59.632 H-73.623v18.423H73.623z"
          transform="matrix(1 0 0 -1 0 0)"></path>
      </symbol>
    </svg></div>
  <h3>SVG Sprite使用示意</h3>
  <ul>
    <li><svg class="webicon">
        <use xlink:href="#qianbi"></use>
      </svg>编辑信息</li>
    <li><svg class="webicon">
        <use xlink:href="#liwu"></use>
      </svg>兑换礼物</li>
    <li><svg class="webicon">
        <use xlink:href="#shangchuan"></use>
      </svg>上传文件</li>
  </ul>
  </div>
</body>

</html>

自定义svg图标步骤

1. 创建components/SvgIcon/index.vue

<template>
  <svg class="svg-icon" aria-hidden="true">
    <use :xlink:href="iconName"></use>
  </svg>
</template>

<script setup>
import { defineProps, computed } from 'vue'
const props = defineProps({
  icon: {
    type: String,
    required: true
  }
})

const iconName = computed(() => {
  return `#icon-${props.icon}`
})
</script>

<style lang="scss" scoped>
.svg-icon {
  width: 1em;
  height: 1em;
  vertical-align: -0.15em;
  fill: currentColor;
  overflow: hidden;
}
</style>

2. 创建icons/index.js,

创建icons/index.js,并创建icons/svg图标所在文件夹,icon的图标就放在这个文件夹中。这里是动态的

import SvgIcon from '@/components/SvgIcon'

const svgRequired = require.context('./svg', false, /\.svg$/)
svgRequired.keys().forEach((item) => svgRequired(item))

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

3. main.js中注册SvgIcon组件

import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'

import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'

//import '@/assets/styles/index.scss'
import '@/assets/styles/border.css'
import '@/assets/styles/reset.css'
import '@/router/permission.js'
// import '@/router/init.js'
import {totalCommon} from '@/sys/mixinFunc.js'

import SvgIcon from '@/icons'

// 国际化中文
import zhCn from 'element-plus/es/locale/lang/zh-cn'


const app = createApp(App)
SvgIcon(app);

app.mixin(totalCommon);

app.use(ElementPlus, {
    locale: zhCn,
})

app.use(store)
app.use(router)
app.use(ElementPlus)

app.mount('#app')

4. vite.config.js配置svg-sprite-loader

首先,安装scg-sprite-loader

const webpack = require('webpack');

const path = require('path')
function resolve(dir) {
  return path.join(__dirname, dir)
}

module.exports = {
  lintOnSave: false,

  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()
    config
        .plugin('ignore')
        .use(
            new webpack.ContextReplacementPlugin(/moment[/\\]locale$/, /zh-cn$/)
        )
    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()
  }
}


http://www.kler.cn/a/2270.html

相关文章:

  • 【ue5学习笔记2】在场景放入一个物体的蓝图输入事件无效?
  • 代码加入SFTP JAVA ---(小白篇3)
  • Android -- 双屏异显之方法二
  • 【bodgeito】攻防实战记录
  • 【WRF教程第3.1期】预处理系统 WPS 详解:以4.5版本为例
  • Android Compose list 下拉刷新、上拉加载更多
  • 8个不能错过的程序员必备网站,惊艳到我了!!!
  • 【技巧】十大深度学习技巧和经验总结
  • 【进阶数据结构】平衡搜索二叉树 —— AVL树
  • DRAM功能介绍与基础概念
  • Android Navigation的四大要点你都知道吗?
  • 操作系统(2.4.5)--管程机制
  • String类为什么被设计成final,这样设计有什么好处
  • 【C语言】你真的了解结构体吗
  • linux系统运维面试题大全(137道题)
  • 博客项目
  • Python中的微型巨人-Flask
  • Spark - 继承 FileOutputFormat 实现向 HDFS 地址追加文件
  • Linux- 系统随你玩之--玩出花活的命令浏览器-双生姐妹花
  • 基于ssm大学生竞赛活动平台(包含万字文档)020
  • 【java】笔试强训Day1
  • 膜拜!阿里自爆十万字Java面试手抄本,脉脉一周狂转50w/次
  • 自定义类型的超详细讲解ᵎᵎ了解结构体和位段这一篇文章就够了ᵎ
  • 蚁群算法c++
  • 【前端八股文】浏览器系列:性能优化——HTML、CSS、JS、渲染优化
  • 【Java集合】Collection接口中的常用方法