基于elementui实现的带搜索功能的懒加载树
1. 思路
elementui的el-tree本身可以实现懒加载功能,但是却不能进行远程搜索,思路就是使用两颗树,一颗用来懒加载,另一颗用来全部加载。
2.实现方式
1.创建一个自定义组件j-tree
2.画页面:一个el-input,两个el-tree
<template>
<div class="treebox">
<h2>{{title}}</h2>
<el-input
prefix-icon="el-icon-search"
style="border-radius:0;margin-top:20px"
clearable
:placeholder="placeholder"
:value="value"
@input="$emit('input',$event)"
@keypress.enter.native="filterTree"
/>
<el-tree
ref="tree"
v-show="!value || value.trim() === ''"
:props="defaultProps"
:load="loadNode"
lazy
:expand-on-click-node="true"
:highlight-current="true"
:accordion="true"
@node-click="handleNodeClick"
></el-tree>
<el-tree
:data="data"
v-show="value && value.trim() !== ''"
:props="defaultProps"
:expand-on-click-node="true"
:highlight-current="true"
:accordion="true"
:default-expand-all="true"
@node-click="handleNodeClick"
></el-tree>
</div>
</template>
3.编写js
<script
>
export default {
name
: "j-tree",
inheritAttrs
: false,
props
: {
title
: {
type
: String
,
default: '组织目录'
},
placeholder
: {
type
: String
,
default: '搜索机构'
},
value
: {
type
: String
,
default: ''
},
defaultProps
: {
type
: Object
,
default: {
children
: "children",
label
: "code_name"
}
},
searchedData
: {
type
: Array
,
default: function () {
return [];
}
},
loadNode
: {
type
: Function
,
required
: true
}
},
data() {
return {
text
: this.value
,
data
: []
}
},
methods
: {
filterTree() {
this.$emit('filter-tree');
},
handleNodeClick(data
) {
this.$emit('node-click',data
)
}
},
watch
: {
value
: function (val
) {
if (val
.trim() === '') {
this.data
= [];
}
},
searchedData
: function (val
) {
this.data
= val
;
}
}
}
</script
>
4.编写样式
<style lang="scss" scoped>
.treebox {
border-radius: 5px;
background: #ffffff;
box-shadow: 0px 0px 8px rgba($color: #bababa, $alpha: 0.3);
padding: 40px 25px;
margin-top: 20px;
.el-tree {
margin-top: 20px;
}
.tags {
margin-top: 30px;
margin-bottom: 30px;
}
}
</style>
5.使用方式
import JTree from '@/components/j-tree.vue';
components: {
JTree
}
<j-tree :load-node="loadNodeTest" //这个是懒加载树的时候需要的数据
:searched-data="searchedData"
v-model="filterText"
@filter-tree="filterTree" //这个是用来输入关键字过滤用的
@node-click="handleNodeClick" //这个是点击之后做什么事情,就不提供了
></j-tree>
6.使用时的js
async loadNodeTest(node
, resolve
) {
let treeData
= {};
if (node
.level
=== 0) {
let parent_id
= '';
let params
= {parent_id
: parent_id
};
const res
= await getOrganizations(params
)
if (!res
) return;
treeData
.code_name
= res
.data
.result
[0].code_name
;
treeData
.id
= res
.data
.result
[0].id
;
if (treeData
.code_name
) {
return resolve([treeData
]);
}
return;
}
const res
= await getOrganizations({parent_id
: node
.data
.id
})
if (!res
) return;
const orgArr
= res
.data
.result
.map((item
) => {
return {
code_name
: item
.code_name
,
id
: item
.id
,
};
});
resolve(orgArr
);
}
async filterTree() {
if(this.filterText
&& this.filterText
.trim() !== '') {
const res
= await getOrganizations4Search({code_name
:this.filterText
});
if(!res
) return;
this.searchedData
= res
.data
.result
;
}
}
7.接口形式
带这种上下级关系的数据结构
{
"id": "123",
"org_type": "1",
"crt_no": null,
"org_code": "",
"code_name": "总部",
"parent_id": null,
"sort": "0",
"children": [
{
"id": "456",
"org_type": "0",
"crt_no": "456",
"org_code": "456",
"code_name": "分部1",
"parent_id": "123",
"sort": "42",
"children": [
{
"id": "789",
"org_type": "1",
"crt_no": "456",
"org_code": "789",
"code_name": "分部1-1",
"parent_id": "456",
"sort": null,
"children": []
}
]
}
3.实现效果
4.参考文档
1.https://cn.vuejs.org/v2/guide/components.html
2.https://cn.vuejs.org/v2/guide/components-props.html
3.https://element.eleme.cn/#/zh-CN/component/tree