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 { describe, expect, test } from 'vitest'
|
||||
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__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 {
|
||||
uid: number | undefined
|
||||
uid: number
|
||||
currentStatus: string
|
||||
setIndex: (val: number) => void
|
||||
calcProgress: (status: string) => void
|
||||
@ -83,6 +83,8 @@ export interface StepItemState {
|
||||
export interface IStepsInject {
|
||||
props: IStepsProps
|
||||
steps: Ref<StepItemState[]>
|
||||
addStep: (item: StepItemState) => void
|
||||
removeStep: (uid: number) => void
|
||||
}
|
||||
|
||||
defineOptions({
|
||||
@ -112,9 +114,7 @@ onMounted(() => {
|
||||
})
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
parent.steps.value = parent.steps.value.filter(
|
||||
(instance) => instance.uid !== currentInstance?.uid
|
||||
)
|
||||
parent.removeStep(stepItemState.uid)
|
||||
})
|
||||
|
||||
const currentStatus = computed(() => {
|
||||
@ -203,11 +203,11 @@ const updateStatus = (activeIndex: number) => {
|
||||
}
|
||||
|
||||
const stepItemState = reactive({
|
||||
uid: computed(() => currentInstance?.uid),
|
||||
uid: currentInstance!.uid,
|
||||
currentStatus,
|
||||
setIndex,
|
||||
calcProgress,
|
||||
})
|
||||
|
||||
parent.steps.value = [...parent.steps.value, stepItemState]
|
||||
parent.addStep(stepItemState)
|
||||
</script>
|
||||
|
@ -5,12 +5,11 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { provide, ref, watch } from 'vue'
|
||||
import { getCurrentInstance, provide, watch } from 'vue'
|
||||
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 type { Ref } from 'vue'
|
||||
import type { StepItemState } from './item.vue'
|
||||
|
||||
defineOptions({
|
||||
@ -21,8 +20,11 @@ const props = defineProps(stepsProps)
|
||||
const emit = defineEmits(stepsEmits)
|
||||
|
||||
const ns = useNamespace('steps')
|
||||
|
||||
const steps: Ref<StepItemState[]> = ref([])
|
||||
const {
|
||||
children: steps,
|
||||
addChild: addStep,
|
||||
removeChild: removeStep,
|
||||
} = useOrderedChildren<StepItemState>(getCurrentInstance()!, 'ElStep')
|
||||
|
||||
watch(steps, () => {
|
||||
steps.value.forEach((instance: StepItemState, index: number) => {
|
||||
@ -30,7 +32,7 @@ watch(steps, () => {
|
||||
})
|
||||
})
|
||||
|
||||
provide('ElSteps', { props, steps })
|
||||
provide('ElSteps', { props, steps, addStep, removeStep })
|
||||
|
||||
watch(
|
||||
() => props.active,
|
||||
|
Loading…
Reference in New Issue
Block a user