(后续的文章 公众号会提前一周更新,欢迎关注文末的微信公众号:程序员搞艺术) 预览本文的实现效果:

# gitee

git clone git@gitee.com:cloudyly/dscloudy-admin-single.git
# github
git clone git@github.com:cloudyly/dscloudy-admin-single.git
git checkout 02_SVGIcon
 

本文主要描写如何让 Vue 工程支持 SVG 图标,以及如何获取 SVG 图标。

Git 本地仓库切换新分支:

git checkout -b 02_SVGIcon
 

确认分支:

git branch
 

1 SVG 图标的获取

无论是 SVG 图标,还是 PNG 等其他格式的图标,都可以从阿里的 iconfont 网站上搜索。网址: https://www.iconfont.cn

打开网站后,自己注册账号。最简单的使用方式,就是直接搜索你要的图标。举个例子,找个主页的图标:

1、 在首页搜索框搜索“主页”,回车

2、 选择需要的图标

3、 鼠标移动到该图标上,点击下载样式的按钮

4、下载或复制该 SVG 图标:

“复制 SVG” 不含文件头,需要手动添加。我的习惯是没有 SVG 图标时,第一次“SVG 下载”,之后创建 SVG 文件,从已下载的 SVG 中复制文件头,然后点击页面上的 “复制 SVG”,将内容贴到 创建的 SVG 文件中。此处先下载该 svg 图标。

该网站也可以创建项目,将你需要的图标添加到项目中,然后一次性生成并下载。我不太喜欢这种使用方式。两个原因:

  • 上述方式生成的 class 命名五花八门,也许不符合项目规范;

  • 项目是持续迭代的,如果你手动更新命名,迭代过程中需要新图标,你如何叠加进去;

  • 我需要些什么图标我自己都不知道,在开发过程中需要什么图标才去搜索下载。

2 使工程支持 SVG

2.1 安装依赖

Vue 项目如果要使用 SVG 图标,需要 SVG Loader。svg-sprite-loader 可以用来加载 svg:

npm install svg-sprite-loader --save-dev

2.2 配置 svg-loader

Vue-cli 3 以上的版本,对 webpack 进行了高度封装,要对 webpack 进行配置,需要在项目根路径下(与 src 同级)创建配置文件:vue.config.js ,在该文件中配置 svg loader。

vue.config.js

const path = require('path')
const resolve = dir => path.join(__dirname, dir)
module.exports = {
  chainWebpack: config => {
    const svgRule = config.module.rule('svg')
    svgRule.uses.clear()
    svgRule.test(/\.svg$/)
      .include.add(resolve('src/icons/svg'))
      .end()
      .use('svg-sprite-loader')
      .loader('svg-sprite-loader')
      .options({
        symbolId: '[name]'
      })
      .end()
  }
}
 3 SVG 封装

后面我会将自己封装的组件库,拆分成独立的工程(类似 Element UI、Ant Design Vue 等),发布 npm 或私服后,通过 npm install 进行安装,便于复用。现在在组件库开发阶段,需要不断迭代完善,为了方便调试测试,故先将组件库放在当前工程的 src/components 目录下。

3.1 封装组件 svg-icon

src/components 目录下创建目录 ds-svg-icon, 在该目录中创建 index.vue 文件。该组件提供两个属性:

属性名 类型 属性描述
class-name String 该图标的样式类(与 HTML 中 class 一样)
icon String svg 图标文件的名称

为了编写方便,父组件传递到 svg 组件时可以省略 icon-, 在 svg-icon 中,通过计算属性将这个前缀 icon- 拼接上去。 如:图标名称为 icon-home.svg, 使用组件时使用:

<svg-icon :icon-name="home"></svg-icon>

src/components/ds-svg-icon/index.vue:

 
<template>
  <svg :class="svgClass" aria-hidden="true">
    <use :xlink:href="svgIcon"></use>
  </svg>
</template>
<script>
export default {
  name: 'ds-svg-icon',
  props: {
    icon: {
      type: String,
      required: true
    },
    className: {
      type: String,
      required: false,
      default: ''
    }
  },
  computed: {
    svgClass () {
      return `ds-svg-icon ${this.className}`
    },
    svgIcon () {
      return `#icon-${this.icon}`
    }
  }
}
</script>
<style scoped lang="scss">
  .ds-svg-icon {
    width: 1em;
    height: 1em;
    vertical-align: -0.15em;
    fill: currentColor;
    overflow: hidden;
  }
