LoginSignup
59
46

More than 5 years have passed since last update.

【Vue.js】transition-groupで縦スクロールのカルーセルを実現

Last updated at Posted at 2019-02-19

完成形(実現したいこと)

自動で縦方向にリストが切り替わるカルーセルを作りたい。
cssで頑張らずにVue.jsのtransitionのみで実現させたい。

ezgif.com-video-to-gif.gif

まずはVue.jsでリスト表示

index.vue
<template>
  <div class="fruit">
    <span v-for="item in items" :key="item.id" class="fruit__list__item">{{ item.title }}</span>
  </div>
</template>

<script>
export default {
  data() {
    return {
      items: [
        { id: 1, title: "apple" },
        { id: 2, title: "banana" },
        { id: 3, title: "orange" },
        { id: 4, title: "peach" },
        { id: 5, title: "plum" },
        { id: 6, title: "grape" }
      ]
    };
  }
};
</script>

最終的には3件表示にしますが、とりあえず全件v-forで表示。
スクリーンショット 2019-02-20 0.44.42.png

リストが動くようにVueの処理を追加

index.vue
<template>
  <!-- itemsをshowItemに変更。他箇所は略。 -->
  <span v-for="item in showItem" :key="item.id" class="fruit__list__item">{{ item.title }}</span>
</template>

<script>
export default {
 // (略)
  created() {
    this.scrollUp();
  },
  computed: {
    showItem() {
      return this.items.slice(0, 3);
    }
  },
  methods: {
    scrollUp() {
      window.setInterval(() => {
        this.items = this.items.concat(this.items.shift());
      }, 2000);
    }
  }
};
</script>
  • created インスタンスが生成された後に1度だけ scrollUp を実行
  • scrollUp で配列の0番目を削除し、配列の後ろに連結することで無限スクロールを実現
  • scrollUpsetInterval することで 2秒に1度配列が変更される
  • showItem 配列の0番目から3番目の3件のみを表示

これで、なめらかな動き以外は、実現したい動きにすることができました。

ezgif.com-video-to-gif (1).gif

transitionでなめらかな動きにする

リストをtransitionさせるときは、 transition-group を使います。

index.vue
<template>
  <div class="fruit">
    <transition-group name="fruit-list" tag="p" class="fruit__list">
      <span v-for="item in showItem" :key="item.id" class="fruit__list__item">{{ item.title }}</span>
    </transition-group>
  </div>
</template>
style.scss
.fruit {
  &__list {
    display: flex;
    flex-direction: column;

    &__item {
      margin: 5px;
      padding: 5px;
      border: 1px solid;
      transition: all 1s;
    }
  }

  &-list-enter {
    opacity: 0;
    transform: translateY(35px);
  }

  &-list-leave-to {
    opacity: 0;
    transform: translateY(-35px);
  }

  &-list-leave-active {
    position: absolute;
  }
}

transition部分はほとんど公式と同じなので詳しくはそちらを参照ください。

注意点としては v-leave-activeposition: absolute を指定しないと
先頭の要素が上に移動しても後続がついてこないため、必須となります。

注意

index.vue
<transition-group name="fruit-list" tag="p" class="fruit__list">
    <span v-for="(item, index) in showItem" :key="index" class="fruit__list__item">{{ item.title }}</span>
</transition-group>

keyをv-forのindexに指定するとエラーになってしまいます。
(わたしは最初やってしまいました。。)

- Do not use v-for index as key on <transition-group> children, this is the same as not using keys.

indexではなく、itemのidなどで指定が必要です。

参考

59
46
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
59
46