fix(components): [carousel] two length transform optimize (#12174)

* fix(components): [carousel] two length transform optimize

* fix(components): [carousel] default init function slot

* fix(components): [carousel] cancel optimize when loop is false

* fix(components): [carousel] filter card type

* fix: test

* style: code lint

* fix: cardtype

* fix: remove test code

* fix: act index

* feat: use flattedchildren

* fix: code lint

* fix: rename and add comment
This commit is contained in:
井柏然
2023-10-11 19:32:26 +08:00
committed by GitHub
parent e32cef1d1b
commit d88cb758d8
3 changed files with 43 additions and 2 deletions

View File

@@ -249,7 +249,6 @@ describe('Carousel', () => {
})
await nextTick()
expect(items[0].classList.contains('is-active')).toBeTruthy()
const container = wrapper.find<HTMLElement>(

View File

@@ -39,11 +39,13 @@
</ElIcon>
</button>
</transition>
<PlaceholderItem />
<slot />
</div>
<ul v-if="indicatorPosition !== 'none'" :class="indicatorsClasses">
<li
v-for="(item, index) in items"
v-show="isTwoLengthShow(index)"
:key="index"
:class="[
ns.e('indicator'),
@@ -94,6 +96,8 @@ const {
setActiveItem,
prev,
next,
PlaceholderItem,
isTwoLengthShow,
throttledArrowClick,
throttledIndicatorHover,
} = useCarousel(props, emit, COMPONENT_NAME)

View File

@@ -1,17 +1,19 @@
import {
computed,
getCurrentInstance,
isVNode,
onBeforeUnmount,
onMounted,
provide,
ref,
shallowRef,
unref,
useSlots,
watch,
} from 'vue'
import { throttle } from 'lodash-unified'
import { useResizeObserver } from '@vueuse/core'
import { debugWarn, isString } from '@element-plus/utils'
import { debugWarn, flattedChildren, isString } from '@element-plus/utils'
import { useOrderedChildren } from '@element-plus/hooks'
import { carouselContextKey } from './constants'
@@ -35,12 +37,15 @@ export const useCarousel = (
'ElCarouselItem'
)
const slots = useSlots()
// refs
const activeIndex = ref(-1)
const timer = ref<ReturnType<typeof setInterval> | null>(null)
const hover = ref(false)
const root = ref<HTMLDivElement>()
const containerHeight = ref<number>(0)
const isItemsTwoLength = ref(true)
// computed
const arrowDisplay = computed(
@@ -79,6 +84,11 @@ export const useCarousel = (
handleIndicatorHover(index)
}, THROTTLE_TIME)
const isTwoLengthShow = (index: number) => {
if (!isItemsTwoLength.value) return true
return activeIndex.value <= 1 ? index <= 1 : index > 1
}
function pauseTimer() {
if (timer.value) {
clearInterval(timer.value)
@@ -210,11 +220,36 @@ export const useCarousel = (
containerHeight.value = height
}
function PlaceholderItem() {
// fix: https://github.com/element-plus/element-plus/issues/12139
const defaultSlots = slots.default?.()
if (!defaultSlots) return null
const flatSlots = flattedChildren(defaultSlots)
const carouselItemsName = 'ElCarouselItem'
const normalizeSlots = flatSlots.filter((slot) => {
return isVNode(slot) && (slot.type as any).name === carouselItemsName
})
if (normalizeSlots?.length === 2 && props.loop && !isCardType.value) {
isItemsTwoLength.value = true
return normalizeSlots
}
isItemsTwoLength.value = false
return null
}
// watch
watch(
() => activeIndex.value,
(current, prev) => {
resetItemPosition(prev)
if (isItemsTwoLength.value) {
current = current % 2
prev = prev % 2
}
if (prev > -1) {
emit('change', current, prev)
}
@@ -287,6 +322,7 @@ export const useCarousel = (
items,
isVertical,
containerStyle,
isItemsTwoLength,
handleButtonEnter,
handleButtonLeave,
handleIndicatorClick,
@@ -295,6 +331,8 @@ export const useCarousel = (
setActiveItem,
prev,
next,
PlaceholderItem,
isTwoLengthShow,
throttledArrowClick,
throttledIndicatorHover,
}