mirror of
https://github.com/tusen-ai/naive-ui.git
synced 2024-12-27 05:00:48 +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
|
# 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)
|
## 2.20.0 (2021-10-28)
|
||||||
|
|
||||||
### Breaking Changes
|
### Breaking Changes
|
||||||
|
@ -1,5 +1,11 @@
|
|||||||
# CHANGELOG
|
# CHANGELOG
|
||||||
|
|
||||||
|
## Pending
|
||||||
|
|
||||||
|
## Fixes
|
||||||
|
|
||||||
|
- 修复 `n-tabs` 在新增 tab 后切换 tab 无法生效,关闭 [#1417]https://github.com/TuSimple/naive-ui/issues/1417)
|
||||||
|
|
||||||
## 2.20.0 (2021-10-28)
|
## 2.20.0 (2021-10-28)
|
||||||
|
|
||||||
### Breaking Changes
|
### Breaking Changes
|
||||||
|
@ -51,9 +51,8 @@ export default defineComponent({
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
const { name: nameProp } = props
|
const { name: nameProp } = props
|
||||||
|
const id = ++nextTabNameRef.id
|
||||||
if (nameProp !== valueRef.value) {
|
if (nameProp !== valueRef.value) {
|
||||||
if (nameProp === nextTabNameRef.value) return
|
|
||||||
nextTabNameRef.value = nameProp
|
|
||||||
const { value: onBeforeLeave } = onBeforeLeaveRef
|
const { value: onBeforeLeave } = onBeforeLeaveRef
|
||||||
if (!onBeforeLeave) {
|
if (!onBeforeLeave) {
|
||||||
handleTabClick(nameProp)
|
handleTabClick(nameProp)
|
||||||
@ -61,7 +60,7 @@ export default defineComponent({
|
|||||||
void Promise.resolve(
|
void Promise.resolve(
|
||||||
(onBeforeLeave as OnBeforeLeaveImpl)(props.name, valueRef.value)
|
(onBeforeLeave as OnBeforeLeaveImpl)(props.name, valueRef.value)
|
||||||
).then((allowLeave) => {
|
).then((allowLeave) => {
|
||||||
if (allowLeave) {
|
if (allowLeave && nextTabNameRef.id === id) {
|
||||||
handleTabClick(nameProp)
|
handleTabClick(nameProp)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -144,7 +144,10 @@ export default defineComponent({
|
|||||||
uncontrolledValueRef
|
uncontrolledValueRef
|
||||||
)
|
)
|
||||||
|
|
||||||
const nextTabNameRef = { value: mergedValueRef.value }
|
const nextTabNameRef = { id: 0 }
|
||||||
|
watch(mergedValueRef, () => {
|
||||||
|
nextTabNameRef.id = 0
|
||||||
|
})
|
||||||
|
|
||||||
const tabWrapperStyleRef = computed(() => {
|
const tabWrapperStyleRef = computed(() => {
|
||||||
if (!props.justifyContent || props.type === 'card') return undefined
|
if (!props.justifyContent || props.type === 'card') return undefined
|
||||||
|
@ -24,7 +24,7 @@ export interface TabsInjection {
|
|||||||
closableRef: Ref<boolean>
|
closableRef: Ref<boolean>
|
||||||
tabStyleRef: Ref<string | CSSProperties | undefined>
|
tabStyleRef: Ref<string | CSSProperties | undefined>
|
||||||
paneStyleRef: Ref<string | CSSProperties | undefined>
|
paneStyleRef: Ref<string | CSSProperties | undefined>
|
||||||
nextTabNameRef: { value: string | number | null }
|
nextTabNameRef: { id: number }
|
||||||
onBeforeLeaveRef: Ref<OnBeforeLeave | undefined>
|
onBeforeLeaveRef: Ref<OnBeforeLeave | undefined>
|
||||||
handleTabClick: (panelName: string | number) => void
|
handleTabClick: (panelName: string | number) => void
|
||||||
handleClose: (panelName: string | number) => void
|
handleClose: (panelName: string | number) => void
|
||||||
|
@ -2,6 +2,7 @@ import { mount } from '@vue/test-utils'
|
|||||||
import { h } from 'vue'
|
import { h } from 'vue'
|
||||||
import { NTabPane, NTabs } from '../index'
|
import { NTabPane, NTabs } from '../index'
|
||||||
import { AddIcon } from '../../_internal/icons'
|
import { AddIcon } from '../../_internal/icons'
|
||||||
|
import { sleep } from 'seemly'
|
||||||
|
|
||||||
describe('n-tabs', () => {
|
describe('n-tabs', () => {
|
||||||
it('should work with import on demand', () => {
|
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, {
|
const wrapper = mount(NTabs, {
|
||||||
props: {
|
props: {
|
||||||
type: 'card',
|
type: 'card',
|
||||||
addable: true
|
addable: true,
|
||||||
|
onAdd
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
expect(wrapper.findComponent(AddIcon).exists()).toBe(true)
|
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 () => {
|
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-if').exists()).toEqual(false)
|
||||||
expect(wrapper.find('.test-show-lazy').exists()).toEqual(true)
|
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