Ant-Design-Vue 3.x 图标库如何实现自动引入?

2023-02-17 15:03:31 浏览数 (1)

需求来源

Ant-Design-Vue升级到2.x以上的版本之后,自带的图标库就不支持通过给组件传递一个代表指定图标的属性来使用了。

1. 之前

代码语言:javascript复制
<-- 显示Home图标 -->
<a-icon type="home" />

2. 现在

代码语言:javascript复制
<template>
  <message-outlined :style="{fontSize: '16px', color: '#08c'}" />
</template>
<script setup>
  import { MessageOutlined } from '@ant-design/icons-vue';
</script>zh

在这种形式下,每个要用到的图标都需要手动引用一次,并且由于每个组件没有统一标准的名称,所以无法使用打包工具提供的一些自动引入组件的插件(比如vite的unplugin-vue-components)

这样做也会带来一定的好处:打包的时候只会打包用到的图标的代码,不会引入其它没用到的图标。

但是任何需求都不是绝对,总有不一样的需求,比如我;

实际测试,完整的图标库打包,经过Gzip压缩后只有130 kb ;完全可以接受

Tree Shaking

Tree Shaking 指的就是当引入一个模块的时候,不引入这个模块的所有代码,只引入需要的代码

Tree-shaking的本质是消除无用的js代码。无用代码消除在广泛存在于传统的编程语言编译器中,编译器可以判断出某些代码根本不影响输出,然后消除这些代码,这个称之为DCE(dead code elimination)

自动引入

1.介绍

本文所指的自动引入指的是,在项目的任意组件内,直接使用这个图标,不需要通过手动引入。同时实现按需引入 自动引入,以我的能力目前没找到....(打包工具的插件应该可以实现);

当然可以直接在开始运行的时候导入整个图标模板,然后循环注册到Vue的组件,但是这样的缺点就是使用图标只能在模板内写死,例如:

代码语言:javascript复制
<message-outlined :style="{fontSize: '16px', color: '#08c'}" />

但是很多时候,我们想要的是传递一个属性,来动态显示不同图标,常见的需求场景:定义路由的时候给每个路由定义一个代表图标的元属性,通过路由生成菜单的时候,直接展示元属性里指定的图标;

模板语法往往适合条件明确的情况,条件不明确了,那就该JSX入场了。

2.实现

首先引入@ant-design/icons-vue整个图标库,然后Jsx组件内,通过渲染函数直接渲染指定的图标;基础代码如下:

代码语言:javascript复制
<script>
import {h} from 'vue'
import * as $icon from '@ant-design/icons-vue';

/*
* 自动引入antd icon图标
* */
export default {
  props:['icon'],
  setup(props){
   return ()=>h(
      $icon[props.icon],
       {
            style:{fontSize:"18px"}
       });
  }
}
</script>

3.拓展

@ant-design/icons-vue图标很全,但也有不够用的时候,这时候就可以考虑,让这个JSX组件兼容 iconfont图标了;

众所周知,阿里巴巴图标库一般都是统一class前缀,@ant-design/icons-vue的名字则是五花八门,这不,判断的标准不就来了吗!

如果传递的icon属性是icon开头,就渲染一个class位图标的i标签,其它的照常作为antd标签渲染;代码如下:

代码语言:javascript复制
<script>
import {h} from 'vue'
import * as $icon from '@ant-design/icons-vue';
import config from '@/config'

/*
* 自动引入antd icon图标
* */

export default {
  props:['icon'],
  setup(props){
    /*
    * 判断是icon还是antd的图标
    * */
    if(props.icon.indexOf('icon-') != -1){
      return ()=>h(
          'i',
          {
            class:"iconfont " props.icon,
            style:{fontSize:"18px"}
          });
    }else{
      return ()=>h(
          $icon[props.icon],
          {
            style:{fontSize:"18px"}
          });
    }
  }
}

</script>

到此结束,如果还需要继续拓展,那,干就完了!

0 人点赞