This repository has been archived on 2026-09-08. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
UserBaseFront/front/src/components/MyTreeSearch.vue
T

235 lines
7.9 KiB
Vue

<template>
<div style="height: 100%;">
<div class="tree-search-bar">
<Input v-model="keyword" placeholder="输入学校,回车查找" suffix="ios-search" clearable @on-enter="onSearch"
@on-clear="onSearch" style="width:100%;margin-bottom: 10px;" />
</div>
<div :id="domId" :ref="domId" class="ztree"></div>
</div>
</template>
<script>
export default {
props: {
treeData: {
type: Object,
},
setting: {
type: Object,
default: {
view: {
dblClickExpand: false,
showIcon: false,
},
edit: {
enable: true,
showRemoveBtn: false,
showRenameBtn: false,
drag: false,
},
check: {
enable: false,
},
callback: {},
},
},
autoClick: {
type: Boolean,
default: true,
},
isCheck: {
typeof: Boolean,
default: false,
},
},
data() {
return {
domId: "",
treeSetting: _.cloneDeep(this.setting),
treeObj: null,
keyword: '',
highlightNodes: []
};
},
created() {
this.$watch("treeData", val => {
console.log(val);
if (val) {
console.log(val);
this.$nextTick(() => {
this.initTree(this.treeData, this.domId);
});
}
});
},
mounted() {
this.domId = this.uuid();
},
methods: {
uuid() {
return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function (c) {
var r = (Math.random() * 16) | 0,
v = c == "x" ? r : (r & 0x3) | 0x8;
return v.toString(16);
});
},
reloadTree() {
this.treeData.open = true;
this.initTree(this.treeData, this.domId);
},
initTree(_data, _domId) {
const _this = this;
_this.treeSetting.callback.onClick = (event, treeId, treeNode, clickFlag) => {
// console.log(event, treeId, treeNode, clickFlag);
if (_this.isCheck) {
var treeObj = $.fn.zTree.getZTreeObj(treeId);
treeObj.checkNode(treeNode, !treeNode.checked, true);
}
_this.$emit("on-tree-click", treeNode);
};
_this.treeSetting.callback.beforeDrop = (treeId, treeNodes, targetNode, moveType) => {
if (moveType == "inner") {
if (!targetNode.isParent) return false;
} else {
if (targetNode.pid === 0) return false;
}
};
_this.treeSetting.callback.beforeClick = (treeId, treeNode, clickFlag) => {
return !(treeNode.click === false);
};
_this.treeSetting.callback.onDrop = (event, treeId, treeNodes, targetNode, moveType) => {
_this.$emit("on-tree-drag", { treeNodes, targetNode, moveType });
};
_this.treeSetting.callback.onCheck = (event, treeId, treeNode) => {
_this.$emit("on-tree-check", treeNode);
};
_this.treeObj = $.fn.zTree.init($("#" + _domId), _this.treeSetting, _data);
if (_this.autoClick) {
if (Array.isArray(this.treeData)) {
let id = this.treeData[0].id;
_this.selectNode(id);
} else {
let id = this.treeData.id;
_this.selectNode(id);
}
}
},
selectNode(id, isClick = true) {
const _domId = this.domId;
var treeObj = $.fn.zTree.getZTreeObj(_domId);
var node = treeObj.getNodesByFilter(node => node.id == id, true);
if (node == null) return false;
treeObj.selectNode(node);
treeObj.expandNode(node, true, false, false);
treeObj.selectNode(node);
if (isClick) this.$emit("on-tree-click", node);
},
openTree(open) {
const _domId = this.domId;
var treeObj = $.fn.zTree.getZTreeObj(_domId);
treeObj.expandAll(open);
},
removeNode(id) {
const _domId = this.domId;
var treeObj = $.fn.zTree.getZTreeObj(_domId);
var node = treeObj.getNodesByFilter(node => node.id == id, true);
var pnode = node.getParentNode();
treeObj.removeNode(node);
pnode.isParent = true;
treeObj.updateNode(pnode);
this.selectNode(pnode.id);
},
getNodeById(id) {
const _domId = this.domId;
var treeObj = $.fn.zTree.getZTreeObj(_domId);
var node = treeObj.getNodesByFilter(node => node.id == id, true);
return node;
},
renameNode(id, name) {
const _domId = this.domId;
var treeObj = $.fn.zTree.getZTreeObj(_domId);
var node = treeObj.getNodesByFilter(node => node.id == id, true);
node.name = name;
treeObj.updateNode(node);
},
addNote(pid, id, name, isParent) {
const _domId = this.domId;
var treeObj = $.fn.zTree.getZTreeObj(_domId);
var pnode = treeObj.getNodesByFilter(node => node.id == pid, true);
var newNode = { pid, id, name, isParent };
treeObj.addNodes(pnode, -1, newNode);
},
onSearch() {
this.clearHighlight();
if (!this.keyword) return;
this.doSearch(this.keyword);
},
doSearch(key) {
const treeObj = this.treeObj;
// 1. 模糊匹配
const matchNodes = treeObj.getNodesByFilter(node =>
node.type == 2 &&
node.name && node.name.toLowerCase().includes(key.toLowerCase())
);
if (!matchNodes.length) {
this.$Message.info('未搜索到匹配学校')
return;
}
// 2. 展开所有命中节点的父节点
matchNodes.forEach(n => {
let p = n.getParentNode();
while (p) {
treeObj.expandNode(p, true, false, false);
p = p.getParentNode();
}
});
// 3. 高亮
this.highlightNodes = matchNodes;
matchNodes.forEach(n => this.setHighlight(n, true));
// const box = document.getElementById('treeBox');
// const nodeEl = document.getElementById(matchNodes[0].tId);
// box.scrollTop = nodeEl.offsetTop - box.clientHeight / 2; // 居中
if (matchNodes.length) {
const treeObj = this.treeObj;
console.log(matchNodes[0]);
this.selectNode(matchNodes[0].id);
// treeObj.selectNode(matchNodes[0]); // 先选中,会自动滚入可视区
//this.$nextTick(() => treeObj.cancelSelectedNode()); // 取消选中,保持纯高亮
}
},
setHighlight(node, on = true) {
const a = $('#' + node.tId + '_a');
if (on) a.addClass('ztree-search-highlight');
else a.removeClass('ztree-search-highlight');
},
clearHighlight() {
this.highlightNodes.forEach(n => this.setHighlight(n, false));
this.highlightNodes = [];
}
},
};
</script>
<style>
.ztree {
height: calc(100% - 60px);
overflow-y: auto;
}
.ztree-search-highlight {
background-color: #ff6600 !important;
}
.ztree li a.curSelectedNode {
background-color: #ffe4bb !important;
}
</style>