elementUI实现selecttree自定义下拉框树形组件支持多选和搜索

7 篇文章 0 订阅
该篇文章展示了如何使用elementUI的el-select和el-tree组件构建一个具有多选和搜索功能的自定义下拉框树形组件,适合前端开发者参考。
摘要由CSDN通过智能技术生成

elementUI实现selecttree自定义下拉框树形组件支持多选和搜索

效果图

在这里插入图片描述

定义子组件

主要结合el-selectel-tree两个组件改造的。

<template>
    <div class="selectTree">
        <el-select filterable :filter-method="filterMethod" class="main-select-tree" ref="selectTree" multiple v-model="transitValue" @remove-tag="removeTag" clearable @clear="clearInput" @focus="blurInput">
            <el-option v-for="item in selectOptions" :key="item.department_id" :label="item.name" :value="item.department_id" style="display: none;" />
            <el-tree class="main-select-el-tree" ref="selecteltree" :filter-node-method="filterNode" show-checkbox @check-change="handleCheckChange" :highlight-current="true" :data="dataArray" :props="defaultProps" :expand-on-click-node="false" node-key="department_id" @node-click="handleNodeClick" :current-node-key="currentKey">
              <span class="custom-tree-node" slot-scope="{ node, data }">
                <span :title="data.description">{{ node.label }}</span>
              </span>
            </el-tree>
        </el-select>
    </div>
</template>

<script>
export default {
  name: 'selectTree',
  props: {
    dataArray: Array
  },
  data () {
    return {
      transitValue: [],
      selectOptions: [],
      currentKey: null,
      defaultProps: {
        label: 'name',
        children: 'children'
      }
    }
  },
  computed: {
    formatData () {
      let result = []
      function getChild (item) {
        item.forEach((i, x) => {
          if (Array.isArray(i['children'])) {
            result.push(i)
            getChild(i['children'])
          } else {
            result.push(i)
          }
        })
      }
      getChild(this.dataArray)
      return result
    }
  },
  methods: {
    filterMethod (value) {
      this.$refs['selecteltree'].filter(value.trim())
    },
    blurInput () {
      console.log('1213')
      this.$refs['selecteltree'].filter('')
    },
    filterNode(value, data) {
      if (!value) return true
      return data.name.indexOf(value) !== -1
    },
    clearInput () {
      this.$refs['selecteltree'].setCheckedKeys([])
    },
    removeTag (e) {
      this.$refs['selecteltree'].setChecked(e, false)
    },
    handleCheckChange () {
      let check = this.$refs['selecteltree'].getCheckedNodes()
      console.log(check)
      let arr = check.filter((i) => !i.children)
      this.transitValue = arr.map((i) => {
        return i.department_id
      })
      this.$emit('treeChange', arr)
    }
  },
  watch: {
    formatData: {
      immediate: true,
      handler: function (n) {
        if (n.length > 0) {
          this.selectOptions = n
        } else {
          this.selectOptions = []
        }
      }
    }
  }
}
</script>
<style lang="less" scoped>
.main-select-el-tree {
  max-height: 300px;
  overflow-y: auto;
}
.el-select-dropdown.is-multiple .el-select-dropdown__item {
  display: none;
}
</style>

父组件应用

<div>
	<template>
	 <p class="pTitle">{{ 选择团队 }}</p>
	  <select-tree ref="selectTree" @treeChange="treeChangeFun" :dataArray="orgList" />
	</template>
</div>

import selectTree from '@/components/selectTreeMulti.vue'
data(){
	orgList: [],
},
mounted(){
	this.orgList = translateDataToTree(data).treeData // data数据格式参看备注1
},
components: {
  selectTree
},
methods: {
	treeChangeFun(val) {
      console.log(val)
    },
	translateDataToTree(data) {
	    data = JSON.parse(JSON.stringify(data))
	    // 删除所有 children,以防止多次调用
	    let checkArr = []
	    data.forEach(function (item) {
	      delete item.children;
	      if (item.is_bind) {
	        checkArr.push(item.department_id)
	      }
	    });
	    let map = {}; // 构建map
	    data.forEach(i => {
	      map[i.department_id] = i; // 构建以id为键 当前数据为值
	    });
	    let treeData = [];
	    data.forEach(child => {
	        const mapItem = map[child.parent_id]; // 判断当前数据的parentId是否存在map中
	        if (mapItem) { // 存在则表示当前数据不是最顶层数据
	            // 注意: 这里的map中的数据是引用了arr的它的指向还是arr,当mapItem改变时arr也会改变,踩坑点
	            // 这里判断mapItem中是否存在children, 存在则插入当前数据, 不存在则赋值children为[]然后再插入当前数据
	            (mapItem.children || ( mapItem.children = [] )).push(child)
	        } else { // 不存在则是组顶层数据
	            treeData.push(child);
	        }
	    });
	    return {
	      treeData: treeData,
	      checkArr: checkArr
	    };
	}
}

data格式:
在这里插入图片描述

  • 15
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
ElementUI是一个基于Vue.js的UI组件库,它提供了丰富的组件和工具,其中包括树形组件。根据引用所述,ElementUI树形选择器可以通过基于ElementUI组件改造来实现。引用中提到了一种懒加载的方式来添加结构,即在点击节点时再进行结构的添加。这种方式可以提高性能,只加载所需的节点数据。 要使用ElementUI树形组件,首先需要在项目中引入ElementUI的样式和组件。可以通过安装ElementUI并在main.js中导入ElementUI的样式和组件实现这一步骤。然后,可以在模板中使用`el-tree`标签来创建树形组件,并通过`data`属性传递的数据。 除了基本的数据传递,还可以通过配置项来自定义树形组件的样式和功能。例如,可以通过`props`属性来设置节点的显示字段,通过`expand-on-click-node`属性来设置是否点击节点时展开或收起子节点。还可以使用`default-expand-all`属性来设置默认展开所有节点。 总之,ElementUI树形组件是一个功能强大且灵活的组件,可以根据项目的需求进行定制和扩展。通过合理使用它的配置项和方法,可以实现各种复杂的树形结构。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [基于Element的组件改造的树形选择器(树形下拉框)](https://download.csdn.net/download/weixin_38706747/12927703)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* *3* [element-ui树形控件el-tree详解](https://blog.csdn.net/m0_63040701/article/details/130892750)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值