Vue component small case-adaptive carousel component

I wrote a relatively adaptable Vue component, which can be used directly if needed.

Click to follow and we will bring you more fancy components and codes ∠( ᐛ  ∠)_

Let’s look at the effect first:

Automatic carousel, hover magnification, and button control may seem like nothing special. Next, I will talk about the unique design of this component.

The first is size adaptation. The component will adjust its size according to the position of the parent component at the reference point.

That is to say, no matter the size of the parent component, the component can always be displayed in a relatively normal form.

Not even the relative position of the arrows changes.

Secondly, this component can adapt to pictures of any size, even if the picture size is not uniform, it can still scroll one by one.

Next, let’s talk about the implementation ideas.

1. First, the `photoList` array is defined in data, which is used to store the path of the pictures to be rotated, and `currentIndex` represents the index of the currently displayed picture.

  data() {
    return {
      photoList: [photo, photo2, photo, photo, photo2, photo2, photo],
      currentIndex: 0,
      time: null,
    };
  },

2. In the `mounted` hook, set a timer `this.time` and trigger the `moveRight` method every 3 seconds, so that the picture automatically rotates to the right.

  mounted() {
    this.time = setInterval(() => {
      if (this.currentIndex < photo.length) {
        this.moveRight();
      }
    }, 3000);
  },

3. The `moveLeft` and `moveRight` methods are used to switch the index of the image, making the image scroll left or right.

    moveLeft() {
      if (this.currentIndex > 0) {
        this.currentIndex = this.currentIndex - 1;
      }
    },
    moveRight() {
      if (this.currentIndex < this.photoList.length - 1) {
        this.currentIndex = this.currentIndex + 1;
      }
    },

4. The `stopScroll` method is used to clear the timer `this.time` and stop the automatic scrolling of images when the mouse moves into the carousel container.

5. The `startScroll` method is used to restart the timer `this.time` and continue the automatic scrolling of the image when the mouse moves out of the carousel container.

    //鼠标移入停止滚动
    stopScroll() {
      clearInterval(this.time);
      console.log("停止滚动");
    },

    //鼠标移出继续滚动
    startScroll() {
      this.time = setInterval(() => {
        if (this.currentIndex < photo.length) {
          this.moveRight();
        }
      }, 3000);
      console.log("继续滚动");
    },

6. Use the `@mouseenter` and `@mouseleave` events to listen to the mouse entry and exit events, and call the `stopScroll` and `startScroll` methods respectively to stop the picture from scrolling when the mouse is hovering, and to continue scrolling when the mouse is moved out.

<template>
  <div class="room" @mouseenter="stopScroll" @mouseleave="startScroll">
    <div class="back">
      <img v-for="(item, index) in photoList" :key="index" :src="item" />
    </div>
    <span class="left" @click="moveLeft">《</span>
    <span class="right" @click="moveRight">》</span>
  </div>
</template>

7. Use `watch` to monitor changes in `currentIndex`, and update the `transform` style of the `.back` element when the image is switched, so that the image container scrolls to the left to display the current image, since the offset is read directly The distance of the child element relative to the left side of the container, so even if the image width is different, it can rotate normally every time .

  watch: {
    currentIndex(newValue) {
      const parentElement = document.querySelector(".back");
      const childrenElement = parentElement.children;
      parentElement.style.transform =
        "translateX(" + -childrenElement[newValue].offsetLeft + "px)";
    },
  },

8. In the style, set the `.room` container to be relatively positioned to limit the display range of its content; set the `.back` container to be absolutely positioned to accommodate pictures and achieve a horizontal scrolling effect; set `.left` and ` The .right` element is absolutely positioned, representing left and right arrows respectively, which are used to switch pictures by clicking on them. At the same time, use `transition` to achieve the animation effect of picture switching.

Attached is the complete code. Remember to modify the image path when using it:

<template>
  <div class="room" @mouseenter="stopScroll" @mouseleave="startScroll">
    <div class="back">
      <img v-for="(item, index) in photoList" :key="index" :src="item" />
    </div>
    <span class="left" @click="moveLeft">《</span>
    <span class="right" @click="moveRight">》</span>
  </div>
</template>

<script>
import photo from "../../image/02.jpg";
import photo2 from "../../image/02 - 副本.jpg";
export default {
  data() {
    return {
      photoList: [photo, photo2, photo, photo, photo2, photo2, photo],
      currentIndex: 0,
      time: null,
    };
  },
  methods: {
    moveLeft() {
      if (this.currentIndex > 0) {
        this.currentIndex = this.currentIndex - 1;
      }
    },
    moveRight() {
      if (this.currentIndex < this.photoList.length - 1) {
        this.currentIndex = this.currentIndex + 1;
      }
    },
    stopScroll() {
      clearInterval(this.time);
      console.log("停止滚动");
    },

    //鼠标移出继续滚动
    startScroll() {
      this.time = setInterval(() => {
        if (this.currentIndex < photo.length) {
          this.moveRight();
        }
      }, 3000);
      console.log("继续滚动");
    },
  },
  mounted() {
    this.time = setInterval(() => {
      if (this.currentIndex < photo.length) {
        this.moveRight();
      }
    }, 3000);
  },
  watch: {
    currentIndex(newValue) {
      const parentElement = document.querySelector(".back");
      const childrenElement = parentElement.children;
      parentElement.style.transform =
        "translateX(" + -childrenElement[newValue].offsetLeft + "px)";
    },
  },
};
</script>

<style scoped>
.room {
  width: 100%;
  height: 100%;
  overflow: hidden;
  position: relative;
}
.back {
  height: 100%;
  display: flex;
  align-items: center;
  flex-wrap: nowrap;
  transition: 0.5s;
}
.back img {
  height: 80%;
  margin: 0 1%;
  transition: 0.5s;
}
.back img:hover {
  height: 100%;
  margin: 0 0;
}
.room span {
  position: absolute;
  top: 50%;
  color: red;
  font-size: 30px;
  font-weight: 700;
  transform: translateY(-50%);
  cursor: pointer;
}
.left {
  left: 0%;
}
.right {
  right: 0%;
}
</style>

Guess you like

Origin blog.csdn.net/weixin_47040861/article/details/131877241