interface StateType {
data: Array;
columns: any;//列可以在自己代码中自己自定义,
}
//下面的写法只是参考。
const state = reactive({
data: [],
columns: computed(() =>
createColumns({
removeSingleRow(row: RowData, index) {
//删除一行
state.data.splice(index, 1);
},
createNextStage(row: RowData, index: number) {
state.data.splice(index + 1, 0, {
id: -1,
name: "",
cheif: [],
startTime: null,
endTime: null,
});
//重置id
state.data = state.data.map((e, i) => {
e.id = i;
return e;
});
console.log("data", state.data);
},
})
),
});
//是否开始拖动
const isDraggingStarted = ref(false);
const draggingRowIndex = ref(0);
const startY = ref(0);
const oldStartY = ref(0);
const throughIndex = ref(0);
//鼠标按下
const mouseDownHandler = function (e: any) {
startY.value = e.clientY;
const originalRow= e.target.parentNode;
originalRow.style.cursor = "move";
originalRow.style.userSelect = "none";
const table = tableRef.value.$el;
draggingRowIndex.value = [].slice
.call(table.querySelectorAll("tr"))
.indexOf(originalRow as never);
throughIndex.value = draggingRowIndex.value;
table.querySelectorAll("tr").forEach((row: any) => {
row.style.position = "relative";
row.style.transition = "transform ease .2s";
row.style.transform = "translateY(0px)";
row.style.zIndex = 0;
});
document.addEventListener("mousemove", mouseMoveHandler);
document.addEventListener("mouseup", moveUpHandler);
};
//鼠标拖动
const mouseMoveHandler = function (e: any) {
const table = tableRef.value.$el;
const moveY = e.clientY - startY.value; //鼠标跟随Y
if (draggingRowIndex.value === -1) {
//未找到
return;
}
const draggingRow: any = [].slice.call(table.querySelectorAll("tr"))[
draggingRowIndex.value
];
const rect = draggingRow.getBoundingClientRect();
const height = rect.height;
draggingRow.style.position = "relative";
draggingRow.style.zIndex = 9998;
draggingRow.style.transform = `translateY(${moveY}px)`;
draggingRow.style.transition = "unset";
let direction = "";
if (e.clientY < oldStartY.value) {
//向上拖
direction = "up";
} else if (e.clientY > oldStartY.value) {
//向下拖
direction = "down";
}
const nextRowMoveDown = (
rowIndex: number,
translateY: number,
callBack: () => void
) => {
const nextDownRow: any = [].slice.call(
table.querySelectorAll(".n-data-table-tr")
)[rowIndex];
if (nextDownRow === undefined) {
return;
}
const nextDownRowRect = nextDownRow.getBoundingClientRect();
if (
nextDownRowRect.top + nextDownRowRect.height - (rect.top + rect.height) <
10
) {
nextDownRow.style.transform = `translateY(${translateY}px)`;
callBack();
}
};
const nextRowMoveUp = (
rowIndex: number,
translateY: number,
callBack: () => void
) => {
const nextUpRow: any = [].slice.call(
table.querySelectorAll(".n-data-table-tr")
)[rowIndex];
if (nextUpRow === undefined) {
return;
}
const nextUpRowRect = nextUpRow.getBoundingClientRect();
if (
rect.top + rect.height - (nextUpRowRect.top + nextUpRowRect.height) <
10
) {
nextUpRow.style.transform = `translateY(${translateY}px)`;
callBack();
}
};
if (draggingRowIndex.value === 1) {
//拖拽第一列
if (direction === "down") {
nextRowMoveDown(throughIndex.value + 1, -height, () => {
throughIndex.value = throughIndex.value + 1;
});
} else if (direction === "up") {
nextRowMoveUp(throughIndex.value, 0, () => {
throughIndex.value = throughIndex.value - 1;
});
}
} else if (draggingRowIndex.value === state.data.length) {
//拖拽最后一列
if (direction === "down") {
if (throughIndex.value < draggingRowIndex.value) {
nextRowMoveDown(throughIndex.value + 1, 0, () => {
throughIndex.value = throughIndex.value + 1;
});
}
} else if (direction === "up") {
nextRowMoveUp(throughIndex.value, height, () => {
throughIndex.value = throughIndex.value - 1;
});
}
} else {
//拖拽中间列
if (direction === "up") {
//向上
if (throughIndex.value === draggingRowIndex.value) {
//中间第一次向上滑动
nextRowMoveUp(throughIndex.value - 1, height, () => {
throughIndex.value = throughIndex.value - 1;
});
} else if (throughIndex.value < draggingRowIndex.value) {
//中间上方向上
nextRowMoveUp(throughIndex.value - 1, height, () => {
throughIndex.value = throughIndex.value - 1;
});
} else if (throughIndex.value > draggingRowIndex.value) {
//中间下方向上
nextRowMoveUp(throughIndex.value, 0, () => {
throughIndex.value = throughIndex.value - 1;
});
}
} else if (direction === "down") {
//向下
if (throughIndex.value === draggingRowIndex.value) {
//中间第一次向下滑动
nextRowMoveDown(throughIndex.value + 1, -height, () => {
throughIndex.value = throughIndex.value + 1;
});
} else if (throughIndex.value < draggingRowIndex.value) {
//中间上方向下
nextRowMoveDown(throughIndex.value, 0, () => {
throughIndex.value = throughIndex.value + 1;
});
} else if (throughIndex.value > draggingRowIndex.value) {
//中间下方向下
nextRowMoveDown(throughIndex.value + 1, -height, () => {
throughIndex.value = throughIndex.value + 1;
});
}
}
}
oldStartY.value = e.clientY;
};
//鼠标抬起
const moveUpHandler = function (e: any) {
isDraggingStarted.value = false;
startY.value = e.clientY;
const table = tableRef.value.$el;
if (throughIndex.value === draggingRowIndex.value) {
//位置未发生偏移执行复位
table.querySelectorAll(".n-data-table-tr").forEach((row: any) => {
row.style.position = "relative";
row.style.transition = "transform ease .2s";
row.style.transform = "translateY(0px)";
row.style.zIndex = 0;
});
} else {
//固定拖拽之后的数据
table
.querySelectorAll(".n-data-table-tr")
.forEach((row: any) => row.removeAttribute("style"));
const elem = state.data.splice(draggingRowIndex.value - 1, 1)[0];
state.data.splice(throughIndex.value - 1, 0, elem);
}
document.removeEventListener("mousemove", mouseMoveHandler);
document.removeEventListener("mouseup", moveUpHandler);
};
仿照antd的table拖拽的效果,目前的代码还是有些不完善的地方,勉强可以用。
https://ant.design/components/table-cn#components-table-demo-drag-sorting
naive ui参考文档
https://www.naiveui.com/zh-CN/os-theme/components/data-table
vue3文档路径
https://cn.vuejs.org/guide/introduction.html