需求來源
Ant-Design-Vue升級到2.x以上的版本之后,自帶的圖標庫就不支持通過給組件傳遞一個代表指定圖標的屬性來使用了。
1. 之前
<-- 顯示Home圖標 --> <a-icon type="home" />
2. 現在
<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的組件,但是這樣的缺點就是使用圖標只能在模板內寫死,例如:
<message-outlined :style="{fontSize: '16px', color: '#08c'}" />
但是很多時候,我們想要的是傳遞一個屬性,來動態顯示不同圖標,常見的需求場景:定義路由的時候給每個路由定義一個代表圖標的元屬性,通過路由生成菜單的時候,直接展示元屬性里指定的圖標;
模板語法往往適合條件明確的情況,條件不明確了,那就該JSX入場了。
2.實現
首先引入@ant-design/icons-vue
整個圖標庫,然后Jsx組件內,通過渲染函數直接渲染指定的圖標;基礎代碼如下:
<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標簽渲染;代碼如下:
<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>
到此結束,如果還需要繼續拓展,那,干就完了!