vue3+ts 项目中使用svg图标配置

01 安装 svg-sprite-loader

npm i svg-sprite-loader -D

02 新建一个文件夹用来存放svg图标

src/assets下新建文件夹icons/svg,用来存放.svg文件

03 创建SvgIcon组件

src/components/SvgIcon.vue

<template>
  <svg :class="svgClass" aria-hidden="true">
    <use :xlink:href="iconName"></use>
  </svg>
</template>
<script lang="ts" setup>
import { computed } from '@vue/reactivity'

const props = defineProps({
  iconClass: { type: String, required: true },
  className: String,
})

const iconName = computed(() => {
  return props.iconClass ? `#icon-${props.iconClass}` : '#icon'
})

const svgClass = computed(() => {
  return props.className ? 'svg-icon ' + props.className : 'svg-icon'
})
</script>
<style scoped>
.svg-icon {
  width: 1em;
  height: 1em;
  vertical-align: -0.15em;
  fill: currentColor;
  overflow: hidden;
}
</style>

这里使用了 vue3 的 defineProps() 宏函数标注props类型,如果eslint报错ESLint: 'defineProps' is not defined.(no-undef),找到eslint配置文件,在env处添加代码 ‘vue/setup-compiler-macros’: true,

 "eslintConfig": {
    "root": true,
    "env": {
      "node": true,
      "vue/setup-compiler-macros": true
    },
    "extends": [
      "plugin:vue/vue3-essential",
      "eslint:recommended",
      "@vue/typescript/recommended"
    ],
    "parserOptions": {
      "ecmaVersion": 2020
    },
    "rules": {}
  },

04 修改 vue.config.js

const path = require('path')

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

module.exports = {
  chainWebpack: config => {
    config.module.rules.delete("svg"); //重点:删除默认配置中处理svg,
    config.module
      .rule('svg-sprite-loader')
      .test(/\.svg$/)
      .include
      .add(resolve('src/assets/icons')) //处理svg目录
      .end()
      .use('svg-sprite-loader')
      .loader('svg-sprite-loader')
      .options({
        symbolId: 'icon-[name]'
      })
  },
};

05 修改 main.ts

import { createApp } from 'vue'
import App from './App.vue'
import SvgIcon from '@/components/SvgIcon.vue' 

const req = require.context('@/assets/icons/svg', false, /\.svg$/)  
req.keys().map(req)

createApp(App).component('SvgIcon', SvgIcon).mount('#app')

06 在组件中使用

App.vue

<template>
  <SvgIcon iconClass="favicon"></SvgIcon>
</template>

iconClass 为 svg 文件名

Q.E.D.


永远自由,永远热爱