vue基于elementui实现的带搜索功能的懒加载树

基于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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值