小程序之自行封装轮播图组件
案例展示:
先上代码:
子组件HTML部分:
<view class="ul">
<view :class="direction == 'column' ? 'columnLi' : 'li'" id="liId" :animation="animate">
<image id="imageId" @touchend="touchEnd" @touchmove="touchMove" @touchstart="touchStart" :src="item" mode="aspectFill"
v-for="(item,index) of bannerList" :key="index"></image>
</view>
<!-- 点索引 -->
<view v-if="dotShowOne" :class="direction == 'column' ? 'column' : 'dotShow'">
<view class="dot" :class="{'activeDot' : dotIndex == index}" v-for="(item,index) of dotList" :key="index"></view>
</view>
<!-- 分数索引 -->
<view class="dotShow" v-if="dotShowtwo">
{{dotIndex+1}} / {{length}}
</view>
</view>
上面代码中,可以根据自己的想要的轮播方向,进行轮播,只要传入参数direction : ‘column’ / ‘row’;
也可以选择索引点的样式.
子组件JS部分:
<script>
export default {
props: {
bannerList: {
type: Array,
default () {
return []
}
},
// 逗点索引方向 默认是row 可选column
direction: {
type: String,
default: 'row'
},
// 样式选择
dotShow:{
type: Boolean,
default: true
}
},
data() {
return {
// 开始X坐标
startX: 0,
// 开始的Y坐标
startY: 0,
// 结束X坐标
endX: 0,
// 结束的Y坐标
endY: 0,
// 当前image索引
currentIndex: 0,
// 自动轮播定时器
timer: '',
// 当前图片的width
imageWidth: 0,
// 当前图片的高度
imageHeight: 0,
// 运行的距离
imageLeft: 0,
imageTop: 0,
// 动画
animate: {},
// 索引点
dotList: [],
// 长度
length: 0,
// 索引点下标
dotIndex: 0,
// 新的bannerList
newBannerList: this.bannerList
}
},
//第一次加载
created() {
this.length = this.bannerList.length
this.dotList = this.length
this.init()
},
//页面显示
onShow() {},
//方法
methods: {
// 初始方法
init() {
this.newBannerList.push(this.bannerList[0])
this.newBannerList.push(this.bannerList[this.length - 1])
this.timer = setInterval(this.slide, 3000);
},
// 动画方法
animationFn(duration, currentIndex) {
var animation = uni.createAnimation({
duration: duration,
timingFunction: 'ease',
delay: 0
});
if (this.direction == 'column') {
this.imageTop = -this.imageHeight * (this.currentIndex)
animation.translateY(this.imageTop).step();
this.animate = animation.export();
} else {
this.imageLeft = -this.imageWidth * (this.currentIndex);
// console.log('this.imageLeft ==>'+this.currentIndex,this.imageLeft)
animation.translateX(this.imageLeft).step();
this.animate = animation.export();
}
},
// 实现自动轮播方法
slide() {
const query = uni.createSelectorQuery().in(this);
query.select('#imageId').boundingClientRect((res) => {
this.imageWidth = res.width;
this.imageHeight = res.height;
}).exec();
this.currentIndex++;
this.dotIndex = this.currentIndex;
// console.log(this.currentIndex)
if (this.currentIndex === parseInt(this.newBannerList.length - 2)) {
this.dotIndex = 0;
};
if (this.currentIndex === parseInt(this.newBannerList.length - 1)) {
this.dotIndex = 0;
this.currentIndex = 0;
const queryli = uni.createSelectorQuery().in(this);
queryli.select('#liId').boundingClientRect((res) => {
res.left = this.imageWidth
}).exec();
this.animationFn(5, this.currentIndex)
} else {
this.animationFn(1000, this.currentIndex)
}
},
touchStart(e) {
this.startX = e.touches[0].pageX;
this.startY = e.touches[0].pageY;
clearInterval(this.timer)
},
touchMove(e) {
this.endX = e.touches[0].pageX;
this.endY = e.touches[0].pageY;
},
touchEnd(e) {
if (this.startX - this.endX > 0 || this.startY - this.endY > 0) {
this.currentIndex++;
this.dotIndex = this.currentIndex
this.animationFn(1000, this.currentIndex)
console.log(this.currentIndex)
if (this.currentIndex === parseInt(this.newBannerList.length - 2)) {
this.dotIndex = 0
}
if (this.currentIndex === parseInt(this.newBannerList.length - 1)) {
this.dotIndex = 0
this.currentIndex = 0;
this.animationFn(0, this.currentIndex)
}
} else {
--this.currentIndex;
this.dotIndex = this.currentIndex
console.log(this.currentIndex)
this.animationFn(1000, this.currentIndex)
if (this.currentIndex < 0) {
this.currentIndex = parseInt(this.newBannerList.length - 2);
this.dotIndex = 0
this.animationFn(0, this.currentIndex)
}
}
clearInterval(this.timer)
this.timer = setInterval(this.slide, 3000)
},
},
//页面隐藏
onHide() {},
//页面卸载
onUnload() {},
//页面下来刷新
onPullDownRefresh() {},
//页面上拉触底
onReachBottom() {},
//用户点击分享
onShareAppMessage(e) {}
}
</script>
本人是通过uni.createAnimation()来实现动画效果的.
子组件CSS部分:
<style lang="scss" scoped>
@import "@/style/mixin.scss";
.ul {
width: 100%;
min-height: 667upx;
overflow: hidden;
position: relative;
left: 0;
top: 0;
.columnLi {
position: absolute;
top: 0;
left: 0;
width: 100%;
>image {
flex-shrink: 0;
width: 100%;
min-height: 667upx;
}
}
.li {
display: flex;
position: absolute;
top: 0;
left: 0;
width: 100%;
// height: 100%;
>image {
flex-shrink: 0;
width: 100%;
min-height: 667upx;
}
}
.dotShow {
display: flex;
justify-content: center;
position: absolute;
bottom: 20upx;
left: 0;
right: 0;
color: #fff;
.dot {
width: 20upx;
height: 20upx;
margin: 0 10upx;
border-radius: 50%;
background-color: aliceblue;
}
.activeDot {
background-color: brown;
}
}
.column {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
position: absolute;
top: 50%;
bottom: 0upx;
right: 0;
margin-top: -332upx;
width: 50upx;
.dot {
width: 20upx;
height: 20upx;
margin: 10upx;
border-radius: 50%;
background-color: aliceblue;
}
.activeDot {
background-color: brown;
}
}
}
</style>
父组件的调用 :
<template>
<view>
<my-slide-show :bannerList="bannerList" direction="row" :dotShow="true"></my-slide-show>
</view>
</template>
<script>
import mySlideShow from '@/components/common/mySlideShow.vue';
export default{
components:{
mySlideShow
},
data(){
return{
bannerList: [
"http://pic51.nipic.com/file/20141025/8649940_220505558734_2.jpg",
"http://img.redocn.com/sheying/20140731/qinghaihuyuanjing_2820969.jpg",
"http://photocdn.sohu.com/20111207/Img328215620.jpg",
"http://pic51.nipic.com/file/20141025/8649940_220505558734_2.jpg",
"http://img.redocn.com/sheying/20140731/qinghaihuyuanjing_2820969.jpg",
],
}
}
}
</script>
<style>
</style>
作为一个前端大白,因为想自己学习封装一下小程序的swiper,便自己写了一个插件.有兴趣的大白们,可以拿去练手. – 大宝