Vue+Element UI 树形控件整合下拉功能菜单(tree + dropdown +input)


Posted in Javascript onAugust 28, 2020

这篇博客主要介绍树形控件的两个小小的功能:

  • 下拉菜单
  • 输入过滤框

以CSS样式为主,也会涉及到Vue组件和element组件的使用。

对于没有层级的数据,我们可以使用表格或卡片来展示。要展示或建立层级关系,就一定会用到树形组件了。
使用Vue + Element UI,构建出最基本的树如下图所示:

Vue+Element UI 树形控件整合下拉功能菜单(tree + dropdown +input)

现在我们就要在这个基础上进行改造,使页面更加符合我们的交互场景。

下拉菜单

将下拉菜单嵌到树节点中,使操作更加简便、紧凑。

效果演示

效果如图:

  • 图示1:悬浮在树节点状态

Vue+Element UI 树形控件整合下拉功能菜单(tree + dropdown +input)

  • 图示2:点击三个点图标状态

Vue+Element UI 树形控件整合下拉功能菜单(tree + dropdown +input)

  • 图示3: 选中并选择菜单

Vue+Element UI 树形控件整合下拉功能菜单(tree + dropdown +input)

如上,当鼠标悬浮在树节点上时,出现竖着的三个小点,点击时弹出下拉菜单,显示可以对树节点进行的操作。

实现步骤

1、使用插槽(slot) + 子组件

父组件(含有树形控件)模板代码

<el-tree :data="resourceTree" :ref="tree" node-key="id" size="small"
  :highlight-current="true" :check-on-click-node="true" >
  <span class="custom-tree-node" slot-scope="{ node, data }">
   <div class="custom-tree-node-wrapper">
   <span class="custom-tree-node-label">
    {{ node.label }}
   </span>
   <span class="operate-btns">  
    <dot-dropdown :events="dropMenuEvents" :data="{node,data}" @addNode="addNode" />
   </span>
   </div>
  </span>
  </el-tree>

2、 DotDropdown 下拉框代码

很多树形结构都会使用该下拉框,所以定义组件,方便复用。

<template>
 <el-dropdown trigger="click" class="custom-tree-menu" size="small">
 <i class="el-icon-more rotate " />
 <el-dropdown-menu slot="dropdown">
  <el-dropdown-item v-for='(item,index) in events' :key="index" :divided="index >0" @click.native="clickMenu(item)">
  {{item.label}}
  </el-dropdown-item>
 </el-dropdown-menu>
 </el-dropdown>
</template>
<script>
export default {
 props: {
 events: {
 type: Array,
 default: function() {
 return [
  {
  label: '新建同级',
  funcName: 'addNode'
  },
  {
  label: '编辑',
  funcName: 'editNode'
  },
  {
  label: '删除',
  funcName: 'deleteNode'
  }
 ]
 }
 },
 // 注入数据
 data: {
 type: Object
 }
 },
 methods: {
 clickMenu(item) {
 this.$emit(item.funcName, this.data)
 }
 }
}

模板代码很简单,是一个点击触发的下拉菜单组件(trigger="click"),菜单循环props中传入的events属性,data为从父组件拿到的数据,定义了菜单和菜单的事件(方法名称),当点击菜单(@click.native)时,触发:

this.$emit(item.funcName, this.data)

容易看出,数据和实现方法都是父组件的,该子组件只做了转发。

3、 父组件使用子组件

引入和注册子组件,并定义好对应的方法即可。下面给出使用示例:

<span class="operate-btns">
  <dot-dropdown v-if="data.type === 1" :events="dropMenuEvents" :data="{node,data}"/>
  <dot-dropdown v-if="data.type === 2" :events="sysDropMenuEvents" :data="{node,data}" @addNode="addResource" />
 </span>

根据数据节点的类型,注入不同的events属性,显示不同的下拉框菜单。(常用场景:根节点不可删除、不可编辑,只能新增子级,叶子节点可以新增同级和子级)。
在父组件中的data中定义:

sysDropMenuEvents: [{ label: '新增资源', funcName: 'addNode' }],

