Vueコンポーネント スモールケース対応カルーセルコンポーネント

必要に応じて直接使用できる、比較的適応性の高い Vue コンポーネントを作成しました。

クリックしてフォローすると、さらに素敵なコンポーネントやコードをお届けします ∠( ᐛ ∠)_

まず効果を見てみましょう。

自動カルーセル、ホバー拡大、ボタン制御などは特別なことではないと思われるかもしれませんが、次にこのコンポーネントのユニークな設計について説明します。

1 つ目はサイズ調整です。コンポーネントは、参照点における親コンポーネントの位置に応じてサイズを調整します。

つまり、親コンポーネントのサイズに関係なく、コンポーネントを常に比較的標準的な形式で表示できます。

矢印の相対的な位置も変わりません。

第二に、このコンポーネントはあらゆるサイズの画像に適応でき、画像サイズが均一でなくても 1 つずつスクロールできます。

次に、実装アイデアについて説明します。

1. まず、回転する画像のパスを格納するために使用される配列 `photoList` がデータ内で定義され、`currentIndex` は現在表示されている画像のインデックスを表します。

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

2. `mounted` フックで、タイマー `this.time` を設定し、3 秒ごとに `moveRight` メソッドをトリガーして、画像が自動的に右に回転するようにします。

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

3. `moveLeft` メソッドと `moveRight` メソッドを使用して画像のインデックスを切り替え、画像を左または右にスクロールします。

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

4. 「stopScroll」メソッドは、マウスがカルーセルコンテナ内に移動したときにタイマー「this.time」をクリアし、画像の自動スクロールを停止するために使用されます。

5. `startScroll` メソッドは、マウスがカルーセル コンテナの外に出たときにタイマー `this.time` を再起動し、画像の自動スクロールを継続するために使用されます。

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

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

6. `@mouseenter` および `@mouseleave` イベントを使用してマウスの出入りイベントをリッスンし、それぞれ `stopScroll` および `startScroll` メソッドを呼び出して、マウスがホバーしているときに画像のスクロールを停止し、マウスを外してもスクロールを続けます。

<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. `watch` を使用して `currentIndex` の変更を監視し、画像が切り替わったときに `.back` 要素の `transform` スタイルを更新します。これにより、画像コンテナが左にスクロールして現在の画像が表示されます。オフセットはコンテナの左側からの子要素の距離を直接読み込むので、画像の幅が違っても毎回正常に回転できます

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

8. スタイルで、コンテンツの表示範囲を制限するために `.room` コンテナを相対的な位置に設定し、画像を収容して水平スクロール効果を実現するために `.back` コンテナを絶対的な位置に設定します。 left` と ` .right` 要素は絶対的に配置され、それぞれ左矢印と右矢印を表し、クリックして画像を切り替えるために使用されます。同時に、「トランジション」を使用して、画像切り替えのアニメーション効果を実現します。

完全なコードを添付します。使用するときは、必ず画像パスを変更してください。

<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>

おすすめ

転載: blog.csdn.net/weixin_47040861/article/details/131877241