Closed jrainlau closed 2 years ago
市面上几乎所有的组件库都会有其独特的图标集,相对应的也有着属于自己的一套图标组件实现方式。一般情况下,其图标会以 icon-font 的形式提供,如 element-ui,也有部分会使用 svg,如 ant-design。在这篇文章内我们不讨论 icon-font 和 svg 的优劣,只讨论如何利用 Vue3 搭配 Vite 来实现基于 svg 的图标组件。
在全局安装好了 Vite 以后,我们首先初始化一个项目:
yarn create vite # 选择 vue 框架,并使用普通的 vue 写法(你要用 vue-ts 也行) ✔ Project name: … svg-icon ✔ Select a framework: › vue ✔ Select a variant: › vue
这样就能初始化一个 Vue3 + Vite 的项目了,目录结构如下:
├── README.md ├── index.html ├── package.json ├── public ├── src │ ├── App.vue │ ├── assets │ │ └── logo.png │ ├── components │ │ └── HelloWorld.vue │ └── main.js └── vite.config.js
接下来我们随便找几个 svg 图标,比如开源的 ionicons,我下载并把它们放在 /src/assets 目录底下。
/src/assets
项目搭建好了,图标素材也准备好了,下面开始编写通用的图标组件。
在 /src/components 目录下新建一个 Icon.vue:
/src/components
Icon.vue
<template> <i class="my-icon"></i> </template>
一般来说,图标组件常用 <i></i> 标签来承载,我们这里也不例外。新建好了图标的 Vue 组件以后,就要开始思考我们应该如何把 SVG 图标给填充上去。
<i></i>
有人可能会说,直接用 <image /> 标签以图片 src 的形式引入 SVG 图标不就好了吗?这样没问题,但这样的方式有一个致命的缺陷,就是难以改变图标的颜色。作为一个通用的图标组件,改变其颜色和大小是非常常见的操作需求,因此我们不能走这条路。
<image />
熟悉 Webpack 的同学应该知道,Webpack 的生态系统里有着千奇百怪的 loader,几乎可以把任意格式的资源加载进来甚至直接变成 Vue 组件,那么在 Vite 生态下有没有呢?经过一番查找,我找到了一个名为 vite-svg-loader 的东西,恰好可以满足”加载 SVG 资源并把它变成 Vue 组件“的场景,马上试一试!
打开项目中的 vite.config.js,引入 vite-svg-loader:
vite.config.js
vite-svg-loader
import { defineConfig } from 'vite' import vue from '@vitejs/plugin-vue' import svgLoader from 'vite-svg-loader' export default defineConfig({ plugins: [vue(), svgLoader()] })
接着在 Icon.vue 中直接 import 一个 SVG 图标:
<template> <i class="my-icon"> <icon /> </i> </template> <script setup> import icon from '../assets/checkmark-circle-outline.svg' </script> <style scoped> i { display: inline-block; width: 50px; height: 50px; color: red; } </style>
啪,完美~
本篇完。
……
等一下,还没完~
开源的东西总是兼顾了很多场景,也经过了千万次的验证,因此特别靠谱也特别理想。但是在实际的开发中往往没有这么理想的情况。比方说我们的设计师给我导出了一个这样的 Check.svg 图标:
和开源的 ionicons 比起来,第一眼印象就是它是看不见的(透明)。放入 VSCode 对比两者的代码,也可以发现区别:
最后放在浏览器看,<i></i> 标签的属性它并没有继承和生效:
通过对其 XML 文件的分析不难看出,我方设计师给导出的图标,写死了大小和颜色,导致无法继承。
解决方法有二:
<svg>
width
height
fill
currentColor
方法 1 是最理想的,但是受限于人力安排和所用的软件等问题,不一定能满足我们的需要,因此我们常常被迫使用第二种方式。
市面上几乎所有的组件库都会有其独特的图标集,相对应的也有着属于自己的一套图标组件实现方式。一般情况下,其图标会以 icon-font 的形式提供,如 element-ui,也有部分会使用 svg,如 ant-design。在这篇文章内我们不讨论 icon-font 和 svg 的优劣,只讨论如何利用 Vue3 搭配 Vite 来实现基于 svg 的图标组件。
一、项目准备
在全局安装好了 Vite 以后,我们首先初始化一个项目:
这样就能初始化一个 Vue3 + Vite 的项目了,目录结构如下:
接下来我们随便找几个 svg 图标,比如开源的 ionicons,我下载并把它们放在
/src/assets
目录底下。项目搭建好了,图标素材也准备好了,下面开始编写通用的图标组件。
二、图标组件
在
/src/components
目录下新建一个Icon.vue
:一般来说,图标组件常用
<i></i>
标签来承载,我们这里也不例外。新建好了图标的 Vue 组件以后,就要开始思考我们应该如何把 SVG 图标给填充上去。有人可能会说,直接用
<image />
标签以图片 src 的形式引入 SVG 图标不就好了吗?这样没问题,但这样的方式有一个致命的缺陷,就是难以改变图标的颜色。作为一个通用的图标组件,改变其颜色和大小是非常常见的操作需求,因此我们不能走这条路。熟悉 Webpack 的同学应该知道,Webpack 的生态系统里有着千奇百怪的 loader,几乎可以把任意格式的资源加载进来甚至直接变成 Vue 组件,那么在 Vite 生态下有没有呢?经过一番查找,我找到了一个名为 vite-svg-loader 的东西,恰好可以满足”加载 SVG 资源并把它变成 Vue 组件“的场景,马上试一试!
打开项目中的
vite.config.js
,引入vite-svg-loader
:接着在
Icon.vue
中直接 import 一个 SVG 图标:啪,完美~
本篇完。
……
……
……
意料之外的 SVG 文件问题
等一下,还没完~
开源的东西总是兼顾了很多场景,也经过了千万次的验证,因此特别靠谱也特别理想。但是在实际的开发中往往没有这么理想的情况。比方说我们的设计师给我导出了一个这样的 Check.svg 图标:
和开源的 ionicons 比起来,第一眼印象就是它是看不见的(透明)。放入 VSCode 对比两者的代码,也可以发现区别:
最后放在浏览器看,
<i></i>
标签的属性它并没有继承和生效:通过对其 XML 文件的分析不难看出,我方设计师给导出的图标,写死了大小和颜色,导致无法继承。
解决方法有二:
<svg>
标签内的width
和height
,同时把所有的fill
属性都改为currentColor
。方法 1 是最理想的,但是受限于人力安排和所用的软件等问题,不一定能满足我们的需要,因此我们常常被迫使用第二种方式。