本文介绍了Vue.js 图标选择组件实践详解,分享给你们,具体以下:
背景vue
最近项目中在作一个自定义菜单需求,其中有一个为菜单设置小图标的功能,就是你们常见的左侧菜单node
设置图标不难,方案就是字体图标,可供使用的图标库也有不少,好比阿里巴巴的 Iconfont,以及 Fontaswsome 等,问题在于如何优雅的提供几百个图标供用户选择,而不须要开发去一个一个的写标签,也不须要一个个的去找图标。程序员
字体图标库 Fontawesome 方案数组
咱们使用字体图标的方式,通常是一个 <i class="iconfont icon-home"></i>
这样的标签,日常开发中用一些图标都是用到一个写一个,展现10个图标,就要写10个标签。浏览器
在项目中本人使用的是 Fontawesome 图标库方案,使用它是由于提供的可用图标比较丰富,基本上不须要特地去找合适的图标,直接把它的图标库下载过来,免费的有800多个。svg
这么多图标难道要一个一个手写800多个 i 标签吗?三连拒绝!学习
Fontawesome 下载后的文件中提供一个 svg格式的精灵图,这个很是人性化,用 VSCode 打开这个SVG文件字体
能够看到是熟悉的DOM,由于SVG本质上就是一个XML,既然是DOM,那么祭出JS大法吧,用浏览器打开这个SVG文件,在控制台编写以下代码获取全部的图标名称:ui
const nodeArray = Array.from(document.querySelectorAll(``'symbol'``));` const names = nodeArray.map(item => item.id)` names.toString()`
Icons组件this
大牛能够忽略
拿到了全部图标的 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></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()` }`
以上就是本文的所有内容,但愿对你们的学习有所帮助
为了学习工做与休闲娱乐互不冲突,现新建圈【码农茶水铺】用于程序员生活,爱好,交友,求职招聘,吐槽等话题交流,但愿各位大神工做之余到茶水铺来喝茶聊天。群号:582735936