mirror of
https://github.com/tusen-ai/naive-ui.git
synced 2024-12-21 04:50:14 +08:00
fix(tabs): refactor before-leave prop (#1420)
* feat: update before-leave prop * fix: optimization * fix: update log * feat: update test * fix: add debug demo * feat: optimization * fix: add debug demo * feat: optimization * feat: optimization Co-authored-by: unknown <liyang@xiaoyouzi.com>
This commit is contained in:
parent
bbf5412c26
commit
75879999c1
@ -1,5 +1,11 @@
|
||||
# CHANGELOG
|
||||
|
||||
## Pending
|
||||
|
||||
## Fixes
|
||||
|
||||
- Fix `n-tabs` switch tab does not work when adding a new tab, closes [#1417](https://github.com/TuSimple/naive-ui/issues/1417).
|
||||
|
||||
## 2.20.0 (2021-10-28)
|
||||
|
||||
### Breaking Changes
|
||||
|
@ -1,5 +1,11 @@
|
||||
# CHANGELOG
|
||||
|
||||
## Pending
|
||||
|
||||
## Fixes
|
||||
|
||||
- 修复 `n-tabs` 在新增 tab 后切换 tab 无法生效,关闭 [#1417]https://github.com/TuSimple/naive-ui/issues/1417)
|
||||
|
||||
## 2.20.0 (2021-10-28)
|
||||
|
||||
### Breaking Changes
|
||||
|
@ -51,9 +51,8 @@ export default defineComponent({
|
||||
return
|
||||
}
|
||||
const { name: nameProp } = props
|
||||
const id = ++nextTabNameRef.id
|
||||
if (nameProp !== valueRef.value) {
|
||||
if (nameProp === nextTabNameRef.value) return
|
||||
nextTabNameRef.value = nameProp
|
||||
const { value: onBeforeLeave } = onBeforeLeaveRef
|
||||
if (!onBeforeLeave) {
|
||||
handleTabClick(nameProp)
|
||||
@ -61,7 +60,7 @@ export default defineComponent({
|
||||
void Promise.resolve(
|
||||
(onBeforeLeave as OnBeforeLeaveImpl)(props.name, valueRef.value)
|
||||
).then((allowLeave) => {
|
||||
if (allowLeave) {
|
||||
if (allowLeave && nextTabNameRef.id === id) {
|
||||
handleTabClick(nameProp)
|
||||
}
|
||||
})
|
||||
|
@ -144,7 +144,10 @@ export default defineComponent({
|
||||
uncontrolledValueRef
|
||||
)
|
||||
|
||||
const nextTabNameRef = { value: mergedValueRef.value }
|
||||
const nextTabNameRef = { id: 0 }
|
||||
watch(mergedValueRef, () => {
|
||||
nextTabNameRef.id = 0
|
||||
})
|
||||
|
||||
const tabWrapperStyleRef = computed(() => {
|
||||
if (!props.justifyContent || props.type === 'card') return undefined
|
||||
|
@ -24,7 +24,7 @@ export interface TabsInjection {
|
||||
closableRef: Ref<boolean>
|
||||
tabStyleRef: Ref<string | CSSProperties | undefined>
|
||||
paneStyleRef: Ref<string | CSSProperties | undefined>
|
||||
nextTabNameRef: { value: string | number | null }
|
||||
nextTabNameRef: { id: number }
|
||||
onBeforeLeaveRef: Ref<OnBeforeLeave | undefined>
|
||||
handleTabClick: (panelName: string | number) => void
|
||||
handleClose: (panelName: string | number) => void
|
||||
|
@ -2,6 +2,7 @@ import { mount } from '@vue/test-utils'
|
||||
import { h } from 'vue'
|
||||
import { NTabPane, NTabs } from '../index'
|
||||
import { AddIcon } from '../../_internal/icons'
|
||||
import { sleep } from 'seemly'
|
||||
|
||||
describe('n-tabs', () => {
|
||||
it('should work with import on demand', () => {
|
||||
@ -42,15 +43,20 @@ describe('n-tabs', () => {
|
||||
})
|
||||
})
|
||||
|
||||
it('should show AddIcon with `addable` prop', () => {
|
||||
it('should show AddIcon with `addable` prop', async () => {
|
||||
const onAdd = jest.fn()
|
||||
const wrapper = mount(NTabs, {
|
||||
props: {
|
||||
type: 'card',
|
||||
addable: true
|
||||
addable: true,
|
||||
onAdd
|
||||
}
|
||||
})
|
||||
|
||||
expect(wrapper.findComponent(AddIcon).exists()).toBe(true)
|
||||
const addIcon = wrapper.find('.n-tabs-tab--addable')
|
||||
await addIcon.trigger('click')
|
||||
expect(onAdd).toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it('should work with `justify-content` prop', async () => {
|
||||
@ -136,4 +142,52 @@ describe('n-tabs', () => {
|
||||
expect(wrapper.find('.test-if').exists()).toEqual(false)
|
||||
expect(wrapper.find('.test-show-lazy').exists()).toEqual(true)
|
||||
})
|
||||
|
||||
it('should work with `on-before-leave` prop', async () => {
|
||||
const wrapper = mount(NTabs, {
|
||||
props: {
|
||||
type: 'card',
|
||||
defaultValue: '3',
|
||||
onBeforeLeave: (name: string) => {
|
||||
switch (name) {
|
||||
case '1':
|
||||
return false
|
||||
case '2':
|
||||
// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
|
||||
return new Promise((resolve) => {
|
||||
setTimeout(() => {
|
||||
resolve(true)
|
||||
}, 1000)
|
||||
}) as Promise<boolean>
|
||||
default:
|
||||
return true
|
||||
}
|
||||
}
|
||||
},
|
||||
slots: {
|
||||
default: () => [
|
||||
h(NTabPane, {
|
||||
tab: '1',
|
||||
name: '1'
|
||||
}),
|
||||
h(NTabPane, {
|
||||
tab: '2',
|
||||
name: '2'
|
||||
}),
|
||||
h(NTabPane, {
|
||||
tab: '3',
|
||||
name: '3'
|
||||
})
|
||||
]
|
||||
}
|
||||
})
|
||||
const tabs = wrapper.findAll('.n-tabs-tab')
|
||||
expect(tabs[2].classes()).toContain('n-tabs-tab--active')
|
||||
await tabs[0].trigger('click')
|
||||
expect(tabs[2].classes()).toContain('n-tabs-tab--active')
|
||||
await tabs[1].trigger('click')
|
||||
expect(tabs[2].classes()).toContain('n-tabs-tab--active')
|
||||
await sleep(1000)
|
||||
expect(tabs[1].classes()).toContain('n-tabs-tab--active')
|
||||
})
|
||||
})
|
||||
|
Loading…
Reference in New Issue
Block a user