version:element-plus 1.0.1-beta.0
item
<template>
<div
v-show="data.ready"
class="el-carousel__item"
:class="{
'is-active': data.active,
'el-carousel__item--card': type === 'card',
'is-in-stage': data.inStage,
'is-hover': data.hover,
'is-animating': data.animating,
}"
:style="itemStyle"
@click="handleItemClick"
>
<div
v-if="type === 'card'"
v-show="!data.active"
class="el-carousel__mask"
></div>
<slot></slot>
</div>
</template>
<script lang="ts">
import {
defineComponent,
reactive,
onMounted,
inject,
computed,
toRefs,
getCurrentInstance,
} from 'vue'
import {
autoprefixer,
PartialCSSStyleDeclaration,
} from '@element-plus/utils/util'
import {
InjectCarouselScope, ICarouselItemProps } from './carousel'
const CARD_SCALE = 0.83
export default defineComponent({
name: 'ElCarouselItem',
props: {
name: {
type: String, default: '' },
label: {
type: [String, Number],
default: '',
},
},
setup(props: ICarouselItemProps) {
// instance
const instance = getCurrentInstance()
instance.uid
// data
const data = reactive({
hover: false,
translate: 0,
scale: 1,
active: false,
ready: false,
inStage: false,
animating: false,
})
// inject
const injectCarouselScope: InjectCarouselScope = inject(
'injectCarouselScope',
)
// computed
const parentDirection = computed(() => {
return injectCarouselScope.direction
})
const itemStyle = computed(() => {
// translate 根据父组件中传递过来的direction是否是垂直来决定
const translateType =
parentDirection.value === 'vertical' ? 'translateY' : 'translateX'
const value = `${
translateType}(${
data.translate}px) scale(${
data.scale})`
const style: PartialCSSStyleDeclaration = {
transform: value,
}
// 自动添加前缀
return autoprefixer(style)
})
// methods
/**
* @description:
* @param {number} index
* @param {number} activeIndex
* @param {number} length
* @return {*}
*/
function processIndex(index, activeIndex, length) {
// 如果activeIndex是第一张轮播 && 当前轮播图是最后一张
if (activeIndex === 0 && index === length - 1) {
return -1
}
// 如果是最后一张轮播 && 当前轮播图是第一张
else if (activeIndex === length - 1 && index === 0) {
return length
}
// 当前轮播图在左侧
// 当前轮播图和activeIndex之间隔了1张以上 && 当前轮播图和activeIndex之间隔了总轮播图数组长度一半以上
else if (index < activeIndex - 1 && activeIndex - index >= length / 2) {
return length + 1
}
// 当前轮播图在右侧
else if (index > activeIndex + 1 && index - activeIndex >= length / 2) {
return -2
}
return index
}
/**
* @description: 计算card类型当前index到activeI之间需要translate的像素
* @param {*} index
* @param {*} activeIndex
* @return {*}
*/
function calcCardTranslate(index, activeIndex) {
// 拿到父组件的最外层容器的宽度
const parentWidth = injectCarouselScope.offsetWidth.value
// 如果在台上
if (data.inStage) {
// index - activeIndex <= 1
// 2 - CARD_SCALE = 1.17
// 分成四份 中间激活的占一半 左右各占1/4
return (
(parentWidth * ((2 - CARD_SCALE) * (index - activeIndex) + 1)) / 4
)
}
// 在左侧
else if (index < activeIndex) {
return (-(1 + CARD_SCALE) * parentWidth) / 4
} else {
return ((3 + CARD_SCALE) * parentWidth) / 4
}
}