封装 svg-icon 组件

109 阅读1分钟

1. @/components/SvgIcon

// SvgIcon.vue
<script lang="ts">
import { defineComponent, computed } from 'vue'
export default defineComponent({
  name: 'SvgIcon',
  props: {
    icon: {
      type: String,
      required: true
    },
    className: {
      type: String,
      default: ''
    }
  },
  setup(props) {
    const iconName = computed(() => `#icon-${props.icon}`)
    const iconStyle = computed(() => props.className)
    return { iconName, iconStyle }
  }
})
</script>

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

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

2. @/icons

  • icons
    • svg
    • index.ts
// index.ts
// 返回 require 函数接受一个request参数,用于require导入
// 共有三个属性:require.keys() 获取到所有svg图标
const svgreq = require.context('@/icons/svg', false, /\.svg$/)

// 遍历svg图标
// svgRequire.keys().forEach((svgInco) => svgRequire(svgInco))
const requireAll = (requireContext: any) => requireContext.keys().map(requireContext)
requireAll(svgreq)

3. vue.config.js

chainWebpack: (config) => {
    config.resolve.alias.set('components', '@/commponent')

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