基于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