之前在JS里面写过轮播图,然后后面都用的是swiper
插件,正好最近vue忘了好多的感觉,使用vue手写一个轮播图封装,目前只实现定时滚动功能,正好用来复习下vue的知识
- 用mockjs模拟图片数据
- 实现父子组件的数据传输
- 实现鼠标放上暂停,移开继续播放
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>