icon图标的使用

START

icon图标的使用,对于番茄我来说,算是一个痛点吧。写这篇文章之前,也看了不少别人有关图标使用的博客。想了很久,还是想自己写一篇属于番茄我自己的一篇图标相关的博客。一来是复习,一来算是总结。这次必不会鸽了,一气呵成,一次到位.

文章的主体顺序,还是按照我接触的先后做排序的,由易到难,这样方便理解。当然,番茄我了解的知识,或许也不够全面,请见谅.

出于比较有责任的想法,我会写比较多的demo,展示具体用法,确保百分百可以运行,方便学习或CV.

为了方便整合,所有演示demo我都会写在一个vue项目中。

演示代码

本文demo的github地址 :https://github/lazy-tomato/icon-example/tree/tomato

初次接触

最开始学习html的时候,往往都是老师布置作业,下课前会给我们发放课后作业需要用到的图片或图标,所以第一个就讲讲最基本图标的使用吧,直接本地引用图片/图标文件

先上代码

<template>
  <div class="first">
    <h2>1.初次接触:直接引入本地图片</h2>
    <div>
      <h4>1.1 引入本地图片</h4>
      <img src="@/assets/images/jacket.png" alt="上衣" />
      <!-- 下面这种用法也可以    `@` 就等于 `/src` -->
      <!-- <img src="../../../../assets/images/jacket.png" alt="上衣" /> -->

      <h4>1.2 引入在线链接</h4>
      <img
        src="https://upload.jianshu.io/users/upload_avatars/13278218/60803b63-0f9d-490e-9c41-1511c56025d4?imageMogr2/auto-orient/strip|imageView2/1/w/240/h/240"
        alt="上衣"
      />

      <h4>1.3 require形式使用</h4>
      <img :src="imageShorts" alt="短裤" />

      <h4>1.4 import形式使用</h4>
      <img :src="socks" alt="袜子" />

      <h4>1.5 for循环遍历使用</h4>
      <div v-for="item in imagesList" :key="item.url">
        <img :src="item.url" alt="" />
      </div>
    </div>
  </div>
</template>


<script>
// @ is an alias to /src
import socks from "@/assets/images/socks.png";
export default {
  data() {
    return {
      imageShorts: require("@/assets/images/shorts.png"),
      socks: socks,
      imagesList: [
        { url: "@/assets/images/jacket.png" },
        { url: "../../../../assets/images/socks.png" },
        {
          url:
            "https://upload.jianshu.io/users/upload_avatars/13278218/60803b63-0f9d-490e-9c41-1511c56025d4?imageMogr2/auto-orient/strip|imageView2/1/w/240/h/240",
        },
        { url: require("@/assets/images/shorts.png") },
        { url: socks },
      ],
    };
  },
};
</script>

<style scoped>
.first {
  color: #fff;
  min-height: 100%;
  height: auto;
  text-align: center;
}
h4 {
  padding: 60px 0 10px;
  border-bottom: 1px solid #21262d;
}
img {
  width: 100px;
  height: 100px;
}
</style>

运行效果

说明

  • 可以看到运行的效果图中,使用v-for循环展示图片。使用本地图片路径,就会加载不出来。具体原因是因为 vue2是基于webpack进行打包运行的,而webpack会解析它为模块依赖 ,文件路径就会出错 ,所以本地图片在进行使用的时候,推荐使用requireimport方式使用。

CSS Sprite

CSS Sprite中文可以叫它,精灵图/雪碧图,两种称呼都可以,番茄个人比较习惯叫它精灵图。

那什么是CSS Sprite?

先上两个有代表性的精灵图,认识一下。


为什么用精灵图?

首先,我们先来了解一下,页面在接受图片的过程。

每张图片的显示是先由浏览器发送请求,然后服务器接受请求,返回请求内容。如果一个页面有上百张图片,哪怕是很小的图标,都需要经历一次这样的过程。那么,毋庸置疑,肯定会由于请求数量的增加让整个页面的加载速度降低。

正应为如此,精灵图(sprite)应运而生,图片整合技术,将大量的小图标整合到一张图,从而减少服务器接收和发送请求的次数,提高页面的加载速度。

怎么使用精灵图呢?

