根据本人在项目的实践提炼出来,在说svg-sprite-loader使用之前,我们先看一下具体效果:

目录结构

  1. 把svg图放置在assets/icons/svg下,
  2. /assets/icons/index.js 注入全局组件
import Vue from 'vue'import SvgIcon from '@/components/SvgIcon'Vue.component('svg-icon', SvgIcon)
const req = require.context('./svg', false, /\.svg$/)
const requireAll = (requireContext) => requireContext.keys().map(requireContext)
requireAll(req)
  1. 在main.js引入 icons
import './assets/icons'
  1. 在components文件夹下新建两个组件

SvgIcon 是元组件,即需要全局注册的组件svg-icon,代码如下

// components/SvgIcon/index.vue
<template><svg:class="`${svgClass} ${spin ? 'scoped-svg-animation' : ''}`"aria-hidden="true"v-on="$listeners"><use :xlink:href="iconName" /></svg>
</template>
<script>
export default {name: 'SvgIcon',props: {name: {type: String,required: true,},className: {type: String,default: '',},// 是否旋转spin: {type: Boolean,default: false,},},computed: {iconName() {return `#icon-${this.name}`},svgClass() {if (this.className) {return 'scoped-svg-icon ' + this.className} else {return 'scoped-svg-icon'}},},
}
</script>
<style lang="less">
.scoped-svg-icon {width: 1em;height: 1em;vertical-align: -0.15em;fill: currentColor;overflow: hidden;&.scoped-svg-animation {animation: rotate 2s linear infinite;}@keyframes rotate {from {transform: rotate(0deg);}to {transform: rotate(360deg);}}&.gray {color: #666;}&.white {color: #fff;}
}
</style>

项目中使用svg-icon组件:

//  /components/IconSelect/index.vue
<template><div class="icon-select-wrapper"><div>当前选择:{{ currentIcon }}</div><el-input v-model="iconVal" placeholder="请输入内容"></el-input><div><ul class="icon-list"><li:class="{ active: item === currentIcon }"v-for="(item, index) in iconList":key="index"@click="selectIcon(item)"><svg-icon:class-name="item === currentIcon ? 'white' : 'gray'":name="item"style="width: 30px; height: 30px"/><span class="icon-label">{{ item }}</span></li></ul></div></div>
</template>
<script>
import icons from './config'
export default {data() {return {iconList: icons,iconVal: '',currentIcon: 'add-circle',iconClass: '',}},watch: {iconVal(val) {if (val) {this.iconList = this.iconList.filter((item) => item.indexOf(val) > -1)} else {this.iconList = icons}},},methods: {selectIcon(item) {this.currentIcon = itemthis.iconClass},},
}
</script><style lang="less">
.icon-select-wrapper {width: 450px;
}
.icon-list {width: 450px;display: flex;flex-wrap: wrap;border-left: 1px solid #dcdfe6;border-top: 1px solid #dcdfe6;margin-top: 20px;li {width: 150px;display: flex;flex-direction: column;justify-content: center;align-items: center;border-right: 1px solid #dcdfe6;border-bottom: 1px solid #dcdfe6;padding: 10px 0;box-sizing: border-box;cursor: pointer;.icon-label {font-size: 12px;color: #666;}&.active {background: burlywood;.icon-label {font-size: 12px;color: #fff;}}}
}
</style>

使用require.context()方法自动化引入所有icons下的svg,并进行处理,取出svg的名称;
如 add.svg --> add

//  /components/IconSelect/config.js
const req = require.context('@/assets/icons/svg', false, /\.svg$/)
console.log(req, 'req')
const requireAll = (requireContext) => requireContext.keys()
const re = /\.\/(.*)\.svg/
const icons = requireAll(req).map((item) => {console.log(item, '88')return item.match(re)[1]
})
console.log(icons, 'icons')
export default icons

vue.config.js 配置svg-sprite-loader、svgo-loader如下:

const path = require('path')
function resolve(dir) {return path.join(__dirname, dir)
}
module.exports = {chainWebpack: (config) => {// 不对assets/icons的svg打包config.module.rule('svg').exclude.add(resolve('src/assets/icons')).end()config.module.rule('icons').test(/\.svg$/).include.add(resolve('src/assets/icons')).end().use('svg-sprite-loader').loader('svg-sprite-loader').options({symbolId: 'icon-[name]',}).end().before('svg-sprite-loader').use('svgo-loader').loader('svgo-loader').end()},
}

总结,在这个应用中,有如下知识点需要掌握了解:

1. require.context

它是webpack中的api,通过执行require.context函数获取一个特定的上下文,主要用来实现自动化导入模块,在前端工程中,如果遇到从一个文件夹引入很多模块的情况,可以使用这个api,它会遍历文件夹中的指定文件,然后自动导入,而不需要每次调用import导入模块

 require.context(directory, useSubdirectories = false, regExp = /^.//);

directory: 要查找的文件路径
useSubdirectories: 是否查找子目录
regExp: 要匹配文件的正则

在本例中,require.context()返回的结果如下:

var map = {"./add-circle.svg": "./src/assets/icons/svg/add-circle.svg","./add.svg": "./src/assets/icons/svg/add.svg","./arrow-double-right.svg": "./src/assets/icons/svg/arrow-double-right.svg","./arrow-down.svg": "./src/assets/icons/svg/arrow-down.svg","./arrow-right.svg": "./src/assets/icons/svg/arrow-right.svg","./ashbin.svg": "./src/assets/icons/svg/ashbin.svg","./bottom.svg": "./src/assets/icons/svg/bottom.svg","./browse.svg": "./src/assets/icons/svg/browse.svg","./column-3.svg": "./src/assets/icons/svg/column-3.svg","./column-4.svg": "./src/assets/icons/svg/column-4.svg","./direction-down.svg": "./src/assets/icons/svg/direction-down.svg","./explain.svg": "./src/assets/icons/svg/explain.svg","./file-open.svg": "./src/assets/icons/svg/file-open.svg","./film.svg": "./src/assets/icons/svg/film.svg","./folder-close.svg": "./src/assets/icons/svg/folder-close.svg"
};function webpackContext(req) {var id = webpackContextResolve(req);return __webpack_require__(id);
}
function webpackContextResolve(req) {if(!__webpack_require__.o(map, req)) {var e = new Error("Cannot find module '" + req + "'");e.code = 'MODULE_NOT_FOUND';throw e;}return map[req];
}
webpackContext.keys = function webpackContextKeys() {return Object.keys(map);
};
webpackContext.resolve = webpackContextResolve;
module.exports = webpackContext;
webpackContext.id = "./src/assets/icons/svg sync \\.svg$";

2. svg标签use的使用

本例中:

<svg:class="`${svgClass} ${spin ? 'scoped-svg-animation' : ''}`"aria-hidden="true"v-on="$listeners"><use :xlink:href="iconName" />
</svg>

渲染结果如下:

3. svg-sprite-loader

4. svgo-loader

svgsprite的svg-sprite-loader在vue中的使用及vue-cli如何配置相关推荐

  1. Vue中路由管理器Vue Router使用介绍(三)

    2019独角兽企业重金招聘Python工程师标准>>> 一.路由定义添加动态参数定义 1.路由定义项,使用:xx 方式 定义动态参数 {path:'/user/:id/:name', ...

  2. Vue中使用百度地图Vue Baidu Map(vue-baidu-map)

    最近负责的一个vue项目中需要调用百度地图api做标记打点的需求,记录一下: vue-baidu-map 官方地址 一.插件的安装 1.npm 安装 $ npm install vue-baidu-m ...

  3. vue中warning_5种处理Vue异常的方法

    本文采用意译,版权归原作者所有 去年一整年,我都在使用最爱的-Vue.js- 来做项目.最近突然意识到,我竟然从来没有认真去处理异常.我可以自恋地说:"我写的代码是完美的,没有BUG.&qu ...

  4. 【Web通信】WebSocket详解:WebSocket是什么?如何使用WebSocket?在Vue中封装WebSocket(心跳监测)。nginx配置websocket。

    一.WebSocket相关定义 1. WebSocket定义 WebSocket 是一种基于TCP的全双工通信协议,它提供了一种在浏览器和服务器之间建立持久连接来交换数据的方法.数据可以作为" ...

  5. [vue] Vue中插件的定义 Vue.use()

    功能: 用于增强Vue 通常用来为 Vue 添加全局功能 简单案例 plugins.js export default {install(){console.log('@install');} } m ...

  6. Vue中v-for必须在vue实例对应元素下的子元素中循环渲染数据

    异常信息 Cannot use v-for on 1 stateful componentroot element because it renders multiple elements 翻译大意: ...

  7. vue中如何返回历史路由_如何配置局域网中的多台无线路由器【图文教程】

    出于无线接入或者无线覆盖范围扩展等需求,我们购买了若干台路由器,本文档主要描述如何通过多台路由器配合使用,达到家庭网络的全面覆盖. 家庭网络有线网络扩展为无线网络的方案 假设已有一条ADSL宽带线(或 ...

  8. Vue中使用SVG-ICON

    在Vue中使用svg-icon,可以按如下配置即可. 1.src/components/SvgIcon目录下创建index.vue,代码如下: <template><svg :cla ...

  9. 怎么将vue模板转换为html,vue中自定义html文件的模板

    如果默认生成的 HTML 文件不适合需求,可以创建/使用自定义模板. 一是通过 inject 选项,然后传递给定制的 HTML 文件.html-webpack-plugin 将会自动注入所有需要的 C ...

  10. vue ts 设置tslint提示_Typescript 在 Vue 中的实践(包含2.x、3.x)

    1 使用 typescript 的优势 聊到 ts 时有一个不能规避的问题:为什么要使用 ts ,相比 js 有什么优势吗?下面我从两个方面试着回答一下这个问题: 1.1 项目开发时的便利 避免低级 ...

最新文章

  1. 中科院韩先培:预训练模型怎样成为下一代知识图谱
  2. python结束不退出_Python 基本功: 1. Hello world
  3. 打开表时提示 Out of resources when opening file......错误解决
  4. AJPFX关于代码块的总结
  5. Burpsuite中protobuf数据流的解析 - Vincent
  6. 《四世同堂》金句摘抄(十六)
  7. Python 各种应用收集
  8. android文件体系,Android文件体系-基础
  9. 第七天20160803
  10. linux关于子网掩码函数,Linux 子网掩码计算, 二进制十进制互相转换
  11. ZOJ3067_Nim
  12. 计算机二级C语言程序设计 第一章 程序设计基本概念
  13. 分数排名 mysql_MYSQL分数排名
  14. Cocos2d-x 3 x游戏开发之旅
  15. “沉浸式”住宿体验——酒店的新瓶,民宿的老酒
  16. 使用Flurry来统计和分析用户行为
  17. 科研过程中Linux相关问题
  18. 计算英文句子中有多少单词?
  19. powershell牛逼啊.
  20. 自定义View实战(一) 汽车速度仪表盘

热门文章

  1. 文件html怎么另存为wps,WPS文字中另存为功能详解(wps文字怎么保存到指定文件夹)...
  2. 聊聊“数据安全与数据治理”那些事
  3. 如何利用云原生技术构建现代化应用
  4. 在本地机房享受专属公共云服务,详解阿里云本地化部署服务云盒
  5. 一击进榜!达摩院十年“扫地僧”,揭秘阿里云数据仓库逆袭之旅
  6. 松下电视机服务器未响应,松下电视遥控器失灵是什么原因?要怎么办?
  7. SecureCRT突然假死的问题(Ctrl+S)
  8. Ubuntu18.04挂载exfat格式移动硬盘
  9. python3 Django框架报错(备忘录)
  10. HDU 4787 GRE Words Revenge