使用Vue快速實現(xiàn)一個無縫輪播效果
需求簡介
輪播圖是我們前端開發(fā)中的一個常見需求,在項目開發(fā)中,我們可以使用element、ant等UI庫實現(xiàn)。某些場景,為了一個簡單的功能安裝一個庫是沒必要的,我們最好的選擇就是手搓。
我們來看一個需求

上述需求核心就是實現(xiàn)一個無縫輪播的切換效果。以這個需求為例,我們看看最終實現(xiàn)效果:

實現(xiàn)思路
要想實現(xiàn)一個無縫的輪播效果,其實非常簡單,核心思想就是動態(tài)改變顯示的列表而已。比如我們有這樣一個數(shù)組
const list = ref([
{ name: 1, id: 1 },
{ name: 2, id: 2 },
{ name: 3, id: 3 }
])
如果我們想無縫切換的展示這個數(shù)據(jù),最簡單的代碼就是動態(tài)的改變下面的代碼的index
<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>
那如何實現(xiàn)切換的樣式呢?也非常簡單,我們只要給元素添加一個出現(xiàn)樣式和離開樣式即可?,F(xiàn)在,我們來具體實現(xiàn)這樣一個需求。
技術(shù)方案
數(shù)據(jù)的動態(tài)切換
要想實現(xiàn)一個數(shù)據(jù)的動態(tài)循環(huán)切換效果,是非常容易的:
<template>
<div v-for="(build, index) in list" :key="index">
<div v-show="index === selectIndex">
卡片自定義內(nèi)容
</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>
上述代碼中,我們設(shè)置了一個定時器,定時器每5s執(zhí)行一次,每次執(zhí)行都會動態(tài)更改當(dāng)前要顯示的數(shù)據(jù)索引值,當(dāng)索引值達(dá)到最大實,在將其重置。通過上述的簡單代碼,我們就實現(xiàn)了一個可以自動切換的循環(huán)渲染的卡片。
動畫添加
要想實現(xiàn)最終效果的動態(tài)效果也非常容易,我們只需要給每個元素出現(xiàn)時設(shè)置一些樣式,離開時設(shè)置一些樣式即可。借助vue的Transition組件,我們能很容易實現(xiàn)這樣一個效果。
如果你不了解vue的Transition組件,請去官網(wǎng)補(bǔ)充下知識:cn.vuejs.org/guide/built-ins/transition.html
<template>
<div class="main-content">
<Transition v-for="(build, index) in list" :key="selectIndex">
<div class="banner-scroll-wrap" v-show="index === selectIndex">
卡片自定義內(nèi)容
</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是動態(tài)的,元素不斷地在顯示與隱藏。因此,Transition標(biāo)簽的進(jìn)入樣式和離開樣式會動態(tài)觸發(fā),從而形成切換效果。
v-enter是元素的進(jìn)入樣式,進(jìn)入時,我們從最右邊偏移100%的距離到正常位置,透明度從0到1,這個過程持續(xù)0.6s,實現(xiàn)了元素左移淡入的效果。
v-leave是元素的離開樣式,離開時,我們從正常位置偏移到100%的左側(cè)位置,透明度從1到0,這個過程持續(xù)0.6s,實現(xiàn)了元素左移淡出的效果。
在這些類的共同作用下,我們實現(xiàn)了元素的動態(tài)切換。
你可能注意到了我給元素設(shè)置了一個banner-scroll-wrap類名,并使用了position: absolute,這樣設(shè)置的注意目的是保證切換離開元素的淡出效果和進(jìn)入元素的淡入效果是連貫的。如果你不這樣寫,可能會出現(xiàn)樣式問題。
此外,注意我給Transition設(shè)置了key="Transition",這樣些會保證每次數(shù)據(jù)在切換時,transition能夠重新渲染,觸發(fā)元素離開和進(jìn)入的樣式。
至此,我們就完成了基本功能樣式

輪播的停止與恢復(fù)
很常見的一種情況就是我們需要鼠標(biāo)放在卡片上時停止輪播,離開卡片的時候恢復(fù)輪播,這非常容易。
<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">
卡片自定義內(nèi)容
</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()
}
// >關(guān)閉輪播
const stop = () => {
clearInterval(timer)
timer = null
}
timeFuc()
<scriptp>
<style lang="less" scoped>
<style/>
解決重影問題
在某些情況下,我們離開這個頁面很久后(瀏覽器切換到其他選項卡),然后在切回來的時候,可能會出現(xiàn)短暫的畫面重影問題,這個問題也很好解決,加上下面的代碼即可
<script setup>
//...
// 解決切屏后重影的問題
onMounted(() => {
document.addEventListener('visibilitychange', () => {
// 用戶息屏、或者切到后臺運行 (離開頁面)
if (document.visibilityState === 'hidden') {
stop()
}
// 用戶打開或回到頁面
if (document.visibilityState === 'visible') {
start()
}
})
})
onBeforeUnmount(() => stop())
<scriptp>
visibilitychange 事件:當(dāng)其選項卡的內(nèi)容變得可見或被隱藏時,會在 document 上觸發(fā) visibilitychange 事件。該事件不可取消。
總結(jié)
在本教程中,我們通過簡單代碼實現(xiàn)了無縫輪播效果,樣式是左右切換,我們也可以通過樣式控制實現(xiàn)上下切換的效果,比如將translateX設(shè)置為translateY即可。
.v-enter-from {
transform: translateY(100%);
opacity: 0;
}
以上就是使用Vue快速實現(xiàn)一個無縫輪播效果的詳細(xì)內(nèi)容,更多關(guān)于Vue無縫輪播的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
vue 全局封裝loading加載教程(全局監(jiān)聽)
這篇文章主要介紹了vue 全局封裝loading加載教程(全局監(jiān)聽),具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-11-11
Vue+axios實現(xiàn)統(tǒng)一接口管理的方法
這篇文章主要介紹了Vue+axios實現(xiàn)統(tǒng)一接口管理的方法,非常不錯,具有一定的參考借鑒價值,需要的朋友可以參考下2018-07-07
Vue.js中provide/inject實現(xiàn)響應(yīng)式數(shù)據(jù)更新的方法示例
這篇文章主要介紹了Vue.js中provide/inject實現(xiàn)響應(yīng)式數(shù)據(jù)更新,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-10-10
ElementUI嵌套頁面及關(guān)聯(lián)增刪查改實現(xiàn)示例
本文主要介紹了ElementUI嵌套頁面及關(guān)聯(lián)增刪查改實現(xiàn)示例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2022-07-07

