前言
基于vue3手写水平无缝轮播图。
无需引入插件。
原理
使用定时器通过一个动态的值去改变页面中图片的位置。
定义变量
首先需要在reactive中定义三个变量。它们分别是
calleft(偏移量)、
timer(存放定时器)、
dataleng(存放动态获取的ul宽度)。
当然还有dataList数组(里面存放的是img)。
模板渲染
<div class="threeImg">
<div class="Containt">
<ul :style="{ left: calleft + 'px', width: dataleng + 'px' }" v-on:mouseover="stopmove()"
v-on:mouseout="move()" class="imgBoxoul">
<li v-for="(item, index) in dataList" :key="index" @click="gotodetails(item.id)" ref="lis">
<img :src="item.thumb" />
</li>
</ul>
</div>
</div>
交互
按需引入
import {reactive,onMounted,toRefs} from "vue";
获取dom并复制
function imgbox() {
var imgBox = document.getElementsByClassName("imgBoxoul")[0];
imgBox.innerHTML += imgBox.innerHTML;
}
获取当前图片的长度,计算出结果之后赋值给detaleng
function datalen() {
user.dataleng = 240 * Number(user.dataList.length * 2);
}
向左移动
function starmove() {
user.calleft -= 1.2;
//-1200可以是动态的值
if (user.calleft <= -1200 + -24) {
user.calleft = -23;
}
}
开启定时器
function move() {
user.timer = setInterval(()=>{
starmove()
},20)
}
鼠标悬停时停止移动
function stopmove() {
clearInterval(user.timer);
}
调用onMounted钩子
onMounted(() => {
move();
imgbox();
datalen();
});
最后要return
return {
...toRefs(user),
stopmove,
move
};
完整代码
<template>
<div class="threeImg">
<div class="Containt">
<ul :style="{ left: calleft + 'px', width: dataleng + 'px' }" v-on:mouseover="stopmove()"
v-on:mouseout="move()" class="imgBoxoul">
<li v-for="(item, index) in dataList" :key="index" @click="gotodetails(item.id)" ref="lis">
<img :src="item.thumb" />
</li>
</ul>
</div>
</div>
</template>
<script>
import {
reactive,
onMounted,
toRefs
} from "vue";
export default {
setup() {
const user = reactive({
calleft: 0,
timer: null,
dataLeng: 0,
dataList: [{
thumb: "https://img1.baidu.com/it/u=952217981,2074570050&fm=26&fmt=auto",
id: 0,
},
{
thumb: "https://img0.baidu.com/it/u=850200754,252620350&fm=26&fmt=auto",
id: 1,
},
{
thumb: "https://img2.baidu.com/it/u=3618348881,1315923269&fm=26&fmt=auto",
id: 2,
},
{
thumb: "https://img0.baidu.com/it/u=389679720,692929014&fm=26&fmt=auto",
id: 3,
},
{
thumb: "https://img0.baidu.com/it/u=850200754,252620350&fm=26&fmt=auto",
id: 1,
}
],
});
function imgbox() {
var imgBox = document.getElementsByClassName("imgBoxoul")[0];
imgBox.innerHTML += imgBox.innerHTML;
}
function move() {
user.timer = setInterval(() => {
starmove()
}, 20)
}
function datalen() {
user.dataleng = 240 * Number(user.dataList.length * 2);
}
function starmove() {
user.calleft -= 1.2;
if (user.calleft <= -1200 + -24) {
user.calleft = -23;
}
}
function stopmove() {
clearInterval(user.timer);
}
onMounted(() => {
move();
imgbox();
datalen();
});
return {
...toRefs(user),
stopmove,
move
};
},
};
</script>
<style scoped>
.threeImg {
position: relative;
}
.threeImg .Containt ul {
margin: 0 auto;
width: 2400px;
position: absolute;
left: 0px;
cursor: pointer;
height: 100%;
z-index: 10;
}
.threeImg .Containt ul li {
float: left;
width: 220px;
height: 350px;
margin-right: 20px;
border-radius: 10px;
overflow: hidden;
background-color: #ffffff;
}
.threeImg .Containt ul li img {
width: 100%;
height: 263px;
}
.Containt {
position: relative;
padding: 60px 0;
overflow-y: auto;
width: 1200px;
height: 365px;
overflow: hidden;
margin: 0 auto;
}
</style>