webpack导入svg图标

26 篇文章 1 订阅
7 篇文章 0 订阅

svg是一种基于XML格式的图像描述语音,它是矢量图,相比较与canvas,放大时不会失真,相对于图像来说,因为它本就是文本形式存在,尺寸会更小。传统使用方式,我们会将svg复制到需要用到的地方,或者到处import,这样代码不仅不美观,而且维护起来很麻烦,特别时图标多了的时候。接下来我们讲讲怎么以组件的方式使用svg图标(以vue为例react同理)。

实现原理:利用svg的use标签,通过id引用对应的svg图标

<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="position: absolute; width: 0; height: 0" aria-hidden="true" id="__SVG_SPRITE_NODE__">
    <symbol xmlns="http://www.w3.org/2000/svg" class="icon" viewBox="0 0 1024 1024"                 id="icon-back">
    <path d="M724 218.3V141c0-6.7-7.7-10.4-12.9-6.3L260.3 486.8c-16.4 12.8-16.4 37.5 0 50.3l450.8 352.1c5.3 4.1 12.9 0.4 12.9-6.3v-77.3c0-4.9-2.3-9.6-6.1-12.6l-360-281 360-281.1c3.8-3 6.1-7.7 6.1-12.6z" p-id="7787" fill="#999999"></path>
    </symbol>
    <symbol xmlns="http://www.w3.org/2000/svg" class="icon" viewBox="0 0 1024 1024" id="icon-close">
    <path d="M794.843 794.843c-14.001 14.001-36.911 14.001-50.912 0L229.157 280.069c-14.001-14.001-14.001-36.911 0-50.912 14.001-14.001 36.911-14.001 50.912 0l514.774 514.774c14 14.001 14 36.911 0 50.912z" p-id="2135" fill="#4E5B75"></path>
    <path d="M794.843 229.157c14.001 14.001 14.001 36.911 0 50.912L280.069 794.843c-14.001 14.001-36.911 14.001-50.912 0-14.001-14.001-14.001-36.911 0-50.912l514.774-514.774c14.001-14 36.911-14 50.912 0z" p-id="2136" fill="#4E5B75"></path>
    </symbol>
</svg>

如上这段svg代码,里面包含两个图标,嵌入html页面是不会显示的,当我们需要使用某个图标时(id="icon-close")为例,可以在html页面如下引用

<svg width="20px" height="20px" aria-hidden="true" class="svg-icon #icon-close">
    <use xlink:href="#icon-close"></use>
</svg>

这样思路就出来了,首先我们将所有svg文件打包成一个svg标签里,并且每个symbol标签都设置id,这里我们可以通过webpack的svg-sprite-lpader来实现,如下

 {
     test: /\.svg$/,
          loader: 'svg-sprite-loader',
          include: [resolve('src/icons/svgs')],
          options: {
               symbolId: 'icon-[name]'
          }
 }

一般我们会将作为图标使用的svg文件全部放在某个文件夹下,然后通过include处理这个文件下的svg文件,为了防止处理其他不要需要通过这个方式使用的svg被处理。

接下来我们要考虑怎么导入所有问svg文件,这里我们使用webpack的require.context来实现

import Vue from 'vue'
import SvgIcon from '@/components/SvgIcon'
Vue.component('svg-icon',SvgIcon)


let req = require.context('./svgs',false,/\.svg$/)
let importAll = r => r.keys().map(r)
importAll(req)

首先我们将SvgIcon注册成全局组件,这样就不用到处import了,下面三行代码就是require.context动态引入svgs下的以.svg结尾的文件,这里我们生成一个局部webpack上下文,即svgs文件夹路径,里面的文件导入基于这个上下文。最后在index.js引入这个文件即可

最后来实现SvgIcon组件

<template>
    <svg
        class="svg-icon"
        :width="w"
        :height="h"
        :class="iconName"
        aria-hidden="true"
        v-on="$listeners"
    >
        <use :xlink:href="iconName" />
    </svg>
</template>
<script>
export default {
    name: 'SvgIcon',
    props: {
        icon: {
            type: String,
            required: true
        },
        w: {
            type: [Number, String],
            default: '20px'
        },
        h: {
            type: [Number, String],
            default: '20px'
        }
    },
    computed: {
        iconName() {
            return '#icon-' + this.icon
        }
    }
}
</script>
<style lang="scss">
.svg-icon {
    vertical-align: middle;
}
</style>

然后可以在组件中使用

<template>
    <div>
        <svg-icon icon="close" />
    </div>
</template>

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值