</style>
 

注意: 定义的每个组件都要指定 name 属性,name 属性的值,与目录名称保持一致。

3.2 封装为插件

上面创建了 ds-svg-icon/index.vue, 随着开发的进行,后面还有很多组件,我们统一将其封装为插件,每个工程需要使用时,在 main.js 全局引入即可。

src/components 目录下创建 index.js

 
import DsSvgIcon from './ds-svg-icon'
const DSComponents = [
  DsSvgIcon
]
function plugin (Vue) {
  if (plugin.installed) {
    return
  }
  DSComponents.forEach(component => {
    Vue.component(component.name, component)
  })
}
export default plugin
 

后续组件开发时,都在这个文件中导入,并添加到数组 DSCompoents 中。

main.js 中引入组件库,并使用:

import DSComponent from '@/components'
...
Vue.use(DSComponent)
 

3.3 icons 目录

在初始化工程的时候,已经创建了 src/icons 目录。在该目录下创建 svg 目录,所有的 svg 文件,都放在这个目录中(src/icons/svg),现在可以将之前下载的主页 svg 图标拷贝到这个目录下,将其重命名为 icon-home.svg (说明:上面的配置约定 所有 svg 图标都使用前缀 icon-)。

svg 图标拷贝到 src/icons/svg 目录下后还不能立即使用,需要加载它才行。使用一个 js 文件统一全部加载:src/icons/index.js:

const allRequireSvg = require.context('./svg', false, /\.svg$/)
const requireAll = requireContext => requireContext.keys().map(requireContext)
requireAll(allRequireSvg)

最后在 main.js 中引入这个 js:

import '@/icons/index'
 

3.4 main.js

到现在为止,main.js 全部代码如下:

 
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
import i18n from '@/i18n'
import ElementUI from 'element-ui'
import '@/assets/scss/index.scss'
import DSComponent from '@/components'
import '@/icons/index'
Vue.use(ElementUI, {
  size: 'mini',
  i18n: (key, value) => i18n.t(key, value)
})
Vue.use(DSComponent)
Vue.config.productionTip = false
new Vue({
  router,
  store,
  i18n,
  render: h => h(App)
}).$mount('#app')

4 测试使用组件

在 App.vue 文件中,测试刚才编写的 ds-svg-icon 组件:

 
<ds-svg-icon icon="home"></ds-svg-icon>
 

重启服务,在浏览器中能看到该图标,则该组件 ok。

提交代码:

 
git add .
git cz
[组件开发] SVG图标组件
 

合并到 master 分支:

git checkout master
git merge 02_SVGIcon
 

将本地分支分别全部推送到 Gitee 和 GitHub

git push --all gitee_origin
git push --all github_origin
 

更多内容请关注我的个人公众号,留言可加我个人微信或交流问题