先上代码
<template>
  <div class="second">
    <h2>2.CSS-Sprite如何使用</h2>
    <h4>2.1 通过css的background-position属性,对包含很多小图片的Sprite图片进行展示</h4>
    <div class="second-icon">
      <div
        :style="{ backgroundImage: 'url(' + icon + ')' }"
        class="icon icon-one"
      ></div>
      <div
        :style="{ backgroundImage: 'url(' + icon + ')' }"
        class="icon icon-two"
      ></div>
      <div
        :style="{ backgroundImage: 'url(' + icon + ')' }"
        class="icon icon-three"
      ></div>
      <div
        :style="{ backgroundImage: 'url(' + icon + ')' }"
        class="icon icon-four"
      ></div>
    </div>
    <div>
      <h4>2.2 通过css的background-position属性,配合动画添加动态的小人(好像有些像素的小游戏,主角的移动就是用这个做的,不过哪个是用监听按键事件,切换不同的精灵图实现的)</h4>
      <div
        :style="{ backgroundImage: 'url(' + snowman + ')' }"
        class="snowman"
      ></div>
    </div>
  </div>
</template>


<script>
export default {
  data() {
    return {
      icon: require("@/assets/images/iconSprite.png"),
      snowman: require("@/assets/images/snowmanSprite.jpg"),
    };
  },
};
</script>

<style scoped>
.second {
  color: #fff;
  min-height: 100%;
  height: auto;
  text-align: center;
}
h4 {
  padding: 60px 0 10px;
  border-bottom: 1px solid #21262d;
}

.second-icon {
  display: flex;
  justify-content: space-around;
  align-items: center;
}

.icon {
  width: 40px;
  height: 40px;
  /* 是否重复 no-repeat 不重复 */
  background-repeat: no-repeat;
}

.icon-one {
  /* 背景定位,可以通过百分比去设置 */
  background-position: 5% 4%;
}

.icon-two {
  /* 背景定位,可以通过px去设置 */
  background-position: -22px -78px;
}

.icon-three {
  /* 背景定位,可以通过top right center left bottom去设置 */
  background-position: center -139px;
}

.icon-four {
  /* 当然也可以组合使用 */
  background-position: 20% -205px;
}

/* 配合css动画可以实现动态的小人 */
.snowman {
  margin: 0 auto;
  width: 122px;
  height: 180px;
  animation: walk 1s steps(4) infinite;
}

@keyframes walk {
  0% {
    background-position: 0;
  }
  100% {
    background-position: -486px;
  }
}
</style>
运行效果

iconfont

后来随着学习的深入,项目越做越大,对图标的需求就多了起来,到这里不得不说一下,iconfont

  • iconfont 是阿里提供的一个开源图库
  • 官方网址:www.iconfont
  • 顾名思义,字体图标, iconfont提供多种格式的icon,平台也可将图标转换为字体,便于前端工程师自由调整与调用。

先看看官方的帮助文档

1.icon单个使用

直接登录账号,搜索自己想要使用的图标。点击下载,本地直接引用即可。

此种方式适合用在图标引用特别少,以后也不需要特别维护的场景。

不过如果是成体系的应用使用,建议用户把icon加入项目,然后使用下面三种推荐的方式。

2.unicode引用

unicode是字体在网页端最原始的应用方式,特点是:

  • 兼容性最好,支持ie6+,及所有现代浏览器。
  • 支持按字体的方式去动态调整图标大小,颜色等等。
  • 但是因为是字体,所以不支持多色。只能使用平台里单色的图标,就算项目里有多色图标也会自动去色。

注意:新版iconfont支持多色图标,这些多色图标在unicode模式下将不能使用,如果有需求建议使用symbol的引用方式

unicode使用步骤如下:

第一步:拷贝项目下面生成的font-face

@font-face {font-family: 'iconfont';
    src: url('iconfont.eot');
    src: url('iconfont.eot?#iefix') format('embedded-opentype'),
    url('iconfont.woff') format('woff'),
    url('iconfont.ttf') format('truetype'),
    url('iconfont.svg#iconfont') format('svg');
}

第二步:定义使用iconfont的样式

.iconfont{
    font-family:"iconfont" !important;
    font-size:16px;font-style:normal;
    -webkit-font-smoothing: antialiased;
    -webkit-text-stroke-width: 0.2px;
    -moz-osx-font-smoothing: grayscale;}

