📅 我们继续 50 个小项目挑战!------ SplitLandingPage
组件

在这篇文章中,我们将实现一个交互式的左右面板对比组件,当用户将鼠标悬停在某一侧时,该侧会自动扩展以获得更多展示空间,提供强烈的视觉聚焦效果 ✨
适用于:商品对比、双选项引导页面、动态首页背景等场景
🎯 组件目标
- 左右两个全屏高度的面板
- 鼠标悬停在任一面板上时,该面板自动扩展至 75% 宽度,另一面板缩小至 25%
- 鼠标移出后恢复 50% 对半布局
- 背景支持图片和透明遮罩,内容居中展示标题与按钮
🛠️ 技术实现点
- 使用 Vue 的
ref
+reactive
实现响应式状态追踪 - 使用 TailwindCSS 原子类管理布局、动画、背景和文本样式
- 利用
@mousemove
和@mouseleave
事件监听鼠标位置 - 根据鼠标区域动态绑定 class 控制宽度动画
🧱 SplitLandingPage.vue
组件实现
html
<template>
<div
class="head-text flex h-screen items-center justify-center text-black"
ref="container"
@mousemove="handleMouseMove"
@mouseleave="resetPanels">
<!-- 左侧面板 -->
<div
ref="leftSide"
:class="[ 'relative h-full transition-all duration-700 ease-in-out', activePanel === 'left' ? 'w-3/4' : activePanel === 'none' ? 'w-1/2' : 'w-1/4' ]">
<div class="absolute inset-0 bg-[url(@/assets/ps.jpg)] bg-cover"></div>
<div class="absolute inset-0 bg-pink-300/50"></div>
<div class="absolute inset-0 flex flex-col items-center justify-center gap-10 text-white">
<p class="text-6xl font-bold">Playstation 5</p>
<button class="rounded-lg bg-pink-500 px-6 py-2 text-white transition-all hover:bg-pink-600">
BUY NOW
</button>
</div>
</div>
<!-- 右侧面板 -->
<div
ref="rightSide"
:class="[ 'relative h-full transition-all duration-700 ease-in-out', activePanel === 'right' ? 'w-3/4' : activePanel === 'none' ? 'w-1/2' : 'w-1/4' ]">
<div class="absolute inset-0 bg-[url(@/assets/xbox.jpg)] bg-cover"></div>
<div class="absolute inset-0 bg-gray-200/50"></div>
<div class="absolute inset-0 flex flex-col items-center justify-center gap-10 text-white">
<p class="text-6xl font-bold">Xbox Series X</p>
<button class="rounded-lg bg-gray-700 px-6 py-2 text-white transition-all hover:bg-gray-800">
BUY NOW
</button>
</div>
</div>
</div>
</template>
🧩 重点效果实现
js
const handleMouseMove = (e) => {
if (!container.value) return
const containerWidth = container.value.offsetWidth
const mouseX = e.clientX
activePanel.value = mouseX < containerWidth / 2 ? 'left' : 'right'
}
const resetPanels = () => {
activePanel.value = 'none'
}
handleMouseMove
:根据鼠标位置设置当前激活面板resetPanels
:鼠标移出容器,恢复为中间对称状态
🎨 TailwindCSS 样式重点讲解
类名 | 作用说明 |
---|---|
w-3/4 、w-1/2 、w-1/4 |
控制宽度动态响应 |
transition-all |
添加平滑过渡效果 |
duration-700 |
设置动画时长 700ms |
ease-in-out |
提升动画曲线体验 |
absolute inset-0 |
实现背景图和遮罩的层叠与填充 |
bg-[url(...)] bg-cover |
加载背景图并保持填充 |
bg-pink-300/50 |
半透明粉色遮罩层 |
text-6xl font-bold |
设置标题文字样式 |
hover:bg-pink-600 |
按钮 hover 态变色 |
🧾 常量定义 + 组件路由建议
constants/index.js
添加组件预览常量:
js
export const projectList = [
{
id: 7,
title: 'Split Landing Page',
image: 'https://50projects50days.com/img/projects-img/7-split-landing-page.png',
link: 'SplitLandingPage',
},
]
router/index.js
中添加路由选项:
js
{
path: '/SplitLandingPage',
name: 'SplitLandingPage',
component: () => import('@/projects/SplitLandingPage.vue'),
},
🧠 小结
通过 Vue 的响应式状态 + Tailwind 的原子类动画能力,我们成功实现了一个交互性十足的左右悬停扩展对比组件。它不仅视觉吸引力强,而且极其易于维护和扩展。如果你在构建商城首页、交互引导页或产品对比模块,这个模式可以完美复用!🚀
👉 下一篇,我们将完成一个简单灵动的 FromWave
组件,适合任何表单搜集页面!🚀