<template>
|
<el-popover ref="tree-select" :title="'请选择'+label" :disabled="disabled || options.disabled" placement="bottom" width="300" trigger="click" class="tree-select" @show="()=>{treeSuffixIcon='el-icon-yrt-xiangxiajiantou1 dropdown'}" @hide="()=>{treeSuffixIcon='el-icon-yrt-xiangxiajiantou1'}">
|
<el-input slot="reference" ref="input" v-model="currentValue" :readonly="true" :style="{width: options.width}" :placeholder="options.placeholder" :disabled="disabled || options.disabled" :suffix-icon="treeSuffixIcon" class="input no-bg" @focus="(event)=>{onFocus($refs['input'], currentValue, event);}" @change="(val)=>{onInputChange($refs['input'], val);}">
|
span>
|
</el-input>
|
<el-scrollbar :noresize="false" :native="false" wrap-class="popover-tree scrollbar-wrap">
|
<el-tree :ref="'tree-'+options.prop+'-tree'" :node-key="nodeKey" :props="treeProps" :load="(node, resolve)=>{_treeLoad(node, resolve)}" highlight-current lazy @node-click="(data, node, el)=>{onTreeNodeClick(data, node, el)}">
|
<span slot-scope="{ node, data }" class="custom-tree-node">
|
<template v-if="!node.isLeaf">
|
<span v-if="node.expanded">
|
<i class="el-icon-yrt-wenjianjiazhankai"></i> {{ node.label }}
|
</span>
|
<span v-else>
|
<i class="el-icon-yrt-wenjianjia"></i> {{ node.label }}
|
</span>
|
</template>
|
<template v-else>
|
<span>
|
<i class="el-icon-yrt-wenjian1"></i> {{ node.label }}
|
</span>
|
</template>
|
</span>
|
</el-tree>
|
</el-scrollbar>
|
<el-button type="text" icon="el-icon-refresh" @click="treeRefresh">刷新</el-button>
|
</el-popover>
|
</template>
|
|
<script>
|
export default {
|
name: "tree-select",
|
props: {
|
// 下拉框绑定值
|
value: {
|
type: String,
|
default: null
|
},
|
// 标题名称
|
label: {
|
type: String,
|
required: true,
|
default: "树选择器"
|
},
|
// 详细参数
|
options: {
|
type: Object,
|
required: true,
|
default: () => {}
|
},
|
// 数据加载函数
|
treeLoad: {
|
type: Function,
|
default: function(node, resolve) {}
|
},
|
// 是否禁用
|
disabled: {
|
type: Boolean,
|
default: false
|
},
|
// 当前选中主键值
|
nodeKeyValue: {
|
type: [String, Number],
|
default: 0
|
},
|
// tree NodeKey
|
nodeKey: {
|
type: [String, Number],
|
default: "value"
|
}
|
},
|
data() {
|
return {
|
// 模块tree prop参数配置
|
treeProps: {
|
label: "label",
|
children: "children",
|
value: "value",
|
isLeaf: function(data, node) {
|
return data.hasChild !== 1;
|
}
|
},
|
// TREE选择器右侧下拉框
|
treeSuffixIcon: "el-icon-yrt-xiangxiajiantou1",
|
// 当前选中值
|
currentNodeKey: 5
|
};
|
},
|
computed: {
|
// 当前值
|
currentValue: {
|
get: function() {
|
this.$nextTick(() => {
|
this.$refs["tree-" + this.options.prop + "-tree"].setCurrentKey(this.nodeKeyValue);
|
});
|
return this.value;
|
},
|
set: function(val) {
|
this.$emit("update:value", val);
|
}
|
}
|
},
|
methods: {
|
// item单击事件
|
onTreeNodeClick(data, node, el) {
|
var ref = this.$refs["tree-select"];
|
let labels = [];
|
let values = [];
|
let _node = node;
|
while (_node) {
|
if (!_node.data) {
|
break;
|
}
|
labels.push(_node.data.label);
|
values.push(_node.data.value);
|
_node = _node.parent;
|
}
|
labels = labels.reverse();
|
values = values.reverse();
|
this.$emit("on-tree-node-click", data, node, el, labels, values);
|
ref.doClose();
|
},
|
// input change事件
|
onInputChange(ref, val) {
|
this.$emit("on-change", ref, val);
|
},
|
// 获得焦点
|
onFocus(ref, val, event) {
|
var disabled = ref.$attrs.disabled;
|
if (disabled) return;
|
|
this.$emit("onFocus", ref, val, event);
|
},
|
// 触发数据加载函数
|
_treeLoad(node, resolve) {
|
this.$nextTick(() => {
|
this.treeLoad(node, resolve);
|
this.$nextTick(() => {
|
this.$refs["tree-" + this.options.prop + "-tree"].setCurrentKey(this.nodeKeyValue);
|
});
|
});
|
},
|
// 刷新tree
|
treeRefresh() {
|
const tree = this.$refs["tree-" + this.options.prop + "-tree"];
|
var root = tree.store.root;
|
while (root.childNodes.length) {
|
tree.remove(root.childNodes[0]);
|
}
|
this._treeLoad(root, data => {
|
root.doCreateChildren(data);
|
});
|
}
|
}
|
};
|
</script>
|
|
<style lang="scss" scoped>
|
.tree-select{
|
padding: 12px 0 0 0;
|
}
|
.input {
|
/deep/ .el-input__icon.el-icon-yrt-xiangxiajiantou1 {
|
transition: all 0.6s;
|
-moz-transition: all 0.6s; /* Firefox 4 */
|
-webkit-transition: all 0.6s; /* Safari and Chrome */
|
-o-transition: all 0.6s; /* Opera */
|
height: 36px;
|
&.dropdown {
|
transform: rotateZ(-180deg) translateY(3px);
|
-ms-transform: rotateZ(-180deg) translateY(3px); /* Internet Explorer */
|
-moz-transform: rotateZ(-180deg) translateY(3px); /* Firefox */
|
-webkit-transform: rotateZ(-180deg) translateY(3px); /* Safari 和 Chrome */
|
-o-transform: rotateZ(-180deg) translateY(3px); /* Opera */
|
}
|
}
|
}
|
.el-scrollbar {
|
/deep/ .popover-tree.scrollbar-wrap {
|
max-height: 300px;
|
overflow-x: hidden;
|
padding: 0px;
|
.el-tree {
|
margin-bottom: 10px;
|
/deep/ .el-tree-node.is-current > .el-tree-node__content {
|
background-color: #409eff;
|
color: white;
|
}
|
}
|
}
|
}
|
</style>
|