el-select+el-tree实现树形分组+多选+搜索的选择器

el-select+el-tree实现树形分组+多选+搜索的选择器_第1张图片

注意父组件用的vue3语法,子组件用的vue2的语法

封装treeList子组件,直接上代码


  
  
  
  

父组件调用

 
        

 传递给子组件的下拉列表数组需要组装

// 获取部门方法
function getdeptsFunc(TenantId: number) {
  api.myFunction.getdepts({ TenantId: TenantId }).then(res => {
    if (res != null && res[0] != null && res[0].status == 200) {
      let initDepartArray = res[0].data

      // 修改属性为label和id;需要将数据组装成子组件需要的样子,也可以将递归方法放在子组件中,这样无论传什么数据都可以处理
      const modifiedArray = initDepartArray.map(item => {
        return { label: item.DeptName, id: item.DeptId, ParentId: item.ParentId}
      })

      // 递归
      selectData.DepartSelectData = buildTree(modifiedArray)
      cloneDepartData.value = selectData.DepartSelectData
    }
  })
}
//递归方法
function buildTree(items) {
  const result = [] // 树的根节点,即没有父节点的节点
  const itemMap = {} // 将每个节点的 id 与节点本身映射起来

  // 将每个节点的 id 与节点本身映射起来
  items.forEach(item => {
    itemMap[item.id] = item
  })

  // 遍历每个节点,将其添加到父节点的 children 属性中
  items.forEach(item => {
    const parentItem = itemMap[item.ParentId]

    if (parentItem != null) {
      // 如果父节点存在,则将当前节点添加到父节点的 children 数组中
      ;(parentItem.children || (parentItem.children = [])).push(item)
    } else {
      // 如果父节点不存在,则将当前节点添加到树的根节点中
      result.push(item)
    }

   
  })

  return result
}

// 获取treeSelect选取的值
const handleGetSeveralValue = (value) => {
  console.log(value)
  //此处通过获取的value得到中文,并赋值即可
  searchData.severalValue = value
}

筛选补充: (实现筛选拼音和不区分大小写)

修改treeList子组件,改装筛选函数filterMethod

上代码:注意这里1区分了单层和多层(只需要父组件在调用treeList子组件时传相应的不同的props就可以了,我这里传的是role这个字段,所以判断的是role

    // 筛选
    filterTree(node, val) {
      if (this.role == 'user') {//只有一层节点
        const deptNameMatch = node.data.label.toLowerCase().includes(val.toLowerCase())
        const pyNameMatch = node.data.PYName.toLowerCase().includes(val.toLowerCase())
        if (deptNameMatch || pyNameMatch) {
          node.visible = true
        } else {
          node.visible = false
        }
      } else if (this.role == 'depart') {//不知道有多少层节点
        const deptNameMatch = node.label.toLowerCase().includes(val.toLowerCase())
        const pyNameMatch = node.data.PYName.toLowerCase().includes(val.toLowerCase())
        const hasChildNodes = Array.isArray(node.childNodes) && node.childNodes.length > 0

        if (deptNameMatch || pyNameMatch) {
          node.visible = true
          if (hasChildNodes) {
            return node.childNodes.forEach(childNode => {
              childNode.visible = true
            })
          }
        } else {
          node.visible = false
        }

        if (hasChildNodes) {
          node.childNodes.forEach(childNode => {
            this.filterTree(childNode, val)
            if (childNode.visible) {
              node.visible = true // 如果子节点可见,则将父节点也设置为可见
            }
          })
        }
      }
    },
    filterMethod(val) {
      this.filterFlag = true
      this.$refs.tree.store.root.childNodes.forEach(node => {
        this.filterTree(node, val)
      })
    },
    // 筛选end

 

父组件:在组装传递给子组件的数据时,需要将后端给的label和拼音名都传递给子组件,以下是完整代码

// 获取部门方法
function getdeptsFunc(TenantId: number) {
  api.myFunction.getdepts({ TenantId: TenantId }).then(res => {
    if (res != null && res[0] != null && res[0].status == 200) {
      let initDepartArray = res[0].data

      // 修改属性为label和id,PYName为拼音数据;需要将数据组装成子组件需要的样子,也可以将递归方法放在子组件中,这样无论传什么数据都可以处理
      const modifiedArray = initDepartArray.map(item => {
        return { label: item.DeptName, id: item.DeptId, ParentId: item.ParentId, PYName: item.PYName }
      })

      // 递归
      selectData.DepartSelectData = buildTree(modifiedArray)
      cloneDepartData.value = selectData.DepartSelectData
    }
  })
}
//递归方法
function buildTree(items) {
  const result = [] // 树的根节点,即没有父节点的节点
  const itemMap = {} // 将每个节点的 id 与节点本身映射起来

  // 将每个节点的 id 与节点本身映射起来
  items.forEach(item => {
    itemMap[item.id] = item
  })

  // 遍历每个节点,将其添加到父节点的 children 属性中
  items.forEach(item => {
    const parentItem = itemMap[item.ParentId]

    if (parentItem != null) {
      // 如果父节点存在,则将当前节点添加到父节点的 children 数组中
      ;(parentItem.children || (parentItem.children = [])).push(item)
    } else {
      // 如果父节点不存在,则将当前节点添加到树的根节点中
      result.push(item)
    }

    // 将PYName属性传递给子节点
    if (item.children && item.children.length > 0) {
      item.children.forEach(child => {
        child.PYName = item.PYName
      })
    }
  })

  return result
}

参考原文:Vue封装select下拉树形选择组件(支持单选,多选,搜索),基于element-ui的select、tree组件 - 知乎

你可能感兴趣的:(elementui,前端,vue.js)