专栏首页做工程师不做码农【实战】Vue.js 图标选择组件开发

【实战】Vue.js 图标选择组件开发

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

效果
左侧菜单

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

字体图标库 Fontawesome 方案

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

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

Fontawesome

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

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

svg格式的精灵图

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

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

Icons组件

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

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

<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 class="fas fas-图标name"></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 文件

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,这里是所有组件的集合

最后一步是在 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()
}

….完。


如果对你有一点点帮助,可以点个关注。

原文链接:https://blog.zhangbing.site/2018/12/01/Vue-js-图标选择组件实践/ 作者简介:做工程不做码农(微信公众号同名),Web前端工程师,7年开发经验,坐标杭州,聚焦大前端技术的公众号,分享我的原创或精选文章,欢迎关注。我的个人微信(dunizb),欢迎添加好友进一步交流。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

相关文章

  • 【图文教程】前端程序员的利器,如何使用LeanCloud存储和更新你的静态页面数据?

    Serverless 云开发是现在的大热门和趋势,各大云服务厂商都已经支持 FaaS(函数即服务) 云开发方式,微信小程序云开发是典型的例子。

    Dunizb
  • 拒绝JavaScript,这三个CSS技巧你一定用的上​

    本文介绍三个非常棒棒的CSS技巧,完全可以在你的项目中代替JavaScript,一起来看看这些技巧吧。

    Dunizb
  • 详解Webpack的loader和plugin编写

    loader是文件加载器,能够加载资源文件,并对这些文件进行一些处理,诸如编译、压缩等,最终一起打包到指定的文件中。

    Dunizb
  • [其它 Other] ci数据库工具类扩展

    ci的数据库工具类、没有获取数据表列表等等的方法。在这里做了个扩展。主要用于做数据中心管理的。

    CrazyCodes
  • 多比又添国际团队:原满币网联合创始人出任多比投资与战略合伙人

    近日,多比交易平台正式任命原Coinbene满币网交易所联合创始人辜宥森为多比投资与战略合伙人一职,并与以辜宥森为首的原Coinbene满币网国际运营团队签署合...

    dobitrade
  • 那些年Struts 1.X 而今我还是不会

    struts1是WEB程序MVC分层架构中的C,属于控制层,主要进行处理用户的请求,基于请求驱动。 获取用户的请求地址并将表单中的数据封装到Form 对象后交给...

    小帅丶
  • 如何在SAP Server Side JavaScript里消费destination

    版权声明:本文为博主汪子熙原创文章,未经博主允许不得转载。 https://jerry.blog....

    Jerry Wang
  • 基于C#的机器学习--c# .NET中直观的深度学习

    Kelp.Net是一个用c#编写的深度学习库。由于能够将函数链到函数堆栈中,它在一个非常灵活和直观的平台中提供了惊人的功能。它还充分利用OpenCL语言平台,在...

    Edison.Ma
  • 百度2014软件开发工程师笔试题详解

    1.有一个数据A = [a_1,a_2,a_3.....a_n],n的大小不定,请设计算法将A中的所有数据组合进行输出

    bear_fish
  • 如何改变AspNetPager当前页码的默认红色?

    AspNetPager一直是我最喜欢用的分页控件(而且作者最近还推出了专门针对MVC的版本http://mvcpager.codeplex.com/),默认情况...

    菩提树下的杨过

扫码关注云+社区

领取腾讯云代金券