mirror of
https://github.com/element-plus/element-plus.git
synced 2025-04-12 16:40:36 +08:00
fix(components): [tabs] ensure correct event order (#20384)
This commit is contained in:
parent
08976b6ed4
commit
9473f9dcb9
@ -837,4 +837,114 @@ describe('Tabs.vue', () => {
|
||||
await flushPromises()
|
||||
expect(activeName.value).toBe('tab2')
|
||||
})
|
||||
|
||||
test('event order: tabClick -> update:modelValue -> tabChange', async () => {
|
||||
const events: string[] = []
|
||||
const handleTabClick = vi.fn(() => {
|
||||
events.push('tabClick')
|
||||
})
|
||||
const handleUpdateModelValue = vi.fn(() => {
|
||||
events.push('update:modelValue')
|
||||
})
|
||||
const handleTabChange = vi.fn(() => {
|
||||
events.push('tabChange')
|
||||
})
|
||||
|
||||
const activeName = ref('tab1')
|
||||
const wrapper = mount(() => (
|
||||
<Tabs
|
||||
v-model={activeName.value}
|
||||
onTabClick={handleTabClick}
|
||||
onUpdate:modelValue={handleUpdateModelValue}
|
||||
onTabChange={handleTabChange}
|
||||
>
|
||||
<TabPane name="tab1" label="tab1">
|
||||
Tab 1 content
|
||||
</TabPane>
|
||||
<TabPane name="tab2" label="tab2">
|
||||
Tab 2 content
|
||||
</TabPane>
|
||||
</Tabs>
|
||||
))
|
||||
|
||||
await nextTick()
|
||||
|
||||
const navWrapper = wrapper.findComponent(TabNav)
|
||||
const navItemsWrapper = navWrapper.findAll('.el-tabs__item')
|
||||
|
||||
// Click on the second tab
|
||||
await navItemsWrapper[1].trigger('click')
|
||||
|
||||
// Verify all events have been called
|
||||
expect(handleTabClick).toHaveBeenCalledTimes(1)
|
||||
expect(handleUpdateModelValue).toHaveBeenCalledTimes(1)
|
||||
expect(handleTabChange).toHaveBeenCalledTimes(1)
|
||||
|
||||
// Verify the event call order
|
||||
expect(events).toEqual(['tabClick', 'update:modelValue', 'tabChange'])
|
||||
})
|
||||
|
||||
test('event order with beforeLeave: tabClick -> update:modelValue -> tabChange', async () => {
|
||||
const events: string[] = []
|
||||
const handleTabClick = vi.fn(() => {
|
||||
events.push('tabClick')
|
||||
})
|
||||
const handleUpdateModelValue = vi.fn(() => {
|
||||
events.push('update:modelValue')
|
||||
})
|
||||
const handleTabChange = vi.fn(() => {
|
||||
events.push('tabChange')
|
||||
})
|
||||
|
||||
// Create a beforeLeave function that uses a timer
|
||||
const beforeLeave = () =>
|
||||
new Promise<void>((resolve) => setTimeout(resolve, 100))
|
||||
|
||||
const activeName = ref('tab1')
|
||||
const wrapper = mount(() => (
|
||||
<Tabs
|
||||
v-model={activeName.value}
|
||||
onTabClick={handleTabClick}
|
||||
onUpdate:modelValue={handleUpdateModelValue}
|
||||
onTabChange={handleTabChange}
|
||||
beforeLeave={beforeLeave}
|
||||
>
|
||||
<TabPane name="tab1" label="tab1">
|
||||
Tab 1 content
|
||||
</TabPane>
|
||||
<TabPane name="tab2" label="tab2">
|
||||
Tab 2 content
|
||||
</TabPane>
|
||||
</Tabs>
|
||||
))
|
||||
|
||||
await nextTick()
|
||||
|
||||
const navWrapper = wrapper.findComponent(TabNav)
|
||||
const navItemsWrapper = navWrapper.findAll('.el-tabs__item')
|
||||
|
||||
// Click on the second tab
|
||||
await navItemsWrapper[1].trigger('click')
|
||||
|
||||
// Verify only tabClick is called immediately
|
||||
expect(handleTabClick).toHaveBeenCalledTimes(1)
|
||||
expect(handleUpdateModelValue).toHaveBeenCalledTimes(0)
|
||||
expect(handleTabChange).toHaveBeenCalledTimes(0)
|
||||
expect(events).toEqual(['tabClick'])
|
||||
|
||||
// Verify the model value has not been updated yet (waiting for timer)
|
||||
expect(activeName.value).toBe('tab1')
|
||||
|
||||
// Fast-forward time to trigger the setTimeout callback
|
||||
await beforeLeave()
|
||||
await flushPromises()
|
||||
|
||||
// Verify all events have been called in the correct order
|
||||
expect(handleUpdateModelValue).toHaveBeenCalledTimes(1)
|
||||
expect(handleTabChange).toHaveBeenCalledTimes(1)
|
||||
expect(events).toEqual(['tabClick', 'update:modelValue', 'tabChange'])
|
||||
|
||||
// Verify the model value has been updated
|
||||
expect(activeName.value).toBe('tab2')
|
||||
})
|
||||
})
|
||||
|
@ -150,8 +150,8 @@ const Tabs = defineComponent({
|
||||
event: Event
|
||||
) => {
|
||||
if (tab.props.disabled) return
|
||||
setCurrentName(tabName, true)
|
||||
emit('tabClick', tab, event)
|
||||
setCurrentName(tabName, true)
|
||||
}
|
||||
|
||||
const handleTabRemove = (pane: TabsPaneContext, ev: Event) => {
|
||||
|
Loading…
x
Reference in New Issue
Block a user