组件调用

 <template>
<!-- 行模式 -->
<el-form inline>
<el-form-item label="inline 默认:">
<select-tree :options="options" v-model="selected" />
</el-form-item>
<el-form-item label="inline 定义宽度:">
<select-tree width="200" :options="options" v-model="selected" />
</el-form-item>
</el-form>
<!-- 块模式 -->
<el-form>
<el-form-item label="自适应:">
<select-tree v-model="selected" :options="options" :props="defaultProps" />
</el-form-item>
</el-form>
</template> <script>
import SelectTree from '@/components/widget/SelectTree.vue'; export default {
name: 'about',
components: {
SelectTree,
},
data() {
return {
// 默认选中值
selected: 'A',
// 数据默认字段
defaultProps: {
parent: 'parentId', // 父级唯一标识
value: 'id', // 唯一标识
label: 'label', // 标签显示
children: 'children', // 子级
},
// 数据列表
options: [
{
parentId: '0',
id: 'A',
label: 'label-A',
children: [
{
parentId: 'A',
id: 'A-1',
label: 'label-A-1',
},
],
},
{
parentId: '0',
value: 'B',
label: 'label-B',
children: [],
},
],
};
},
};
</script>

SelectTree.vue

 <!-- 树状选择器 -->
<template>
<el-popover
ref="popover"
placement="bottom-start"
trigger="click"
@show="onShowPopover"
@hide="onHidePopover">
<el-tree
ref="tree"
class="select-tree"
highlight-current
:style="`min-width: ${treeWidth}`"
:data="data"
:props="props"
:expand-on-click-node="false"
:filter-node-method="filterNode"
:default-expand-all="false"
@node-click="onClickNode">
</el-tree>
<el-input
slot="reference"
ref="input"
v-model="labelModel"
clearable
:style="`width: ${width}px`"
:class="{ 'rotate': showStatus }"
suffix-icon="el-icon-arrow-down"
:placeholder="placeholder">
</el-input>
</el-popover>
</template> <script>
export default {
name: 'Pagination',
props: {
// 接收绑定参数
value: String,
// 输入框宽度
width: String,
// 选项数据
options: {
type: Array,
required: true,
},
// 输入框占位符
placeholder: {
type: String,
required: false,
default: '请选择',
},
// 树节点配置选项
props: {
type: Object,
required: false,
default: () => ({
parent: 'parentId',
value: 'rowGuid',
label: 'areaName',
children: 'children',
}),
},
},
// 设置绑定参数
model: {
prop: 'value',
event: 'selected',
},
computed: {
// 是否为树状结构数据
dataType() {
const jsonStr = JSON.stringify(this.options);
return jsonStr.indexOf(this.props.children) !== -1;
},
// 若非树状结构,则转化为树状结构数据
data() {
return this.dataType ? this.options : this.switchTree();
},
},
watch: {
labelModel(val) {
if (!val) {
this.valueModel = '';
}
this.$refs.tree.filter(val);
},
value(val) {
this.labelModel = this.queryTree(this.data, val);
},
},
data() {
return {
// 树状菜单显示状态
showStatus: false,
// 菜单宽度
treeWidth: 'auto',
// 输入框显示值
labelModel: '',
// 实际请求传值
valueModel: '0',
};
},
created() {
// 检测输入框原有值并显示对应 label
if (this.value) {
this.labelModel = this.queryTree(this.data, this.value);
}
// 获取输入框宽度同步至树状菜单宽度
this.$nextTick(() => {
this.treeWidth = `${(this.width || this.$refs.input.$refs.input.clientWidth) - 24}px`;
});
},
methods: {
// 单击节点
onClickNode(node) {
this.labelModel = node[this.props.label];
this.valueModel = node[this.props.value];
this.onCloseTree();
},
// 偏平数组转化为树状层级结构
switchTree() {
return this.cleanChildren(this.buildTree(this.options, '0'));
},
// 隐藏树状菜单
onCloseTree() {
this.$refs.popover.showPopper = false;
},
// 显示时触发
onShowPopover() {
this.showStatus = true;
this.$refs.tree.filter(false);
},
// 隐藏时触发
onHidePopover() {
this.showStatus = false;
this.$emit('selected', this.valueModel);
},
// 树节点过滤方法
filterNode(query, data) {
if (!query) return true;
return data[this.props.label].indexOf(query) !== -1;
},
// 搜索树状数据中的 ID
queryTree(tree, id) {
let stark = [];
stark = stark.concat(tree);
while (stark.length) {
const temp = stark.shift();
if (temp[this.props.children]) {
stark = stark.concat(temp[this.props.children]);
}
if (temp[this.props.value] === id) {
return temp[this.props.label];
}
}
return '';
},
// 将一维的扁平数组转换为多层级对象
buildTree(data, id = '0') {
const fa = (parentId) => {
const temp = [];
for (let i = 0; i < data.length; i++) {
const n = data[i];
if (n[this.props.parent] === parentId) {
n.children = fa(n.rowGuid);
temp.push(n);
}
}
return temp;
};
return fa(id);
},
// 清除空 children项
cleanChildren(data) {
const fa = (list) => {
list.map((e) => {
if (e.children.length) {
fa(e.children);
} else {
delete e.children;
}
return e;
});
return list;
};
return fa(data);
},
},
};
</script> <style>
.el-input.el-input--suffix {
cursor: pointer;
overflow: hidden;
}
.el-input.el-input--suffix.rotate .el-input__suffix {
transform: rotate(180deg);
}
.select-tree {
max-height: 350px;
overflow-y: scroll;
}
/* 菜单滚动条 */
.select-tree::-webkit-scrollbar {
z-index: 11;
width: 6px;
}
.select-tree::-webkit-scrollbar-track,
.select-tree::-webkit-scrollbar-corner {
background: #fff;
}
.select-tree::-webkit-scrollbar-thumb {
border-radius: 5px;
width: 6px;
background: #b4bccc;
}
.select-tree::-webkit-scrollbar-track-piece {
background: #fff;
width: 6px;
}
</style>

