20260915221013
This commit is contained in:
1 parent
1f56cc3efb
commit
dce29f250e
54 files changed
+3732
-574
No files matched your search
@@ -1,4 +1,5 @@
|
||||
import { describe, it, expect, vi } from 'vitest'
|
||||
import { describe, it, expect, vi, afterEach } from 'vitest'
|
||||
import { nextTick } from 'vue'
|
||||
import { mount } from '@vue/test-utils'
|
||||
import Tree from '@/components/ui/tree/tree.vue'
|
||||
|
||||
@@ -91,27 +92,103 @@ describe('Tree 右键菜单', () => {
|
||||
|
||||
describe('Tree 行内元素顺序', () => {
|
||||
/**
|
||||
* 回归点:箭头槽(非叶为真箭头、叶子为等宽占位)必须排在拖拽手柄之前。
|
||||
* 放到手柄之后时,叶子行的手柄与标题之间会空出一整个箭头宽,读起来像多余空隙;
|
||||
* 排在前面则这段空白归入左侧缩进带,手柄紧跟标题(见 tree-node.vue 模板注释)。
|
||||
* 回归点:行内只有「箭头槽 → 标题」,不再有拖拽手柄列 ——
|
||||
* 拖拽改由长按整行发起,行与行之间不存在「有手柄 / 无手柄」的宽度差异。
|
||||
* 箭头槽是全行唯一的固定槽:非叶为真箭头、叶子为等宽占位,
|
||||
* 保证同层标题左边界一致(去掉叶子占位会让叶子标题左移一格)。
|
||||
*/
|
||||
const rowClasses = (row) => [...row.element.children].map((el) => el.className)
|
||||
|
||||
it('拖拽开启时:箭头槽在拖拽手柄之前', () => {
|
||||
it('非叶行:箭头槽在标题之前,且不渲染拖拽手柄', () => {
|
||||
const wrapper = mount(Tree, { props: { treeData, fieldNames, draggable: true } })
|
||||
const parentRow = wrapper.findAll('.tree-node')[0]
|
||||
expect(rowClasses(parentRow)).toEqual(['tree-node-switcher', 'tree-node-grip', 'tree-node-content'])
|
||||
expect(rowClasses(parentRow)).toEqual(['tree-node-switcher', 'tree-node-content'])
|
||||
})
|
||||
|
||||
it('叶子行的占位与手柄顺序一致,保证标题横坐标与非叶兄弟相同', () => {
|
||||
it('叶子行渲染等宽箭头占位,标题与非叶兄弟对齐', () => {
|
||||
const wrapper = mount(Tree, {
|
||||
props: { treeData, fieldNames, draggable: true, defaultExpandedKeys: ['1'] },
|
||||
})
|
||||
const childRow = wrapper.findAll('.tree-node')[1]
|
||||
expect(rowClasses(childRow)).toEqual([
|
||||
'tree-node-switcher is-placeholder',
|
||||
'tree-node-grip',
|
||||
'tree-node-content',
|
||||
])
|
||||
expect(rowClasses(childRow)).toEqual(['tree-node-switcher is-placeholder', 'tree-node-content'])
|
||||
})
|
||||
|
||||
it('不可拖拽的节点与可拖拽节点行内结构一致', () => {
|
||||
const wrapper = mount(Tree, {
|
||||
props: {
|
||||
fieldNames,
|
||||
draggable: true,
|
||||
defaultExpandedKeys: ['1'],
|
||||
treeData: [
|
||||
{
|
||||
b_id: '1',
|
||||
b_name: '全部分类',
|
||||
draggable: false,
|
||||
children: [{ b_id: '2', b_name: '子节点' }],
|
||||
},
|
||||
],
|
||||
},
|
||||
})
|
||||
const rows = wrapper.findAll('.tree-node')
|
||||
expect(rowClasses(rows[0])).toEqual(['tree-node-switcher', 'tree-node-content'])
|
||||
expect(rowClasses(rows[1])).toEqual(['tree-node-switcher is-placeholder', 'tree-node-content'])
|
||||
})
|
||||
})
|
||||
|
||||
describe('Tree 长按拖拽', () => {
|
||||
const rowOf = (wrapper, index = 0) => wrapper.findAll('.tree-node')[index]
|
||||
const press = (row) => row.trigger('mousedown', { button: 0, clientX: 0, clientY: 0 })
|
||||
|
||||
afterEach(() => vi.useRealTimers())
|
||||
|
||||
it('长按到位后才置为可拖拽,短按保持普通行', async () => {
|
||||
vi.useFakeTimers()
|
||||
const wrapper = mount(Tree, { props: { treeData, fieldNames, draggable: true } })
|
||||
const row = rowOf(wrapper)
|
||||
|
||||
await press(row)
|
||||
// 未到长按时长:仍是普通行,短按/双击/多选点击的语义不受影响
|
||||
expect(row.attributes('draggable')).toBe('false')
|
||||
|
||||
vi.advanceTimersByTime(400)
|
||||
await nextTick()
|
||||
expect(row.attributes('draggable')).toBe('true')
|
||||
wrapper.unmount()
|
||||
})
|
||||
|
||||
it('长按期间位移超过余量则放弃本次拖拽', async () => {
|
||||
vi.useFakeTimers()
|
||||
const wrapper = mount(Tree, { props: { treeData, fieldNames, draggable: true } })
|
||||
const row = rowOf(wrapper)
|
||||
|
||||
await press(row)
|
||||
document.dispatchEvent(new MouseEvent('mousemove', { clientX: 40, clientY: 0 }))
|
||||
vi.advanceTimersByTime(400)
|
||||
await nextTick()
|
||||
expect(row.attributes('draggable')).toBe('false')
|
||||
wrapper.unmount()
|
||||
})
|
||||
|
||||
it('未开启 draggable 或节点标记 draggable:false 时不进入拖拽', async () => {
|
||||
vi.useFakeTimers()
|
||||
const plain = mount(Tree, { props: { treeData, fieldNames } })
|
||||
await press(rowOf(plain))
|
||||
vi.advanceTimersByTime(500)
|
||||
await nextTick()
|
||||
expect(rowOf(plain).attributes('draggable')).toBe('false')
|
||||
plain.unmount()
|
||||
|
||||
const locked = mount(Tree, {
|
||||
props: {
|
||||
fieldNames,
|
||||
draggable: true,
|
||||
treeData: [{ b_id: '1', b_name: '根节点', draggable: false, children: [] }],
|
||||
},
|
||||
})
|
||||
await press(rowOf(locked))
|
||||
vi.advanceTimersByTime(500)
|
||||
await nextTick()
|
||||
expect(rowOf(locked).attributes('draggable')).toBe('false')
|
||||
locked.unmount()
|
||||
})
|
||||
})
|
||||
Reference in new issue
Block a user