前端知识体系
GitHub (opens new window)

GuoLiBin6

程序员永不下班
GitHub (opens new window)
  • 介绍
  • 前端基础

  • 浏览器基础

  • 软件开发

  • 数据结构

  • 性能优化

  • Node.js

  • 项目实战

    • vue2 大型项目实战

      • Icon
        • 1. Icon 如何使用
          • 1.1 自定义 SVG 图标
          • 1.2 Ant Design Vue 图标
        • 2. Icon 如何封装
          • 2.1 vue.config.js 中的 webpack 配置
          • 2.2 自定义 <Icon> 组件
        • 3. 优缺点
          • 3.1 优点 (Advantages)
          • 3.2 缺点 (Disadvantages)
      • 一键换肤
  • 收录

  • 搞事啦

  • 前端知识体系
  • 项目实战
  • vue2 大型项目实战
GuoLiBin6
2025-09-09
目录

Icon

# 1. Icon 如何使用

实战项目主要采用两种 Icon 使用方式:自定义 SVG 图标和 Ant Design Vue 图标。

# 1.1 自定义 SVG 图标

对于项目特有的业务图标或定制化图标,项目将其作为 SVG 文件引入,并通过一个封装的 <Icon> 组件进行使用。

使用示例:

vue

<template>

  <div>

    <!-- 使用名为 "menu-dashboard" 的自定义图标 -->

    <icon type="menu-dashboard" />

    <!-- 在配置中引用图标 -->

    <icon :type="item.meta.icon" />

    <!-- 带有默认图标的用法 -->

    <icon :type="{ icon: getIcon(item.path), defaultIcon: 'star' }" />

  </div>

</template>

<script>

// ...

export default {

  // ...

}

</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31

说明:

  • 自定义 SVG 图标通过 <icon> 组件的 type 属性指定,type 的值对应 SVG 文件的名称(不包含 .svg 后缀)。

  • 这些 SVG 文件通常放置在 src/components/Icon 或 scope/assets 等目录下,通过 webpack 配置统一处理。

# 1.2 Ant Design Vue 图标

对于一些通用的、系统级的图标(如箭头、加载、删除等),项目直接使用 Ant Design Vue 提供的 <a-icon> 组件。

使用示例:

vue

<template>

  <div>

    <!-- 使用 Ant Design Vue 的向下箭头图标 -->

    <a-icon type="down" />

    <!-- 使用 Ant Design Vue 的向上箭头图标 -->

    <a-icon type="up" />

  </div>

</template>

<script>

// ...

export default {

  // ...

}

</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27

说明:

  • Ant Design Vue 图标通过 <a-icon> 组件的 type 属性指定,其 type 值遵循 Ant Design Vue 的图标命名规范。

# 2. Icon 如何封装

项目的自定义 SVG 图标通过 vue.config.js 中的 webpack 配置和自定义的 <Icon> 组件进行封装。

# 2.1 vue.config.js 中的 webpack 配置

在 vue.config.js 中,通过 chainWebpack 配置对 SVG 文件进行了特殊处理,以生成 SVG 雪碧图。

javascript

chainWebpack: (config) => {
  const svgRule = config.module.rule('svg')
  svgRule.uses.clear()
  svgRule.include.add(resolve('./src/components/Icon')) // 包含自定义图标路径
  svgRule.include.add(resolve('./scope/assets')) // 包含自定义图标路径
  svgRule
    .test(/\.svg$/)
    .use('svg-sprite-loader')
    .loader('svg-sprite-loader')
    .options({
      symbolId: 'oc-[name]', // 雪碧图中每个 SVG 的 ID 前缀
      extract: true,
      spriteFilename: 'sprite.svg', // 生成的 SVG 雪碧图文件名
    })
    .end()
    .use('svgo-loader')
    .loader('svgo-loader')
    .options({
      configFile: false, // 不使用默认配置文件
    })
    .end()
  const imagesRule = config.module.rule('images')
  imagesRule.exclude.add(resolve('./src/components/Icon')) // 排除自定义图标路径,避免被images loader处理
  imagesRule.exclude.add(resolve('./scope/assets'))
  config.module.rule('images').test(/\.(png|jpe?g|gif|svg)(\?.*)?$/)
},
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

