Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
90 changes: 66 additions & 24 deletions packages/plugins/page/src/Tree.vue
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
</template>

<script lang="ts" setup>
import { computed, defineEmits, defineProps, ref } from 'vue'
import { computed, defineEmits, defineProps, ref, watch } from 'vue'
import LayerLines from './LayerLines.vue'

const props = defineProps({
Expand Down Expand Up @@ -81,27 +81,36 @@ const emit = defineEmits(['clickRow', 'moveNode'])
const useCollapseMap = () => {
const collapseMap = ref<Record<string, boolean>>({})

const setCollapse = (id: string, value: boolean) => {
const setCollapse = (id: string | number, value: boolean) => {
collapseMap.value[id] = value
}

const switchCollapse = (id: string) => {
const switchCollapse = (id: string | number) => {
collapseMap.value[id] = !collapseMap.value[id]
}
Comment thread
gene9831 marked this conversation as resolved.

return { collapseMap, setCollapse, switchCollapse }
}

const { collapseMap, switchCollapse } = useCollapseMap()
const { collapseMap, setCollapse, switchCollapse } = useCollapseMap()

const handleSwitchCollapse = (node) => {
interface TreeNode {
id: string | number
label: string
parentId?: string | number
level: number
collapsed?: boolean
rawData?: any
}

const handleSwitchCollapse = (node: TreeNode) => {
const children = node.rawData[props.childrenKey]
if (Array.isArray(children) && children.length > 0) {
switchCollapse(node.id)
}
}

const flattenTreeData = (node, parentId, level = 0, collapsed = false) => {
const flattenTreeData = (node: any, parentId?: string | number, level = 0, collapsed = false): TreeNode[] => {
const { idKey, labelKey, childrenKey } = props

const currentNode = {
Expand All @@ -112,7 +121,7 @@ const flattenTreeData = (node, parentId, level = 0, collapsed = false) => {
collapsed,
rawData: node
}
const result = [currentNode]
const result: TreeNode[] = [currentNode]

const children = node[childrenKey]

Expand All @@ -129,18 +138,14 @@ const nodes = computed(() => {
return flattenTreeData({ [props.idKey]: props.rootId, [props.childrenKey]: props.data }).slice(1)
})

const nodesMap = computed(() => {
const nodesMap = computed<Record<string | number, TreeNode>>(() => {
return nodes.value.reduce((result, node) => {
result[node.id] = node
return result
}, {})
})

const filteredNodes = computed(() => {
return nodes.value.filter((node) => node.label.toLowerCase().includes(props.filterValue.toLowerCase()))
}, {} as Record<string | number, TreeNode>)
})

const getAncestorIds = (nodeId) => {
const getAncestorIds = (nodeId: string | number): (string | number)[] => {
const currentNode = nodesMap.value[nodeId]

if (!currentNode || !currentNode.parentId) {
Expand All @@ -154,6 +159,43 @@ const getAncestorIds = (nodeId) => {
return ancestors
}

const filteredNodes = ref<TreeNode[]>([])

// 下面两个 watch 对应的两个重新计算 filteredNodes 的场景。场景2比场景1多了展开匹配到的节点的操作

// 场景1. 页面树的结构发生变化,或者有节点收起或者展开,重新计算 filteredNodes
watch(nodes, (nodes) => {
filteredNodes.value = nodes.filter((node) => node.label.toLowerCase().includes(props.filterValue.toLowerCase()))
})

// 场景2. 过滤条件发生变化,重新计算 filteredNodes,并且展开匹配到的节点
watch(
() => props.filterValue,
(filterValue) => {
const filtered = nodes.value.filter((node) => node.label.toLowerCase().includes(filterValue.toLowerCase()))

let collapseMapChanged = false

filtered.forEach((node) => {
// 每个节点的祖先节点中,如果存在折叠的节点,则展开
for (const id of getAncestorIds(node.id)) {
if (collapseMap.value[id]) {
setCollapse(id, false)
collapseMapChanged = true
}
}
})

// - 如果 collapseMap 有变化,会自动重新计算 nodes,更新路径:
// props.filterValue -> collapseMap -> nodes -> filteredNodes -> filteredNodesWithAncestors
// - 如果 collapseMap 没有变化,则重新设置 filteredNodes,更新路径:
// props.filterValue -> filteredNodes -> filteredNodesWithAncestors
if (!collapseMapChanged) {
filteredNodes.value = filtered
}
}
)

Comment thread
gene9831 marked this conversation as resolved.
const filteredNodesWithAncestors = computed(() => {
const idSet = new Set()

Expand All @@ -174,7 +216,7 @@ const lines = {
}

const layerLine = computed(() => {
const result = {}
const result: Record<number, Record<number, number>> = {}

const nodes = filteredNodesWithAncestors.value

Expand All @@ -193,14 +235,14 @@ const layerLine = computed(() => {
return result
})

const handleClickRow = (node) => {
const handleClickRow = (node: TreeNode) => {
emit('clickRow', node)
}

const draggedNode = ref(null)
const hoveringNodeId = ref(null)
const draggedNode = ref<TreeNode | null>(null)
const hoveringNodeId = ref<string | number | null>(null)

const handleDragStart = (event, node) => {
const handleDragStart = (_event: DragEvent, node: TreeNode) => {
if (!props.draggable) {
return
}
Expand All @@ -209,12 +251,12 @@ const handleDragStart = (event, node) => {
}

// dragover和dragenter事件回调函数都为handleDragOver。跨行拖动时,禁止拖拽图标可能会闪一下,所以将dragenter事件也加上回调函数
const handleDragOver = (event, node) => {
const handleDragOver = (event: DragEvent, node: TreeNode) => {
if (!props.draggable) {
return
}

const isDescendant = getAncestorIds(node.id).includes(draggedNode.value.id)
const isDescendant = getAncestorIds(node.id).includes(draggedNode.value!.id)

if (!isDescendant) {
// 阻止默认行为以允许放置
Expand All @@ -225,7 +267,7 @@ const handleDragOver = (event, node) => {
}
}

const handleDrop = (event, node) => {
const handleDrop = (event: DragEvent, node: Pick<TreeNode, 'id'>) => {
event.preventDefault()

const dragged = draggedNode.value
Expand All @@ -246,7 +288,7 @@ const handleDragEnd = () => {
hoveringNodeId.value = null
}

const handleContainerDragOver = (event) => {
const handleContainerDragOver = (event: DragEvent) => {
if (!props.draggable) {
return
}
Expand All @@ -259,7 +301,7 @@ const handleContainerDragOver = (event) => {
hoveringNodeId.value = props.rootId
}

const handleContainerDragLeave = (event) => {
const handleContainerDragLeave = (event: DragEvent) => {
if (!props.draggable) {
return
}
Expand Down