需要解決的問題
近幾日一直在看怎樣製作微信小程序的swiper輪播圖。因爲我既需要生成小程序的代碼,也需要生成H5版代碼,如果編寫兩套效率會比較低下,所以選擇了uni-app。
uni-app
已經在基礎組件swiper中已經直接支持了輪播動畫。
我主要需要解決的是以下幾個問題:
- ①在swiper中怎樣添加css3流行的
animate.css
動畫。 - ②添加好後如果滑動了輪播圖,怎樣能保證下一屏的動畫不自動播放。
- ③怎樣能實現輪播圖的無限循環播放。
- ④怎樣能實現,當用戶點擊一個按鈕之後,可以跳轉到指定的
swiper-item
中。也就是跳轉到指定的屏。 - ⑤小程序和H5版的代碼會生成一個頭部,在H5版中需要隱藏掉導航欄。
以下就是我整個製作的思路過程,僅供參考。另外,代碼是uni-app
開發,所以在小程序中和H5中測試都沒有問題。另外爲了方便小程序
開發同學瞭解,會提供小程序
版代碼和uni-app
代碼供參考。
代碼實現
在H5開發中經常使用的就是animate.css。在微信中自然是支持的,因爲微信會對上傳的小程序有大小限制,所以這裏我使用了一個極簡化的animate.css
,其中刪掉了很多-webkit-animation
開頭的css3。因爲我們只需要在小程序和H5中運行,這樣做影響也不大。如果需要的話,可以從下面的代碼中獲取。
我們先來看下代碼:
<template>
<view class="content">
<button type="primary" @tap="goChange">跳轉到第二屏</button>
<swiper class="content-swiper" :vertical="true" :indicator-dots="true" :autoplay="false" :interval="3000" :duration="1000" @change="changeSwiper" @animationfinish="changeFinish" :current-item-id="item_id" circular="true">
<swiper-item item-id="slide0">
<view class="swiper-item">
<image src="../../static/uni.png" :class="animate_0"></image>
</view>
</swiper-item>
<swiper-item item-id="slide1">
<view class="swiper-item">
<image src="../../static/uni.png" :class="animate_1"></image>
</view>
</swiper-item>
<swiper-item item-id="slide2">
<view class="swiper-item">
<image src="../../static/uni.png" :class="animate_2"></image>
</view>
</swiper-item>
<swiper-item item-id="slide3">
<view class="swiper-item">
<image src="../../static/uni.png" :class="animate_3"></image>
</view>
</swiper-item>
</swiper>
</view>
</template>
<script>
export default {
data() {
return {
item_id: 'slide2',
animate_0: 'animated swing',
animate_1: '',
animate_2: '',
animate_3: ''
}
},
onLoad() {
},
methods: {
changeSwiper(event){ // 清空除了當前swiper以外的所有動畫
let current = event.detail.current; // 當前頁下標
this.item_id = 'slide'+current; // 這裏必須記錄,否則只能跳轉一次
switch (current){
case 0:
this['animate_1'] = this['animate_2'] = this['animate_3'] = '';
break;
case 1:
this['animate_0'] = this['animate_2'] = this['animate_3'] = '';
break;
case 2:
this['animate_0'] = this['animate_1'] = this['animate_3'] = '';
break;
case 3:
this['animate_0'] = this['animate_1'] = this['animate_2'] = '';
break;
}
},
changeFinish(event){ // swiper動畫完成之後,給當前swiper添加動畫效果
let current = event.detail.current;
switch(current){
case 0:
this['animate_0'] = 'animated swing';
break;
case 1:
this['animate_1'] = 'animated shake';
break;
case 2:
this['animate_2'] = 'animated tada';
break;
case 3:
this['animate_3'] = 'animated heartBeat';
break;
}
},
goChange(){
this.item_id = 'slide1';
}
}
}
</script>
<style lang="scss">
@import '../../common/animate.css';
.content {
text-align: center;
.content-swiper{
height: 100vh;
image{
height: 200upx;
width: 200upx;
margin-top: 200upx;
}
}
}
</style>
- 首先
uni-app
支持sass。在css中直接引入了簡潔版animate.css
。問題① - 之後通過查看文檔,發現
circular
這個參數可以實現類似H5頁面使用swiper.jsloop
參數的功能。這裏我掉到了uni-app
和微信小程序
文檔描述的坑中。因爲一直在找loop
(循環)這個參數,我甚至都以爲實現不了這個無限循環的功能了呢。原來小程序
中這個參數叫做circular
(圓形)。o(╯□╰)o 問題③ - 因爲我這裏要實現一個豎屏的滑動效果,所以將參數
vertical
設置爲true
。 - 在
uni-app
中,通過change
事件,可以監聽每一個輪播屏的改變。在這個事件中,我記錄的當前屏的下標current
。然後將非當前屏的全部css3動畫取消掉。最後在animationfinish
事件中,當swiper
滑動動畫結束後,給當前屏的元素添加css3動畫。問題② - 在
uni-app
中有個current-item-id
參數,代表當前所在滑塊的item-id
。這個文檔我看了好久,才明白。原來是需要在swiper-item
中指定上item-id
。然後當用戶點擊事件觸發時,修改綁定到current-item-id
上的值即可。我的代碼初始化時指定到了item-id
爲slide2
這一屏上。問題④ - 最後一個問題時
uni-app
中隱藏掉H5導航欄。只需要在pages.json
中設置titleNView
爲false
即可。
我將代碼託管到了騰訊雲開發者平臺,需要的話可以參考。在代碼目錄unpackage/dist/build/h5
中,就是生成好的H5版頁面。需要注意的是,要部署到web服務器使用,不支持本地file協議打開。
微信小程序代碼
<!--index.wxml-->
<view class="container">
<button bindtap='goChange'>跳轉到</button>
<swiper vertical="true" circular="true" current="{{currentId}}" indicator-dots="true" bindchange="changeSwiper" bindanimationfinish="changeFinish">
<swiper-item>
<image src='../../static/uni.png' class='animated {{animate_0}}'></image>
</swiper-item>
<swiper-item>
<image src='../../static/uni.png' class='animated {{animate_1}}'></image>
</swiper-item>
<swiper-item>
<image src='../../static/uni.png' class='animated {{animate_2}}'></image>
</swiper-item>
</swiper>
</view>
//index.js
const app = getApp()
Page({
data: {
currentId: 0,
animate_0: 'swing',
animate_1: '',
animate_2: ''
},
onLoad: function() {
},
goChange: function() {
this.setData({
currentId: 2
});
},
changeSwiper: function(event) {
let current = event.detail.current;
switch (current) {
case 0:
this.setData({
animate_1: '',
animate_2: ''
});
break;
case 1:
this.setData({
animate_0: '',
animate_2: ''
});
break;
case 2:
this.setData({
animate_0: '',
animate_1: ''
});
break;
}
},
changeFinish: function(event) {
let current = event.detail.current;
switch (current) {
case 0:
this.setData({
animate_0: 'swing',
});
break;
case 1:
this.setData({
animate_1: 'shake',
});
break;
case 2:
this.setData({
animate_2: 'tada',
});
break;
}
}
})