📅 我们继续 50 个小项目挑战!------ DoubleVerticalSlider
组件
仓库地址:https://github.com/SunACong/50-vue-projects
项目预览地址:https://50-vue-projects.vercel.app/

使用 Vue 3 的 Composition API(<script setup>
)结合 TailwindCSS 创建一个全屏、左右联动的垂直轮播组件。左侧为文字内容,右侧为图片展示,两者通过按钮控制上下滑动切换。
这种设计非常适合用于企业官网首页、产品介绍页、作品集展示等需要视觉冲击力的页面。
🎯 组件目标
- 创建一个全屏垂直轮播组件
- 左右区域内容联动滑动
- 支持点击按钮切换当前 Slide
- 使用 Vue 响应式变量管理状态
- 使用 TailwindCSS 快速构建布局和动画
- 实现优雅的滑动过渡效果
⚙️ 技术实现点
技术点 | 描述 |
---|---|
Vue 3 <script setup> |
使用响应式变量管理当前 slide 索引 |
ref 响应式变量 |
控制当前激活的 slide 索引 (activeSlideIndex ) |
动态类绑定 :class |
控制当前 slide 的层级和动画状态 |
内联样式绑定 :style |
动态设置每个 slide 的背景色或图片及位移动画 |
按钮事件绑定 @click |
触发上一页/下一页切换 |
TailwindCSS 布局类 | 构建全屏容器、左右分栏、居中对齐 |
TailwindCSS 过渡类 | 添加平滑的滑动动画 |
🧱 组件实现
模板结构 <template>
html
<template>
<div class="relative flex h-screen w-screen overflow-hidden">
<!-- 左侧 -->
<div class="relative h-full w-[35%] overflow-hidden">
<div
v-for="(slide, index) in leftSlides"
:key="index"
class="absolute inset-0 flex flex-col items-center justify-center text-white transition-all duration-500 ease-in-out"
:class="[index === activeSlideIndex ? 'z-10' : 'pointer-events-none z-0']"
:style="{
backgroundColor: slide.bgColor,
transform: `translateY(${-(index - activeSlideIndex) * 100}%)`,
}">
<h1 class="-mt-8 mb-2 text-4xl">{{ slide.title }}</h1>
<p class="text-lg">{{ slide.description }}</p>
</div>
<!-- 向下按钮 -->
<div class="absolute top-1/2 right-0 z-20 -translate-y-1/2">
<button
class="rounded-l-md bg-white p-4 text-gray-500 shadow hover:text-black"
@click="changeSlide('down')">
👇
</button>
</div>
</div>
<!-- 右侧 -->
<div class="relative h-full w-[65%] overflow-hidden">
<div
v-for="(slide, index) in rightSlides"
:key="index"
class="absolute inset-0 h-full w-full bg-cover bg-center bg-no-repeat transition-all duration-500 ease-in-out"
:class="[index === activeSlideIndex ? 'z-10' : 'pointer-events-none z-0']"
:style="{
backgroundImage: `url(${slide.imageUrl})`,
transform: `translateY(${(index - activeSlideIndex) * 100}%)`,
}"></div>
<!-- 向上按钮 -->
<div class="absolute top-1/2 left-0 z-20 -translate-y-1/2">
<button
class="rounded-r-md bg-white p-4 text-gray-500 shadow hover:text-black"
@click="changeSlide('up')">
👆
</button>
</div>
</div>
</div>
</template>
脚本逻辑 <script setup>
js
<script setup>
import { ref } from 'vue'
const activeSlideIndex = ref(0)
const leftSlides = [
{ title: 'Flying eagle', description: 'in the sunset', bgColor: '#FFB866' },
{ title: 'Lonely castle', description: 'in the wilderness', bgColor: '#252E33' },
{ title: 'Bluuue Sky', description: "with it's mountains", bgColor: '#2A86BA' },
{ title: 'Nature flower', description: 'all in pink', bgColor: '#FD3555' },
]
const rightSlides = [
{
imageUrl:
'https://images.unsplash.com/photo-1508768787810-6adc1f613514?auto=format&fit=crop&w=1350&q=80',
},
{
imageUrl:
'https://images.unsplash.com/photo-1519981593452-666cf05569a9?auto=format&fit=crop&w=715&q=80',
},
{
imageUrl:
'https://images.unsplash.com/photo-1486899430790-61dbf6f6d98b?auto=format&fit=crop&w=1002&q=80',
},
{
imageUrl:
'https://images.unsplash.com/photo-1510942201312-84e7962f6dbb?auto=format&fit=crop&w=1050&q=80',
},
]
function changeSlide(direction) {
if (direction === 'up') {
activeSlideIndex.value = (activeSlideIndex.value + 1) % leftSlides.length
} else {
activeSlideIndex.value =
(activeSlideIndex.value - 1 + leftSlides.length) % leftSlides.length
}
}
</script>
🔍 重点效果实现
✅ 全屏容器布局
我们使用了以下结构创建全屏容器:
html
<div class="relative flex h-screen w-screen overflow-hidden">
这样可以确保整个组件占满浏览器视口,同时防止滚动条出现。
💡 左右区域联动滑动
通过 transform: translateY(...)
来实现滑动动画:
js
transform: `translateY(${-(index - activeSlideIndex) * 100}%)`
左侧向上滑动时,文字向上;右侧向下,图片向上,形成"联动"视觉效果。
🎮 按钮控制滑动方向
通过两个按钮分别控制上一张和下一张:
js
function changeSlide(direction) {
if (direction === 'up') {
activeSlideIndex.value = (activeSlideIndex.value + 1) % leftSlides.length
} else {
activeSlideIndex.value =
(activeSlideIndex.value - 1 + leftSlides.length) % leftSlides.length
}
}
实现了循环切换功能,避免索引越界。
🎨 TailwindCSS 样式重点讲解
类名 | 作用 |
---|---|
flex h-screen w-screen |
全屏 Flex 容器 |
overflow-hidden |
防止内容溢出 |
absolute inset-0 |
绝对定位,覆盖父容器 |
transition-all duration-500 ease-in-out |
平滑动画过渡 |
bg-cover , bg-center , bg-no-repeat |
图片自适应背景 |
text-white , text-4xl |
文字样式 |
rounded-l-md , p-4 , hover:text-black |
按钮样式 |
top-1/2 -translate-y-1/2 |
居中垂直定位按钮 |
这些 TailwindCSS 类帮助我们快速构建了一个美观、响应式的全屏轮播组件。
📁 数据分离建议(可选)
你可以将 leftSlides
和 rightSlides
提取到单独的 JSON 文件中,便于维护和国际化:
json
// slides.js
export const leftSlides = [
{ title: 'Flying eagle', description: 'in the sunset', bgColor: '#FFB866' },
...
]
并在组件中导入:
js
import { leftSlides, rightSlides } from '@/data/slides'
📁 常量定义 + 组件路由
constants/index.js
添加组件预览常量:
js
{
id: 26,
title: 'Double Vertical Slider',
image: 'https://50projects50days.com/img/projects-img/26-double-vertical-slider.png',
link: 'DoubleVerticalSlider',
},
router/index.js
中添加路由选项:
js
{
path: '/DoubleVerticalSlider',
name: 'DoubleVerticalSlider',
component: () => import('@/projects/DoubleVerticalSlider.vue'),
},
🏁 总结
Vue 3 和 TailwindCSS 的全屏垂直轮播组件不仅实现了左右联动的滑动效果,还展示了如何通过响应式数据驱动 UI 变化。
适合用于需要高视觉表现力的网页场景,如企业主页、产品介绍页、摄影作品展示等。
你可以进一步扩展此组件的功能包括:
- ✅ 自动播放(定时切换)
- ✅ 支持键盘上下键切换
- ✅ 添加分页指示器(圆点或数字)
- ✅ 支持触摸滑动(移动端适配)
- ✅ 将组件封装为
<AppCarousel />
可复用组件
👉 下一篇,我们将完成ToastNotification
组件,一个非常有趣的气泡消息通知。🚀
感谢阅读,欢迎点赞、收藏和分享 😊