Blog
首页
文档
收藏
关于
  • 在线转换时间戳 (opens new window)
  • 在线压缩图片 (opens new window)
  • Float-Double转二进制 (opens new window)
  • 文件转Hex字符串 (opens new window)

HiuZing

🍑
首页
文档
收藏
关于
  • 在线转换时间戳 (opens new window)
  • 在线压缩图片 (opens new window)
  • Float-Double转二进制 (opens new window)
  • 文件转Hex字符串 (opens new window)
  • 前端面试题

  • JavaScript

  • Vue2

  • port

  • CSS

  • Node.js

  • JavaScript优化

  • uniapp

  • Mini Program

  • TypeScript

  • 面向对象编程

  • UI组件

  • Plugin

  • Vue3

    • 教程

    • Vue Router

    • API

    • Vuex

    • 实例处理方案

      • 图标处理方案
        • Icon 图标处理方案:SvgIcon
        • 处理外部图标
        • 处理内部 svg 图标显示
        • 使用 svg-sprite-loader 处理 svg 图标
      • 本地缓存处理方案
      • 响应拦截器处理方案
      • 登录鉴权处理方案
      • 退出登录处理方案
      • 国际化处理方案
      • 动态换肤处理方案
      • Screenfull全屏处理方案
      • HeaderSearch 处理方案
      • TagsView处理方案
      • Guide 处理方案
      • Excel 导入处理方案
      • 打印详情处理方案
      • 权限受控处理方案
      • 动态表格处理方案
      • 富文本和markdown处理方案
      • 项目部署处理方案
      • 可视化处理方案
    • 文档

    • 用法

  • 性能优化

  • Axios

  • 状态管理

  • React

  • Mock

  • Icon

  • Template

  • 构建工具

  • 项目规范配置

  • Taro

  • SVG

  • React Native

  • 前端
  • Vue3
  • 实例处理方案
HiuZing
2023-03-23
目录

图标处理方案

# Icon 图标处理方案:SvgIcon

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

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

这也是通常情况下企业级项目开发时,所遇到的一种常见情况。

element-plus 的图标:通过 el-icon 来进行显示

自定义图标:需要一个自定义的组件,来显示我们自定义的 svg 图标。

通用解决方案:需要自定义组件处理 自定义 svg 图标的形式

对于这个组件的话,它就需要拥有两种能力:

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

# 处理外部图标

创建 components/SvgIcon/index.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 setup>
import { isExternal as external } from '@/utils/validate'
import { defineProps, computed } from 'vue'
const props = defineProps({
  // icon 图标
  icon: {
    type: String,
    required: true
  },
  // 图标类名
  className: {
    type: String,
    default: ''
  }
})

/**
 * 判断是否为外部图标
 */
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}`)
</script>

<style scoped>
.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>
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
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62

创建 utils/validate.js:

/**
 * 判断是否为外部资源
 */
export function isExternal(path) {
  return /^(https?:|mailto:|tel:)/.test(path)
}
1
2
3
4
5
6

在 views/login/index.vue 中使用 外部 svg (https://res.lgdsunday.club/user.svg):

<span class="svg-container">
	<svg-icon icon="https://res.lgdsunday.club/user.svg"></svg-icon>
</span>
1
2
3

# 处理内部 svg 图标显示

  1. 首先导入所有的 svg 图标

  2. 在 icons 下创建 index.js 文件,该文件中需要完成两件事情:

    1. 导入所有的 svg 图标
    2. 完成 SvgIcon 的全局注册
  3. 得出以下代码:

    import SvgIcon from '@/components/SvgIcon'
    
    // https://webpack.docschina.org/guides/dependency-management/#requirecontext
    // 通过 require.context() 函数来创建自己的 context
    const svgRequire = require.context('./svg', false, /\.svg$/)
    // 此时返回一个 require 的函数,可以接受一个 request 的参数,用于 require 的导入。
    // 该函数提供了三个属性,可以通过 require.keys() 获取到所有的 svg 图标
    // 遍历图标,把图标作为 request 传入到 require 导入函数中,完成本地 svg 图标的导入
    svgRequire.keys().forEach(svgIcon => svgRequire(svgIcon))
    
    export default app => {
      app.component('svg-icon', SvgIcon)
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
  4. 在 main.js 中引入该文件

    ...
    // 导入 svgIcon
    import installIcons from '@/icons'
    ...
    installIcons(app)
    ...
    
    1
    2
    3
    4
    5
    6
  5. 删除 views/login 下 局部导入 SvgIcon 的代码

  6. 在 login/index.vue 中使用 SvgIcon 引入本地 svg

    // 用户名   
    <svg-icon icon="user" />
    // 密码
    <svg-icon icon="password" />
    // 眼睛
    <svg-icon icon="eye" />
    
    1
    2
    3
    4
    5
    6
  7. 此时 处理内容 svg 图标的代码 已经完成

打开浏览器,我们发现 图标依然无法展示! 这又是因为什么原因呢?

# 使用 svg-sprite-loader 处理 svg 图标

svg-sprite-loader (opens new window) 是 webpack 中专门用来处理 svg 图标的一个 loader ,在上一节中我们的图标之所有没有展示,就是因为我们缺少该 loader。

  1. 下载该 laoder

  2. 执行

    npm i --save-dev [email protected]
    
    1
  3. 创建 vue.config.js 文件,新增如下配置:

    const path = require('path')
    function resolve(dir) {
      return path.join(__dirname, dir)
    }
    // https://cli.vuejs.org/zh/guide/webpack.html#%E7%AE%80%E5%8D%95%E7%9A%84%E9%85%8D%E7%BD%AE%E6%96%B9%E5%BC%8F
    module.exports = {
      chainWebpack(config) {
        // 设置 svg-sprite-loader
        config.module
          .rule('svg')
          .exclude.add(resolve('src/icons'))
          .end()
        config.module
          .rule('icons')
          .test(/\.svg$/)
          .include.add(resolve('src/icons'))
          .end()
          .use('svg-sprite-loader')
          .loader('svg-sprite-loader')
          .options({
            symbolId: 'icon-[name]'
          })
          .end()
      }
    }
    
    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
上次更新: 2025/06/23, 07:26:12
动态样式
本地缓存处理方案

← 动态样式 本地缓存处理方案→

最近更新
01
CodePush
06-22
02
打包发布
03-09
03
常用命令
03-09
更多文章>
Theme by Vdoing | Copyright © 2021-2025 WeiXiaojing | 友情链接
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式