Vue.js 图标选择组件实践详解


Posted in Javascript onDecember 03, 2018

本文介绍了Vue.js 图标选择组件实践详解,分享给大家,具体如下:

Vue.js 图标选择组件实践详解

背景

最近项目中在做一个自定义菜单需求,其中有一个为菜单设置小图标的功能,就是大家常见的左侧菜单

Vue.js 图标选择组件实践详解

设置图标不难,方案就是字体图标,可供使用的图标库也有很多,比如阿里巴巴的 Iconfont,以及 Fontaswsome 等,问题在于如何优雅的提供几百个图标供用户选择,而不需要开发去一个一个的写标签,也不需要一个个的去找图标。

字体图标库 Fontawesome 方案

我们使用字体图标的方式,一般是一个 <i class="iconfont icon-home"></i>  这样的标签,平常开发中用一些图标都是用到一个写一个,展示10个图标,就要写10个标签。

在项目中本人使用的是 Fontawesome 图标库方案,使用它是因为提供的可用图标比较丰富,基本上不需要特意去找合适的图标,直接把它的图标库下载过来,免费的有800多个。

Vue.js 图标选择组件实践详解

这么多图标难道要一个一个手写800多个 i 标签吗?三连拒绝!

Fontawesome 下载后的文件中提供一个 svg格式的精灵图,这个非常人性化,用 VSCode 打开这个SVG文件

Vue.js 图标选择组件实践详解

可以看到是熟悉的DOM,因为SVG本质上就是一个XML,既然是DOM,那么祭出JS大法吧,用浏览器打开这个SVG文件,在控制台编写如下代码获取所有的图标名称:

const nodeArray = Array.from(document.querySelectorAll('symbol'));
const names = nodeArray.map(item => item.id)
names.toString()

Vue.js 图标选择组件实践详解

Icons组件

大牛可以忽略

拿到了所有图标的 name 那就好办了,一个数组循环呗。先别急着写代码,我们的目的是封装成组件复用,那么先创建一个 Icons 组件

Vue.js 图标选择组件实践详解

提供一个筛选框,然后给一个事件即可

<template>
 <div class="ui-fas">
  <el-input v-model="name" @input.native="filterIcons" suffix-icon="el-icon-search" placeholder="请输入图标名称"></el-input>
  <ul class="fas-icon-list">
   <li v-for="(item, index) in iconList" :key="index" @click="selectedIcon(item)">
    <i class="fas" :class="['fa-' + item]" />
    <span>{{item}}</span>
   </li>
  </ul>
 </div>
</template>
<script>
import fontawesome from '@/extend/fontawesome/solid.js'
export default {
 name: 'compIcons',
 data () {
  return {
   name: '',
   iconList: fontawesome
  }
 },
 methods: {
  filterIcons () {
   if (this.name) {
    this.iconList = this.iconList.filter(item => item.includes(this.name))
   } else {
    this.iconList = fontawesome
   }
  },
  selectedIcon (name) {
   this.$emit('selected', name)
  },
  reset () {
   this.name = ''
   this.iconList = fontawesome
  }
 }
}
</script>

先把拿到的所有图标name放到一个 solid.js 文件中,输出为数组,在组件中引入,然后就是循环数组 iconList,输出i标签,Fontawesome 的使用方式是:<i></i>

筛选功能利用数组的 filter 方法,this.$emit('selected', name) 方式返回给父组件图标名称。

以上样式都是利用Element UI 的 Popover、Input 组件实现

<el-form-item label="图标:" >
 <el-popover
  placement="left-start"
  width="540"
  trigger="click"
  @show="$refs.icons.reset()"
  popper-class="popper-class">
  <ui-icons ref="icons" @selected="selectedIcon" />
  <el-input slot="reference" placeholder="请输入内容" readonly v-model="form.menu_icon" style="cursor: pointer;">
   <template slot="prepend"><i class="fas" :class="['fa-' + form.menu_icon]"></i></template>
  </el-input>
 </el-popover>
</el-form-item>

组件实现了,接下来就是引用,既可以直接到导入此组件引用,也可以挂载到全局进行使用,这里说说挂载到全局使用的方式,因为我的项目中所有的公共组件都是挂载到全局的方式使用。

在组件平级新建一个 index.js 文件

Vue.js 图标选择组件实践详解

import IconsCompontent from './Icons.vue'
const Icons = {
 install(Vue) {
  Vue.component('ui-icons', IconsCompontent);
 }
}
export default Icons;

第4行为组件命名,此名称决定了如何使用组件,这里是ui-icons,那么使用的时候就是:

<ui-icons />

接着在项目 components 根目录新建 index.js,这里是所有组件的集合

Vue.js 图标选择组件实践详解

最后一步是在 main.js 中注册:

import CustomComponents from './components/index.js'
Object.keys(CustomComponents).forEach(key => Vue.use(CustomComponents[key]))

这样就可以在项目中任意.vue文件中以<ui-icons />方式使用组件了。

