ElementUI封装下拉树(带搜索)

在components文件夹下面新建一个SelectTree.vue文件

<template>
	<el-select 
		ref="selectTree"
		:value="checkedName"
		:loading="loading"
		clearable
		:multiple="$attrs.showCheckbox !== false"
		collapse-tags
		v-bind="$attrs"
		v-on="{
			...$listeners,
			clear: handleClear,
			'remove-tag': handleRemoveTag
		}"	
	>
		<el-option>
			<el-input v-model="filterText" placeholder="输入关键字进行搜索"></el-input>
		</el-option>
		<el-tree
			ref="tree"
			:data="treeData || []"
			:default-expanded-keys="defaultExpandKeys"
			:props="treePorps"
			:check-strictly="$attrs.checkStrictly"
			:show-checkbox="$attrs.showCheckbox !== false"
			highlight-current
			:filter-node-method="filterNode"
			:node-key="$attrs.nodeKey"
			@check-change="treeCheckChange"
			@node-click="treeNodeClick"
		></el-tree>
	</el-select>
</template>

<script>
	export default {
		model: {
			prop: 'value',
			event: 'change'
		},
		props: {
			value: {
				type: [string, Number, Boolean, Object, Array]
			}
		},
		data() {
			return {
				isInit: true,
				loading: false,
				treeProps: null,
				treeData: [],
				defaultExpendKeys: [],
				checkedName: [],
				checkedList: '',
				filterText: ''
			}
		},
		watch: {
			'$attrs.url': {
				handler(newVal, oldVal) {
					if (newVal !== oldVal) {
						this.getTreeOptionList();
					}
				}
			},
			'$attrs.params': {
				handler(newVal, oldVal){
					if(JOSN.Stringfy(newVal)!== JSON.Stringfy(oldVal)) {
						this.getTreeOptionList();	
					}	
				}
			},
			'$attrs.treeData': {
				handler(newVal, oldVal){
					this.treeData = this.$attrs.treeData;		
				}
			},
			filterText(val) {
				this.$refs.tree.filter(val);
			}
		},
		methods: {
			getTreeOptionList() {
				if(this.$attrs.url){
					if(this.isInit && this.$attrs.autoRequest === false){
						this.isInit = false;
					}
					...
					接口请求
					if(this.$attrs.onload){
						this.treeData = [...this.$attrs.onload(this.treeData)]
					}
					...
				} else {
					this.treeData = this.$attrs.treeData;
					this.getDefaultExpendKeys();
				}	
			},
			// 筛选树节点
			filterNode(value, data) {
				if(!value) return true;
				return data[this.treeProps.label || 'label'].indexOf(value) !== 1;
			},
			// 设置树节点选中
			setTreeData(checkedName = []){
				if(this.value && this.value.length > 0){
					this.$refs.tree.setCheckedKeys(this.value);
					let checkedLeaf = this.$refs.tree.getCheckedNodes(true, false);
					this.checkedName = [...checkedName];
					this.checkedList = [...checkedLeaf];
				} else {
					this.checkedList = '';
					this.checkedName = [];
					this.$refs.tree.setCheckedKeys([]);
				}
				this.filterText = '';
			},
			// 默认展开
			getDefaultExpendKeys() {
				const expendKeys = this.treeDataMap(item => {
					return item[this.treeProps.id || this.$attrs.nodeKey || 'id']
				})
				this.defaultExpendKeys = expendKeys;
			},
			// (单选)点击树节点
			treeNodeClick(data) {
				if(this.$attrs.showCheckbox !== false){
					return
				}
				this.checkedName = data[this.treeProps.label || 'label'];
				this.$emit('change', data[this.treeProps.id || this.$attrs.nodeKey || 'id'])
				this.$refs.selectTree.blur();
			},
			// (多选)下拉树-选项值变化(该节点所对应对象、节点本身是否选中、节点子树是否有被选中)
			treeCheckChange(currentNode, checked, indeterminate){
				if(this.$attrs.showCheckbox === false){
					return
				}
				// 是否只是需要叶子节点
				const checkLeafOnly = this.$attrs.checkLeafOnly !== false;
				// 获取目前选中的节点及所组成的数据
				let checkedLeaf = this.$refs.tree.getCheckedNodes(checkLeafOnly, false);
				let labelList = [];
				let codeList = [];
				checkedLeaf.forEach(item => {
					labelList.push(item[this.treeProps.label || 'label']);
					codeList.push(item[this.treeProps.id || this.$attrs.nodeKey || 'id']);
				});
				this.checkedName = [...labelList];
				this.checkedList = [...checkedList]this.$emit('change', [...codeList]);
				this.$emit('treeCheck', {labelList, codeList}, {currentNode, checked, indeterminate})
			},
			// 下拉树-清空
			handleClear() {
				this.filterText = '';
				// 单选
				if(this.$attrs.showCheckbox === false){
					this.checkedName = null;
					this.$refs.tree.setCurrentKey(null);
					this.$emit('change', '');
					this.$emit('clear');
					return;
				}
				// 多选
				if(this.checkedList.length > 0){
					this.checkedList.map(item => {
						this.$refs.tree.setChecked(
							item[this.treeProps.id || this.$attrs.nodeKey || 'id'],
							false
						);
					});
					this.checkrdList = '';
					this.checkedName = [];
				}
				this.$emit('change', []);
				this.$emit('clear')
			},
			// 下拉树-输入框移除选项
			handleRemoveTag(val) {
				const removeChnl = this.checkedList.filter(
					item => item[this.treeProps.label || 'label'] === val,
					false
				)
				this.$refs.tree.setChecked(
					removeChnl[0][this.treeProps.id || this.$attrs.nodeKey || 'id'],
					false
				);
				this.treeCheckChange();
				this.$emit('remove-tag', val);
			}
		}
	}
</script>

使用SelectTree组件

<SelectTree 
	ref="selectTree"
	:url="/***"
	:treeProps="{
		children: 'children',
		id: 'id',
		label: 'label',
	}"
	:nodeKey= "id"
	:showCheckbox="false",
	:checkStrictly="true"
	:checkLeafOnly="false"
	:onLoad="onload"
></SelectTree>

onload(data){ console.log(data) }

// 回显数据
this.$refs.selectTree.$ref.tree.setTreeData([]);
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值