第三步:挑选相应图标并获取字体编码,应用于页面

<i class="iconfont">&#x33;</i>

3.font-class引用


font-class是unicode使用方式的一种变种,主要是解决unicode书写不直观,语意不明确的问题。

与unicode使用方式相比,具有如下特点:

  • 兼容性良好,支持ie8+,及所有现代浏览器。
  • 相比于unicode语意明确,书写更直观。可以很容易分辨这个icon是什么。
  • 因为使用class来定义图标,所以当要替换图标时,只需要修改class里面的unicode引用。
  • 不过因为本质上还是使用的字体,所以多色图标还是不支持的。

使用步骤如下:

第一步:拷贝项目下面生成的fontclass代码:

//at.alicdn/t/font_8d5l8fzk5b87iudi.css

第二步:挑选相应图标并获取类名,应用于页面:

<i class="iconfont icon-xxx"></i>

4.symbol引用


这是一种全新的使用方式,应该说这才是未来的主流,也是平台目前推荐的用法。相关介绍可以参考这篇文章 这种用法其实是做了一个svg的集合,与上面两种相比具有如下特点:

  • 支持多色图标了,不再受单色限制。
  • 通过一些技巧,支持像字体那样,通过font-size,color来调整样式。
  • 兼容性较差,支持 ie9+,及现代浏览器。
  • 浏览器渲染svg的性能一般,还不如png。

使用步骤如下:

第一步:拷贝项目下面生成的symbol代码:

//at.alicdn/t/font_8d5l8fzk5b87iudi.js

第二步:加入通用css代码(引入一次就行):

<style type="text/css">
    .icon {
       width: 1em; height: 1em;
       vertical-align: -0.15em;
       fill: currentColor;
       overflow: hidden;
    }
</style>

第三步:挑选相应图标并获取类名,应用于页面:

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

5.实际代码中如何使用iconfont?

  1. 访问www.iconfont
  2. 登录你的账号,搜索你想要的图标
  3. 添加到购物车中
  4. 为了方便管理,创建一个新的项目,将所有的图标保存在这个项目中
  5. 使用图标的时候,需要使用引用一些css和js文件,引入在线链接也可以,下载到本地也可以,这里就演示一下,下载到本地如何使用

本地使用

  • 点击下载到本地按钮

  • 复制我们需要的文件到assets中保存

  • main.js中引入一下

  • 修改一下iconfont.css

开始使用 (对应的编码,或class名,或id名,可以iconfont中复制即可)

<template>
  <div class="third">
    <h2>3.iconfont如何使用</h2>
    <h4>3.1 使用Unicode</h4>
    <i class="iconfont">&#xe602;</i>
    <i class="iconfont">&#xe603;</i>
    <i class="iconfont">&#xe604;</i>
    <i class="iconfont">&#xe607;</i>
    <i class="iconfont">&#xe608;</i>
    <i class="iconfont">&#xe60e;</i>
    <i class="iconfont">&#xe60f;</i>
    <i class="iconfont">&#xe610;</i>

    <h4>3.2使用font-class</h4>
    <i class="iconfont icon-shengdantubiao-01"></i>
    <i class="iconfont icon-shengdantubiao-02"></i>
    <i class="iconfont icon-shengdantubiao-03"></i>
    <i class="iconfont icon-shengdantubiao-06"></i>
    <i class="iconfont icon-shengdantubiao-07"></i>
    <i class="iconfont icon-shengdantubiao-12"></i>
    <i class="iconfont icon-shengdantubiao-13"></i>
    <i class="iconfont icon-shengdantubiao-14"></i>

    <h4>3.3使用symbol</h4>
    <svg class="icon" aria-hidden="true">
      <use xlink:href="#icon-shengdantubiao-01"></use>
    </svg>
    <svg class="icon" aria-hidden="true">
      <use xlink:href="#icon-shengdantubiao-02"></use>
    </svg>
    <svg class="icon" aria-hidden="true">
      <use xlink:href="#icon-shengdantubiao-03"></use>
    </svg>
    <svg class="icon" aria-hidden="true">
      <use xlink:href="#icon-shengdantubiao-06"></use>
    </svg>
    <svg class="icon" aria-hidden="true">
      <use xlink:href="#icon-shengdantubiao-07"></use>
    </svg>
    <svg class="icon" aria-hidden="true">
      <use xlink:href="#icon-shengdantubiao-12"></use>
    </svg>
    <svg class="icon" aria-hidden="true">
      <use xlink:href="#icon-shengdantubiao-13"></use>
    </svg>
    <svg class="icon" aria-hidden="true">
      <use xlink:href="#icon-shengdantubiao-14"></use>
    </svg>
  </div>
