import { ref, watch, type SetupContext, computed, reactive, onMounted, nextTick } from 'vue';
|
import type { LeftTreeProps, LeftTreeEmits } from '/@/components/tree/leftTreeByMgr';
|
import type { AllowDropType, NodeDropType } from 'element-plus/es/components/tree/src/tree.type';
|
import type { ElTree } from 'element-plus';
|
import type Node from 'element-plus/es/components/tree/src/model/node';
|
import { useTextOverflow } from '/@/hooks/useOverflow';
|
import { debounce } from '/@/utils/util';
|
import { useFilterTree } from '/@/hooks/useFilterTree';
|
|
export const useLeftTree = (props: LeftTreeProps, emits: SetupContext<LeftTreeEmits>['emit']) => {
|
//定义树的实例
|
const listTreeRef = ref<InstanceType<typeof ElTree>>(null);
|
const { filterNode: handleSearch, filterText } = useFilterTree(listTreeRef, props.defaultProps.label);
|
|
const state = reactive({
|
selectValue: '' as any,
|
currentNodeKey1: '',
|
});
|
|
/**拖动树结束事件 */
|
const handleEdit = (data, node) => {
|
emits('treeEdit', data, node);
|
};
|
const handleDelete = (data, node) => {
|
emits('treeDelete', data, node);
|
};
|
const treeSearchClear = () => {
|
emits('treeSearchClear');
|
};
|
|
const handleAdd = () => {
|
emits('treeAdd');
|
};
|
const selectChange = (node) => {
|
filterText.value = '';
|
emits('selectchange', node);
|
};
|
const handleNodeClick = (data) => {
|
emits('click', data);
|
};
|
const handleCheckChange = (data, obj) => {
|
emits('check', data, obj);
|
};
|
//#region ====================== 树拖拽 ======================
|
const dragSwitch = ref(false);
|
const treeDraggable = ref(false);
|
/**
|
* 在初始拖拽状态,获取初始树的数据,便于在排序失败后回滚
|
*/
|
let originTreeData = [];
|
|
const handleDragStart = (draggingNode: Node, ev: DragEvent) => {
|
originTreeData = [].concat(props.treedata);
|
emits('nodeDragStart', draggingNode, ev);
|
};
|
const handleDragEnd = (draggingNode: Node, dropNode: Node, dropType: NodeDropType, ev: DragEvent) => {
|
emits('nodeDragEnd', draggingNode, dropNode, dropType, ev, originTreeData);
|
};
|
/**
|
* 过滤掉跨级拖拽
|
*/
|
const allowDrop = (draggingNode: Node, dropNode: Node, type: AllowDropType) => {
|
return (
|
props.allowDropNode(draggingNode, dropNode, type) &&
|
dropNode.level === draggingNode.level &&
|
dropNode.parent === draggingNode.parent &&
|
type !== 'inner'
|
);
|
};
|
|
const allowDrag = (node: Node) => {
|
return props.allowDragNode(node);
|
};
|
|
const handleDragStatusChange = (value) => {
|
treeDraggable.value = value;
|
};
|
//#endregion
|
const findMaxLevel = (treeData, childrenKey, level = 0, maxLevel = 0) => {
|
level++;
|
if (level > maxLevel) {
|
maxLevel = level;
|
}
|
for (const item of treeData) {
|
if (item[childrenKey] && item[childrenKey].length > 0) {
|
maxLevel = findMaxLevel(item[childrenKey], childrenKey, level, maxLevel);
|
}
|
}
|
|
return maxLevel;
|
};
|
|
const treeDataIsNull = computed(() => {
|
return !props.treedata || props.treedata.length === 0;
|
});
|
/**
|
* 树的最大Level
|
*/
|
const maxLevel = computed(() => {
|
const childrenKey = props.defaultProps.children;
|
|
return findMaxLevel(props.treedata, childrenKey);
|
});
|
|
const selectMaxLevel = computed(() => {
|
const childrenKey = props.selectProps.children;
|
|
return findMaxLevel(props.selectData, childrenKey);
|
});
|
|
//#region ====================== 过长显示在 tooltip 中 ======================
|
const { disableTooltip, textMouseOver } = useTextOverflow();
|
|
//#endregion
|
|
//#region ====================== leftTree 列表树节点后缀图标 ======================
|
const suffixIconFun = (node: any, data: any) => {
|
if (!props.suffixIcon)
|
return {
|
name: undefined,
|
color: undefined,
|
};
|
const iconResult = props.suffixIcon(node, data);
|
|
if (typeof iconResult === 'string') {
|
return {
|
name: iconResult,
|
color: 'rgb(64,158,255)',
|
};
|
} else {
|
return iconResult;
|
}
|
};
|
//#endregion
|
|
watch(
|
() => props.currentNodeKey,
|
(val) => {
|
let key = val;
|
if (props.treedata.length && key === '') {
|
key = props.treedata[0][props.defaultProps.id];
|
}
|
state.currentNodeKey1 = key;
|
|
nextTick(() => {
|
listTreeRef.value.setCurrentKey(key); // 设置默认选中
|
});
|
}
|
);
|
watch(
|
() => props.defaultSelectValue,
|
(val) => {
|
state.selectValue = val as any;
|
}
|
);
|
onMounted(() => {
|
state.selectValue = props.defaultSelectValue;
|
});
|
return {
|
listTreeRef,
|
filterText,
|
handleEdit,
|
handleDelete,
|
treeSearchClear,
|
handleAdd,
|
selectChange,
|
handleNodeClick,
|
handleCheckChange,
|
//#region ====================== 拖拽 ======================
|
allowDrop,
|
dragSwitch,
|
handleDragStart,
|
handleDragEnd,
|
allowDrag,
|
handleDragStatusChange,
|
//#endregion
|
handleSearch,
|
treeDataIsNull,
|
maxLevel,
|
selectMaxLevel,
|
|
treeDraggable,
|
state,
|
//#region ====================== 过长显示在 tooltip 中 ======================
|
disableTooltip,
|
textMouseOver,
|
//#endregion
|
//#region ====================== 列表树节点后缀图标 ======================
|
suffixIconFun,
|
//#endregion
|
};
|
};
|