vue 实现滑动门
Vue 实现滑动门效果
滑动门效果通常指通过点击或悬停触发内容区域的平滑切换,常见于标签页、导航菜单等场景。以下是几种实现方式:
使用动态组件 + transition
通过 Vue 的 <component> 和 <transition> 实现内容切换动画:
<template>
<div>
<div class="tabs">
<button
v-for="tab in tabs"
:key="tab"
@click="currentTab = tab"
:class="{ active: currentTab === tab }"
>
{{ tab }}
</button>
</div>
<transition name="slide" mode="out-in">
<component :is="currentTabComponent" class="tab-content" />
</transition>
</div>
</template>
<script>
export default {
data() {
return {
tabs: ['Home', 'About'],
currentTab: 'Home'
}
},
computed: {
currentTabComponent() {
return this.currentTab.toLowerCase()
}
}
}
</script>
<style>
.slide-enter-active, .slide-leave-active {
transition: all 0.3s ease;
}
.slide-enter-from {
transform: translateX(100%);
opacity: 0;
}
.slide-leave-to {
transform: translateX(-100%);
opacity: 0;
}
</style>
结合 CSS transform 实现横向滑动
通过动态绑定样式控制滑动位置:
<template>
<div class="slider-container">
<div class="slider-track" :style="{ transform: `translateX(${offset}px)` }">
<div v-for="item in items" :key="item.id" class="slide">
{{ item.content }}
</div>
</div>
<button @click="prev">Prev</button>
<button @click="next">Next</button>
</div>
</template>
<script>
export default {
data() {
return {
items: [
{ id: 1, content: 'Slide 1' },
{ id: 2, content: 'Slide 2' },
{ id: 3, content: 'Slide 3' }
],
currentIndex: 0,
slideWidth: 300
}
},
computed: {
offset() {
return -this.currentIndex * this.slideWidth
}
},
methods: {
next() {
this.currentIndex = Math.min(this.currentIndex + 1, this.items.length - 1)
},
prev() {
this.currentIndex = Math.max(this.currentIndex - 1, 0)
}
}
}
</script>
<style>
.slider-container {
overflow: hidden;
width: 300px;
}
.slider-track {
display: flex;
transition: transform 0.5s ease;
}
.slide {
flex: 0 0 300px;
height: 200px;
}
</style>
使用第三方库(如 Swiper)
对于复杂滑动需求,可集成 Swiper.js:
-
安装 Swiper:
npm install swiper -
Vue 组件实现:
<template> <swiper :slides-per-view="1" :space-between="50" @swiper="onSwiper" @slideChange="onSlideChange" > <swiper-slide v-for="item in items" :key="item.id"> {{ item.content }} </swiper-slide> </swiper> </template>
export default { components: { Swiper, SwiperSlide }, data() { return { items: [ { id: 1, content: 'Slide 1' }, { id: 2, content: 'Slide 2' } ] } }, methods: { onSwiper(swiper) { console.log(swiper) }, onSlideChange() { console.log('slide change') } } }
```移动端手势支持
通过 @touchstart、@touchmove 等事件实现手势滑动:
<template>
<div
@touchstart="startDrag"
@touchmove="onDrag"
@touchend="endDrag"
class="drag-container"
>
<div class="draggable" :style="{ transform: `translateX(${dragOffset}px)` }">
<!-- 内容 -->
</div>
</div>
</template>
<script>
export default {
data() {
return {
startX: 0,
dragOffset: 0,
isDragging: false
}
},
methods: {
startDrag(e) {
this.startX = e.touches[0].clientX
this.isDragging = true
},
onDrag(e) {
if (!this.isDragging) return
const x = e.touches[0].clientX
this.dragOffset = x - this.startX
},
endDrag() {
this.isDragging = false
// 添加复位逻辑
}
}
}
</script>
以上方案可根据具体需求选择或组合使用。CSS transform 方案性能最佳,第三方库功能最完善,原生事件方案最灵活。







