preface

This is probably the most convenient and appropriate way to use Icon right now, especially in Vue3. Wait, you think it’s only for Vue3? No, don’t be fooled by the title, it supports many major frameworks like Vue2/Vue3, React, Preact, Solid, Svelte, and again, It also supports Vite, Roullp, Webpack, Nuxt, VueCLI, Svelte Kit, Svelte + Vite, next.js, and many other major build tools. Vue3 and ElementPlus are in the title simply because this is the context in which this article was written, and the sample code is based.

If you are not this environment also do not hinder, you still can see this article, because different environment is just on configuration a little different, use is completely consistent, of course, whether to use ultimately depends on your own choice!

Writing in the front

In the last year or so, Vue has officially changed its default branch to Vue3.0, ElementPlus has been released, and the technology has changed rapidly, bringing with it more and more fun, new and creative tools to the ecosystem.

If there is a condition, must try to update, on the one hand, large versions of iteration, especially as the framework use the huge change and the surrounding ecological big update will allow you to discover new lands, on the other hand like Vue3 official has been set to the default library, there will be more users in succession to use Vue3 directly, when everyone is using what you think of something new, If you’re not using it, you’re already behind the curve.

A few years ago, I wrote an article called the elegant use of icon in Vue project, which mainly introduced several mainstream ways of using ICONS in the project at that time, such as Img icon, CSS Sprite image, Font icon, SVG icon. This article focuses on the description of SVG Icon and provides an elegant way to use SVG Icon. Let’s review this way: In the development environment, separate the custom Icon into a separate module, use svgLoader to parse the SVG Icon, and then write a Vue component
to load it uniformly. Download an SVG Icon into the Icon module every time you need to use an Icon. Use the component and pass in the SVG file name to load the Icon, see above if you don’t know. This approach is probably what most students are using in their Vue2 project.

So one might ask, does this not work in Vue3?

No, it still applies. So why are we changing it?

That’s a lot to talk about.

PS: BelowElementUIRefers to the component library for Vue2,ElementPlusRefers to the component library for Vue3!

I’m sure many of you have built your project component library based on ElementUI, but the built-in icon library in ElementUI is the font icon. Many of you, including myself, use the built-in font icon more or less to save trouble (especially the action ICONS on buttons), and only use custom ICONS if you have to. This leads to both font ICONS and SVG ICONS being used in the same project, which is not a big problem.

The problem is that Vue has been upgraded, it’s now Vue3, and if we want to use Vue3 in our project, ElementUI has to be upgraded to ElementPlus, and the upgrade of ElementPlus is a lot more disruptive than before, especially the icon component. Because it’s migrated from font ICONS to SVG ICONS, it’s used in a very different way.












For the unity of the project (ok, ocD!!) , this situation must not be allowed. There are two solutions:

  • Do not use component library built-in ICONS.
  • Keep custom icon usage consistent with the component library.

B: well.. I happened to find antFu’s unplugin-icons plugin that makes it possible to use custom ICONS in the same way as the ICONS in the component library and also provides a lot of convenience for our development (in fact, I think ElementPlus references this as well), which is really nice, so this article came about.

So in this article we will still use SVG Icon, the difference is that it is used in a different way, and as the title says, it is more elegant!!

Huh? Why use SVG Icon?

Well, you still don’t know why you use SVG Icon?

Then we will simply compare the use of several Icon, of course, Img and CSS Sprite, because now the most commonly used are vector ICONS, so we will simply compare the advantages and disadvantages of the most commonly used font ICONS and SVG ICONS.

As you can see above, SVG ICONS are superior to font ICONS except for browser support, which makes no sense in this era of Chrome kernel dominance.

All right, here we go!

ICONS are used in ElementPlus

Let’s take a quick look at how ICONS are used in ElementPlus. If you want to use ElementPlus’s Icon library, you need to install the official Icon library package first, as it is not included in the ElementPlus package.

Install icon Library

