Implementing Responsive Sliders in Vue with Swiper.js
Package Installation
npm install swiper@5 vue-awesome-swiper --save
Plugin Initialization
Register the carousel wrapper globally before mounting your application. The second parameter allows you to define default configuration values that apply to every instance.
import Vue from 'vue'
import CarouselWrapper from 'vue-awesome-swiper'
import 'swiper/css/swiper.css'
const globalDefaults = {
loop: false,
freeMode: false
}
Vue.use(CarouselWrapper, globalDefaults)
Component Implementation
The following example demonstrates a reusable slider component. The implementation replaces hardcoded slide markup with a data-driven approach, extracts the viewport detection logic into a dedicated method, and applies BEM-style styling for easier maintenance.
<template>
<section class="carousel-layout">
<swiper
ref="trackRef"
:options="sliderConfig"
class="fluid-slider">
<swiper-slide v-for="(content, idx) in panelData" :key="idx" class="slide-panel">
{{ content }}
</swiper-slide>
<div slot="pagination" class="control-pager"></div>
<div slot="button-prev" class="control-arrow prev"></div>
<div slot="button-next" class="control-arrow next"></div>
</swiper>
</section>
</template>
<script>
export default {
name: 'FluidCarousel',
data() {
return {
sliderConfig: {
visibleItems: 3,
spacing: 28,
axisDirection: 'horizontal',
pageIndicator: {
selector: '.control-pager'
},
directionalNav: {
nextTarget: '.control-arrow.next',
prevTarget: '.control-arrow.prev'
},
listeners: {
resize: () => {
this.adjustTrackOrientation()
}
}
},
panelData: [
'Display Area Alpha',
'Display Area Beta',
'Display Area Gamma',
'Display Area Delta',
'Display Area Epsilon',
'Display Area Zeta'
]
}
},
methods: {
adjustTrackOrientation() {
const MOBILE_LIMIT = 960
const currentWidth = window.innerWidth
if (this.$refs.trackRef && this.$refs.trackRef.$swiper) {
const targetAxis = currentWidth <= MOBILE_LIMIT ? 'vertical' : 'horizontal'
this.$refs.trackRef.$swiper.changeDirection(targetAxis)
}
}
}
}
</script>
<style lang="scss" scoped>
.carousel-layout {
margin: 24px;
}
.fluid-slider {
min-height: 280px;
width: 100%;
.slide-panel {
box-sizing: border-box;
display: flex;
justify-content: center;
align-items: center;
text-align: center;
font-size: 28px;
font-weight: 700;
background-color: #ffffff;
}
}
@media (max-width: 960px) {
.control-arrow {
transform: rotate(90deg);
&.prev { left: 12px !important; }
&.next { right: 12px !important; }
}
}
</style>
Configuration Breakdown
- visibleItems: Controls how many slides render simultaneously on desktop viewports.
- spacing: Defines the pixel gap between adjacent panels.
- listeners.resize: Triggers a dynamic axis swap when the browser crosses the 960px threshold, ensuring touch-friendly vertical scrolling on smaller screens.
- Control Elements: Pagination and navigation arrows are injected via named slots, keeping the internal DOM clean while allowing external CSS targeting.