svgIcon组件的构建与使用
svgIcon是一个可以在项目任意地方使用的「图标组件」
构建目标:组件使用者只需指定图标名称、颜色等属性,HTML页面渲染出对应的svg图标
背景
SVG是什么?
SVG (Scalable Vector Graphics)可缩放矢量图形,是一种用于描述基于二维的矢量图形的XML标记语言,其基本矢量显示对象包括矩形、圆、椭圆、多边形、直线、任意曲线等,还能显示文字对象和嵌入式外部图像(包括PNG、JPEG、SVG等)。实际项目中大多数图标都是使用的 SVG 图标文件,其主要有以下几个 优点:
- 内容可读,文件是纯粹的XML
- 图像文件小,可伸缩性强
- 矢量放缩,能以不牺牲图像质量为前提,进行任意缩放
- 还能基于DOM模型实现动态和一些交互功能
如何将 SVG 效果应用于HTML内容中?
在 HTML 文档写入类似于以下的内容,则能在页面中渲染出对应的图标
<div>
<svg xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 0 24 24" width="24">
<path d="M0 0h24v24H0V0z" fill="none"/>
<path d="M18 20H4V6h9V4H4c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2v-9h-2v9zm-7.79-3.17l-1.96-2.36L5.5 18h11l-3.54-4.71zM20 4V1h-2v3h-3c.01.01 0 2 0 2h3v2.99c.01.01 2 0 2 0V6h3V4h-3z"/>
</svg>
</div>
用一句话概括总结就是,SVG 文件内容写入HTML文档即可将 SVG 效果渲染展示到页面中
如何在项目中优雅的使用大量的 SVG 图片文件?
前端实践项目时,为了追求良好的用户体验,难免会使用到大量的符合项目特色的各种图标,以此来丰富美化页面内容。所以随着项目逐步完善,需要使用到的图标文件肯定也会随之增加,如何优雅的在项目中使用大量的 SVG 图片文件?这是我们目前需要考虑以及解决的重点问题之一
实际项目开发中,采用 直接将svg文件内容(实质的XML内容)写入到HTML文档 对应位置去渲染我们所预期的图标图形这种方式,可行但不可取!因为这种方式要求使用者在项目每个页面中每个需要展示 SVG 图标的位置,都要将图标文件内容完整的写入对应的 DOM 中,而且 SVG 内容较繁杂,直接写入 DOM 非常影响我们代码的美观和可阅读性。总之这样的操作太过笨重,严重缺乏灵活性和可扩展性。
经过技术调研,我们不难发现sprite-svg
结合 use 元素的使用方式,可以很好的解决这个问题
将项目中各个图标合并成一个包含多个 symbol 的 SVG 文件。在需要使用图标的地方,用 use 元素去引用对应的 symbol 即可。
其工作原理大致是:use 元素会去 SVG 文档内取得目标节点,并且复制它的内容,效果等同于目标节点被深克隆到一个不可见的DOM中,然后将其粘贴到 use 元素的位置上。
demo:
<!-- sprite.svg文件目录:/dist/images/sprite.svg -->
<svg width="0" height="0" class="hidden">
<symbol xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" id="add">
<path fill="none" d="M0 0h24v24H0V0z"></path>
<path d="M19 13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z"></path>
</symbol>
<symbol xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" id="add_photo">
<path d="M0 0h24v24H0V0z" fill="none"/>
<path d="M18 20H4V6h9V4H4c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2v-9h-2v9zm-7.79-3.17l-1.96-2.36L5.5 18h11l-3.54-4.71zM20 4V1h-2v3h-3c.01.01 0 2 0 2h3v2.99c.01.01 2 0 2 0V6h3V4h-3z"/>
</symbol>
</svg>
<div>
<svg>
<use xlinkHref={`/dist/images/sprite.svg#add_photo`} />
</svg>
</div>
当然,如果