Vue企业级优雅实战04-组件开发01-SVG图标组件的更多相关文章

  1. Vue企业级优雅实战05-框架开发01-登录界面

    预览本文的实现效果: # gitee git clone git@gitee.com:cloudyly/dscloudy-admin-single.git # github git clone git ...

  2. Vue企业级优雅实战-00-开篇

    从2018.1.开始参与了多个企业的中台建设,这些中台的技术选型几乎都是基于 Spring Cloud 微服务架构 + 基于 Vue 全家桶的前端.我前后端架构及开发我几乎各占一半的精力,在企业级前端 ...

  3. Vue企业级优雅实战03-准备工作04-全局设置

    本文包括如下几个部分: 初始化环境变量文件 JS 配置文件初始化:如是否开启 Mock 数据.加载本地菜单.URL 请求路径等: 国际化文件初始化:初始化国际化文件的结构: 整合 Element UI ...

  4. Vue企业级优雅实战02-准备工作03-提交 GIT 平台

    代码管理.版本管理是件老大难的事情,尤其多人开发中的代码冲突.突击功能时面临的 hotfix 等.本文只是简单说说如何将一套代码提交到两个 Git 平台(GitHub.GitEE)上.其他的 Git ...

  5. Vue3 企业级优雅实战 - 组件库框架 - 1 搭建 pnpm monorepo

    前两篇文章分享了基于 vite3 vue3 的组件库基础工程 vue3-component-library-archetype 和用于快速创建该工程的工具 yyg-cli,但在中大型的企业级项目中,通 ...

  6. vue.js2.0实战(1):搭建开发环境及构建项目

    Vue.js学习系列: vue.js2.0实战(1):搭建开发环境及构建项目 https://my.oschina.net/brillantzhao/blog/1541638 vue.js2.0实战( ...

  7. vue3 vite2 封装 SVG 图标组件 - 基于 vite 创建 vue3 全家桶项目续篇

    在<基于 vite 创建 vue3 全家桶>一文整合了 Element Plus,并将 Element Plus 中提供的图标进行全局注册,这样可以很方便的延续 Element UI 的风 ...

  8. Vue3 企业级优雅实战 - 组件库框架 - 3 搭建组件库开发环境

    前文已经初始化了 workspace-root,从本文开始就需要依次搭建组件库.example.文档.cli.本文内容是搭建 组件库的开发环境. 1 packages 目录 前面在项目根目录下创建了 ...

  9. Vue3 企业级优雅实战 - 组件库框架 - 4 组件库的 CSS 架构

    在前一篇文章中分享了搭建组件库的基本开发环境.创建了 foo 组件模块和组件库入口模块,本文分享组件库的样式架构设计. 1 常见的 CSS 架构模式 常见的 CSS 架构模式有很多:OOCSS.ACS ...

随机推荐

  1. Qt信号与槽使用方法最完整总结

    在图形界面编程中(参考<C++最好的图形库是什么?>),组件之间如何实现通信是核心的技术内容.Qt 使用了信号与槽的机制,非常的高效.简单.易学,方便开发者的使用.本文详细的介绍了Qt 当 ...

  2. VUE数据更新视图不更新的原因

    当你利用索引直接设置一个项时,例如:vm.items[indexOfItem] = newValue当你修改数组的长度时,例如:vm.items.length = newLength 数组更新只能通过 ...

  3. 免费API接口记录

    用来记录一些无次数限制的免费API接口,主要是聚合数据上和API Store上的一些,还有一些其他的. 手机号码归属地API接口: https://www.juhe.cn/docs/api/id/11 ...

  4. JavaScript学习系列博客_23_JavaScript 构造函数

    构造函数 - 构造函数是专门用来创建对象的函数 创建一个对象时,通过构造函数的方式来创建.这是通过Object()这个构造函数来创建的一个实例obj. var obj=new Object(); - ...

  5. Linux基础 Day2

    Linux-Day2 1.文件目录结构 文件和目录被组织成一颗倒置的树的结构 文件系统从根开始,"/" 文件名称严格区分大小写 隐藏文件以"."开头 路径的分隔 ...

  6. Vue源码分析之数据驱动

    响应式特点 数据响应式 修改数据时,视图自动更新,避免繁琐Dom操作,提高开发效率 双向绑定 数据改变,视图随之改变.视图改变,数据随之改变 数据驱动 开发时仅需要关注数据本身,不需要关心数据如何渲染 ...

  7. python numpy常用的数学和统计函数

    numpy模块的核心就是基于数组的运算,相比于列表和其他数据结构,数组的运算效率是最高的.在统计分析和挖掘过程中,经常会使用到numpy模块的函数,以下是常用的数学函数和统计函数: 常数p就是圆周率  ...

  8. Hadoop 2.6.1 集群安装配置教程

    集群环境: 192.168.56.10 master 192.168.56.11 slave1 192.168.56.12 slave2 下载安装包/拷贝安装包 # 存放路径: cd /usr/loc ...

  9. C#-接口(Interface)详解

    定义 在 C# 语言中,类之间的继承关系仅支持单重继承,而接口是为了实现多重继承关系设计的.一个类能同时实现多个接口,还能在实现接口的同时再继承其他类,并且接口之间也可以继承.无论是表示类之间的继承还 ...

  10. 关于华为服务器 双路E52620安装系统时遇到的问题

    一   准备好u盘启动盘,centos7的,用UltraISO制作启动盘 双击图标 进入 点击启动下的刻录磁盘映像 几分钟之后制作完场 二 :按装centos7的系统 1 首先将 u盘插到服务器上 2 ...