Vue3+Swiper.js實(shí)現(xiàn)無縫輪播圖組件的最佳實(shí)踐
前言
在數(shù)據(jù)可視化大屏項(xiàng)目中,輪播圖組件是一個(gè)常見的需求。本文將詳細(xì)介紹如何使用 Vue3 和 Swiper.js 開發(fā)一個(gè)功能完善的無縫輪播圖組件,并分享實(shí)際項(xiàng)目中的最佳實(shí)踐。
技術(shù)棧
- Vue 3 (Composition API)
- TypeScript
- Swiper.js
- CSS3
組件概述
SeamlessCarousel 是一個(gè)基于 Swiper.js 的 Vue 3 輪播圖組件,專門用于展示虛擬電廠信息。該組件支持自動(dòng)播放、手動(dòng)導(dǎo)航、響應(yīng)式布局等功能,適用于數(shù)據(jù)可視化大屏展示。
組件功能預(yù)覽
我們即將開發(fā)的輪播圖組件具備以下功能:
? 自動(dòng)播放與手動(dòng)切換
? 中心突出顯示效果
? 響應(yīng)式布局
? 詳細(xì)信息展示
? 導(dǎo)航按鈕
? 數(shù)據(jù)綁定
步驟一:創(chuàng)建項(xiàng)目并安裝依賴
npm install swiper npm install -D @types/swiper # 如果使用TypeScript
步驟二:創(chuàng)建組件
- 創(chuàng)建一個(gè)名為SeamlessCarousel.vue 的組件文件,并定義組件的屬性、數(shù)據(jù)、方法、事件等。
<template>
<div class="seamless-carousel-container">
<div class="carousel-wrapper">
<!-- 主輪播 -->
<swiper
ref="mainSwiperRef"
:preload-classes="true"
:lazy="true"
:initial-slide="0"
:modules="modules"
:space-between="180"
:slides-per-view="3"
:centered-slides="true"
:loop="true"
:loop-additional-slides="1"
:grab-cursor="true"
:effect="'slide'"
:speed="800"
:allow-touch-move="true"
:watch-slides-progress="true"
:watch-slides-visibility="true"
:autoplay="{
delay: 3000,
disableOnInteraction: true,
pauseOnMouseEnter: true,
waitForTransition: false,
}"
:navigation="{
nextEl: '.right-arrow',
prevEl: '.left-arrow',
}"
class="main-swiper"
@swiper="setMainSwiper"
@slide-change="onSlideChange"
>
<swiper-slide v-for="(plant, index) in slides" :key="index">
<div class="test-plant-card" :class="{
'slide-center': activeIndex === index,
'slide-side': activeIndex !== index,
'initialized': activeIndex >= 0
}">
<div class="title" :title="plant.name">{{ plant.name }} </div>
<div class="card-content">
<img :src="getImage(plant.image)"/>
<div class="common-content">
<p>位置:{{ plant.location }}</p>
</div>
<div class="full-content">
<p >類型:{{ plant.type }}</p>
<p >數(shù)量:{{ plant.num }}臺(tái)</p>
</div>
</div>
</div>
</swiper-slide>
<img ref="prevRef" class="left-arrow" src="@/assets/arrow-left.png"/>
<img ref="nextRef" class="right-arrow" src="@/assets/arrow-right.png" />
</swiper>
</div>
</div>
</template>
<script setup lang="ts">
import { ref, computed, onMounted, watch } from 'vue';
import { Swiper, SwiperSlide } from 'swiper/vue';
import { Navigation, Autoplay, EffectFade, Controller } from 'swiper/modules';
import 'swiper/css';
import 'swiper/css/navigation';
import 'swiper/css/effect-fade';
// Swiper 模塊
const modules = [Navigation, Autoplay, EffectFade, Controller];
// Swiper 實(shí)例引用
const mainSwiperRef = ref<any>(null);
let mainSwiper: any = null;
// 當(dāng)前激活的幻燈片索引
const activeIndex = ref(0);
// 獲取圖片資源
const getImage = (name: string) => {
return new URL(`../assets/${name}.png`, import.meta.url).href
}
interface TestPlant {
name: string
location: string
image?: string
num?: number
type?: string
}
// 定義組件屬性
interface Props {
title?: string;
autoPlayDelay?: number;
speed?: number;
hasLoaded?: boolean;
plants: TestPlant[];
}
const props = withDefaults(defineProps<Props>(), {
autoPlayDelay: 3000,
speed: 800,
hasLoaded: false,
plants: []
});
// 定義事件
const emit = defineEmits(['swiper-change'])
// 設(shè)置主 Swiper 實(shí)例
const setMainSwiper = (swiper: any) => {
mainSwiper = swiper;
};
// 幻燈片切換回調(diào)
const onSlideChange = (index) => {
if (mainSwiper) {
activeIndex.value = mainSwiper.realIndex;
emit('swiper-change', slides.value[activeIndex.value]);
}
};
// 使用傳入的幻燈片數(shù)據(jù)或默認(rèn)數(shù)據(jù)
const slides = computed(() => props.plants || []);
// 監(jiān)聽數(shù)據(jù)加載狀態(tài)
watch(
() => props.hasLoaded,
(newVal) => {
if (newVal && mainSwiper) {
mainSwiper.update();
emit('swiper-change', slides.value[mainSwiper.realIndex]);
}
},
{ immediate: true }
);
</script>
<style scoped>
<style>
.seamless-carousel-container {
width: 100%;
height: 100%;
box-sizing: border-box;
}
.carousel-wrapper {
position: relative;
width: 100%;
height: 100%;
overflow: visible;
padding: 0;
}
.swiper {
height: 170px !important;
}
.swiper .left-arrow {
position: absolute;
left: 0;
top: 0;
bottom: 0;
display: inline-block;
margin: auto;
width: 34px;
height: 34px;
z-index: 99;
cursor: pointer;
}
.swiper .right-arrow {
position: absolute;
right: 0;
top: 0;
bottom: 0;
display: inline-block;
margin: auto;
width: 34px;
height: 34px;
z-index: 99;
cursor: pointer;
}
.main-swiper {
width: 100%;
height: 170px;
}
.main-swiper .swiper-slide {
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-webkit-box-pack: center;
-ms-flex-pack: center;
justify-content: center;
height: 170px;
}
.main-swiper .swiper-slide.swiper-slide-active .test-plant-card {
width: 500px !important;
border: 2px solid #FFA200;
}
/* 卡片樣式 */
.test-plant-card {
overflow: hidden;
transition: all 0.6s cubic-bezier(0.25, 0.46, 0.45, 0.94);
}
.main-swiper .swiper-slide .test-plant-card {
width: 190px !important;
height: 170px;
background: white;
border-radius: 8px;
padding: 22px 20px 20px;
box-sizing: border-box;
box-shadow: 0px 0px 10px 0px rgba(6, 0, 1, 0.05);
flex-shrink: 0;
transition: all 0.6s cubic-bezier(0.25, 0.46, 0.45, 0.94);
}
.main-swiper .swiper-slide .test-plant-card .title {
font-size: 20px;
font-weight: 600;
color: #666666;
font-family: "MiSans-semibold";
margin-bottom: 20px;
width: 100%;
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
}
/* 激活狀態(tài)下的樣式 */
.main-swiper .swiper-slide.swiper-slide-active .test-plant-card .title {
color: #282828;
margin-bottom: 18px;
}
</style>使用方法
- 引入組件:在需要使用的地方引入組件:
<script setup>
import SeamlessCarousel from './SeamlessCarousel.vue';
// 如果需要監(jiān)聽卡片切換事件,請(qǐng)定義此方法
const handleSlideChange = (currentPlant) => {
console.log('當(dāng)前選中的卡片:', currentPlant);
};
</script>- 定義數(shù)據(jù):定義需要展示的卡片數(shù)據(jù),可以是靜態(tài)數(shù)據(jù),也可以是動(dòng)態(tài)數(shù)據(jù)。
<script setup>
const plants = [
{
name: 'Plant 1',
location: 'Location 1',
image: 'plant1.png',
num: 10,
type: 'Type 1'
},
... more plants
]
</script>- 配置參數(shù):根據(jù)需要配置組件的參數(shù),如自動(dòng)播放延遲、切換速度、數(shù)據(jù)加載狀態(tài)等。
- 渲染組件:將組件渲染到頁面中。
<template>
<SeamlessCarousel
:auto-play-delay="5000"
:speed="1000"
:has-loaded="true"
@swiper-change="handleSlideChange"
/>
</template>監(jiān)聽卡片切換事件:如果需要監(jiān)聽卡片切換事件,請(qǐng)定義一個(gè)方法,并綁定到組件的 swiper-change 事件上。
運(yùn)行程序:在瀏覽器中運(yùn)行程序,即可看到效果。
注意事項(xiàng):
- 確保已安裝所需的依賴包。
- 確保已正確配置組件的參數(shù),如自動(dòng)播放延遲、切換速度、數(shù)據(jù)加載狀態(tài)等。
- 確保已正確定義數(shù)據(jù)源,數(shù)據(jù)源可以是靜態(tài)數(shù)據(jù),也可以是動(dòng)態(tài)數(shù)據(jù)。
- 確保已正確渲染組件,并綁定了監(jiān)聽事件。
- 運(yùn)行程序并查看效果。
總結(jié)
到此這篇關(guān)于Vue3+Swiper.js實(shí)現(xiàn)無縫輪播圖組件的文章就介紹到這了,更多相關(guān)Vue3+Swiper.js無縫輪播圖組件內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
vue iview實(shí)現(xiàn)動(dòng)態(tài)新增和刪除
這篇文章主要為大家詳細(xì)介紹了vue iview實(shí)現(xiàn)動(dòng)態(tài)新增和刪除,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-06-06
cesium開發(fā)之如何在vue項(xiàng)目中使用cesium,使用離線地圖資源
這篇文章主要介紹了cesium開發(fā)之如何在vue項(xiàng)目中使用cesium,使用離線地圖資源問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-04-04
解決Vue路由導(dǎo)航報(bào)錯(cuò):NavigationDuplicated:?Avoided?redundant?navig
這篇文章主要給大家介紹了關(guān)于解決Vue路由導(dǎo)航報(bào)錯(cuò):NavigationDuplicated:?Avoided?redundant?navigation?to?current?location的相關(guān)資料,這是最近做項(xiàng)目時(shí)候遇到的一個(gè)問題,現(xiàn)將解決辦法分享出來,需要的朋友可以參考下2023-01-01