# NPM
$ npm install @element-plus/icons-vue
# Yarn
$ yarn add @element-plus/icons-vue
# pnpm
$ pnpm install @element-plus/icons-vue
Copy the code

Use the ICONS

ElementPlus’s Icon library migrates SVG ICONS from the previous Icon Font and uses them in a very different way. We simply import the ICONS we use and use them as a Vue component, as follows:

<template>
  <Expand />
  <Fold />
</template>

<script setup>
import { Expand, Fold } from '@element-plus/icons-vue';
</script>
Copy the code

In addition, ElementPlus also provides an ElIcon component that can be used to change the style of the icon by passing it in as a slot and changing the color and size of the icon through the color and size properties of the component. Of course, You can also use the class and style attributes to define the style of the icon if you have special requirements, but generally we just change the color and size, as follows:

<template>
  <el-icon color="# 000" size="22">
    <Expand />
  </el-icon>

  <el-icon style="color: #000; font-size: 22px;">
    <Fold />
  </el-icon>
</template>

<script setup>
import { Expand, Fold } from '@element-plus/icons-vue';
</script>
Copy the code

As you can see, ElementPlus takes the SVG Icon out of the way. For loading an Icon, we don’t need to worry about changing its style, just importing the loading, and then a unified component does the styling.

Some people are a little bit uncomfortable with this at first, but when you use it for a long time it’s super easy to use, because you don’t have to write CSS classes and then styles to change ICONS, you just have to import and use ICONS, and style changes, Sometimes we don’t even need to pass in the attributes. The default style of ElIcon is OK and uniform, and we don’t have to write a component to load the SVG icon when we customize the icon.

Now let’s look at how to customize ICONS.

Custom Icon

The custom ICONS will use the unplugin-icons plugin written by antFu. Let’s first look at what this plugin does.

The core of the plugin is designed to parse and load SVG ICONS on demand, and it supports on-demand access to thousands of ICONS based on the Iconify Icon library, which we can do without.

Installing a plug-in

First we need to install this plugin:

npm i -D unplugin-icons
Copy the code

The use of plug-in

Once the plugin is installed, it is also very simple to use. Let’s take Vue3 + VueCLI as an example to see how it is used. Configure the following contents in vue.config.js:

// vue.config.js
/ / introduction
const Icons = require('unplugin-icons/webpack')
module.exports = {
  configureWebpack: {
    plugins: [
      / / use
      Icons({ compiler: 'vue3'})],}}Copy the code

If you are Vue3 + Vite, just do the following configuration in vite.config.js:

// vite.config.js
import Icons from 'unplugin-icons/vite'

export default defineConfig({
  plugins: [
    Icons({ compiler: 'vue3'})],})Copy the code

Yes, it’s as simple as that, but if you’re in another environment, you can also follow the documentation on GitHub.

Using the Icon Library

As mentioned above, the plugin supports on-demand access to tens of thousands of ICONS based on the Iconify library. Let’s take a look at how to use the Iconify library.

The iconify library works as a data source for the unplugin-icons plug-in because it’s really useful. It has 100+ icon sets inside, and each set has thousands of ICONS, so it’s very, very complete.

In the Iconify library, you can think of the icon set as a module. Each module (icon set) is the corresponding icon file, and the number of ICONS in each icon set is very large.

Let’s open the icon library’s official website:

In the image above, the ones circled in red are the set of Icons. Take the first Google Material Icons, and under this set there will be 1W + Icons.

Let’s open the icon set and select an icon:

We selected the icon 5G, as shown in the red circle above, and the full name of the icon is IC: Baseline – 5G, where IC is the name of the icon set and baseline- 5G is the icon name, which we need to know first.

Now that you know about the Iconify icon library, let’s use it with the plugin, which you must install if you want to use it. The unplugin-icons plug-in supports three ways of installing this icon library, which we will look at one by one.

Manually install the icon library

The first option is to manually install the iconify library, as named, and install the entire Iconify library directly. This library is about 120MB in size, but you don’t need to worry, it will only pack the ICONS you use in production.

npm i -D @iconify/json
Copy the code

