网站首页 > 技术文章 正文
需求简介
轮播图是我们前端开发中的一个常见需求,在项目开发中,我们可以使用element、ant等UI库实现。某些场景,为了一个简单的功能安装一个库是没必要的,我们最好的选择就是手搓。
我们来看一个需求
上述需求核心就是实现一个无缝轮播的切换效果。以这个需求为例,我们看看最终实现效果:
实现思路
要想实现一个无缝的轮播效果,其实非常简单,核心思想就是动态改变显示的列表而已。比如我们有这样一个数组
js复制代码const list = ref([
{ name: 1, id: 1 },
{ name: 2, id: 2 },
{ name: 3, id: 3 }
])
如果我们想无缝切换的展示这个数据,最简单的代码就是动态的改变下面的代码的index
js复制代码<template>
<div>
{{ list[index] }}
</div>
</template>
<script setup>
const index = ref(0)
const list = ref([{ name: 1, id: 1 }, { name: 2, id: 2 }, { name: 2, id: 2 }])
<scriptp>
那如何实现切换的样式呢?也非常简单,我们只要给元素添加一个出现样式和离开样式即可。现在,我们来具体实现这样一个需求。
技术方案
数据的动态切换
要想实现一个数据的动态循环切换效果,是非常容易的:
js复制代码<template>
<div v-for="(build, index) in list" :key="index">
<div v-show="index === selectIndex">
卡片自定义内容
</div>
</div>
</template>
<script setup>
const selectIndex = ref(0)
const list = ref(
[{ name: "卡片1", id: 1 }, { name: "卡片1", id: 2 }, { name: "卡片1", id: 2 }]
)
// #计时器实例
let timer: any = null
// >计时器逻辑
const timeFuc = () => {
timer = setInterval(() => {
// 更改选中的index
if (selectIndex.value >= list.value.length - 1) {
selectIndex.value = 0
} else {
selectIndex.value++
}
}, 5000)
}
timeFuc()
<scriptp>
上述代码中,我们设置了一个定时器,定时器每5s执行一次,每次执行都会动态更改当前要显示的数据索引值,当索引值达到最大实,在将其重置。通过上述的简单代码,我们就实现了一个可以自动切换的循环渲染的卡片。
动画添加
要想实现最终效果的动态效果也非常容易,我们只需要给每个元素出现时设置一些样式,离开时设置一些样式即可。借助vue的Transition组件,我们能很容易实现这样一个效果。
如果你不了解vue的Transition组件,请去官网补充下知识:cn.vuejs.org/guide/built…
js复制代码<template>
<div class="main-content">
<Transition v-for="(build, index) in list" :key="selectIndex">
<div class="banner-scroll-wrap" v-show="index === selectIndex">
卡片自定义内容
</div>
</Transition>
</div>
</template>
<script setup>
const selectIndex = ref(0)
const list = ref(
[{ name: "卡片1", id: 1 }, { name: "卡片1", id: 2 }, { name: "卡片1", id: 2 }]
)
// #计时器实例
let timer: any = null
// >计时器逻辑
const timeFuc = () => {
timer = setInterval(() => {
// 更改选中的index
if (selectIndex.value >= list.value.length - 1) {
selectIndex.value = 0
} else {
selectIndex.value++
}
}, 5000)
}
timeFuc()
<scriptp>
<style lang="less" scoped>
.main-content {
position: relative;
height: 100%;
.banner-scroll-wrap {
position: absolute;
top: 0;
bottom: 0;
right: 0;
left: 0;
}
}
.v-enter-from {
transform: translateX(100%);
opacity: 0;
}
.v-enter-active,
.v-leave-active {
transition: transform 600ms ease-in-out, opacity 600ms ease-in-out;
}
.v-enter-to {
transform: translateX(0);
opacity: 1;
}
.v-leave-from {
transform: translateX(0);
opacity: 1;
}
.v-leave-to {
transform: translateX(-100%);
opacity: 0;
}
<style/>
上述代码中,由于 selectIndex是动态的,元素不断地在显示与隐藏。因此,Transition标签的进入样式和离开样式会动态触发,从而形成切换效果。
v-enter是元素的进入样式,进入时,我们从最右边偏移100%的距离到正常位置,透明度从0到1,这个过程持续0.6s,实现了元素左移淡入的效果。
v-leave是元素的离开样式,离开时,我们从正常位置偏移到100%的左侧位置,透明度从1到0,这个过程持续0.6s,实现了元素左移淡出的效果。
在这些类的共同作用下,我们实现了元素的动态切换。
你可能注意到了我给元素设置了一个banner-scroll-wrap类名,并使用了position: absolute,这样设置的注意目的是保证切换离开元素的淡出效果和进入元素的淡入效果是连贯的。如果你不这样写,可能会出现样式问题。
此外,注意我给Transition设置了key="Transition",这样些会保证每次数据在切换时,transition能够重新渲染,触发元素离开和进入的样式。
至此,我们就完成了基本功能样式
轮播的停止与恢复
很常见的一种情况就是我们需要鼠标放在卡片上时停止轮播,离开卡片的时候恢复轮播,这非常容易。
js复制代码<template>
<div class="main-content" @mouseenter="stop()" @mouseleave="start()">
<Transition v-for="(build, index) in list" :key="selectIndex">
<div class="banner-scroll-wrap" v-show="index === selectIndex">
卡片自定义内容
</div>
</Transition>
</div>
</template>
<script setup>
const selectIndex = ref(0)
const list = ref(
[{ name: "卡片1", id: 1 }, { name: "卡片1", id: 2 }, { name: "卡片1", id: 2 }]
)
// #计时器实例
let timer: any = null
// >计时器逻辑
const timeFuc = () => {
timer = setInterval(() => {
// 更改选中的index
if (selectIndex.value >= list.value.length - 1) {
selectIndex.value = 0
} else {
selectIndex.value++
}
}, 5000)
}
// >开启轮播
const start = () => {
if (timer) return
timeFuc()
}
// >关闭轮播
const stop = () => {
clearInterval(timer)
timer = null
}
timeFuc()
<scriptp>
<style lang="less" scoped>
<style/>
解决重影问题
在某些情况下,我们离开这个页面很久后(浏览器切换到其他选项卡),然后在切回来的时候,可能会出现短暂的画面重影问题,这个问题也很好解决,加上下面的代码即可
js复制代码<script setup>
//...
// 解决切屏后重影的问题
onMounted(() => {
document.addEventListener('visibilitychange', () => {
// 用户息屏、或者切到后台运行 (离开页面)
if (document.visibilityState === 'hidden') {
stop()
}
// 用户打开或回到页面
if (document.visibilityState === 'visible') {
start()
}
})
})
onBeforeUnmount(() => stop())
<scriptp>
visibilitychange 事件:当其选项卡的内容变得可见或被隐藏时,会在 document 上触发 visibilitychange 事件。该事件不可取消。
总结
在本教程中,我们通过简单代码实现了无缝轮播效果,样式是左右切换,我们也可以通过样式控制实现上下切换的效果,比如将translateX设置为translateY即可。
js复制代码 .v-enter-from {
transform: translateY(100%);
opacity: 0;
}
时间原因,本教程也没有对技术上做深究,也希望各位大佬能提供自己的思路与建议,感谢大家分享!
作者:石小石Orz 链接:https://juejin.cn/post/7351790785743978537
- 上一篇: 谈谈工作中常用的设计模式(工作设计中三种方法是什么)
- 下一篇: 使用CSS实现苹果官网文字渐入效果
猜你喜欢
- 2024-10-30 基于Web的“戳泡泡”解压小游戏(戳泡泡用英文怎么说)
- 2024-10-30 暗夜发光,独自闪耀,网页暗黑模式下的特效和动效,CSS3实现
- 2024-10-30 HTML多行代码搞定微信8.0的炸裂特效!C/C++怎么能输
- 2024-10-30 Nick_N像素画教程:像素画动画缓入缓出
- 2024-10-30 CSS动画制作(css动画制作电池充电效果)
- 2024-10-30 前端系列:在线认识贝塞尔曲线的运动轨迹(中文版网站)
- 2024-10-30 CSS3 transition过渡效果(css3过度效果)
- 2024-10-30 15个CSS 常见错误,请一定要注意避免
- 2024-10-30 css动画之transition(css transition动画)
- 2024-10-30 daisyUI - 主题漂亮、代码纯净!免费开源的 Tailwind CSS 组件库
- 最近发表
- 标签列表
-
- cmd/c (57)
- c++中::是什么意思 (57)
- sqlset (59)
- ps可以打开pdf格式吗 (58)
- phprequire_once (61)
- localstorage.removeitem (74)
- routermode (59)
- vector线程安全吗 (70)
- & (66)
- java (73)
- org.redisson (64)
- log.warn (60)
- cannotinstantiatethetype (62)
- js数组插入 (83)
- resttemplateokhttp (59)
- gormwherein (64)
- linux删除一个文件夹 (65)
- mac安装java (72)
- reader.onload (61)
- outofmemoryerror是什么意思 (64)
- flask文件上传 (63)
- eacces (67)
- 查看mysql是否启动 (70)
- java是值传递还是引用传递 (58)
- 无效的列索引 (74)