前端框架Vue(14)—— 利用 vue 過渡效果(transition)+定時器 實現輪播圖通用元件
序論:
輪播圖 相信都不會陌生,很多的網站都會有,而且實現的方式也是千變萬化,可以利用封裝好的 UI 庫 (bootstrap),
也可以原生的 JS 進行編寫。但是其中,動畫(transition)和定時器都是必不可少的。本文就是利用 vue 自帶的
transition 動畫過渡效果加上定時器編寫輪播圖。
效果:
1、功能分析。
從上面的效果圖中看,有四個基本功能:
1、自動的輪播的功能;
2、點選左右箭頭(pre、next)進行的切換;
3、點選數字切換到對應的圖片的功能。
4、滑鼠懸停、移出控制輪播圖的停、啟。
2、場景介紹、分析。
環境是 vue 元件的形式,輪播圖模組是以元件的形式,內嵌在父元件中。這樣的好處是輪播圖功能,低耦合,複用性高,即插即用。這邊我將輪播圖的元件取名為 Carousel.vue,父元件為 app.vue。
3、原始碼分析。
1、父元件 app.vue。
<template>
<div id="WBAQPage" class="WBAQPage">
<carousel :slides="slides" :inv="invTime"></carousel>
</div>
</template>
<script>
import carousel from '../../components/Carousel.vue'
export default {
data () {
return {
invTime: 2000,
slides: [
{
src:require('../../assets/pic1.jpg'),
title:'xxx1',
},
{
src:require('../../assets/pic2.jpg'),
title:'xxx2'
},
{
src:require('../../assets/pic3.jpg'),
title:'xxx3'
},
{
src:require('../../assets/pic4.jpg'),
title:'xxx4'
}
]
}
},
components: {
carousel
}
}
</script>
<style scoped></style>
父元件中主要有三件事:
1、import 引入子元件進行顯示。
2、將歸納輪播圖屬性的陣列 slides 傳給子元件。
3、將輪播間隔的時間引數 invTime 傳給子元件。
2、子元件 Carousel.vue
<template>
<div class="slide-show" @mouseover="clear" @mouseout="run">
<div class="slide-img">
<a>
<transition name="slide-trans">
<img v-if="isShow" :src="slides[nowIndex].src">
</transition>
<transition name="slide-trans-old">
<img v-if="!isShow" :src="slides[nowIndex].src">
</transition>
</a>
</div>
<h2>{{ slides[nowIndex].title }}</h2>
<ul class="slide-pages">
<li @click="goto(prevIndex)"><</li>
<li v-for="(item, index) in slides" @click="goto(index)">
<a :class="{on: index === nowIndex}">{{ index + 1 }}</a>
</li>
<li @click="goto(nextIndex)">></li>
</ul>
</div>
</template>
<script>
export default {
props: {
slides: {
type: Array,
default: []
},
inv: {
type: Number,
default: 1000
}
},
data () {
return {
nowIndex: 0,
isShow: true
}
},
computed: {
prevIndex () {
if (this.nowIndex === 0) {
return this.slides.length - 1
}
else {
return this.nowIndex - 1
}
},
nextIndex () {
if (this.nowIndex === this.slides.length - 1) {
return 0
}
else {
return this.nowIndex + 1
}
}
},
methods: {
goto (index) {
this.isShow = false
setTimeout(() => {
this.isShow = true
this.nowIndex = index
}, 10)
},
run () {
this.invId = setInterval(() => {
this.goto(this.nextIndex)
}, this.inv)
},
clear () {
clearInterval(this.invId)
}
},
mounted () {
this.run();
}
}
</script>
<style scoped>
.slide-trans-enter-active {
transition: all .5s;
}
.slide-trans-enter {
transform: translateX(900px);
}
.slide-trans-old-leave-active {
transition: all .5s;
transform: translateX(-900px);
}
.slide-show {
position: relative;
margin: 15px 15px 15px 0;
width: 900px;
height: 500px;
overflow: hidden;
}
.slide-show h2 {
position: absolute;
width: 100%;
height: 100%;
color: #fff;
background: #000;
opacity: .5;
bottom: 0;
height: 30px;
text-align: left;
padding-left: 15px;
}
.slide-img {
width: 100%;
}
.slide-img img {
width: 100%;
position: absolute;
top: 0;
left: 0;
}
.slide-pages {
position: absolute;
bottom: 10px;
right: 15px;
}
.slide-pages li {
display: inline-block;
padding: 0 10px;
cursor: pointer;
color: #fff;
}
.slide-pages li .on {
text-decoration: underline;
}
</style>
接下來,我會對上面提到的四個功能對應的方法,進行簡單的分析:
1、圖片的切換(pre、next),實現輪播。
原理:利用切換 img 中的 src 來達到圖片的切換,在之前的父元件中,我們已經對四張圖片的屬性,進行了陣列封裝, 那麼我們只需要不斷改變陣列的下標就能達到目的。如 img 中 :src="slides[0].src"
, 那麼顯示的就是第一張圖片。這樣我們就可以抽象出一個 nowIndex 的變數當做是當前圖片的下表,這樣我們只需要去控制 nowIndex 就能切換。用到的是 goto(index) 的方法。
goto (index) {
this.nowIndex = index
},
首先定義 nowIndex 為 0,所以初始化的時候,顯示的是第一張圖片。當我點選 pre 的時候,
prevIndex () {
if (this.nowIndex === 0) {
return this.slides.length - 1
}
else {
return this.nowIndex - 1
}
},
如果 nowIndex 為 0,那麼現在應該顯示的最後一張圖片。程式碼中 this.slides.length - 1
,不然就是 減1. 上一張圖片。點選 next 同理:
nextIndex () {
if (this.nowIndex === this.slides.length - 1) {
return 0
}
else {
return this.nowIndex + 1
}
}
這邊的一大坑點是,你需要將這兩個方法寫在 計算屬性computed 中會比較的優雅,這樣一旦 nowIndex 改變,就會觸發這兩個事件,返回對應的值。
2、點選數字切換到對應的圖片。
這個的原理和 pre、next 一致,且更加的簡單,因為他不需要進行計算,切換的方法只有一個,就是 goto( index ), 所以這邊你只需要對每個數字繫結 goto(index)的 click 方法。
3、自動輪播功能。
自動輪播,需要用到的就是定時器,即每隔一個時間就呼叫一次 goto(index):
run () {
this.invId = setInterval(() => {
this.goto(this.nextIndex)
}, this.inv)
},
這邊寫了一個 run 的方法,每隔 inv 的時間,就去傳入 nextIndex 。這樣就可以自動的進行圖片切換。
4、滑鼠懸停、移出時進行輪播控制。
@mouseover="clear" @mouseout="run"
當滑鼠移出的時候,可以輪播,那就呼叫 run;如果滑鼠移入,停止輪播,那就清除定時器,clear。
clear () {
clearInterval(this.invId)
}
4、vue 動畫過渡效果
vue 中 transition 可以利用 v-show 和 v-if 進行觸發,我這邊利用的是 v-if 的顯示隱藏觸發動畫。
<transition name="slide-trans">//新的圖片進入
<img v-if="isShow" :src="slides[nowIndex].src">
</transition>
<transition name="slide-trans-old">//舊的圖片移出
<img v-if="!isShow" :src="slides[nowIndex].src">
</transition>
這邊在配合 CSS 中的 transform 平移,實現切換動畫:
.slide-trans-enter-active {
transition: all .5s;
}
.slide-trans-enter {
transform: translateX(900px);//大小需要和 show-img 外框的大小一致
}
.slide-trans-old-leave-active {
transition: all .5s;
transform: translateX(-900px);//大小需要和 show-img 外框的大小一致
}
上面的兩個元件的程式碼可以直接使用,輪播 carousel 元件是獨立的,可擴充套件的,可複用在任何的 vue 專案中。你只需要將圖片的屬性進行自定義,就可以有自己的輪播圖了。