elementUI 下拉树

elementUI 下拉树的实现

一、记录点
1、弹出框+输入框+树形控件实现。
2、点击输入框下拉弹出框展示树形结构数据。
3、弹出框限制树形结构数据展示面积,滚动加持。
4、结构树:懒加载,复选框
5、选中数据在输入框展示,同步取消操作。
6、重点:根据不同的类型,重新渲染树结构内容方法handlerReLoad。
二、代码

<template>
  <el-popover
    ref="popover"
    placement="bottom-start"
    trigger="click"
    :visible-arrow="false"
    :popper-class="datumSelectTree"
  >
	<div class="addM-win">
		<el-scrollbar
			class="default-scrollbar srcoll-bar-init"
			wrap-class="default-scrollbar__wrap"
			view-class="default-scrollbar__view"
		>
			<div class="dimension-tree">
				<el-tree
					lazy
					show-checkbox
					ref="tree"
					node-key="code"
					empty-text="暂无数据"
					:data="dataTreeList"
					:props="propsData"
					:load="loadNode"
					:check-on-click-node="false"
					:default-checked-keys="selectdArray"
					:expand-on-click-node="false"
					@check-change="handleCheckChange"
				/>
			</div>
		</el-scrollbar>
	</div>

    <el-input
      ref="input"
      slot="reference"
      v-model="labelModel"
      :style="` ${width}px`"
      :placeholder="placeholder"
    ></el-input>
  </el-popover>
</template>