dropMenuEvents: [
 { label: '新建同级', funcName: 'addPeerNode' },
 { label: '新建子级', funcName: 'addNode' },
 { label: '分配操作', funcName: 'distributeAction' },
 { label: '编辑', funcName: 'editNode' },
 { label: '删除', funcName: 'removeNode' }
 ]

父组件编写实际功能方法:

// 打开新增资源弹窗
 addResource({ node, data }) {
 ...
 }

父组件注入data时,将树节点插槽中的node和data都注入了进去(:data="{node,data}"),在使用时也可以用过同样的大括号+属性名的方式拿到对应的属性,这里体现了ES6解构赋值的特性。

4、父组件样式

父组件中,树节点的样式:

.el-tree-node__content {
 position: relative;
 .operate-btns {
  position: absolute;
  right: 2px;
  display: none;
 }
 // 鼠标悬停时,展示
 &:hover,
 :focus-within {
  .operate-btns {
  display: inline;
  }
 }
 }
 }
  • 子绝对,父相对,使操作按钮靠贴边显示
  • 无状态时不显示,hover或内部元素被激活时显示(:hover :focus-within)

5、子组件样式

Vue+Element UI 树形控件整合下拉功能菜单(tree + dropdown +input)

旋转图标
原本的图标使用的是element UI提供的 <i class="el-icon-more" />,是横着的点点点↓

Vue+Element UI 树形控件整合下拉功能菜单(tree + dropdown +input)

图标有点小,颜色也不喜欢。改下字体让它变大一点。这里注意需要修改的是元素的before伪类:

.el-icon-more:before {
 content: "\E794";
 color: #c0c4cc;
 font-size: 20px;
}

加一个transform将它旋转90°,悬停时鼠标样式为pointer:

.rotate {
 cursor: pointer;
 margin-left: 5px;
 transform: rotate(90deg);
 }

点击时,增加圆形半透明的灰色背景:

.rotate:focus {
 width: 20px;
 height: 20px;
 border-radius: 4em;
 background-color: rgba(130, 132, 138, 0.2);
}

至此,下拉全部完成。
除了用在树节点中,也可以用在表格中。

输入过滤框

el-tree提供了过滤方法,使用:filter-node-method="filterNode"属性即可。这里主要分享样式:
效果:

Vue+Element UI 树形控件整合下拉功能菜单(tree + dropdown +input)

Vue+Element UI 树形控件整合下拉功能菜单(tree + dropdown +input)

模板代码:

<div class="filter-input">
 <el-input placeholder="输入资源名称进行过滤" v-model="filterText" size="small" prefix-icon="el-icon-search">
 </el-input>
</div>

去掉输入框上、左右边框和圆角,并两侧留出10px边距

.el-input__inner,.el-input-group__prepend{
 width: calc(100% - 20px);
 margin:0 10px;
 height: 40px;
 border-top:none;
 border-width: 0 0 1px;
 border-radius:0;
 }

调整搜索图标大小、颜色和粗细,并稍微调整位置:

.el-input__prefix{
 .el-input__icon{
 margin-right: 15px;
 display: inline-block;
 }
 font-size:18px;
 }

此时点击输入框,只有下边变蓝色,希望图标的样式也随之更改。
只有input被触发了focus事件,icon感知不到,:focus伪类不满足需求了。我们可以使用:focus-within伪类,加在icon和input共同的父类上。

.el-input:focus-within{
 .el-icon-search:before {
  color: #3c6eff;
  font-weight: bold;
 }
 }

至此完成。

总结

没写前端之前以为前端只是展示从后端拿到的数据,但现在觉得,前端作为面向用户的直接门面,承担了绝大部分交互体验优化的任务。
合理的布局和样式能避免用户的无效操作,体验的优化是一个漫长而细致的过程,可能需要仔细打磨,才能做出好用的产品。

以上就是Vue+Element UI 树形控件整合下拉功能菜单(tree + dropdown +input)的详细内容,更多关于Vue+Element UI 整合下拉菜单的资料请关注三水点靠木其它相关文章!

