返回

树型组件Tree懒加载+搜索框远程请求数据应用经验大揭秘

前端

Vue.js + Element UI打造树形组件Tree:懒加载与搜索框功能详解

一、组件搭建

1. 安装依赖

首先,通过npm或Yarn安装Vue.js和Element UI:

npm install vue element-ui

2. 创建组件

新建一个Vue组件TreeComponent.vue,代码如下:

<template>
  <el-tree :data="data" :lazy="true" @node-click="handleNodeClick"></el-tree>
</template>

<script>
import { ref } from 'vue'
import { ElTree } from 'element-ui'

export default {
  components: { ElTree },
  setup() {
    const data = ref([])

    const handleNodeClick = (node) => {
      console.log(node)
    }

    return {
      data,
      handleNodeClick,
    }
  },
}
</script>

3. 注册组件

在main.js文件中注册组件:

import Vue from 'vue'
import TreeComponent from './components/TreeComponent.vue'

Vue.component('TreeComponent', TreeComponent)

二、实现懒加载

1. 配置懒加载

在树形组件中,设置lazy属性为true即可实现懒加载:

<el-tree :data="data" :lazy="true" @node-click="handleNodeClick"></el-tree>

2. 加载数据

当用户点击节点时,可以通过Element UI的load方法加载子节点数据:

const handleNodeClick = (node) => {
  if (node.loading) return
  node.loading = true
  // 使用自己的接口加载子节点数据
  fetch(`api/get-children?id=${node.id}`)
    .then(res => res.json())
    .then(data => {
      node.loading = false
      node.children = data
    })
    .catch(err => {
      node.loading = false
      console.error(err)
    })
}

三、实现搜索框

1. 添加搜索框

使用Element UI的ElInput组件添加搜索框:

<template>
  <el-input v-model="searchText" placeholder="搜索"></el-input>
  <el-tree :data="data" :lazy="true" @node-click="handleNodeClick"></el-tree>
</template>

<script>
import { ref } from 'vue'
import { ElTree, ElInput } from 'element-ui'

export default {
  components: { ElTree, ElInput },
  setup() {
    const searchText = ref('')
    const data = ref([])

    const handleNodeClick = (node) => {
      console.log(node)
    }

    return {
      searchText,
      data,
      handleNodeClick,
    }
  },
}
</script>

2. 过滤数据

使用Vue的计算属性过滤数据,仅显示匹配搜索框内容的节点:

<template>
  <el-input v-model="searchText" placeholder="搜索"></el-input>
  <el-tree :data="filteredData" :lazy="true" @node-click="handleNodeClick"></el-tree>
</template>

<script>
import { ref, computed } from 'vue'
import { ElTree, ElInput } from 'element-ui'

export default {
  components: { ElTree, ElInput },
  setup() {
    const searchText = ref('')
    const data = ref([])

    const filteredData = computed(() => {
      return data.value.filter(node => node.label.includes(searchText.value))
    })

    const handleNodeClick = (node) => {
      console.log(node)
    }

    return {
      searchText,
      data,
      filteredData,
      handleNodeClick,
    }
  },
}
</script>

四、示例代码

<template>
  <el-input v-model="searchText" placeholder="搜索"></el-input>
  <el-tree :data="filteredData" :lazy="true" @node-click="handleNodeClick"></el-tree>
</template>

<script>
import { ref, computed } from 'vue'
import { ElTree, ElInput } from 'element-ui'

export default {
  components: { ElTree, ElInput },
  setup() {
    const searchText = ref('')
    const data = ref([])

    const filteredData = computed(() => {
      return data.value.filter(node => node.label.includes(searchText.value))
    })

    const handleNodeClick = (node) => {
      if (node.loading) return
      node.loading = true
      // 使用自己的接口加载子节点数据
      fetch(`api/get-children?id=${node.id}`)
        .then(res => res.json())
        .then(data => {
          node.loading = false
          node.children = data
        })
        .catch(err => {
          node.loading = false
          console.error(err)
        })
    }

    return {
      searchText,
      data,
      filteredData,
      handleNodeClick,
    }
  },
}
</script>

五、常见问题解答

1. 如何自定义节点样式?

通过node-key属性自定义节点样式。

2. 如何禁用节点的拖放?

设置draggable属性为false

3. 如何展开/收起所有节点?

使用expand-on-click-node属性。

4. 如何获取选中的节点?

使用current-change事件。

5. 如何使用自定义图标?

通过iconexpand-icon属性设置自定义图标。