基于vue原生js实现轮播图,中间大两边小,循环轮播,突破element中的走马灯最多放三个的限制。以显示轮播5个为例,可以添加多个图片进行循环。显示多少个由自己决定
5、单数据超过5条时,每一次切换图片下标时,都更新数据,这里需要两个数组数据,一个数组(A)存放5个,用户页面的显示。另一个数组(B)数据则是当前一共有多少张图片。3、点击右边小图标或者点击下一张时,每个图片当前位置下标加一,当加到下标超过数组数据长度时,下标重置0开始,循环(点击左边相反)2、点击两边某个图片要是显示在中间时,当前的图片位置与中间位置进行互换。4、每换一次下标,最中间的图片都要放
·
实现效果图:
直接上代码
<template>
<div>
<!-- 低于四张 -->
<div class="oneBox" v-if="!isShow">
<div v-for="(item,index) in propsData" :key="index" class="oneItemBox" @click="itemImgClick(item,index)"><img :src="item.imgUrl"></div>
</div>
<!-- 超过五张以上或者只有三张显示 -->
<div class="box" v-else>
<div v-for="(item,index) in imgList" :key="index" class="itemBox" @click="itemImgClick(item,index)"><img :src="item.imgUrl"></div>
<div class="left" @click="left">减</div>
<div class="right" @click="right">加</div>
</div>
</div>
</template>
<script name="LBBox" setup>
import banner1 from '@/assets/images/banner1.png'
import banner2 from '@/assets/images/banner2.png'
import banner3 from '@/assets/images/banner3.png'
import banner4 from '@/assets/images/taitan1.jpg'
import banner5 from '@/assets/images/taitan2.jpg'
import banner6 from '@/assets/images/s8.jpg'
import banner7 from '@/assets/images/s1.jpg'
import test1 from '@/assets/images/s2.png'
import test2 from '@/assets/images/s3.jpg'
import test3 from '@/assets/images/s4.jpg'
import test4 from '@/assets/images/s4.png'
import test5 from '@/assets/images/s8.jpg'
import test6 from '@/assets/images/s7.jpg'
import {nextTick} from "vue";
let props = defineProps({
propsData:{
type:Array,
default: [
{imgUrl: test1},
{imgUrl: test2},
{imgUrl: test3},
{imgUrl: test4},
{imgUrl: test5},
{imgUrl: test6},
{imgUrl: banner1},
{imgUrl: banner2},
{imgUrl: banner3},
{imgUrl: banner4},
{imgUrl: banner5},
{imgUrl: banner6},
{imgUrl: banner7},
]
}
})
let state = reactive({
imgList: []
})
const { imgList } = toRefs(state)
let itemBox = ref(null) // 存放所有图片dom
function right() {
// 点一次加号,就循环让当前数组的索引加一,循环后强制刷新数据,让数据更新,达到视图更新
let zero = state.imgList[0] //保存第一个,以免进入循环第一个和最后一个重复
for (let i = 0; i < state.imgList.length; i++) {
if (i == state.imgList.length - 1) {
state.imgList[i] = zero
} else {
state.imgList[i] = state.imgList[i + 1]
}
}
updateData(props.propsData,null)
cuttentShadowStyle()
}
function left() {
// 点一次减号,就循环让当前数组的索引减一,循环后强制刷新数据,让数据更新,达到视图更新
let last = state.imgList[state.imgList.length - 1] //保存最后一个,以免进入循环第一个和最后一个重复
for (let i = state.imgList.length - 1; i >= 0; i--) {
if (i == 0) {
state.imgList[i] = last
} else {
state.imgList[i] = state.imgList[i - 1]
}
}
cuttentShadowStyle()
}
function setStyle() {
// 一开始就根据数据的奇偶数来确定中位数,中位数一般都是奇数,如果数组的length为5,则中位数为2
// 基于中位数,给每个元素设置相应的类,类控制元素的大小
let Axis = null
itemBox.value = document.getElementsByClassName('itemBox')
Axis = parseInt(state.imgList.length / 2) //拿到中间数
itemBox.value[Axis].className = "current itemBox";
if (Axis - 1 >= 0) {
itemBox.value[Axis - 1].className = "current1 itemBox";
}
if (Axis - 2 >= 0) { //左边第一个
itemBox.value[Axis - 2].className = "current2 itemBox";
}
if (Axis + 1 <= state.imgList.length - 1) {
itemBox.value[Axis + 1].className = "current1 itemBox";
}
if (Axis + 2 <= state.imgList.length - 1) { //右边第一个
itemBox.value[Axis + 2].className = "current2 itemBox";
}
}
let timer = ref(null)
function tumble(){
if (timer.value){
window.clearInterval(timer.value)
timer.value = null
}
if (!timer.value){
timer.value = window.setInterval(()=>{
right()
},3000)
}
}
function itemImgClick(item,index){
let Axis = parseInt(state.imgList.length / 2)
if (index == Axis) return;
switchPosition(index,Axis)
}
// 点击当前图片显示在中间,与中间的图片进行切换位置
function switchPosition(currentIndex,axisIndex){
let temp = state.imgList[currentIndex]
state.imgList[currentIndex] = state.imgList[axisIndex]
state.imgList[axisIndex] = temp
cuttentShadowStyle() // 让中间样式高亮
}
let shadowTimer = ref('')
function cuttentShadowStyle(){
window.clearTimeout(shadowTimer.value)
let Axis = parseInt(state.imgList.length / 2)
itemBox.value[Axis].style.boxShadow = `0px 0px 6px 10px #D3E7FF`
itemBox.value[Axis].style.borderRadius = `20px`
itemBox.value[Axis].style.transform = `scale(1.02)`
shadowTimer.value = window.setTimeout(()=>{
itemBox.value[Axis].style.boxShadow = `0px 0px 0px 0px #D3E7FF`
itemBox.value[Axis].style.borderRadius = `0px`
itemBox.value[Axis].style.transform = `scale(1)`
},500)
}
// 当图片数据大于5时,做处理 用于更新数据,每次跳转都执行一次
function updateData(data,isOne){
// isOne是否是第一次执行此方法,用于初始化数据,只执行一次
if (isOne){ // 只执行一次
for (let i=0;i<data.length;i++){
if (i<5){
state.imgList.push(data[i])
}
}
}
if (props.propsData.length>cuttentCheckIndex.value){ //默认显示五个轮播 默认显示五个轮播,当数据超过5个时,从第五开始加入新的数据
cuttentCheckIndex.value++ // 第五个开始切换
if (cuttentCheckIndex.value==data.length){
cuttentCheckIndex.value = 0
}
state.imgList.push(data[cuttentCheckIndex.value])
state.imgList.shift()
}
}
//初始化数据
let cuttentCheckIndex = ref(4) //默认显示五个,用于记录数据的更新
let isShow = ref(true)
function initData(){
isShow.value = (props.propsData.length==3||props.propsData.length>=5);
if (isShow.value){
updateData(props.propsData,true)
nextTick(() => {
setStyle()
tumble()
})
}
}
onMounted(() => {
initData()
})
onUnmounted(()=>{ // 清除定时器
window.clearInterval(timer.value)
window.clearInterval(shadowTimer.value)
})
</script>
<style lang="scss" scoped>
.oneBox{
width: 1840px;
height: 530px;
border: 1px solid blue;
margin: 0 auto;
display: flex;
justify-content: space-around;
align-items: center;
padding-bottom: 75px;
position: relative;
.oneItemBox{
width: 295px;
height: 295px;
border: 1px solid #11ff00;
position: relative;
overflow: hidden;
img {
max-width: 100%;
max-height: 100%;
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
margin: auto;
}
}
}
.box {
width: 1840px;
height: 530px;
border: 1px solid red;
margin: 0 auto;
display: flex;
justify-content: space-around;
align-items: end;
padding-bottom: 75px;
position: relative;
.itemBox{
position: relative;
transition: all 0.5s;
img {
max-width: 100%;
max-height: 100%;
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
margin: auto;
}
&:hover{
border-radius: 20px;
transform: scale(1.02);
}
}
.left, .right {
position: absolute;
bottom: 20px;
cursor: pointer;
}
.left {
margin-right: 40px;
}
.right {
margin-left: 40px;
}
}
.current {
width: 402px;
height: 402px;
border: 1px solid red;
}
.current1 {
width: 295px;
height: 295px;
border: 1px solid #11ff00;
}
.current2 {
width: 241px;
height: 241px;
border: 1px solid #0059ff;
}
</style>
实现思路
1、初始化的时候,给当前五个图片设置固定的样式(中间图片大,两边小)
2、点击两边某个图片要是显示在中间时,当前的图片位置与中间位置进行互换
3、点击右边小图标或者点击下一张时,每个图片当前位置下标加一,当加到下标超过数组数据长度时,下标重置0开始,循环(点击左边相反)
4、每换一次下标,最中间的图片都要放大,总之按照自己需求,添加变化样式
5、单数据超过5条时,每一次切换图片下标时,都更新数据,这里需要两个数组数据,一个数组(A)存放5个,用户页面的显示。另一个数组(B)数据则是当前一共有多少张图片。每一次下标更改,都要从B里面拿到一个数据放到A里面去刷新数据
更多推荐
已为社区贡献3条内容
所有评论(0)