Skip to content

一、Icon图标处理方案

1. SvgIcon

在项目中所使用的 icon 图标,一共分为两类:

  1. element-plus的图标
  2. 自定义的 svg 图标

处理方案:针对于 element-plus 的图标可以直接通过 el-icon 来进行显示,但是自定义图标的话,暂时缺少显示方式,需要一个自定义的组件,来显示自定义的 svg 图标

针对于自定义的 svg 图标的形式,通用解决方案,定义一个自定义组件处理。

那么对于这个组件需要具备两种能力:

  1. 显示外部的 svg 图标
  2. 显示项目内的 svg 图标

2. 组件搭建

  • 新建XSvgIcon.vue
    vue
    <template>
      <!-- 展示外部图标 -->
      <div
        v-if="isExternal"
        :style="styleExternalIcon"
        class="svg-external-icon svg-icon"
        :class="className"
      />
      <!--  展示内部图标-->
      <svg v-else class="svg-icon" :class="className" aria-hidden="true">
        <use :xlink:href="iconName" />
      </svg>
    </template>
    
    <script lang="ts">
    import { defineComponent, computed } from 'vue';
    import external from '@/utils/Validate';
    
    export default defineComponent({
      name: 'XSvgIcon',
      props: {
        // icon 图标
        icon: {
          type: String,
          required: true
        },
        // 图标类名
        className: {
          type: String,
          default: ''
        }
      },
    
      setup(props) {
        /**
         * 判断当前图标是否为外部图标
         */
        const isExternal = computed(() => external(props.icon))
    
        /**
         * 外部图标样式
         */
        const styleExternalIcon = computed(() => ({
          mask: `url(${props.icon}) no-repeat 50% 50%`,
          '-webkit-mask': `url(${props.icon}) no-repeat 50% 50%`
        }))
    
        /**
         * 项目内部图标
         */
        const iconName = computed(() => `#icon-${props.icon}`)
        return {
          isExternal,
          styleExternalIcon,
          iconName
        }
      }
    })
    </script>
    
    <style scoped lang="less">
    .svg-icon {
      width: 1em;
      height: 1em;
      vertical-align: -0.15em;
      fill: currentColor;
      overflow: hidden;
    }
    
    .svg-external-icon {
      background-color: currentColor;
      mask-size: cover !important;
      display: inline-block;
    }
    </style>
  • 创建工具类
    typescript
      /**
       * 判断是否为外部资源
       * @param path
       */
      const isExternal = (path: string): boolean => /^(https?:|mailto:|tel:)/.test(path);
  • 外部 svg 引用方式
    html
    <span class="svg-container">
       <svg-icon icon="https://res.lgdsunday.club/user.svg"></svg-icon>
    </span>
  • 可以考虑将阿里的 iconfont 也封装进来

Released under the MIT License.