element-ui element-plus carousel - 分析

main源代码地址
item源代码地址

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
      }
    }
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值