Javascript 相关文章推荐
Ucren Virtual Desktop V2.0
Nov 07 Javascript
服务器安全设置的几个注册表设置
Jul 28 Javascript
JS验证控制输入中英文字节长度(input、textarea等)具体实例
Jun 21 Javascript
javascript中键盘事件用法实例分析
Jan 30 Javascript
javascript获得当前的信息的一些常用命令
Feb 25 Javascript
Bootstrap导航条鼠标悬停下拉菜单
Jan 04 Javascript
javaScript封装的各种写法
Aug 14 Javascript
vue-resouce设置请求头的三种方法
Sep 12 Javascript
细说webpack源码之compile流程-rules参数处理技巧(1)
Dec 26 Javascript
vue项目打包上传github并制作预览链接(pages)
Apr 19 Javascript
js实现省级联动(数据结构优化)
Jul 17 Javascript
iview实现动态表单和自定义验证时间段重叠
Jan 10 Javascript
vue自定义指令和动态路由实现权限控制
Aug 28 #Javascript
vue 动态给每个页面添加title、关键词和描述的方法
Aug 28 #Javascript
vue-cli+webpack项目打包到服务器后,ttf字体找不到的解决操作
Aug 28 #Javascript
vue select 获取value和lable操作
Aug 28 #Javascript
VSCode 添加自定义注释的方法(附带红色警戒经典注释风格)
Aug 27 #Javascript
js实现弹幕飞机效果
Aug 27 #Javascript
jQuery编写QQ简易聊天框
Aug 27 #jQuery
You might like
在mysql数据库原有字段后增加新内容
2009/11/26 PHP
PHP反射学习入门示例
2019/06/14 PHP
php中文语义分析实现方法示例
2019/09/28 PHP
利用谷歌地图API获取点与点的距离的js代码
2012/10/11 Javascript
28个常用JavaScript方法集锦
2015/01/14 Javascript
浅谈JavaScript的Polymer框架中的事件绑定
2015/07/29 Javascript
在其他地方你学不到的jQuery小贴士和技巧(欢迎收藏)
2016/01/20 Javascript
js创建数组的简单方法
2016/07/27 Javascript
BootStrap下拉菜单和滚动监听插件实现代码
2016/09/26 Javascript
SelecT下拉框选中和取值的解决方法
2016/11/22 Javascript
javascript事件的绑定基础实例讲解(34)
2017/02/14 Javascript
Javascript(es2016) import和require用法和区别详解
2017/08/11 Javascript
使用SVG基本操作API的实例讲解
2017/09/14 Javascript
浅谈webpack编译vue项目生成的代码探索
2017/12/11 Javascript
Vue中使用Sortable的示例代码
2018/04/07 Javascript
如何检查一个对象是否为空
2019/04/11 Javascript
vue+layui实现select动态加载后台数据的例子
2019/09/20 Javascript
JS+HTML5本地存储Localstorage实现注册登录及验证功能示例
2020/02/10 Javascript
原生javascript中this几种常见用法总结
2020/02/24 Javascript
基于Element的组件改造的树形选择器(树形下拉框)
2020/02/27 Javascript
[47:45]DOTA2-DPC中国联赛 正赛 Phoenix vs Dragon BO3 第一场 2月26日
2021/03/11 DOTA
python生成指定尺寸缩略图的示例
2014/05/07 Python
python实现简单的socket server实例
2015/04/29 Python
Python import用法以及与from...import的区别
2015/05/28 Python
Python错误提示:[Errno 24] Too many open files的分析与解决
2017/02/16 Python
matplotlib savefig 保存图片大小的实例
2018/05/24 Python
Python爬虫beautifulsoup4常用的解析方法总结
2019/02/25 Python
详解Python下载图片并保存本地的两种方式
2019/05/15 Python
如何用Python制作微信好友个性签名词云图
2019/06/28 Python
python实现将两个文件夹合并至另一个文件夹(制作数据集)
2020/04/03 Python
你懂得怎么写自荐信吗?
2013/12/27 职场文书
《珍珠泉》教学反思
2014/02/20 职场文书
中学生评语大全
2014/04/18 职场文书
2014年作风建设剖析材料
2014/10/23 职场文书
Nginx 根据URL带的参数转发的实现
2021/04/01 Servers
B站评分公认最好看的动漫,你的名字评分9.9,第六备受喜欢
2022/03/18 日漫