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)
}
}