概述

这几天研究了一下在vue中使用svg sprite,有些心得,记录下来,供以后开发时参考,相信对其它人也有用。

在vue中导入svg

在vue中导入svg的方法有很多种,比如在img标签的src属性中导入,但是这样就不能使用class改变svg的颜色。所以一般利用svg的use标签使用内联svg的方法导入。例如下面:

  1. <svg>
  2. <use xlink:href="@/assets/sprite.svg#notification"/>
  3. </svg>

使用这种方法需要注意一点,就是如果你想把路径写成变量的形式,下面的写法是行不通的:

  1. <svg>
  2. <use :xlink:href="'@/assets/sprite.svg#notification'"/>
  3. </svg>

因为vue没有解析里面的字符串,所以不能生成所需要的路径,而且,即使能够解析里面的字符串,也由于没有加上hash值导致解析不了。

解决方法是使用require生成相对路径。示例如下:

  1. <svg>
  2. <use :xlink:href="`${require('@/assets/sprite.svg')}#notification`"/>
  3. </svg>

需要注意的是,使用require的下面写法是不行的。因为路径中的#解析不了。

  1. <svg>
  2. <use :xlink:href="require('@/assets/sprite.svg#notification')"/>
  3. </svg>

使用svg雪碧图

如果svg图标有很多的话,会发出很多http请求,资源消耗量很大。这个时候最好把svg做成雪碧图。一般情况下,我们手动把要做成雪碧图的svg文件编上id,全部放到一个svg文件比如sprite.svg文件里面去,然后用如下方式引用就可以了(其中notification是引用的svg的id):

  1. <svg>
  2. <use xlink:href="@/assets/sprite.svg#notification"/>
  3. </svg>

上面的方法看起来很完美,但是有一个很严重的缺点,它的svg雪碧图是存在内存里面的,所以在切换路由的时候,svg雪碧图就没有了,需要重新下载这个svg雪碧图。很浪费资源啊。

改进方案

参考svg-sprite-loader实现加载svg自定义组件VUE-cli3使用 svg-sprite-loader可以看到,可以利用svg-sprite-loader来做svg雪碧图。但是都需要修改webpack的loader配置。

webpack-chain

vue-cli内部是利用webpack-chain插件修改webpack配置的,这是源码。外部也只能在vue.config.js里面利用webpack-chain来修改webpack配置。

具体的使用方法可以参考:webpack-chain文档webpack-配置-module

但是这里有一个坑,就是怎么按条件修改loader配置,比如在某个文件夹使用一种loader,在其它文件夹使用其它loader。看了半天文档,我最后发现,可以用oneOf来实现,其中oneOf(name)的name是自定义的,随便写语义化的名称就行。webpack-chain里面的oneOf和webpack配置里面的oneOf是对应的。实例如下:

  1. module.exports = {
  2. chainWebpack: config => {
  3. const resolve = dir => path.join(__dirname, dir);
  4. const svgRule = config.module.rule('svg');
  5. svgRule.uses.clear();
  6. svgRule
  7. .test(/\.svg$/)
  8. .oneOf('normal')
  9. .exclude
  10. .add(resolve('src/assets/svg-sprite'))
  11. .end()
  12. .use('file-loader')
  13. .loader('file-loader')
  14. .end()
  15. .end()
  16. .oneOf('sprite')
  17. .include
  18. .add(resolve('src/assets/svg-sprite'))
  19. .end()
  20. .use('svg-sprite-loader')
  21. .loader('svg-sprite-loader')
  22. .options({
  23. symbolId: 'sprite-[name]'
  24. });
  25. }
  26. };

还有一个坑就是end方法的使用,在适当的嵌套中需要加end方法返回上一层,否则后面的语句不会执行。

实现svg雪碧图

具体可以参考我写的yi-svg-sprite插件;

解释一下相关的原理和配置:

原理是利用svg-sprite-loader自动形成一个大的svg雪碧图内嵌到app的html里面,然后只需要在其它地方使用id引用里面的svg片段即可。

vue.config.js里面的操作是删除vue-cli里面对svg的loader处理,然后加上自己对svg的loader处理:在svg-sprite文件夹里面使用svg-sprite-loader,在其它文件夹里面使用file-loader(抄的vue-cli原配置);

main.js里面的操作是导入yi-svg-sprite库,并且把svg-sprite文件夹里面的svg文件组装成一个svg雪碧图,id是各自的文件名。

其它svg-sprite库

后来我才发现,已经有很多svg-sprite库了,下面对它们一一评价:

  • vue-svg-sprite:这个svg sprite库使用directive让人眼前一亮,但是它仍然有在切换路由的时候会重新加载svg雪碧图的缺点。
  • vue-cli-plugin-svg-sprite: 这个svg sprite库看起来很完美,也是包装的svg-sprite-loader,但是配置项太多,担心出现其它问题,而且好像没有维护了。