配置解析:

  • svg-sprite-loader: 这个 loader 负责将多个 SVG 文件合并成一个 SVG 雪碧图(sprite)。它会为每个 SVG 生成一个 <symbol> 标签,并将其 id 设置为 symbolId 选项中定义的格式(例如 oc-menu-dashboard)。

  • svgo-loader: 在 SVG 合并之前,svgo-loader 会对 SVG 文件进行优化,移除不必要的代码,减小文件大小。

  • imagesRule.exclude: 通过将自定义 SVG 图标的路径从 images 规则中排除,确保这些 SVG 文件只由 svg-sprite-loader 处理,而不是作为普通的图片文件。

# 2.2 自定义 <Icon> 组件

项目中存在一个自定义的 <Icon> Vue 组件(通常在 src/components/Icon/index.vue 附近)。这个组件接收 type 属性,并根据 type 的值渲染对应的 SVG 雪碧图中的图标。

vue

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

<script>
export default {
  name: 'Icon',
  props: {
    type: {
      type: [String, Object],
      required: true,
    },
  },
  computed: {
    iconName() {
      // 处理传入的type属性,例如:
      // 如果type是字符串 'menu-dashboard',则返回 '#oc-menu-dashboard'
      // 如果type是对象 { icon: 'some-icon', defaultIcon: 'star' }
      // 则根据逻辑返回 '#oc-some-icon' 或 '#oc-star'
      if (typeof this.type === 'string') {
        return `#oc-${this.type}`
      } else if (typeof this.type === 'object' && this.type.icon) {
        return `#oc-${this.type.icon}`
      } else if (typeof this.type === 'object' && this.type.defaultIcon) {
        return `#oc-${this.type.defaultIcon}`
      }
      return '' // 或其他默认处理
    },
  },
}
</script>

<style scoped>
.icon {
  width: 1em; /* 根据需要调整 */
  height: 1em; /* 根据需要调整 */
  vertical-align: -0.15em; /* 保持对齐 */
  fill: currentColor; /* 图标颜色继承父元素颜色 */
  overflow: hidden;
}
</style>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43

说明:

  • <Icon> 组件内部通过 <svg><use></use></svg> 标签来引用 SVG 雪碧图中的具体图标。

  • xlink:href 属性的值通常是 # 加上雪碧图中 SVG <symbol> 的 id。

# 3. 优缺点

# 3.1 优点 (Advantages)

  1. 减少 HTTP 请求:所有自定义 SVG 图标被打包成一个雪碧图文件,减少了浏览器的网络请求数量,提高了页面加载性能。

  2. 灵活的样式控制:SVG 是矢量图,可以通过 CSS 灵活控制图标的颜色、大小、旋转等属性,而不会失真。

  3. 高分辨率支持:作为矢量图,SVG 在任何分辨率和缩放比例下都能保持清晰,无需为不同 DPI 设备准备多套图标。

  4. 便于管理和维护:

  • 通过自定义 <Icon> 组件统一管理图标的引用,使得代码更具可读性和一致性。

  • 在 vue.config.js 中集中配置 SVG 处理,方便统一优化和维护。

  • 可以方便地将图标名称作为字符串在各种配置(如菜单配置)中使用。

  1. 与 UI 库良好结合:项目可以在使用自定义品牌图标的同时,方便地集成 Ant Design Vue 提供的丰富通用图标,互不冲突,提高了开发效率。

# 3.2 缺点 (Disadvantages)

  1. 构建配置复杂性:需要额外的 webpack 配置(svg-sprite-loader 和 svgo-loader)来处理 SVG 雪碧图,增加了项目的构建配置复杂性。

  2. 新增图标流程:每次新增自定义 SVG 图标时,需要确保文件放置在正确目录,并遵循命名约定,以被 webpack 正确打包。

  3. 初始加载大小:虽然减少了请求数量,但雪碧图文件在首次加载时可能会相对较大。不过,一旦加载并缓存,后续页面切换时无需再次下载。

  4. 调试:在某些情况下,调试 SVG 雪碧图中的单个图标可能比调试独立的 SVG 文件稍微复杂一点,因为所有图标都集中在一个文件中。

总结:

项目的 Icon 策略通过结合 SVG 雪碧图和 Ant Design Vue 图标,实现了自定义图标的灵活管理和高效加载,同时兼顾了通用图标的便捷性。这种策略在性能、可维护性和样式控制方面表现出色,是大型前端项目常用的优秀实践。

上次更新: 2025-09-09 10:46:43
预加载
一键换肤

← 预加载 一键换肤→

最近更新
01
Border为none和0的区别
09-13
02
BFC原理
09-11
03
一键换肤
09-10
更多文章>
Theme by Vdoing | Copyright © 2022-2025 GuoLiBin6
冀ICP备2022013865号-1
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式