elementui 走马灯卡片化,三张变五张

682 阅读1分钟

采用vue2+element-ui,将elementui中carousel中item.vue组件内容复制创建新的swiper组件,进行二次封装,实现图片堆叠三张变五张,图片数量可以多于五张 父组件

 <el-carousel
          :interval="3000"
          type="card"
          height="440px"
          @change="handleCarouselChange"
          ref="carousel"
          arrow="never"
          indicator-position="none"
        >
          <Swiper v-for="(item, i) in page8List" :key="i">
            <div class="imgBox">
              <img class="imgItem" :src="item.bg" alt srcset />
            </div>
          </Swiper>
</el-carousel>

子组件

<template>
  <div
    v-show="ready"
    class="el-carousel__item"
    :class="{
      'is-active': active,
      'el-carousel__item--card': $parent.type === 'card',
      'is-in-stage': inStage,
      specialIndex: specialIndex,
      'is-hover': hover,
      'is-animating': animating,
    }"
    @click="handleItemClick"
    :style="itemStyle"
  >
    <div v-if="$parent.type === 'card'" v-show="!active" class="el-carousel__mask"></div>
    <slot></slot>
  </div>
</template>
<script>
import { autoprefixer } from "element-ui/src/utils/util";
const CARD_SCALE = 0.83;
export default {
  name: "ElCarouselItem",
  props: {
    name: String,
    label: {
      type: [String, Number],
      default: ""
    }
  },

  data() {
    return {
      hover: false,
      translate: 0,
      scale: 1,
      active: false,
      ready: false,
      inStage: false,
      specialIndex: false,
      animating: false,
      zIndex: 0
    };
  },
  created() {
    this.$parent && this.$parent.updateItems();
  },

  destroyed() {
    this.$parent && this.$parent.updateItems();
  },

  methods: {
    processIndex(index, activeIndex, length) {
      if (activeIndex === 0 && index === length - 1) {
        return -1;
      } else if (activeIndex === length - 1 && index === 0) {
        return length;
      } else if (index < activeIndex - 2 && activeIndex - index >= length / 2) {
        let num = length - activeIndex;
        if (num <= 3 && 3 - num > index) {
          return length + index;
        }
        return length + 2;
      } else if (index < activeIndex - 1 && activeIndex - index >= length / 2) {
        return length + 1;
      } else if (index > activeIndex + 2 && index - activeIndex >= length / 2) {
        if (activeIndex < 3) {
          return activeIndex - (length - (index - activeIndex));
        }
      }
      return index;
    },

    calcCardTranslate(index, activeIndex) {
      const parentWidth = this.$parent.$el.offsetWidth;
      if (index == activeIndex) {
        return parentWidth * 0.28;
      } else if (this.inStage) {
        let num = index - activeIndex;
        if (num > 0) return parentWidth * (0.3 + 0.12 * num);
        else return parentWidth * (0.12 * (num + 2));
      } else if (index < activeIndex) {
        return (-(1 + CARD_SCALE) * parentWidth) / 4;
      } else {
        return ((3 + CARD_SCALE) * parentWidth) / 4;
      }
    },

    calcTranslate(index, activeIndex, isVertical) {
      const distance = this.$parent.$el[
        isVertical ? "offsetHeight" : "offsetWidth"
      ];
      return distance * (index - activeIndex);
    },

    translateItem(index, activeIndex, oldIndex) {
      const parentType = this.$parent.type;
      const parentDirection = this.parentDirection;
      const length = this.$parent.items.length;
      if (parentType !== "card" && oldIndex !== undefined) {
        this.animating = index === activeIndex || index === oldIndex;
      }
      index = this.processIndex(index, activeIndex, length);
      if (parentType === "card") {
        if (parentDirection === "vertical") {
          console.warn(
            "[Element Warn][Carousel]vertical direction is not supported in card mode"
          );
        }
        this.inStage = Math.round(Math.abs(index - activeIndex)) <= 2;
        this.active = index === activeIndex;
        this.translate = this.calcCardTranslate(index, activeIndex);
        this.zIndex = Math.abs(activeIndex - index); 
        this.scale = this.active
          ? 1
          : this.inStage
          ? this.zIndex == 1
            ? 0.9
            : 0.8
          : 0.5; 
      } else {
        this.active = index === activeIndex;
        const isVertical = parentDirection === "vertical";
        this.translate = this.calcTranslate(index, activeIndex, isVertical);
      }
      this.ready = true;
    },

    handleItemClick() {
      const parent = this.$parent;
      if (parent && parent.type === "card") {
        const index = parent.items.indexOf(this);
        parent.setActiveItem(index);
      }
    }
  },

  computed: {
    parentDirection() {
      return this.$parent.direction;
    },

    itemStyle() {
      const translateType =
        this.parentDirection.value === "vertical" ? "translateY" : "translateX";
      const value = `${translateType}(${this.translate}px) scale(${this.scale})`;
      const style = {
        transform: value,
        zIndex: 10 - this.zIndex
      };
      return autoprefixer(style);
    }
  }
};
</script>
<style scoped>

</style>