Manually install the icon set

Although plug-in in a production environment will only packaging you are using to the Icon, but 120 MB installed or too slow, so, the second installation manually install Icon set, because there are too many ICONS, sometimes we just need to use a set of Icon Icon is enough, then we can only install and use the Icon sets.

npm i -D @iconify-json/xxx
Copy the code

With the above command, we just need to select the icon set we want to use and replace the name of the icon set with XXX. You can check the name of the icon set on the official website of the icon library by the way we mentioned above.

Automatically installs the icon set

Is it hard to install an icon set? It doesn’t matter, the plugin also supports automatic installation of icon sets, which is as simple as adding a line of code to the configuration.

// vue.config.js
const Icons = require('unplugin-icons/webpack')
module.exports = {
  configureWebpack: {
    plugins: [
      Icons({ 
        compiler: 'vue3'.// Automatic installation
        autoInstall: true})],}}Copy the code

As shown above, as long as we pass the autoInstall attribute true in our configuration, the plug-in will automatically download the icon set when it detects that we have introduced it, which is a lot easier.

No need to think about it, everyone should use automatic installation.

Using the Icon Library

Let’s look again at how ICONS from an icon library can be used in a project. Take the 5G icon above as an example. Its icon set is IC and its icon name is baseline- 5G, used as follows:

<template>
  <IconBaseline5g />
</template>

<script setup>
import IconBaseline5g from '~icons/ic/baseline-5g'
</script>
Copy the code

Yes, it is that simple. If we configure automatic installation, the plugin will detect and install the IC icon set automatically through the package management tool when the above code is written and saved.

We found that this use of Icon is exactly the same as that of ElementPlus. Is it possible to use the ElIcon component of ElementPlus?

The answer is yes:

<template>
  <el-icon size="22" color="# 000">
    <IconBaseline5g />
  </el-icon>
</template>

<script setup>
import IconBaseline5g from '~icons/ic/baseline-5g'
</script>
Copy the code

Well, that’s interesting at last.

Customize SVG ICONS

Finally, there are our custom ICONS. Although Iconify offers a huge library of ICONS, and ElementPlus has a few, sometimes UI designers have to create their own, but that’s fine, you can just ask the designer to export an SVG file to you.

Using Vue3 + VueCLI as an example, we will make some preparations first. First, we will add SVG/directory under SRC/Assets (according to our own preferences). We can create different folders under SVG/according to modules, and these folders are used to store our customized SVG icon files.

src/assets/svg/home/jihua.svg
src/assets/svg/about/kefu.svg
Copy the code

Above are the two ICONS I created. Next, let’s configure the loading of custom ICONS.

The unplugin-icons plugin has a customCollections property for loading custom ICONS, but since we need to import SVG files, we also need a loader for parsing SVG files. This is also taken into account by the plugin. Unplugin-icons plug-in package has this loader, we can directly introduce and use, as follows:

