因为是直接在html文件中实现
直接复制到html运行即可,将图片地址修改,目录下要有vue.js文件
基本参考了以下视频代码,并对其做了一些小改进以及注释
1.增加了移动端触摸进行滑动的功能(手指滑动轮播)
2.增加了鼠标进入该区域时使轮播停止
3.代码中对原理做了详细的注释
https://www.bilibili.com/video/BV1RF411v77Z?spm_id_from=333.1007.top_right_bar_window_default_collection.content.click
代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src = "vue.js"></script>
<style>
body{
background-image:linear-gradient(to top,#37ecba,#72afd3) ;
/* 设置线性渐变的效果 */
/* 从 #37ecba 朝上渐变 #72afd3 */
}
.big-box{
position: relative;
margin: 20px auto; /* 上下20px 左右居中 */
height: 400px;
width: 650px;
overflow: hidden; /* 超出部分隐藏 */
}
.show-box{
display: flex;
height: 100%;
width: 100%;
opacity: 1; /* 不透明度 0~1 */
transition: all 0.5s;
}
.show-box img{
float: left;
min-height: 400px; /*图片的最小宽高 如果去掉 图片不能完全充满视图*/
min-width: 650px;
}
.arrowhead-box{
position: absolute; /* 绝对定位 */
width: 100%;
top: 40%;
float: left;
height: 50px;
opacity: 1;
/*transition: all 0.5s;*/
}
.arrowhead-box span{
width: 50px;
height: 50px;
display: block;
float: left;
cursor: pointer;
background: url("left.svg") no-repeat center; /* 设置背景图片 不重复 并且居中*/
background-color: rgba(0,0,0,0.4); /*背景颜色*/
border-radius: 50%; /* 让组件角变圆 */
}
.arrowhead-box span:nth-child(2){ /* nth-child 选择器 选择到.button类中的第二个span*/
float: right;
transform: rotate(180deg); /* 将背景图片旋转 使其朝右 */
}
.swiper-box{
display: flex;
position: absolute;
bottom: 0;
width: 100%;
height: 40px;
justify-content: center; /* flex布局中justify-content 内容居中 原本这样的[000 ] 变成 [ 000 ] 居中 */
align-items: center; /* 竖直方向上居中 justify-content:center水平居中 两者结合 居中 */
}
.swiper-box span{
float: left;
width: 12px;
height: 12px;
background: pink;
border-radius: 50px;
margin-left: 10px;
cursor: pointer; /* 鼠标在组件上方时 鼠标样式变成小手指*/
transition: all 0.5s;
}
.swiper-box span:nth-child(1){ /* 初始时 让第一个圆点长度变长 因为此时显示第一张图*/
width: 100px;
}
</style>
</head>
<body>
<div id = "app">
<!-- @mouseenter:鼠标进入组件时触发事件,不会冒泡 -->
<!-- @mouseleave:鼠标离开组件会触发事件,不会冒泡 -->
<!-- 移动端 -->
<!-- @touchstart: 触摸到时触发事件 -->
<!-- @touchmove: 按住屏幕并且移动时触发 -->
<!-- @touchend: 手指离开屏幕时触发 -->
<div class = "big-box" @mouseenter = "stop" @mouseleave = "start" @touchstart = "touchstart" @touchend = "touchend" @touchmove = "touchmove">
<!-- 图片的切换主要是通过transform:translateX() ,transition:all 0.5s 使切换时有切换效果 -->
<div class = "show-box" :style = "{transform:'translateX('+translate+'px)',transition:isShow?'all 0.5s':'none'}">
<img src = "img6.jpg">
<img v-for = "item in list" :src = "item">
<img src="img1.jpg">
</div>
<div class = "arrowhead-box">
<span @click = "last"></span>
<span @click = "next"></span>
</div>
<div class = "swiper-box" ref = "swiper">
<span v-for = "(item,index) in list" @click = "swiper(index)"></span>
</div>
</div>
</div>
<script>
new Vue({
el:"#app",
data(){
return {
list:["img1.jpg","img2.jpg","img3.jpg","img4.jpg","img5.jpg","img6.jpg"],
translateX:0,
isShow:true,
timer:null,
startX:0,
move:0,
}
},
mounted(){
this.timer = setInterval(()=>{
this.next();
},2000)
},
computed:{
translate(){
return -(this.translateX+1)*650
}
},
watch:{
translateX:{
handler:function (val){
let a = this.$refs.swiper.querySelectorAll('span');
a.forEach((span)=>{
span.style.width = '12px'
// console.log(span);
})
if(this.translateX > this.list.length-1){
val = 0
}
if(this.translateX < 0){
val = this.list.length-1;
}
a[val].style.width = '100px'
}
}
},
methods:{
last(){
this.translateX--;
this.isShow = true; //每次切换的时候都会重新打开transition属性
// 6 [1 2 3 4 5 6] 1
/*
*
* 目前视图是是1,然后用户点击来到了6,此时下标为-1 视图就在6(6 1 2 的6)这个过度图上 然后要切换到真正的 6(5 6 1 中的6)
* 如果继续使用transition:all 0.5s 属性,切换的过程会有卡帧,就是很乱(可以从显示第一个图时,点击切换到最后一个图体验)
*
* 为了与之前的transition:all 0.5s 同步,我们也需要等待0.5s
* 然后将transition属性关掉 即this.trans = false;
* 因为是6 切换到 6,关闭了transition属性,所以这种切换用户是看不出来的,如果没关会有切换的效果,就是上述所说的乱
*
*
*/
if(this.translateX < 0 ){
setTimeout(()=>{
this.translateX = this.list.length-1;
this.isShow = false;
},500)
}
},
next(){
this.translateX++;
this.isShow = true;
if(this.translateX > this.list.length-1){
setTimeout(()=>{
this.translateX = 0;
this.isShow = false;
},500)
}
},
swiper(i){ //通过点击圆点过的下标进而切换图片
this.translateX = i
},
stop(){ //关闭自动轮播
clearInterval(this.timer)
},
start(){ //开始自动轮播
this.timer = setInterval(()=>{
this.next();
},2000)
},
/**
*
* touchmove:是触摸在屏幕上滑动时连续触发
* touchend:是手指离开屏幕时触发
* touchstart:手指触碰到屏幕时触发
*
* 首先把屏幕的自动轮播停止
* 然后计算手指滑动的距离,取整
* 根据 distance - startX 的数值得出 负数:切换下一张 正数:上一张图片
* startX是在用户触摸那一刻出发touchStart事件已经记录好的(在touchmove方法下面)
*
*
* 在touchend中(手指离开屏幕后)
* 得到距离我们也要判断手指划过的距离,如果划过的距离太小(比如小于照片宽度的0.15)那就不翻页
* 超过才进行翻页
* 通过调用next()或者last()
*
* 然后重新调用自动轮播函数 start()
*
*
*/
touchmove(e){
this.stop();
let distance = Math.ceil( e.touches[0].pageX ); //获得横向移动距离
this.move = Math.ceil(distance-this.startX) //负的往左移动即切换下一张图片 startX是手指按下的那一刻下面的touchstart方法中已经记录好
console.log(this.move);
},
touchstart(e){
this.stop();
this.startX = e.touches[0].pageX;
},
touchend(e){
if(this.move >0 && this.move >650*0.15){
this.last();
}
if(this.move < 0 && this.move <-650*0.15){
this.next();
}
this.start(); //重新开始自动轮播,因为之前触摸时被关闭
}
}
})
</script>