diff --git a/packages/components/tree/__tests__/tree.test.ts b/packages/components/tree/__tests__/tree.test.ts index 123d423e63..b3d554ebd5 100644 --- a/packages/components/tree/__tests__/tree.test.ts +++ b/packages/components/tree/__tests__/tree.test.ts @@ -1481,6 +1481,102 @@ describe('Tree.vue', () => { expect(flag).toBe(true) }) + test('collapse and navigate down and up', async () => { + const { wrapper } = getTreeVm(``, { + template: ` +
+ +
+ `, + }) + await nextTick() + let flag = false + function handleFocus() { + return () => (flag = true) + } + const tree = wrapper.findComponent({ name: 'ElTree' }) + const targetElement = wrapper.find('div[data-key="2"]').element + const fromElement = wrapper.find('div[data-key="1"]') + await fromElement.trigger('click') + + expect(fromElement.classes('is-expanded')).toBe(false) // 判断是否已折叠 + + await nextTick() + defineGetter(targetElement, 'focus', handleFocus) + ;(tree.vm as InstanceType).setCurrentKey(1) + // 模拟按下下箭头键 + fromElement.element.dispatchEvent( + new KeyboardEvent('keydown', { + code: 'ArrowDown', + bubbles: true, + cancelable: false, + }) + ) + expect(flag).toBe(true) + + await nextTick() + + flag = false + defineGetter(fromElement.element, 'focus', handleFocus) + // 模拟按下上箭头键 + targetElement.dispatchEvent( + new KeyboardEvent('keydown', { + code: 'ArrowUp', + bubbles: true, + cancelable: false, + }) + ) + expect(flag).toBe(true) + }) + + test('filter-node-method and navigate down', async () => { + const { wrapper } = getTreeVm(``, { + template: ` +
+ +
+ `, + methods: { + filterNode(value, data) { + if (!value) return true + return data.label.includes(value) + }, + }, + }) + let flag = false + function handleFocus() { + return () => (flag = true) + } + + const treeWrapper = wrapper.findComponent(Tree) + ;(treeWrapper.vm as InstanceType).filter('-1') + + await sleep() + const tree = wrapper.findComponent({ name: 'ElTree' }) + ;(tree.vm as InstanceType).setCurrentKey(1) + + const allNodes = treeWrapper.findAll('.el-tree-node') + const visibleNodes = allNodes.filter( + (node) => !node.classes().includes('is-hidden') + ) + const len = visibleNodes.length + for (let i = 0; i < len; i++) { + if (visibleNodes[i + 1]) { + defineGetter(visibleNodes[i + 1].element, 'focus', handleFocus) + // 模拟按下下箭头键 + visibleNodes[i].element.dispatchEvent( + new KeyboardEvent('keydown', { + code: 'ArrowDown', + bubbles: true, + cancelable: false, + }) + ) + expect(flag).toBe(true) + flag = false + } + } + }) + test('navigate with disabled', async () => { const wrapper = mount({ template: ` diff --git a/packages/components/tree/src/model/node.ts b/packages/components/tree/src/model/node.ts index 24db8976db..9fa84505b3 100644 --- a/packages/components/tree/src/model/node.ts +++ b/packages/components/tree/src/model/node.ts @@ -79,6 +79,13 @@ const getPropertyFromData = function (node: Node, prop: string): any { } } +const setCanFocus = function (childNodes: Node[], focus: boolean): void { + childNodes.forEach((item) => { + item.canFocus = focus + setCanFocus(item.childNodes, focus) + }) +} + let nodeIdSeed = 0 class Node { @@ -359,9 +366,7 @@ class Node { } this.expanded = true if (callback) callback() - this.childNodes.forEach((item) => { - item.canFocus = true - }) + setCanFocus(this.childNodes, true) } if (this.shouldLoadData()) { @@ -395,9 +400,7 @@ class Node { collapse(): void { this.expanded = false - this.childNodes.forEach((item) => { - item.canFocus = false - }) + setCanFocus(this.childNodes, false) } shouldLoadData() { diff --git a/packages/components/tree/src/model/useKeydown.ts b/packages/components/tree/src/model/useKeydown.ts index bbd9be2dc5..ae243de863 100644 --- a/packages/components/tree/src/model/useKeydown.ts +++ b/packages/components/tree/src/model/useKeydown.ts @@ -46,8 +46,13 @@ export function useKeydown({ el$ }: UseKeydownOption, store: Ref) { : treeItems.length - 1 const startIndex = nextIndex while (true) { - if (store.value.getNode(treeItems[nextIndex].dataset.key!).canFocus) + const currentNode = store.value.getNode( + treeItems[nextIndex].dataset.key! + ) + if (currentNode.canFocus && currentNode.visible) { break + } + nextIndex-- if (nextIndex === startIndex) { nextIndex = -1 @@ -66,8 +71,13 @@ export function useKeydown({ el$ }: UseKeydownOption, store: Ref) { : 0 const startIndex = nextIndex while (true) { - if (store.value.getNode(treeItems[nextIndex].dataset.key!).canFocus) + const currentNode = store.value.getNode( + treeItems[nextIndex].dataset.key! + ) + if (currentNode.canFocus && currentNode.visible) { break + } + nextIndex++ if (nextIndex === startIndex) { nextIndex = -1