本文主要是介绍Vue2走马灯(Carousel),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
Vue2走马灯扩展版(Carousel)
移入时暂停,移出后自动轮播
可自定义设置以下属性:
- 轮播图片数组(imageData),默认[]
- 滑动轮播间隔(interval),默认3000ms
- 图片宽度(imageWidth),默认400px
- 图片高度(imageHeight),默认300px
共使用两种滑动效果实现方式:
- 延时调用setInterval(setTimeout类似)
- requestAnimationFrame()(效果更好)
效果如下图:
①创建图片轮播组件Carousel.vue:
- 滑动效果使用setInterval延时调用(使用setTimeout超时调用类似)
<template><!-- 方法1:使用 will-change: transform; translateX(-${left}px); --><!-- <div class="m-slider" :style="`width: ${imageWidth}px;`" @mouseenter="onStop" @mouseleave="onStart"><div :class="{ 'transition': transition }" :style="`width: ${width}px; will-change: transform; transform: translateX(${-left}px);`"> --><!-- 方法2:使用position: relative;和position: absolute; left: ${-left}px; --><div class="m-slider" :style="`position: relative; width: ${imageWidth}px; height: ${imageHeight + 36}px;`" @mouseenter="onStop" @mouseleave="onStart"><div :class="{ 'transition': transition }" :style="`width: ${width}px; position: absolute; left: ${-left}px;`"><divv-for="(item, index) in imageData":key="index":style="`width: ${imageWidth}px;`"class="m-image"><img v-lazy="getDefault(item.imgUrl)" :alt="item.title" :style="`width: ${imageWidth}px; height: ${imageHeight}px;`" class="u-img"/><p class="u-img-title" :title="item.title">{{ item.title }}</p></div><div class="m-image" :style="`width: ${imageWidth}px;`"><img v-lazy="getDefault(imageData[0].imgUrl)" :alt="imageData[0].title" :style="`width: ${imageWidth}px; height: ${imageHeight}px;`" class="u-img"/><p class="u-img-title" :title="imageData[0].title">{{ imageData[0].title }}</p></div></div></div>
</template>
<script>
import Vue from 'vue'
import VueLazyLoad from 'vue-lazyload' // 图片懒加载插件使用版本v1.3.3
Vue.use(VueLazyLoad)
export default {name: 'Carousel',props: {imageData: { // 轮播图片数组type: Array,default: () => {return []}},interval: { // 滑动轮播间隔type: Number,default: 3000},imageWidth: { // 图片宽度type: Number,default: 400},imageHeight: { // 图片高度type: Number,default: 300}},data () {return {left: 0, // 滑动偏移值transition: false, // 暂停时未完成滑动的过渡标志slideTimer: null, // 自动切换定时器moveTimer: null // 向左滑动定时器}},computed: {width () { // 容器宽度:(图片数组长度+1) * 图片宽度return (this.imageData.length + 1) * this.imageWidth},len () {return this.imageData.length || 0}},mounted () {window.onfocus = () => { // 页面激活状态this.onStart()}window.onblur = () => { // 页面未激活状态this.onStop()}this.onStart()},methods: {getDefault (src) { // 获取懒加载默认图return {src: src,error: require('../assets/images/default.png'),loading: require('../assets/images/default.png')}},onStart () {if (this.len > 1) { // 超过一条时滑动this.transition = falsethis.onAutoSlide() // 自动滑动轮播console.log('imageSlider start')}},onStop () {clearTimeout(this.slideTimer)clearInterval(this.moveTimer)this.sliderTimer = nullthis.moveTimer = nullthis.transition = truethis.left = Math.ceil(this.left / this.imageWidth) * this.imageWidth // ceil:向上取整,floor:向下取整console.log('imageSlider stop')},onAutoSlide () {this.slideTimer = setTimeout(() => {const target = this.left % (this.len * this.imageWidth) + this.imageWidththis.autoMoveLeft(target)}, this.interval)},// 滑动使用setInterval延时调用autoMoveLeft (target) { // 自动切换,向左滑动效果if (this.left === this.len * this.imageWidth) { // 最后一张时,重置leftthis.left = 0}this.moveTimer = setInterval(() => {if (this.left >= target) {clearInterval(this.moveTimer)this.moveTimer = nullthis.onAutoSlide() // 自动间隔切换下一张} else {var step = Math.ceil((target - this.left) / 10) // 越来越慢的滑动过程this.left += step}}, 25)},beforeDestroy () {clearTimeout(this.slideTimer)clearInterval(this.moveTimer)this.slideTimer = nullthis.moveTimer = null}}
}
</script>
<style lang="less" scoped>
@themeColor: #1890FF;
.m-slider {margin: 0 auto;overflow: hidden;.transition {transition: transform 0.3s ease-out;}.m-image {display: inline-block;.u-img {vertical-align: bottom; // 消除img标签底部的5pxcursor: pointer;}.u-img-title {font-size: 18px;color: #333;line-height: 36px;text-align: left;cursor: pointer;overflow: hidden;text-overflow: ellipsis;white-space: nowrap;&:hover {color: @themeColor;}}}
}
</style>
- 滑动效果使用requestAnimationFrame()
-
<template><div class="m-slider" :style="`width: ${imageWidth}px;`" @mouseenter="onStop" @mouseleave="onStart"><div :class="{ 'transition': transition }" :style="`width: ${width}px; will-change: transform; transform: translateX(${-left}px);`"><divv-for="(item, index) in imageData":key="index":style="`width: ${imageWidth}px;`"class="m-image"><img v-lazy="getDefault(item.imgUrl)" :alt="item.title" :style="`width: ${imageWidth}px; height: ${imageHeight}px;`" class="u-img"/><p class="u-img-title" :title="item.title">{{ item.title }}</p></div><div class="m-image" :style="`width: ${imageWidth}px;`"><img v-lazy="getDefault(imageData[0].imgUrl)" :alt="imageData[0].title" :style="`width: ${imageWidth}px; height: ${imageHeight}px;`" class="u-img"/><p class="u-img-title" :title="imageData[0].title">{{ imageData[0].title }}</p></div></div></div> </template> <script> import Vue from 'vue' import VueLazyLoad from 'vue-lazyload' Vue.use(VueLazyLoad) // 图片懒加载插件 export default {name: 'Carousel',props: {imageData: { // 轮播图片数组type: Array,default: () => {return []}},interval: { // 滑动轮播间隔type: Number,default: 3000},imageWidth: { // 图片宽度type: Number,default: 400},imageHeight: { // 图片高度type: Number,default: 300}},data () {return {left: 0, // 滑动偏移值transition: false, // 暂停时未完成滑动的过渡标志slideTimer: null, // 自动切换定时器moveRaf: null, // 动画回调标识target: null, // 要移动到的目标位置start: 0,end: 0,fpsRaf: null, // fps回调标识step: 15 // 默认移动参数,对应60fps}},computed: {width () { // 容器宽度:(图片数组长度+1) * 图片宽度return (this.imageData.length + 1) * this.imageWidth},len () {return this.imageData.length || 0}},mounted () {window.onfocus = () => { // 页面激活状态this.onStart()}window.onblur = () => { // 页面未激活状态this.onStop()}this.fpsRaf = requestAnimationFrame(this.getFPS) // 获取浏览器的刷新率},methods: {getDefault (src) { // 获取懒加载默认图return {src: src,error: require('../assets/images/default.png'),loading: require('../assets/images/default.png')}},getFPS (timestamp) {// 单位ms,用1000ms/两个时间的间隔≈刷新频率fps// console.log('timestamp:', timestamp)if (this.fpsRaf === 2) {this.start = timestamp}if (this.fpsRaf === 3) {this.end = timestampconst fps = Math.floor(1000 / (this.end - this.start))if (fps === 120) {this.step = 30}}this.fpsRaf = requestAnimationFrame(this.getFPS)if (this.fpsRaf > 3) {cancelAnimationFrame(this.fpsRaf)this.onStart()}},onStart () {if (this.len > 1) { // 超过一条时滑动this.transition = falsethis.onAutoSlide() // 自动滑动轮播console.log('imageSlider start')}},onStop () {clearTimeout(this.slideTimer)this.slideTimer = nullcancelAnimationFrame(this.moveRaf)this.transition = truethis.left = Math.ceil(this.left / this.imageWidth) * this.imageWidth // ceil:向上取整,floor:向下取整console.log('imageSlider stop')},onAutoSlide () {this.slideTimer = setTimeout(() => {const target = this.left % (this.len * this.imageWidth) + this.imageWidththis.autoMoveLeft(target)}, this.interval)},// 滑动效果使用requestAnimationFrameautoMoveLeft (target) { // 自动切换,向左滑动效果if (this.left === this.len * this.imageWidth) { // 最后一张时,重置leftthis.left = 0}this.target = targetthis.moveRaf = requestAnimationFrame(this.autoLeftSlideEffect)},autoLeftSlideEffect () { // 自动向左滑动效果if (this.left >= this.target) {cancelAnimationFrame(this.moveRaf)this.onAutoSlide() // 自动间隔切换下一张} else {const move = Math.ceil((this.target - this.left) / this.step)this.left += movethis.moveRaf = requestAnimationFrame(this.autoLeftSlideEffect)}},beforeDestroy () {clearTimeout(this.slideTimer)this.slideTimer = null}} } </script> <style lang="less" scoped> @themeColor: #1890FF; .m-slider {margin: 100px auto;overflow: hidden;.transition {transition: transform 0.3s ease-out;}.m-image {display: inline-block;.u-img {vertical-align: bottom; // 消除img标签底部的5pxcursor: pointer;}.u-img-title {font-size: 18px;color: #333;line-height: 36px;text-align: left;cursor: pointer;overflow: hidden;text-overflow: ellipsis;white-space: nowrap;&:hover {color: @themeColor;}}} } </style>
②在要使用滑动轮播图片的页面引入使用:
-
<Carousel :imageData="imageData" :imageWidth="460" :imageHeight="320" :interval="3000" /> import Carousel from '@/components/Carousel' components: {Carousel } data () {return {imageData: [{title: 'image-1,image-1,image-1,image-1,image-1,image-1,image-1,image-1,image-1',imgUrl: 'image src...'},{title: 'image-2,image-2,image-2,image-2,image-2,image-2,image-2,image-2,image-2',imgUrl: 'image src...'},{title: 'image-3,image-3,image-3,image-3,image-3,image-3,image-3,image-3,image-3',imgUrl: 'image src...'}]} }
这篇关于Vue2走马灯(Carousel)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!