これは何?
画像がフェードイン&フェードアウトするサンプル。
作った経緯
勉強のため。
かつ、ネットには動かないサンプルが大量に転がっていて腹がたったから。
今回重視したのは以下2つです。
-
v-for
とv-if
を同時に使いたい時にどうするか理解する - transition によるアニメーション挙動を理解する
そもそも、v-for
と v-if
を同時に使うことは非推奨だとドキュメントに書いてあるのに、
ネットでは同時に使っているサンプルが出てくるので、ドキュメントのことを思い出すまでに時間がかかりました。
スタイリングガイドによると、要は
- フィルタ済みの Object で for を回す
- template 構文を使って、 for と if を分ける
このどちらかにしなければいけないので、今回は後者を選びました。
コード
<template>
<div class="slider-outer">
<div class="slider-inner">
<template v-for="(slide, idx) in slides" :key="idx">
<transition name="fade" mode="in-out">
<img v-if="idx == currentSlide" v-bind:src="slide.img" width="450" height="300">
</transition>
</template>
</div>
<div class="slider-trigger">
<button class="prev" v-on:click="prev()"> < </button>
<button class="next" v-on:click="next()"> > </button>
</div>
</div>
</template>
<script>
export default {
data: function(){
return({
currentSlide: 0,
timerId: 0,
slides: [
{ img: require('./assets/img1.jpg') },
{ img: require('./assets/img2.jpg') },
{ img: require('./assets/img3.jpg') },
{ img: require('./assets/img4.jpg') },
],
})
},
created: function(){
setTimeout(this.autoPlay, 3 * 1000);
},
methods: {
prev: function(){
this.currentSlide--;
if(this.currentSlide == -1){
this.currentSlide = this.slides.length -1;
}
this.cancelTimer();
this.autoPlay();
},
next: function(){
this.currentSlide++;
if(this.currentSlide == this.slides.length){
this.currentSlide = 0;
}
this.cancelTimer();
this.autoPlay();
},
autoPlay: function(){
this.currentSlide++;
if(this.currentSlide == this.slides.length){
this.currentSlide = 0;
}
this.timerId = setTimeout(this.autoPlay, 3 * 1000);
},
cancelTimer: function() {
clearTimeout(this.timerId);
}
},
}
</script>
<style lang="scss">
*, *:before, *:after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
.slider-outer{
position: relative;
width: 100%;
height: 600px;
overflow: hidden;
margin: 0;
}
.slider-inner{
position: relative;
width: 100%;
height: 100%;
background-color: #222222;
img {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
display: block;
width: 100%;
height: auto;
}
}
.slider-trigger{
position: absolute;
top: 50%;
transform: translateY(-50%);
width: 100%;
z-index: 10;
button {
position: absolute;
background-color: transparent;
border: none;
cursor: pointer;
outline: none;
padding: 0;
appearance: none;
font-size: 24px;
color: #FFFFFF;
}
.next { right: 30px; }
.prev { left: 30px; }
}
.fade-enter-active {
transition: all 1s ease;
position: absolute;
z-index: 2;
}
.fade-leave-active {
transition: all 1s ease;
position: absolute;
z-index: 3;
}
.fade-enter { opacity: 0; }
.fade-leave-to { opacity: 0; }
</style>
最後に
次回からは先にドキュメントとスタイルガイドを読むことにします。