vue 轮播图


因为是直接在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>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值