后记

点击图标后要不要关闭图标弹出层(Popover)呢?Popover 是需要鼠标点击其他地方才会隐藏的,选择一个图标后就关闭 Popover 呢,我的做法是:document.body.click()

selectedIcon (name) {
 this.form.menu_icon = name
 // document.body.click()
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
js操作textarea 常用方法总结
Dec 03 Javascript
jquery插件如何使用 jQuery操作Cookie插件使用介绍
Dec 15 Javascript
从数据结构分析看:用for each...in 比 for...in 要快些
Apr 17 Javascript
JQuery以JSON方式提交数据到服务端示例代码
May 05 Javascript
jQuery窗口、文档、网页各种高度的精确理解
Jul 02 Javascript
javascript实现滑动解锁功能
Dec 31 Javascript
使用Node.js为其他程序编写扩展的基本方法
Jun 23 Javascript
JavaScript实现点击单选按钮改变输入框中文本域内容的方法
Aug 12 Javascript
js窗口关闭提示信息(兼容IE和firefox)
Oct 23 Javascript
使用vue的v-for生成table并给table加上序号的实例代码
Oct 27 Javascript
微信小程序 拍照或从相册选取图片上传代码实例
Aug 28 Javascript
Vue中使用wangeditor富文本编辑的问题
Feb 07 Vue.js
vue-music 使用better-scroll遇到轮播图不能自动轮播问题
Dec 03 #Javascript
vue-cli3.0+element-ui上传组件el-upload的使用
Dec 03 #Javascript
利用jquery和BootStrap实现动态滚动条效果
Dec 03 #jQuery
微信小程序实现页面下拉刷新和上拉加载功能详解
Dec 03 #Javascript
微信小程序在地图选择地址并返回经纬度简单示例
Dec 03 #Javascript
vue.js实现的全选与全不选功能示例【基于elementui】
Dec 03 #Javascript
创建Vue项目以及引入Iview的方法示例
Dec 03 #Javascript
You might like
ThinkPHP调试模式与日志记录概述
2014/08/22 PHP
两千行代码的PHP学习笔记汇总
2014/10/05 PHP
php文件缓存类用法实例分析
2015/04/22 PHP
简单JS代码压缩器
2006/10/12 Javascript
网上应用的一个不错common.js脚本
2007/08/08 Javascript
JavaScript XML操作 封装类
2009/07/01 Javascript
JavaScript 中的日期和时间及表示标准介绍
2013/08/21 Javascript
javascript中setTimeout使用指南
2015/07/26 Javascript
JS判断字符串字节数并截取长度的方法
2016/03/05 Javascript
谈谈JavaScript中的几种借用方法
2016/08/09 Javascript
使用纯JS代码判断字符串中有多少汉字的实现方法(超简单实用)
2016/11/12 Javascript
详解微信小程序开发—你期待的分享功能来了,微信小程序序新增5大功能
2016/12/23 Javascript
javascript checkbox/radio onchange不能兼容ie8处理办法
2017/06/13 Javascript
使用node.js对音视频文件加密的实例代码
2017/08/30 Javascript
javaScript中的空值和假值
2017/12/18 Javascript
bootstrap-table.js扩展分页工具栏(增加跳转到xx页)功能
2017/12/28 Javascript
详解基于Vue cli生成的Vue项目的webpack4升级
2018/06/19 Javascript
vue实现表格过滤功能
2019/09/27 Javascript
vscode中的vue项目报错Property ‘xxx‘ does not exist on type ‘CombinedVueInstance<{ readyOnly...Vetur(2339)
2020/09/11 Javascript
[01:13]DOTA2群星解读国服召集令 一起说出回归的理由
2013/07/17 DOTA
[55:44]OG vs NAVI 2019国际邀请赛小组赛 BO2 第一场 8.15
2019/08/17 DOTA
Python 绘图和可视化详细介绍
2017/02/11 Python
详解Python3操作Mongodb简明易懂教程
2017/05/25 Python
Django生成PDF文档显示在网页上以及解决PDF中文显示乱码的问题
2019/07/04 Python
Python下利用BeautifulSoup解析HTML的实现
2020/01/17 Python
python excel多行合并的方法
2020/12/09 Python
英国一家集合了众多有才华设计师品牌的奢侈店:Wolf & Badger
2018/04/18 全球购物
美国战术品牌:5.11 Tactical
2019/05/01 全球购物
Java面试题:说出如下代码的执行结果
2015/10/30 面试题
含预算的公司户外活动方案
2014/08/16 职场文书
挂职学习心得体会
2014/09/09 职场文书
会计求职信怎么写
2015/03/20 职场文书
汽车销售员工作总结
2015/08/12 职场文书
学校中层领导培训心得体会
2016/01/11 职场文书
Vue Element-ui表单校验规则实现
2021/07/09 Vue.js
【海涛七七解说】DCG第二周:DK VS 天禄
2022/04/01 DOTA