<script>
import ApiService from "@/services/API-service.js";
export default {
  name: "SelectTree",
  props: {
    interfaceName: {
      type: String,
      default: ""
    },
    propsObject: {
      type: Object,
      default: () => {}
    },
    selectedList: {
      type: Array,
      default: () => []
    },
    paramsObject: {
      type: Object,
      default: () => {}
    },
    inputTextShow: {
      type: Object,
      default: () => {}
    },
    // 输入框宽度
     String,
    // 输入框占位符
    placeholder: {
      type: String,
      required: false,
      default: "请选择"
    }
  },
  watch: {
    paramsObject: {
      handler: function(n, o) {
		  this.params = n;
      }
    },
    inputTextShow: {
      handler: function(n, o) {
		  this.inputTextShow = n;
	  },
	  deep: true
    }
  },
  data() {
    return {
		depositNode: null,
		depositResolve: null,
		treeList: [],
		dataTreeList: [],
		searchList: [],
		propsData: this.propsObject,
		params: this.paramsObject,
		selectdArray: this.selectedList,
		appearText: this.inputTextShow,
		datumSelectTree: "datum-select-tree",
		// 树状菜单显示状态
		showStatus: false,
		// 输入框显示值
		labelModel: ""
    };
  },
  created() {
    // 查询后回显
    if (Object.keys(this.appearText).length) {
        this.appearText.text && (this.labelModel = this.appearText.text);
        this.appearText.value.length ? this.appearText.value.forEach(item=>{
			this.selectdArray.push(item);
		}) : this.selectdArray = [];
    }
  },
  destroyed() {
  },
  methods: {
    loadNode(node, resolve) {
		this.depositNode = node;
		this.depositResolve = resolve;
		node.data && node.data.code && (this.params.parentCode = node.data.code);
		ApiService.permission.dimensionTree(this.params).then(res => {
			if (res.code === "0000") {
				// console.log("树结构数据=====", res);
				!res.data.detail.length && this.$message("无下级数据!");
				this.selectdArray = this.selectedList;
				this.dueDataList(res.data.detail);
				this.treeList = res.data.detail;
				resolve(res.data.detail);
			} else {
				this.$message.error(res.message);
			}
		})
		.catch(err => {
			this.$message.error("err:" + err);
		});
    },
    dueDataList(list) {
      if (list && list.length) {
        list.forEach(item => {
          item.leaf = item.nextlevel === "1" ? false : true;
        });
      }
    },
    handleCheckChange(data, checked, indeterminate) {
		let obj = { insertkey: data.code, insertValue: data.name };
		
		if (checked) {
			// 选中
			// 在原有的基础上新增查询项
			this.selectdArray.push(data.code);
			this.searchList.push(obj);
			this.labelModel ? (this.labelModel += "," + data.name) : (this.labelModel = data.name);
		} else {
			// 取选
			let index = this.selectdArray.indexOf(data.code);
			if (index > -1) {
				this.selectdArray.splice(index, 1);
			}

			this.searchList.forEach((item, index)=> {
				if (item.insertkey === data.code) {
					this.searchList.splice(index, 1);
				}
			})

			// 查询回显
			let resultLabel = null;
			if (this.labelModel.indexOf(',') !== -1) {
				let labelSplit = this.labelModel.split(',');
				if (labelSplit.length) {
					resultLabel = labelSplit.filter((x) => x !== data.name);
				}
			}
			this.labelModel = (resultLabel && resultLabel.length && resultLabel.join(','));
		}
		
		this.$emit("handleSelected", this.selectdArray, this.searchList, this.labelModel);
    },
    // 显示时触发
    onShowPopover() {
      this.showStatus = true;
    },
    // 隐藏时触发
    onHidePopover() {
      this.showStatus = false;
	},
	handlerReLoad() {
		this.appearText = {};
		this.searchList = [];
		this.selectdArray.splice(0);
		this.depositNode.childNodes = [];
		this.depositNode.defaultCheckedKeys = [];
		this.$refs.tree && this.$refs.tree.load(this.depositNode, this.depositResolve);
		this.$emit( "handleSelected", [], [], '' );
		this.labelModel = null;
	}
  }
};
</script>
<style lang="less" scoped>
@import "~@/assets/el-tree.less";
/deep/.el-input{
	height: 40px;
	line-height: 40px;
}
.addM-win{
     100%;
    /deep/.default-scrollbar__view {
        height: 200px;
    }
    /deep/.el-scrollbar {
        position: relative;
        .el-scrollbar__wrap {
            max-height: 220px;
            overflow-x: hidden;
        }
	}
}
</style>
<style lang="less">
.datum-select-tree {
  background: var(--elTreeBg);
  border: 1px solid var(--elTreeBg);
}
/deep/.el-checkbox__inner::after{
    -webkit-box-sizing: content-box;
    box-sizing: content-box;
    content: "";
    border: 1PX solid #FFF;
    border-left: 0;
    border-top: 0;
    height: 7px;
    left: 4px;
    position: absolute;
    top: 1PX;
    -webkit-transform: rotate(45deg) scaleY(0);
    transform: rotate(45deg) scaleY(0);
     3px;
    -webkit-transition: -webkit-transform .15s ease-in .05s;
    transition: -webkit-transform .15s ease-in .05s;
    transition: transform .15s ease-in .05s;
    transition: transform .15s ease-in .05s, -webkit-transform .15s ease-in .05s;
    transition: transform .15s ease-in .05s,-webkit-transform .15s ease-in .05s;
    -webkit-transform-origin: center;
    transform-origin: center;
    
}
</style>
css 下拉框样式文件
.dimension-tree{
    /deep/.el-tree{
        background: var(--elTreeBg);    //#ffffff
        color: var(--elTreeTextColor); // #606266;
    }
    /deep/.el-tree-node:focus>.el-tree-node__content{
        background-color: var(--elTreeBg);
    }
    /deep/.el-tree-node__content:hover{
        background-color: var(--elTreeBg); // #F5F7FA;
        color: var(--elTreeTextColor);
    }
    /deep/.el-checkbox__input.is-checked .el-checkbox__inner, 
    /deep/.el-checkbox__input.is-indeterminate .el-checkbox__inner{
        // 选择复选框
        background-color: var(--elTreeCheckbox);
        border-color: var(--elTreeCheckbox);
    }
    /deep/.el-checkbox__inner:hover{
        // 复选框鼠标经过
        border-color: var(--elTreeTextColor);;
    }
    /deep/.el-tree--highlight-current .el-tree-node.is-current>.el-tree-node__content{
        // 选择高亮背景色
        background-color:var(--elTreeHighlight)
    }
}

原文地址:https://www.cnblogs.com/min77/p/15320622.html