</template>
<script>
export default {};
</script>

<style scoped>
.third {
  color: #fff;
  min-height: 100%;
  height: auto;
  text-align: center;
}
h4 {
  padding: 60px 0 10px;
  border-bottom: 1px solid #21262d;
}

.iconfont{
  font-size: 40px;
}
</style>

运行效果

SVG图标使用进阶

如何优雅的使用SVG?

推荐博客 https://juejin/post/6844903517564436493#heading-5

对于svg图标使用,一开始番茄就是学习这篇博客的,后来自己根据作者的内容,亲自动手实现了一下,有兴趣可以去看看原作者的博客。

我番茄这里就主要讲解一下实际项目如何操作。

1.创建一个组SVG组件

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

<script>
export default {
  name: 'icon-svg',
  props: {
    iconClass: {
      type: String,
      required: true
    }
  },
  computed: {
    iconName() {
      return `#icon-${this.iconClass}`
    }
  }
}
</script>

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

2.src文件夹中创建一个Icons文件夹

  • Icons文件夹用于存储和图标有关的文件

  • Icons文件夹中创建一个svg文件夹用于存储我们需要使用到的svg图标

  • Icons文件夹中创建一个index.js 用于引入注册第一步编写的svg组件

    import Vue from 'vue';
    import SvgIcon from '@/components/SvgIcon';// svg component
    
    // register globally
    Vue.component('svg-icon', SvgIcon);
    const req = require.context('./svg', false, /\.svg$/);
    const requireAll = requireContext => requireContext.keys().map(requireContext);
    requireAll(req);
    

    首先我们创建一个专门放置图标 icon 的文件夹如:@/src/icons,将所有 icon 放在这个文件夹下。
    之后我们就要使用到 webpack 的 require.context。很多人对于 require.context可能比较陌生,直白的解释就是

    require.context("./test", false, /.test.js$/);
    这行代码就会去 test 文件夹(不包含子目录)下面的找所有文件名以 .test.js 结尾的文件能被 require 的文件。
    更直白的说就是 我们可以通过正则匹配引入相应的文件模块。

    require.context有三个参数:

    directory:说明需要检索的目录
    useSubdirectories:是否检索子目录
    regExp: 匹配文件的正则表达式

    了解这些之后,我们就可以这样写来自动引入 @/src/icons 下面所有的图标了

  • mian.js中引用一下 index.js

    import '@/icons'; // icon
    
  • 安装svg-sprite-loader

    npm i svg-sprite-loader --save
    

    使用这个插件,第一可以精简svg中无用的信息,第二,合并所有的svg文件为一个svg雪碧图

  • 配置一下 解析svg的loader

    'use strict';
    const path = require('path');
    
    function resolve(dir) {
        return path.join(__dirname, dir);
    }
    
    module.exports = {
    
        configureWebpack: {
            resolve: {
                alias: {
                    '@': resolve('src')
                }
            }
        },
        chainWebpack(config) {
            // set 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();
        }
    };
    
    
  • 在iconfont下载好我们需要使用的svg文件保存在svg文件夹即可

  • 页面中直接使用(svg文件名替换icon-class)

     <svg-icon icon-class="santaClaus" />
     <svg-icon icon-class="reindeer" />
     <svg-icon icon-class="snowman" />
    
  • 以后使用svg图标下载下来,直接<svg-icon icon-class="xxx" />即可。

代码

  • 代码博客里面就不上了,想了解的,请访问 github

END

本文写于2021/01/11,番茄本想写成很有深度的博客,奈何能力有限。只能说尽我所能,去编写这篇文章了,不知多年以后,回头再看这篇文章,我会有何感想。┓( ´∀` )┏

更多推荐

手把手教你在vue中使用icon图标,附demo代码