Element-UI 实现下拉树的更多相关文章

  1. vue+element下拉树选择器

    项目需求:输入框点击弹出树形下拉结构,可多选或者单选. 解决方案:1.使用layui formSelect多选插件 2.基于vue+elementui 下拉框和树形控件组合成树形下拉结构 <el ...

  2. zTree开发下拉树

    最近,因为工作需要一个树形下拉框的组件,经过查资料一般有两种的实现方法.其一,就是使用zTree实现:其二,就是使用easyUI实现.因为公司的前端不是使用easyUI设计的,故这里我选择了zTree ...

  3. 开源框架.netCore DncZeus学习(五)下拉树的实现

    千里之行,始于足下,先从一个小功能研究起,在菜单管理页面有一个下拉树,先研究下它怎么实现的 1.先找到menu.vue页面 惯性思维先搜索请选择三个字,原来是动态生成的 再向上找DropDown组件, ...

  4. vue 模拟下拉树

    // 使用vue 做表格部分其他部分暂不修改 var app = new Vue({ el: "#freightTbl", watch: { //监听表格数据的变化[使用 watc ...

  5. vue-Treeselect实现组织机构(员工)下拉树的功能

    知识点:前端使用vuetree的组件库,调用后台查询组织机构,包括人员的接口 实现下拉树的功能 查考: vue-treeselect官网:https://vue-treeselect.js.org/ ...

  6. Extjs下拉树代码测试总结

    http://blog.csdn.net/kunoy/article/details/8067801 首先主要代码源自网络,对那些无私的奉献者表示感谢! 笔者对这些代码做了二次修改,并总结如下: Ex ...

  7. EXTJS下拉树ComboBoxTree参数提交及回显方法

    http://blog.csdn.net/wjlht/article/details/6085245 使用extjs可以构造出下拉数,但是不方便向form提交参数,在此,笔者想到一个办法,很方便Com ...

  8. layui扩展组件,下拉树多选

      项目介绍 项目中需要用到下拉树多选功能,找到两个相关组件moretop-layui-select-ext和wujiawei0926-treeselect,但是moretop-layui-selec ...

  9. EasyUI-combotree 下拉树 数据回显时默认选中

    组合树(combotree)把选择控件和下拉树结合起来.它与组合框(combobox)相似,不同的是把列表替换成树组件.组合树(combotree)支持带有用于多选的树状态复选框的树. 依赖 comb ...

  10. elementUI下拉树组件封装

    使用组件:Popover 弹出框.Tree 树形控件 和 input 输入框 用法: 1.新建一个.vue文件,粘贴以下组件封装的代码(完全可以使用) 2.在页面需要使用下拉树的地方调用即可. (1) ...

随机推荐

  1. Mysql Having的用法:对group by之后的分组加限制条件(复制)

    在使用聚合函数之前,我们可以通过where对查询加限制条件,那么如果在group by之后我们要对分组里面的数据再加限制条件怎么办呢?答案是having. HAVING子句可以让我们筛选成组后的各组数 ...

  2. hdu6208 The Dominator of Strings

    地址: 题目: The Dominator of Strings Time Limit: 3000/3000 MS (Java/Others)    Memory Limit: 65535/32768 ...

  3. cdoj1587 失恋772002天

    地址:http://acm.uestc.edu.cn/#/problem/show/1587 题目: 失恋772002天 Time Limit: 3000/1000MS (Java/Others)   ...

  4. Codeforces Round #112 (Div. 2) D. Beard Graph

    地址:http://codeforces.com/problemset/problem/165/D 题目: D. Beard Graph time limit per test 4 seconds m ...

  5. js正则匹配两位小数

    今天写一个用js正则校验最多保留两位小数的格式. a = /^\d+|\d+\.\d{1,2}$/; 测试 a.test(1.222); 结果:true 一下蒙了,怎么可能,最后找了好久,原来需要把^ ...

  6. 阿里云 Linux 启用465端口发送邮件

    阿里云 Linux 启用465端口发送邮件 环境:阿里云 Linux Centos 7.4 x64 注:阿里云默认禁用25邮件端口,需要启动465端口加密进行邮件发送. 注:确保邮箱开启SMTP服务, ...

  7. 注意:PHP7中十个需要避免的坑

    1.不要使用mysql_函数 这一天终于来了,从此你不仅仅“不应该”使用mysql_函数.PHP7已经把它们从核心中全部移除了,也就是说你需要迁移到好得多的mysqli_函数,或者更灵活的PDO实现. ...

  8. 20145328 《Java程序设计》第7周学习总结

    20145328 <Java程序设计>第7周学习总结 教材学习内容总结 第十二章 Lambda 12.1 认识Lambda语法 Lambda 教材的引入循序渐近.深入浅出 Lambda去重 ...

  9. java语言学习笔记1

    最近也在春节的节假日里,总是会有各种各样的事情出现,没有很完整的时间来学习java以及其他方面的知识. 从昨天开始有了完整的学习体系,我去娄老师推荐的极客学院网站开始学习java语言的语法.在假期之初 ...

  10. Tomcat热部署,Web工程中线程没有终止

    近期项目中,用 jenkins 热部署 web工程时,发现工程中静态持有的线程(将ScheduledExecutorService定时任务存储在静态Map中),导致不定时出现数据库访问事务关闭异常,如 ...