function findSubtreeById(arr, targetId) {
function findNode(node) {
if (node.id === targetId) {
return { ...node } // 创建一个新对象存储目标节点
}
// console.log({ ...node }, 789)
if (node.children && node.children.length > 0) {
for (const childNode of node.children) {
const result = findNode(childNode) // 递归查找子节点
if (result) {
return { ...node, children: [result] } // 创建一个新对象,保留父节点和目标节点
}
}
}
return null
}
for (const node of arr) {
const result = findNode(node)
if (result) {
return result // 返回包含目标节点的新对象
}
}
return null
}
const targetId = handleTreeDataList.value.id
const result = findSubtreeById(dataSourcing.value, targetId)
dataSourcing.value是tree全部数据dataSourcing.value是目标节点id
实现节点间上下移动
// 存放上下移动,删除,编辑,添加显示状态
const showMoveUp = (data, node) => {
const siblings =
node.parent.data.children === undefined ? dataSource.value : node.parent.data.children
const currentIndex = siblings.findIndex((item) => item === data)
return currentIndex > 0
}
const showMoveDown = (data, node) => {
const siblings =
node.parent.data.children === undefined ? dataSource.value : node.parent.data.children
const currentIndex = siblings.findIndex((item) => item === data)
return currentIndex < siblings.length - 1
}
const showDelete = (data) => {
return !data.children || data.children.length === 0
}
const showAddChild = (data) => {
return data.layer < 5
}
const showEdit = (data) => {
return data.isEditing
}
const handleNodeClicks = () => {
Catalogue(1, null)
getCatalogue()
ElMessage({
message: '添加成功',
type: 'success'
})
AddSuccess(1)
// router.push({
// name: 'home'
// })
}
const defaultProps = {
children: 'children',
name: 'name'
}
/**
* 添加子目录
* **/
const append = async (data: any, node: any) => {
if (data.layer > 4) {
ElMessage({
message: '已达到最大层级,不允许再添加子节点',
type: 'warning'
})
return
}
const newChild = {
id: 0,
sort: 0,
floor: 0,
name: '子目录',
pid: data.pid,
layer: data.layer + 1,
children: [],
label: false
}
if (!data.children) {
data.children = []
}
data.children.push(newChild)
dataAddition.value = data.children
dataSource.value = [...dataSource.value]
editNode.value = newChild
nextTick(() => {
Catalogued(1, data)
// 初始化数据
// getCatalogue()
})
}
/**
* 新建父目录
* **/
const appedEnter = async (data: any) => {
if (input1.value === '') {
return // 不允许空目录名称
}
const newFather = {
id: 0,
sort: 1,
floor: 0,
name: input1.value,
pid: 0,
layer: 0,
children: [],
label: false
}
// 检查同级目录是否有相同名称
const siblings = dataSource.value
const isNameDuplicate = siblings.some((sibling) => sibling.name === input1.value)
if (isNameDuplicate) {
ElMessage({
message: '名字已存在!',
type: 'warning'
})
return
}
dataSource.value = [...dataSource.value]
dataSource.value.push(newFather)
editNode.value = newFather
input1.value = '' // 清空输入框
nextTick(async () => {
Catalogue(1, null)
await new Promise((resolve) => setTimeout(resolve, 300)) // 延迟 300 毫秒
getCatalogue()
})
}
/**
*删除功能
**/
const remove = (node: Node, data: any) => {
if (data.label) {
// ElMessage({
// message: '此目录下已上传标注文件, 无法删除!',
// type: 'warning'
// })
centerDialogVisible.value = true
return
}
const parent = node.parent
const children: any = parent.data.children || parent.data
const index = children.findIndex((d) => d.id === data.id)
children.splice(index, 1)
dataSource.value = [...dataSource.value]
editNodeData.value = node.parent.data.children || node.parent.data
editNode.value = data
// const parentNode = node.parent.data.length > 2 ? null : node.parent.data
// console.log(parentNode)
// Catalogue(2, null)
Catalogueing(2, node.parent.data.length > 2 ? null : node.parent.data)
}
/**
* 编辑功能
* **/
const startEdit = (data) => {
data.isEditing = true
}
const saveEdit = (data, node) => {
if (dataSource.value) {
const siblings = data.layer <= 1 ? dataSource.value : node.parent.data.children
const isNameDuplicate = siblings.some(
(sibling) => sibling !== data && sibling.name === data.name
)
if (isNameDuplicate) {
ElMessage({
message: '同级目录中存在相同名称',
type: 'warning'
})
return
}
if (data.layer <= 1) {
editNodeData.value = dataSource.value
editNode.value = data
} else {
editNodeData.value = node.parent.data.children
editNode.value = data
}
data.isEditing = false
// 可以在这里提交修改后的数据到后端
Catalogueing(4, node.parent.data.length > 2 ? null : node.parent.data) // 调用保存数据的方法
// getCatalogue()
}
}
// 交换两个位置的数据
const swapPositions = (array, index1, index2) => {
const temp = array[index1]
array[index1] = array[index2]
array[index2] = temp
}
const move = (data, direction, node) => {
const children =
node.parent.data.children === undefined ? dataSource.value : node.parent.data.children
const currentIndex = children.findIndex((item) => item.id === data.id)
if (direction === 'up' && currentIndex > 0) {
swapPositions(children, currentIndex, currentIndex - 1)
} else if (direction === 'down' && currentIndex < children.length - 1) {
swapPositions(children, currentIndex, currentIndex + 1)
} else {
ElMessage({
message: '到头了呢~',
type: 'success'
})
return
}
// 更新数据源后触发重新渲染
dataSource.value = [...dataSource.value]
// 更新编辑节点的数据
editNodeData.value = children || node.parent.data
editNode.value = data
// 调用保存数据的方法
Catalogueing(3, children.length > 2 ? null : node.parent.data)
}
<!-- 编辑 -->
<div class="catalogue-tree-icon1" @click="startEdit(data)"></div>
<!--添加 -->
<div
v-show="showAddChild(data)"
class="catalogue-tree-icon2"
@click="
() => {
nextTick(() => append(data, node))
}
"
></div>
<!-- 删除 -->
<div
v-show="showDelete(data)"
class="catalogue-tree-icon3"
@click="remove(node, data)"
></div>
<!-- 向上移动 -->
<div
class="catalogue-tree-icon4"
v-show="showMoveUp(data, node)"
@click="move(data, 'up', node)"
></div>
<!-- 向下移动 -->
<div
class="catalogue-tree-icon5"
v-show="showMoveDown(data, node)"
@click="move(data, 'down', node)"
></div>