import debounce from 'lodash/debounce'; import throttle from 'lodash/throttle'; import { onBeforeUnmount, onMounted, ref } from 'vue' export function useCellHover(tableDomRef) { // 鼠标悬浮的行 const hoveringCellInfo = ref<{ rowIndex: number; columnProperty: string; }>({ rowIndex: -1, columnProperty: ''}); const isMouseWheeling = ref(false); onMounted(() => { tableDomRef.value.$el.addEventListener('mouseleave', resetHoveringCellInfo); document.addEventListener('wheel', throttledHandleMouseWheel); }) onBeforeUnmount(() => { tableDomRef.value.$el.removeEventListener('mouseleave', resetHoveringCellInfo); document.removeEventListener('wheel', throttledHandleMouseWheel); }) const setCellClassName = ({ column, rowIndex }) => { // hoving-cell-[name]-[rowIndex] if (!column.property) return ''; return `hoving-cell-(${column.property})-(${rowIndex})`; } const resetHoveringCellInfo = () => { hoveringCellInfo.value = { rowIndex: -1, columnProperty: '' }; } let timerHandler: any = null // 性能考虑,在鼠标滚动时,停止处理cell的hover事件 const handleMouseWheel = () => { isMouseWheeling.value = true; clearTimeout(timerHandler); // 停止滚动后,恢复hover事件 timerHandler = setTimeout(() => { isMouseWheeling.value = false; }, 100) } const throttledHandleMouseWheel = throttle(handleMouseWheel, 50); const handleCellMouseEnter = (row, column, cell, event) => { // 性能考虑,表格滚动时会不断触发该事件,导致滚动性能变差 if (isMouseWheeling.value) return const className = [...event.target.classList].find(c => /hoving-cell-\(\w+\)-\(\d+\)/.test(c)) if (!className) return; // 正则匹配括号中的内容 const matchArr = className.match(/hoving-cell-\((\w+)\)-\((\d+)\)/); hoveringCellInfo.value = { rowIndex: +matchArr?.[2], columnProperty: matchArr?.[1] } } const debouncedHoverHandler = debounce(handleCellMouseEnter, 10); return { hoveringCellInfo, setCellClassName, debouncedHoverHandler } }