完成形(実現したいこと)
自動で縦方向にリストが切り替わるカルーセルを作りたい。
cssで頑張らずにVue.jsのtransitionのみで実現させたい。
まずは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で表示。
リストが動くように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番目を削除し、配列の後ろに連結することで無限スクロールを実現 -
scrollUp
でsetInterval
することで 2秒に1度配列が変更される -
showItem
配列の0番目から3番目の3件のみを表示
これで、なめらかな動き以外は、実現したい動きにすることができました。
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-active
に position: 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などで指定が必要です。