在vue中使用svg sprite的更多相关文章

  1. 如何在vue中使用svg

    1.安装依赖 npm install svg-sprite-loader --save-dev 2.在config文件中配置    const path = require('path'); func ...

  2. vue中使用svg字体图标

    1.在src/ 下面新建目录icons,里面新建文件夹svg,和文件index.js .svg用于存放从iconfont下载下来的svg格式的图标,index.js用于引入使用到svg文件和对应的组件 ...

  3. vue中引入.svg图标,使用iconfont图标库

    阿里巴巴的iconfont是一个很好的图标库,海量的素材可以快速满足开发人员日常对图标的诉求,我们采用symbol引用,官方介绍 创建SvgIcon组件 <template> <sv ...

  4. vue中,svg图标添加click事件,部分浏览器不生效

    vue项目中,使用svg图标,但是发现,为svg图标绑定click事件时,部分浏览器会出现,点击没有反应的情况,代码如下: <icon name="icon_add" @cl ...

  5. vue中 使用SVG实现鼠标点击绘图 提示鼠标移动位置 显示绘制坐标位置

    <div class="div1"> <svg id="svg1" xmlns="http://www.w3.org/2000/sv ...

  6. 在 React、Vue项目中使用 SVG

    在一些现代的扁平化设计网站,特别是移动端网站,经常会包含许多简单而清晰的小图标,例如网站图标.用户的默认头像.移动端网页首页底部固定的切换栏等,这些小图标一般都是由美工做好,可能会放到精灵图上,前端再 ...

  7. Vue项目中使用svg图标

    svg的图片有着颜色自定义大小自定义的优势.在阿里图标库可以下载svg图片. 那么在vue框架中我们该怎么使用svg图片呢 这个时候就用到了 webpack 插件 svg-sprite-loader ...

  8. vue中引用swiper轮播插件

    有时候我们需要在vue中使用轮播组件,如果是在vue组件中引入第三方组件的话,最好通过npm安装,从而进行统一安装包管理. 申明:本文所使用的是vue.2x版本. 通过npm安装插件: npm ins ...

  9. vue中config/index.js:配置的详细理解

    当我们需要和后台分离部署的时候,必须配置config/index.js: 用vue-cli 自动构建的目录里面  (环境变量及其基本变量的配置) var path = require('path') ...

随机推荐

  1. 前端angular使用crypto-js进行加密

    首先下载大包 npm install crypto-js 然后下载ts版本的包 npm install --save @types/crypto-js 接着在头部导入crypto-js模块 impor ...

  2. 学习笔记_J2EE_Mybatis_02_mybatis注解配置入门

    mybatis入门示例 声明式 1.概述 mybatis的注解配置版,为了偷懒,直接在之前xml版本的文件上修改的:同样为了偷懒,今天只写示例V1.0版基础配置版 ,后面再更新细节.    一个不偷懒 ...

  3. Python3学习笔记十五

    ---恢复内容开始--- 1.  jquery的属性操作  $().attr(属性名)    取值 $().attr(属性名,属性值)      赋值 <!DOCTYPE html> &l ...

  4. pyqt5与QML开发小结

    遇见的坑 qt 5.11 与 qt 5.12 中Qquick的差异还是蛮大的,由开发环境:Pyqt5.11 + Qt5.12 部署到 Pyqt5.11 + Qt5.11时遇到以下问题: 1.当一个It ...

  5. 从Uber微服务看最佳实践如何炼成?

    导读:Uber成长非常迅速,工程师团队快速扩充,据说Uber有2000名工程师,8000个代码仓库,部署了1000多个微服务.微服务架构是Uber应对技术团队快速增长,功能快速上线很出色的解决方案.本 ...

  6. EJS 入门学习

    EJS(Embedded JavaScript templates)是一个简单高效的模板语言,通过数据和模板,可以生成HTML标记文本.可以说EJS是一个JavaScript库,EJS可以同时运行在客 ...

  7. java编程(2)——servlet和Ajax异步请求的接口编程(有调用数据库的数据)

    第一步: 1.为项目配置 Tomcat 为 server: 2.导入 mysql的jar包 到项目目录中: 第二步:编码 1.数据库连接类ConnectMysql.java代码: package co ...

  8. JWT 超详细分析

    请参考以下链接 https://learnku.com/articles/17883

  9. 百度地图Web引用

    上海中心二楼 示例 http://api.map.baidu.com/geocoder?address=北京市海淀区上地信息路9号奎科科技大厦&output=html&src=weba ...

  10. python-MYSQL(包括ORM)交互

    1.首先,我们必须得连上我们的MYSQL数据库.个人遇到连不上MYSQL数据的问题主要有:数据库的权限问题.数据库表权限的问题 同时获取数据库中的数据等. //==================== ...