// vue.config.js
const Icons = require('unplugin-icons/webpack')
/ / into the loader
const { FileSystemIconLoader } = require('unplugin-icons/loaders')
module.exports = {
  configureWebpack: {
    plugins: [
      Icons({ 
        compiler: 'vue3'.autoInstall: true.// Custom icon loading
        customCollections: {
          // Home icon set
          // Set the SVG file to fill="currentColor" to make the color of the icon adaptable
          home: FileSystemIconLoader('src/assets/svg/home'.svg= > svg.replace(/^<svg /.'<svg fill="currentColor" ')),
	  // about icon set
          about: FileSystemIconLoader('src/assets/svg/about'.svg= > svg.replace(/^<svg /.'<svg fill="currentColor" '),},}),],}}Copy the code

As shown above, each folder in SVG/directory can be used as a module, and the following files can be parsed by loader, and then we can use happily:

<template>
  <el-icon size="22" color="# 000"><IconBaseline5g /></el-icon>
  <el-icon size="22" color="# 000"><IconHomeJiHua /></el-icon>
  <el-icon size="22" color="# 000"><IconAboutKeFu /></el-icon>
</template>

<script setup>
/ / iconify icon
import IconBaseline5g from '~icons/ic/baseline-5g';
// Customize the icon
import IconHomeJiHua from '~icons/home/jihua';
import IconAboutKeFu from '~icons/about/kefu';
</script>
Copy the code

At this point, there is only one way to use the entire project icon, just use it at will. Nice!

Wait, you think this is the end of it? No!

When you use it, you also need to introduce it, which is really quite troublesome. Is there a way to automatically introduce it so that we can use it wherever we want?

Sure, let’s keep going.

Automatically is introduced into

In order to achieve automatic introduction, we also need a plug-in, also written by antFu boss unplugin-vue-Components plug-in.

I have to say that antFu is really a brother of Vue3 ecological wheels!!

This plugin is designed to automatically import components to Vue. It supports Vue2 and Vue3 out of the box, components and directives, as well as Vite, Webpack, VueCLI, Rollup, and ESbuild. Most importantly, it fits perfectly into unplugin-icons.

Installing a plug-in

The first is installation:

npm i unplugin-vue-components -D
Copy the code

The use of plug-in

The next step is to use or follow the environment of Vue3 + VueCLI. Other environments can view the document by themselves. In fact, it is just a package introduced in another environment.

To start, use the plug-in as follows:

// vue.config.js
const Icons = require('unplugin-icons/webpack')
const { FileSystemIconLoader } = require('unplugin-icons/loaders')
// Import automatically import plug-ins
const Components = require('unplugin-vue-components/webpack')
module.exports = {
  configureWebpack: {
    plugins: [
      // Use automatic import plug-in
      Components({ /** options **/ }),
      Icons({ 
        compiler: 'vue3'.autoInstall: true.customCollections: {
          home: FileSystemIconLoader('src/assets/svg/home'.svg= > svg.replace(/^<svg /.'<svg fill="currentColor" ')),
          about: FileSystemIconLoader('src/assets/svg/about'.svg= > svg.replace(/^<svg /.'<svg fill="currentColor" '),},}),],}}Copy the code

As mentioned above, there is no need to introduce our custom components in the project after we use the plug-in.

For example, let’s write a HelloWord component anywhere in the SRC/directory and find a place to use it directly:

<template>
  <div>
    <HelloWorld msg=Vue 3.0 + Vite />
  </div>
</template>

<script>
// No need to import the HelloWorld component
</script>
Copy the code

As above, using this component in a page component as usual will import the component on demand, with no import and component registration required. The plug-in will automatically parse the above code at compile time to look like this:

<template>
  <div>
    <HelloWorld msg=Vue 3.0 + Vite />
  </div>
</template>

<script>
import HelloWorld from './src/xxxxxxxxx/HelloWorld.vue'

export default {
  components: {
    HelloWorld
  }
}
</script>
Copy the code

Of course, this is limited to components we wrote ourselves in the project (this is also supported in the case of asynchronous registration of the parent or delayed routing, where the auto-imported component will be split with its parent).

The resolution automatically introduced by the components in the project is built-in in the plug-in. However, for the Icon component above, since it is imported from outside, we need to configure its own parser. The unplugin-icons plug-in provides us with an unplugin-icons/resolver package. This package is used to handle Icon related automatic import parser, we call it Icon automatic import parser, in fact, is very simple to implement, specific wait to see the following custom automatic import will understand.

Then our configuration is as follows:

// vue.config.js
const Icons = require('unplugin-icons/webpack')
const { FileSystemIconLoader } = require('unplugin-icons/loaders')
// Import Icon automatically import the parser
const IconsResolver = require('unplugin-icons/resolver')
// Import automatically import plug-ins
const Components = require('unplugin-vue-components/webpack')
module.exports = {
  configureWebpack: {
    plugins: [
      // Use automatic import plug-in
      Components({
	// Configure the parser
        resolvers: [
	  // Icon automatically imports parsers
          IconsResolver({
	    // Automatically imported Icon component uniform prefix, default is I, set false to no prefix required
            prefix: 'icon'.// When the icon set name is too long, the set alias can be used
            alias: {
              system: 'system-uicons'
            }
          })
        ]
      }),
      Icons({ 
        compiler: 'vue3'.autoInstall: true.customCollections: {
          home: FileSystemIconLoader('src/assets/svg/home'.svg= > svg.replace(/^<svg /.'<svg fill="currentColor" ')),
          about: FileSystemIconLoader('src/assets/svg/about'.svg= > svg.replace(/^<svg /.'<svg fill="currentColor" '),},}),],}}Copy the code

Note that when using the Icon component parser, you must follow the name conversion to correctly infer the Icon. That is, to automatically import the Icon component, you must write the component name as follows:

// prefix - prefix, which defaults to I and is configured as icon, i.e. component names start with icon
// collection - Icon set name
// icon - Icon name
{prefix}-{collection}-{icon}

// You can also use a big hump
Copy the code

Let’s first look at the case without auto-import:

<template>
  <el-icon size="22" color="# 000"><IconBaseline5g /></el-icon>
  <el-icon size="22" color="# 000"><IconSystemUiconsBell /></el-icon>
  <el-icon size="22" color="# 000"><IconHomeJiHua /></el-icon>
  <el-icon size="22" color="# 000"><IconAboutKeFu /></el-icon>
</template>

<script setup>
// Iconify icon, icon set IC
import IconBaseline5g from '~icons/ic/baseline-5g';
// iconify icon, set of system-uicons
import IconSystemUiconsBell from '~icons/system-uicons/bell';
// Customize the icon
import IconHomeJiHua from '~icons/home/jihua';
import IconAboutKeFu from '~icons/about/kefu';
</script>
Copy the code

Now let’s look at the auto-import (note that iconify’s set of system-uicons have been aliases to System and the bell icon has been loaded below) :

<template>
  <el-icon size="22" color="# 000"><IconBaseline5g /></el-icon>
  <! -- IconSystemUiconsBell -> IconSystemBell -->
  <el-icon size="22" color="# 000"><IconSystemBell /></el-icon>
  <el-icon size="22" color="# 000"><IconHomeJiHua /></el-icon>
  <el-icon size="22" color="# 000"><IconAboutKeFu /></el-icon>
</template>
<script setup>
// There is no need to manually import the icon component
</script>
Copy the code

Isn’t it very simple!!

Custom ICONS are automatically introduced

If you wrote the demo while reading this article, you must have noticed that the two ICONS we customized were not loaded when they were automatically imported.

This is because custom Icon sets that want to be imported automatically need to be tagged with the customCollections attribute in the configuration of the Icon auto-import resolver (IconsResolver).

We used two custom icon sets above, so just pass in the names of the two custom icon sets so that the auto-import plugin can recognize and parse them:

// vue.config.js
const Icons = require('unplugin-icons/webpack')
const { FileSystemIconLoader } = require('unplugin-icons/loaders')
const IconsResolver = require('unplugin-icons/resolver')
const Components = require('unplugin-vue-components/webpack')
module.exports = {
  configureWebpack: {
    plugins: [
      Components({
        resolvers: [
          IconsResolver({
            prefix: 'icon'.alias: {
              system: 'system-uicons'
            },
            // Identifies a custom icon set
            customCollections: ['home'.'about']
          })
        ]
      }),
      Icons({ 
        compiler: 'vue3'.autoInstall: true.customCollections: {
          home: FileSystemIconLoader('src/assets/svg/home'.svg= > svg.replace(/^<svg /.'<svg fill="currentColor" ')),
          about: FileSystemIconLoader('src/assets/svg/about'.svg= > svg.replace(/^<svg /.'<svg fill="currentColor" '),},}),],}}Copy the code

As shown above, run the project again and you can see that the four ICONS are fully displayed!

Some other uses for automatic introduction

Now that we have automatic import plug-ins, do we need to manually import component libraries on demand?

When using ElementPlus, for example, it is known that it can be used in two ways:

  • Introduced the global
  • According to the need to introduce

We usually choose import on demand, but import on demand requires us to import the corresponding component separately every time we use it, which is very troublesome. Then, with the help of the auto-import plug-in, this will be extremely easy.

In fact, there are several parsers built directly into the auto-import plug-in for popular UI libraries such as Vuetify, Ant Design Vue, and ElementPlus, and we don’t even need a handwritten parser to use them seamlessly.

Again, take ElementPlus:

// vue.config.js
const Icons = require('unplugin-icons/webpack')
const { FileSystemIconLoader } = require('unplugin-icons/loaders')
const IconsResolver = require('unplugin-icons/resolver')
const Components = require('unplugin-vue-components/webpack')
// Import ElementPlus automatically import the parser
const { ElementPlusResolver } = require('unplugin-vue-components/resolvers')
module.exports = {
  configureWebpack: {
    plugins: [
      Components({
        resolvers: [
          IconsResolver({
            prefix: 'icon'.alias: {
              system: 'system-uicons'
            },
            customCollections: ['home'.'about']}),// Automatically import parsers using ElementPlus
          ElementPlusResolver(),
        ]
      }),
      Icons({ 
        compiler: 'vue3'.autoInstall: true.customCollections: {
          home: FileSystemIconLoader('src/assets/svg/home'.svg= > svg.replace(/^<svg /.'<svg fill="currentColor" ')),
          about: FileSystemIconLoader('src/assets/svg/about'.svg= > svg.replace(/^<svg /.'<svg fill="currentColor" '),},}),],}}Copy the code

Let’s write a sample code:

<template>
  <el-button>This is the El button that is automatically introduced</el-button>
</template>
<script setup>
// There is no need to manually import component library components
</script>
Copy the code

As mentioned above, it can be loaded perfectly, without importing the component library globally, nor need to import on demand, if you want to use directly write components can be!

Customize scenarios that automatically introduce parsers

If the company has its own component library, how to do automatic import?

Since the internal component library is also an imported component, and there is no parser written for us on the official website, we need to write our own parser!!

It is also very simple. For example, the component library name of our company is XX-UI, and the component prefix is XX. Xx-button component is used in the project.

First we install the component library XX-UI:

npm install xx-ui
Copy the code

Let’s configure the automatic import parser for this component library:

Components({
  resolvers: [
    / /... Other parsers
    // Customize the xx-UI parser
    (name) = > {
      // Name is the custom component loaded when the project is compiled
      // For example: name = XxButton
      // Determine the component prefix
      if (name.startsWith('Xx')) {return { 
          // package name, XxButton -> Button
          importName: name.slice(2), 
          // Just write the package name, since we already have the package installed
          path: 'xx-ui'}}}]})Copy the code

Thus in use:

<template>
  <xx-button></xx-button>
</template>
<script setup>// There is no need to import the component library component<script>
Copy the code

The above code will be converted to the following at compile time:

<template>
  <xx-button></xx-button>
</template>
<script setup>
import { Button } from "xx-ui"
<script>
Copy the code

The unplugin-vue-Components plugin supports directives as well as components, but you need to find out for yourself!

thinking

Do you think it’s more elegant?

There will be more and better ways to use Icon, if you know, please comment!!

The CompositionAPI smells great, script Setup smells great, and you can’t learn Vue3 just by looking at the documentation — for those of you who haven’t used Vue3 yet.

Write this, the next article topic seems to have, Get Vue3 you do not know the tips! So use it to smell good…

The last

If there is any mistake, welcome to point out the comment area, thank you!

If it is helpful to you, I am very honored, the code word is not easy, move your little hands point a thumbs-up! Little attention do not get lost!!

Day 678th of nuggets code word, day 679th expected nuggets private chat function, but it doesn’t!!

So, if there is a problem, add WX “Lijianchao666”, you can also pay attention to the public number “not serious front end”, learn more front end knowledge, a no advertising, no bother, only the original, and occasionally a little little welfare of the public number, three grams of oil!!