用Vue写一个简单轮播图

之前在JS里面写过轮播图,然后后面都用的是swiper插件,正好最近vue忘了好多的感觉,使用vue手写一个轮播图封装,目前只实现定时滚动功能,正好用来复习下vue的知识

  1. 用mockjs模拟图片数据
  2. 实现父子组件的数据传输
  3. 实现鼠标放上暂停,移开继续播放

vue项目的创建就不额外说了,先来直接构建数据

构建mock数据

通过mock构建虚拟数据,感觉是前端的一个必备技能,因为后台不一定很快搭建好,所以需要自己创建数据来测试组件,这里使用的是]Mockjs](http://mockjs.com/examples.html),当然还有更多在线mock平台这里就不说了
安装完成之后需要创建对应的js文件

// 要求生成300*400的图片,图片内容为序号
// 生成的数量以传入的值为准
// 导入mockjs
var Mock = require('mockjs')
// 随机函数
let Random = Mock.Random
// 开始生成数据,设置为一个function,每次调用函数的时候就能随机生成数据
let getPicture = function (n) {
   // 保存图片的数组
   let list = []
   // 循环填充list
   for(let i = 0;i<n;i++) {
     let text = Random.csentence(3,5)
     // 生成单张图片数据,图片大小300*400
     var data = Random.image('300x400', '#38a1db', `所有图片中第${i+1}张内容为${text}`)
     // 放入list
     list.push(data)
   }
   // 返回list
   return list
}
export default getPicture

这里在之前的项目中学到的是用一个函数包裹Mock,之后返回整个函数,那么在组件内调用的时候,就能实现传参,并且如果数据内容是变化的也能实现函数再次调用的时候生成不同内容的数据。

实际生成的数据

之后需要在父组件中调用暴露出来的gertPicture函数,并且传入需要多少张图片即可
import getPicture from '../public/imgdata'来获取函数,之后在created生命周期内调用函数,就模拟出在组件创建阶段发送网络请求的感觉了

实现父子组件的数据传输

父传子传参用Props
父组件内要在子组件的标签内写:子组件接受变量名 = “父组件传递变量名”
子组件要用props接收

  props:{
    // 子组件接受的变量名字
    list: {
       // 变量的默认类型
       type:Array,
       // 变量的默认参数,如果是复杂数据类型,需要用return,这样是固定写法
       default() {
       return []
       }
    }
  }

子组件布局的实现

用flex布局实现盒子都在一行显示

<template>
   <div class="box">
     <ul class='content'>
       <li class='pic' v-for="(item,i) in list" :key="i" > 
          <img :src="item">
       </li> 
     </ul>
   </div>
</template>
.box
  width 300px
  height 400px
  overflow hidden 
  .content 
    position relative
    padding 0
    margin 0
    width 2400px
    height 100%
    list-style none
    left -300px
    .pic
      float left
      width 300px
      height 400px
      img 
        width 100%
        height 100%

实现动画

接下来实现的是动画和无缝切换
动画的实现
动画的话主要用transition以及transform来实现
transform来移动包裹图片的盒子,每次移动一张图片的长度实现图片的切换,并且移动多少距离可以通过vue内保存的变量来计算

<ul class='content' :style = "{transform:'translate('+-currentpic*300+'px,0)'}" @mouseover="stop()" @mouseout="play()">
       <li class='pic' v-for="(item,i) in list" :key="i" > 
          <img :src="item">
       </li> 
     </ul>

transition来实现动画,监听的是transform属性,并且保证它0.2s内完成

transition transform .2s

无缝切换的实现
就是每当到最后一张图片的时候,立马切回到第一张图片就能实现无缝切换

实现鼠标放上去暂停,移出来之后继续滚动

利用Vue给元素绑定事件,当鼠标移上去的时候,清除滚动定时器,移出来的时候就重新设置定时器即可

swiper组件完整代码

<template>
   <div class="box">
    <ul class='content' :style = "{transform:'translate('+-currentpic*300+'px,0)'}" @mouseover="stop()" @mouseout="play()">
       <li class='pic' v-for="(item,i) in list" :key="i" > 
          <img :src="item">
       </li> 
     </ul>
   </div>
</template>

<script>
   export default {
     name:'swiper',
     data() {
        return {
           // 当前的图片
           currentpic: 0,
           // 保存定时器
           timer: null
        }
     },
     props:{
       list: {
          type:Array,
          default() {
            return []
          }
       }
     },
     methods: {
        // 通过递增参数来移动图片
        move () {
           // 递增
          this.currentpic++
          if(this.currentpic > 7) this.currentpic = 0
        },
        // 鼠标放在图片上面的时候停止运动
        stop () {
          // 清除定时器
          clearInterval(this.timer)
        },
        play () {
           this.timer = setInterval(() => {
              this.move()
           }, 2000);
        } 
     },
     mounted() {
        setTimeout(() => {
           this.play()
        }, 3000);
     },
   }
</script>

<style lang='stylus' scoped>
.box
  width 300px
  height 400px
  margin 100px auto 
  overflow hidden
  .content 
    position relative
    padding 0
    margin 0
    width 2400px
    height 100%
    list-style none
    transition transform .2s
    .pic
      float left
      width 300px
      height 400px
      img 
        width 100%
        height 100%
</style>
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容