mirror of
https://gitee.com/element-plus/element-plus.git
synced 2024-11-30 02:08:12 +08:00
fix(components): [steps] preserve the order of subcomponents (#12896)
* fix(components): [steps] preserve the order of subcomponents * fix: remove unused type * add test cases
This commit is contained in:
parent
015ac099cb
commit
8fd857aa8a
@ -1,4 +1,4 @@
|
|||||||
import { markRaw, nextTick } from 'vue'
|
import { markRaw, nextTick, ref } from 'vue'
|
||||||
import { mount } from '@vue/test-utils'
|
import { mount } from '@vue/test-utils'
|
||||||
import { describe, expect, test } from 'vitest'
|
import { describe, expect, test } from 'vitest'
|
||||||
import { Edit } from '@element-plus/icons-vue'
|
import { Edit } from '@element-plus/icons-vue'
|
||||||
@ -190,4 +190,26 @@ describe('Steps.vue', () => {
|
|||||||
expect(wrapper.find('.el-step__title').text()).toBe('A')
|
expect(wrapper.find('.el-step__title').text()).toBe('A')
|
||||||
expect(wrapper.find('.el-step__description').text()).toBe('B')
|
expect(wrapper.find('.el-step__description').text()).toBe('B')
|
||||||
})
|
})
|
||||||
|
|
||||||
|
test('order of step', async () => {
|
||||||
|
const data = ref(['first', 'second', 'thrid'])
|
||||||
|
const wrapper = _mount(() => (
|
||||||
|
<Steps active={0}>
|
||||||
|
{data.value.map((t) => (
|
||||||
|
<Step
|
||||||
|
key={t}
|
||||||
|
v-slots={{
|
||||||
|
title: () => t,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</Steps>
|
||||||
|
))
|
||||||
|
await nextTick()
|
||||||
|
data.value = ['a', 'b', 'c']
|
||||||
|
await nextTick()
|
||||||
|
wrapper.findAll('.el-step__icon-inner').forEach((domWrapper, index) => {
|
||||||
|
expect(domWrapper.element.textContent).toEqual((index + 1).toString())
|
||||||
|
})
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
@ -74,7 +74,7 @@ export interface IStepsProps {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface StepItemState {
|
export interface StepItemState {
|
||||||
uid: number | undefined
|
uid: number
|
||||||
currentStatus: string
|
currentStatus: string
|
||||||
setIndex: (val: number) => void
|
setIndex: (val: number) => void
|
||||||
calcProgress: (status: string) => void
|
calcProgress: (status: string) => void
|
||||||
@ -83,6 +83,8 @@ export interface StepItemState {
|
|||||||
export interface IStepsInject {
|
export interface IStepsInject {
|
||||||
props: IStepsProps
|
props: IStepsProps
|
||||||
steps: Ref<StepItemState[]>
|
steps: Ref<StepItemState[]>
|
||||||
|
addStep: (item: StepItemState) => void
|
||||||
|
removeStep: (uid: number) => void
|
||||||
}
|
}
|
||||||
|
|
||||||
defineOptions({
|
defineOptions({
|
||||||
@ -112,9 +114,7 @@ onMounted(() => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
onBeforeUnmount(() => {
|
onBeforeUnmount(() => {
|
||||||
parent.steps.value = parent.steps.value.filter(
|
parent.removeStep(stepItemState.uid)
|
||||||
(instance) => instance.uid !== currentInstance?.uid
|
|
||||||
)
|
|
||||||
})
|
})
|
||||||
|
|
||||||
const currentStatus = computed(() => {
|
const currentStatus = computed(() => {
|
||||||
@ -203,11 +203,11 @@ const updateStatus = (activeIndex: number) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const stepItemState = reactive({
|
const stepItemState = reactive({
|
||||||
uid: computed(() => currentInstance?.uid),
|
uid: currentInstance!.uid,
|
||||||
currentStatus,
|
currentStatus,
|
||||||
setIndex,
|
setIndex,
|
||||||
calcProgress,
|
calcProgress,
|
||||||
})
|
})
|
||||||
|
|
||||||
parent.steps.value = [...parent.steps.value, stepItemState]
|
parent.addStep(stepItemState)
|
||||||
</script>
|
</script>
|
||||||
|
@ -5,12 +5,11 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { provide, ref, watch } from 'vue'
|
import { getCurrentInstance, provide, watch } from 'vue'
|
||||||
import { CHANGE_EVENT } from '@element-plus/constants'
|
import { CHANGE_EVENT } from '@element-plus/constants'
|
||||||
import { useNamespace } from '@element-plus/hooks'
|
import { useNamespace, useOrderedChildren } from '@element-plus/hooks'
|
||||||
import { stepsEmits, stepsProps } from './steps'
|
import { stepsEmits, stepsProps } from './steps'
|
||||||
|
|
||||||
import type { Ref } from 'vue'
|
|
||||||
import type { StepItemState } from './item.vue'
|
import type { StepItemState } from './item.vue'
|
||||||
|
|
||||||
defineOptions({
|
defineOptions({
|
||||||
@ -21,8 +20,11 @@ const props = defineProps(stepsProps)
|
|||||||
const emit = defineEmits(stepsEmits)
|
const emit = defineEmits(stepsEmits)
|
||||||
|
|
||||||
const ns = useNamespace('steps')
|
const ns = useNamespace('steps')
|
||||||
|
const {
|
||||||
const steps: Ref<StepItemState[]> = ref([])
|
children: steps,
|
||||||
|
addChild: addStep,
|
||||||
|
removeChild: removeStep,
|
||||||
|
} = useOrderedChildren<StepItemState>(getCurrentInstance()!, 'ElStep')
|
||||||
|
|
||||||
watch(steps, () => {
|
watch(steps, () => {
|
||||||
steps.value.forEach((instance: StepItemState, index: number) => {
|
steps.value.forEach((instance: StepItemState, index: number) => {
|
||||||
@ -30,7 +32,7 @@ watch(steps, () => {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
provide('ElSteps', { props, steps })
|
provide('ElSteps', { props, steps, addStep, removeStep })
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
() => props.active,
|
() => props.active,
|
||||||
|
Loading…
Reference in New Issue
Block a user