vue3 封装配置svg图片全局组件

882 阅读1分钟

组件内容

// SvgIcon.vue
<template>
  <svg aria-hidden="true" class="svg-icon" :style="style">
    <use :xlink:href="svgName"></use>
  </svg>
</template>
<script lang="ts">
  import { defineComponent, computed } from 'vue'
  
  export default defineComponent({
    name: 'SvgIcon',
    props: {
      type: {
        type: String,
        required: true
      },
      color: {
        type: String,
        default: ''
      },
      fontSize: {
        type: String,
        default: ''
      }
    },
    setup (props) {
      const style = computed(() => ({
        fontSize: props.fontSize,
        color: props.color
      }))
      const svgName = computed(() => `#icon-${props.type}`)
      return {
        style,
        svgName
      }
    }
  })
</script>

<style scoped lang="less">
  .svg-icon {
    width: 1em;
    height: 1em;
  }
</style>

资源引入

// main.js
// 引入所有svg文件 src/assets/svg 可以包含子目录
const req = require.context('@/assets/svg', true, /.svg$/)
req.keys().map(item => {
  require(`@/assets/svg${item.slice(1)}`)
})

webpack配置

const { resolve } = require('path')

module.exports = {
  chainWebpack: (config) => {
    // 移除cli内部svg文件处理
    config.module
      .rule('svg')
        .exclude
          .add(resolve(__dirname, 'src/assets/svg'))
        .end()
    // 配置svg图标的加载器
    config.module
      .rule('svg-icons')
        .test(/.svg$/)
        .include
          .add(resolve(__dirname, 'src/assets/svg'))
          .end()
        .use('svg-sprite-loader')
          .loader('svg-sprite-loader')
          .options({
            symbolId: 'icon-[name]'
          })
  }
}