mirror of
https://github.com/element-plus/element-plus.git
synced 2025-08-26 12:32:17 +08:00
refactor(components): [select] modify manuallyRenderSlots
execute (#20854)
* refactor(components): [select] modify `manuallyRenderSlots` execute * refactor(components): [select] modify ’manuallyRenderSlots‘ execute * fix(components): [select] fix render slots attempt when persistent=false * fix: remove duplicate judgments --------- Co-authored-by: Dsaquel <291874700n@gmail.com> Co-authored-by: btea <2356281422@qq.com>
This commit is contained in:
@ -1,7 +1,7 @@
|
||||
// @ts-nocheck
|
||||
import { defineComponent, markRaw, nextTick, ref } from 'vue'
|
||||
import { mount } from '@vue/test-utils'
|
||||
import { afterEach, beforeEach, describe, expect, it, test, vi } from 'vitest'
|
||||
import { afterEach, describe, expect, it, test, vi } from 'vitest'
|
||||
import { EVENT_CODE } from '@element-plus/constants'
|
||||
import { ArrowDown, CaretTop, CircleClose } from '@element-plus/icons-vue'
|
||||
import { usePopperContainerId } from '@element-plus/hooks'
|
||||
@ -311,13 +311,8 @@ const TAG_NAME = `${WRAPPER_CLASS_NAME} .el-tag`
|
||||
|
||||
describe('Select', () => {
|
||||
let wrapper: ReturnType<typeof _mount>
|
||||
beforeEach(() => {
|
||||
// This is convenient for testing the default value label rendering when persistent is false.
|
||||
process.env.RUN_TEST_WITH_PERSISTENT = true
|
||||
})
|
||||
afterEach(() => {
|
||||
document.body.innerHTML = ''
|
||||
delete process.env.RUN_TEST_WITH_PERSISTENT
|
||||
})
|
||||
|
||||
test('create', async () => {
|
||||
@ -1386,6 +1381,9 @@ describe('Select', () => {
|
||||
})
|
||||
|
||||
test('multiple select with collapseTagsTooltip', async () => {
|
||||
// This is convenient for testing the default value label rendering when persistent is false.
|
||||
process.env.RUN_TEST_WITH_PERSISTENT = true
|
||||
|
||||
wrapper = _mount(
|
||||
`
|
||||
<el-select v-model="selectedList" multiple collapseTags collapse-tags-tooltip placeholder="请选择">
|
||||
@ -1433,6 +1431,8 @@ describe('Select', () => {
|
||||
const tags = document.querySelectorAll('.el-select__tags-text')
|
||||
expect(tags.length).toBe(2)
|
||||
expect(tags[1].textContent).toBe(' + 2')
|
||||
|
||||
delete process.env.RUN_TEST_WITH_PERSISTENT
|
||||
})
|
||||
|
||||
test('multiple select with maxCollapseTags', async () => {
|
||||
|
@ -300,7 +300,7 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { computed, defineComponent, provide, reactive, toRefs, watch } from 'vue'
|
||||
import { Fragment, computed, defineComponent, h, nextTick, provide, reactive, toRefs, watchEffect } from 'vue'
|
||||
import { ClickOutside } from '@element-plus/directives'
|
||||
import ElTooltip from '@element-plus/components/tooltip'
|
||||
import ElScrollbar from '@element-plus/components/scrollbar'
|
||||
@ -316,7 +316,7 @@ import { selectKey } from './token'
|
||||
import ElOptions from './options'
|
||||
import { selectProps } from './select'
|
||||
|
||||
import type { VNode } from 'vue';
|
||||
import type { VNode, VNodeNormalizedChildren } from 'vue';
|
||||
import type { SelectContext } from './type'
|
||||
|
||||
const COMPONENT_NAME = 'ElSelect'
|
||||
@ -366,29 +366,27 @@ export default defineComponent({
|
||||
const API = useSelect(_props, emit)
|
||||
const { calculatorRef, inputStyle } = useCalcInputWidth()
|
||||
|
||||
const manuallyRenderSlots = (defaultSlots: VNode[] | undefined) => {
|
||||
const manuallyRenderSlots = (vnodes: VNodeNormalizedChildren) => {
|
||||
// After option rendering is completed, the useSelect internal state can collect the value of each option.
|
||||
// If the persistent value is false, option will not be rendered by default, so in this case,
|
||||
// manually render and load option data here.
|
||||
if (!props.persistent && defaultSlots) {
|
||||
const children = flattedChildren(defaultSlots) as VNode[]
|
||||
children.filter((item) => {
|
||||
// @ts-expect-error
|
||||
return isObject(item) && item!.type.name === 'ElOption'
|
||||
}).forEach(item => {
|
||||
const obj = { ...item.props } as any
|
||||
obj.currentLabel = obj.label || (isObject(obj.value) ? '' : obj.value)
|
||||
API.onOptionCreate(obj)
|
||||
const children = flattedChildren(vnodes) as VNode[]
|
||||
children.filter((item) => {
|
||||
// @ts-expect-error
|
||||
return isObject(item) && item!.type.name === 'ElOption'
|
||||
}).forEach(item => {
|
||||
const obj = { ...item.props } as any
|
||||
obj.currentLabel = obj.label || (isObject(obj.value) ? '' : obj.value)
|
||||
API.onOptionCreate(obj)
|
||||
})
|
||||
}
|
||||
watchEffect(() => {
|
||||
if (!props.persistent) {
|
||||
nextTick(() => {
|
||||
const defaultSlots = h(Fragment, slots.default?.() ?? []).children
|
||||
manuallyRenderSlots(defaultSlots)
|
||||
})
|
||||
}
|
||||
}
|
||||
watch(() => {
|
||||
const currentSlot = slots.default?.()
|
||||
return currentSlot
|
||||
}, (newSlot) => {
|
||||
manuallyRenderSlots(newSlot)
|
||||
}, {
|
||||
immediate: true,
|
||||
})
|
||||
|
||||
provide(
|
||||
|
@ -33,7 +33,7 @@ export const useTree = (
|
||||
}
|
||||
) => {
|
||||
watch(
|
||||
() => props.modelValue,
|
||||
[() => props.modelValue, tree],
|
||||
() => {
|
||||
if (props.showCheckbox) {
|
||||
nextTick(() => {
|
||||
|
Reference in New Issue
Block a user