vue2版本希望能帮到你
首先看的是轮播图组件:
<template>
<div class="swipe-banner">
<div class="my-swipe">
<div class="swipe_trank" style="width: 1500px;" ref="imgBox" @transitionend="animateEnd"
@touchstart="TouchStart" @touchmove="TouchMove" @touchend="TouchEnd">
<div class="swipe-item" style="width: 100vw">
<img src="http://43.138.15.137:4000//uploads/banner/9c3c5330-9267-11ee-9221-2175bc63238c.jpg"
v-if="imgfalg" class="img">
<img src="https://img14.360buyimg.com/n0/jfs/t1/131776/9/23287/325305/621f295fE9dc6a3ce/117b4d1ed262266a.jpg"
alt="" v-else>
</div>
<div class="swipe-item" style="width: 100vw;" v-for="item, index in swipeList" :key="index">
<img :src="'http://43.138.15.137:4000/' + item.img" v-if="imgfalg" class="img">
<img :src="item" alt="" v-else>
</div>
<div class="swipe-item" style="width: 100vw;">
<img src=" http://43.138.15.137:4000//uploads/banner/ed9d6b20-8f4b-11ee-9ff0-8d10ce4a0674.png"
v-if="imgfalg" class="img">
<img src=" http://43.138.15.137:4000//uploads/a68a96a0-8d29-11ee-9228-7b4607ce3ac3.jpg" v-else>
</div>
</div>
<div class="swipe_indicators" v-if="imgfalg">
<i class="swipe_indicator" v-for="item, index in swipeList" :key="index"
:class="{ 'swipe_indicator-active': index === circleIndex }"></i>
</div>
</div>
</div>
<!-- 轮播图 这个是轮播图的布局 在遍历轮播图数据的前后需要手动加上一图片,这样才能实现无缝轮播 -->
</template>
<script>
export default {
// 因为是封装的组件,这个需要传递的参数,一个是轮播图的数据,另一个是小圆点的显示隐藏
props: {
swipeList: {
type: Array
},
imgfalg: {
type: Boolean,
default: true
}
},
data() {
return {
flag: true, // 节流阀 防止快速滑动
circleIndex: 0, // 当前展示图片对应圆点
imgIndex: 0, // 当前展示图片
timer: null, // 圆点定时器
imgWidth: 0, // 图片宽度
startX: 0, // 手指开始触摸位置
moveX: 0, // 手指移动距离
interval: 2000, // 滚动间隔时间
}
},
destroyed() {
// 销毁dom元素的时候
clearInterval(this.timer);
},
methods: {
TouchStart(event) {
clearInterval(this.timer)// 关闭自动轮播
// 手指开始触摸事件
if (this.flag) {
// flag节流
console.log(event.changedTouches[0].pageX);
this.startX = event.changedTouches[0].pageX;// 获取开始触摸位置
}
},
TouchMove(event) {// 手指开始移动
console.log(event.changedTouches[0].pageX);
if (this.flag) {
this.moveX = event.changedTouches[0].pageX - this.startX // 手指移动位置
this.$refs.imgBox.style = `transition: none;transform: translateX(${this.translatex + this.moveX}px);`
//通过ref获取imbox然后获取手指的滑动距离 手指划过的距离加上图片ul当前距离
}
},
TouchEnd(event) {
if (this.moveX == 0) return
// 结束触摸
if (this.flag) {
if (this.moveX > 80) {// 移动距离大于80,图片索引---
this.imgIndex--;
this.circleIndex--;
} else if (this.moveX < -80) { // 移动距离小于-80,图片索引++
this.imgIndex++;
this.circleIndex++;
}
// 展示当前索引图片
this.$refs.imgBox.style = `transition: all .5s;transform: translateX(${this.translatex}px);`
// 触摸事件完成,继续自动轮播
clearInterval(this.timer);
// 防止定时器叠加
if (this.imgfalg) {
this.timer = setInterval(() => {
this.imgIndex++;
this.circleIndex++;
this.$refs.imgBox.style = `transition: all .5s;transform: translateX(${this.translatex}px);`
}, this.interval);
}
this.$emit('zyj', this.circleIndex)
this.flag = false; // 关闭节流阀,等待动画完成
}
},
animateEnd() {
// 事件在 动画完成时触发。如果在动画完成前中止了动画,将会把元素从 DOM 中移除,或将动画从元素上移除,animationend 事件不会触发。
if (this.imgIndex >= this.swipeList.length) {// 判断当前图片索引是否为最后一张图
this.imgIndex = 0;
// 当前展示图片
this.$refs.imgBox.style = `transition: none;transform: translateX(-${this.imgWidth}px);`
}
if (this.imgIndex < 0) { // 判断当前图片索引是否为第一张图
this.imgIndex = this.swipeList.length - 1;
this.$refs.imgBox.style = `transition: none;transform: translateX(${this.translatex}px);`
}
this.flag = true;
},
},
computed: {
translatex() {
// 计算图片ul当前距离
return -(this.imgWidth + this.imgWidth * this.imgIndex);
// 图片的宽成语滑动了几张图片成语滑动了几张图片
// 变成负数是看他划了多少距离
}
},
mounted() {
let that = this
window.addEventListener('resize', () => {
that.imgWidth = window.innerWidth;
document.querySelectorAll('.swipe-item').forEach((item) => {
item.style = `width: ${that.imgWidth || window.innerWidth}px;`
})
})
this.imgWidth = window.innerWidth;// 获取图片宽度
console.log(window.innerHeight, 'yutr');
// 先左移动一个图片距离,显示第一张图片
this.$refs.imgBox.style = `transform: translateX(-${this.imgWidth}px);`
if (this.imgfalg) {
this.timer = setInterval(() => {
this.imgIndex++;
this.circleIndex++;// 自动轮播
this.$refs.imgBox.style = `transition: all .5s;transform: translateX(${this.translatex}px);`// 切换下一张图片
}, this.interval)
}
},
watch: {
circleIndex() {
// 监视原点索引变化
if (this.circleIndex >= this.swipeList.length) {
this.circleIndex = 0;
}
if (this.circleIndex < 0) {
this.circleIndex = this.swipeList.length - 1;
}
}
},
}
</script>
<style scoped lang="scss">
$rem: 37.5;
.swipe-banner {
margin: (2.5rem / $rem) 0;
.my-swipe {
position: relative;
overflow: hidden;
transform: translateZ(0);
.swipe_trank {
display: flex;
height: 100%;
align-items: center;
.swipe-item {
position: relative;
flex-shrink: 0;
height: 100%;
img {
width: 100%;
}
.img {
height: 200rem / $rem;
}
}
}
.swipe_indicators {
position: absolute;
bottom: 12rem / $rem;
left: 50%;
display: flex;
transform: translateX(-50%);
.swipe_indicator {
width: 6rem / $rem;
height: 6rem / $rem;
margin-right: 6rem / $rem;
background-color: #ebedf0;
border-radius: 100%;
opacity: 0.3;
}
.swipe_indicator-active {
background-color: white;
opacity: 1;
}
}
}
}
.borders {
background-color: rgb(255, 255, 255);
transform: translateX(69px) translateX(-50%);
transition-duration: 0.3s;
}
.home[data-v-3dd2e005] {
min-height: 100vh;
background: #EEE;
}
.nav[data-v-65221434] {
width: 100vw;
height: 1.06667rem;
line-height: 1.06667rem;
text-align: center;
background: #FF6040;
color: white;
position: fixed;
top: 0;
left: 0;
font-size: 0.4rem;
z-index: 100;
}
.back[data-v-65221434] {
position: absolute;
left: 0.26667rem;
}
.head[data-v-3dd2e005] {
width: 100%;
height: 2.33333rem;
background: linear-gradient(#FF6040, #FF8A80);
}
.search[data-v-3dd2e005] {
height: 1.06667rem;
width: 100%;
display: flex;
justify-content: space-around;
align-items: center;
}
.search img[data-v-3dd2e005]:nth-of-type(1) {
width: 0.53333rem;
height: 0.58667rem;
}
.search .search_input[data-v-3dd2e005] {
width: 4.53333rem;
height: 0.85333rem;
background-color: white;
border-radius: 0.10667rem;
padding: 0.06667rem 0.26667rem;
box-sizing: border-box;
}
.van-field[data-v-3dd2e005] {
padding: 0;
width: 80%;
font-size: 0.30667rem;
}
.van-cell {
position: relative;
display: -webkit-box;
display: -webkit-flex;
display: flex;
box-sizing: border-box;
width: 100%;
padding: 0.26667rem 0.42667rem;
overflow: hidden;
color: #323233;
font-size: 0.37333rem;
line-height: 0.64rem;
background-color: #fff;
}
.van-field__left-icon {
margin-right: 0.10667rem;
}
.van-field__left-icon .van-icon,
.van-field__right-icon .van-icon {
display: block;
font-size: 0.42667rem;
line-height: inherit;
}
.van-icon {
position: relative;
display: inline-block;
font: normal normal normal 0.37333rem / 1 vant-icon;
font-size: inherit;
text-rendering: auto;
-webkit-font-smoothing: antialiased;
}
.van-icon-search:before {
content: '\e710';
}
.van-icon:before {
display: inline-block;
}
.search img[data-v-3dd2e005]:nth-of-type(2) {
width: 2.42667rem;
height: 0.64rem;
}
.dp[data-v-3dd2e005] {
width: 0.53333rem;
height: 0.53333rem;
}
.cate[data-v-3dd2e005] {
display: flex;
}
.catenavtab[data-v-3dd2e005] {
width: 8.26667rem;
}
.van-tabs {
position: relative;
}
.van-tabs--line .van-tabs__wrap {
height: 1.17333rem;
}
.van-tabs__wrap {
overflow: hidden;
}
.van-tabs__nav--line.van-tabs__nav--complete {
padding-right: 0.21333rem;
padding-left: 0.21333rem;
}
.van-tabs__wrap--scrollable .van-tabs__nav {
overflow-x: auto;
overflow-y: hidden;
-webkit-overflow-scrolling: touch;
}
.van-tabs__nav--line {
box-sizing: content-box;
height: 100%;
padding-bottom: 0.4rem;
}
.van-tabs__nav {
position: relative;
display: -webkit-box;
display: -webkit-flex;
display: flex;
background-color: #fff;
-webkit-user-select: none;
user-select: none;
}
.van-tabs__wrap--scrollable .van-tab {
-webkit-box-flex: 1;
-webkit-flex: 1 0 auto;
flex: 1 0 auto;
padding: 0 0.32rem;
}
.van-tab--active {
color: #323233;
font-weight: 500;
}
.van-tab {
position: relative;
display: -webkit-box;
display: -webkit-flex;
display: flex;
-webkit-box-flex: 1;
-webkit-flex: 1;
flex: 1;
-webkit-box-align: center;
-webkit-align-items: center;
align-items: center;
-webkit-box-pack: center;
-webkit-justify-content: center;
justify-content: center;
box-sizing: border-box;
padding: 0 0.10667rem;
color: #646566;
font-size: 0.37333rem;
line-height: 0.53333rem;
cursor: pointer;
}
.category[data-v-3dd2e005] {
display: flex;
justify-content: center;
align-items: center;
width: 1.73333rem;
}
.category img[data-v-3dd2e005] {
width: 0.34667rem;
height: 0.37333rem;
}
.category span[data-v-3dd2e005] {
margin-left: 0.2rem;
color: white;
font-size: 0.34667rem;
}
.swiper_banner[data-v-3dd2e005] {
margin: 0.06667rem 0;
}
.van-swipe {
position: relative;
overflow: hidden;
-webkit-transform: translateZ(0);
transform: translateZ(0);
cursor: grab;
-webkit-user-select: none;
user-select: none;
}
.van-swipe__track {
display: -webkit-box;
display: -webkit-flex;
display: flex;
height: 100%;
}
.my-swipe .van-swipe-item[data-v-3dd2e005] {
color: #fff;
font-size: 0.26667rem;
}
.van-swipe-item {
position: relative;
-webkit-flex-shrink: 0;
flex-shrink: 0;
width: 100%;
height: 100%;
}
.van-swipe-item img[data-v-3dd2e005] {
width: 100%;
height: 5.33333rem;
}
.lpops {
display: flex;
}
.apsaa {
width: 100%;
height: 20rem;
position: relative;
}
li.title {
flex: 1;
text-align: center;
height: 0.9rem;
line-height: 0.9rem;
font-size: 0.4rem;
cursor: pointer;
}
.ols {
color: gray;
font-size: 1.8rem;
}
.active {
color: #FFF;
background: #FFA500;
}
.con-active {
display: block;
}
.ddds[data-v-12beccd8] {
width: 14rem;
font-size: 0.5rem;
margin-top: 1rem;
margin-bottom: 3rem;
}
.dddd {
width: 3rem;
font-size: 1.2rem;
color: black;
}
.lss[data-v-12beccd8] {
width: 3rem;
height: 0.8rem;
margin-top: 7rem;
font-size: 0.2rem;
color: white;
text-align: center;
background-color: #FF6040;
border: none;
}
.dyx {
float: left;
height: 3rem;
background-color: red;
}
.dyx2 {
float: left;
height: 0.1rem;
}
.dyx3 {
float: left;
height: 10rem;
}
</style>
然后就是如何使用:在父组件直接使用即可
<lunbotu :swipeList="swipeList"></lunbotu>
用法就是先引入你的轮播图组件:里面的swipeList是你在父组件通过接口拿到的轮播图数据然后在子传父穿过去渲染就行了