50天50个小项目 (Vue3 + Tailwindcss V4) ✨ | DoubleClickHeart(双击爱心)
📅 我们继续 50 个小项目挑战!—— DoubleClickHeart
组件
仓库地址:https://github.com/SunACong/50-vue-projects
项目预览地址:https://50-vue-projects.vercel.app/
使用 Vue 3 的 Composition API(<script setup>
)结合 TailwindCSS 和 Font Awesome 创建一个双击点赞动画组件。用户可以双击图片区域触发一个“❤️ 爱心飞出”动画,并统计点赞次数。
这个交互体验非常适用于社交媒体、照片墙、内容点赞等场景。
🎯 组件目标
- 用户双击图片区域时显示爱心动画
- 显示当前点赞总次数
- 动画结束后自动移除爱心元素
- 使用 Vue 3 Composition API 管理状态
- 使用 TailwindCSS 构建 UI 样式与布局
- 支持动态定位和点击时间判断
⚙️ 技术实现点
技术点 | 描述 |
---|---|
Vue 3 <script setup> | 使用响应式变量管理点赞数、爱心列表 |
ref 响应式变量 | 控制 likes 、hearts 和 DOM 容器引用 |
双击检测逻辑 | 判断两次点击时间间隔是否小于 800ms |
动态创建元素 | 在点击位置生成爱心图标并添加动画 |
TailwindCSS 样式 | 设置图片容器、文字样式、动画基础属性 |
自定义字体加载 | 使用 JS 动态加载 Oswald 字体与 Font Awesome 图标库 |
CSS 关键帧动画 | 实现放大淡出的爱心动画效果 |
🧱 组件实现
模板结构 <template>
<template><div class="flex min-h-screen flex-col items-center justify-center overflow-hidden font-[Oswald] text-white"><h3 class="mb-0 text-center">Double click on the image to<i class="fas fa-heart text-red-600"></i>it</h3><small class="mb-5 block text-center">You liked it<span>{{ likes }}</span>times</small><!-- 图片容器 --><divclass="relative h-[440px] w-[300px] cursor-pointer overflow-hidden bg-cover bg-center shadow-lg":style="{ backgroundImage: `url(${imageUrl})` }"@click="handleClick"ref="container"><iv-for="heart in hearts":key="heart.id"class="fas fa-heart heart-anim absolute text-red-600":style="{ top: heart.y + 'px', left: heart.x + 'px' }"></i></div></div>
</template>
脚本逻辑 <script setup>
<script setup>
import { onMounted, ref } from 'vue'const likes = ref(0)
const hearts = ref([])
const container = ref(null)
let clickTime = 0const handleClick = (e) => {const now = new Date().getTime()if (clickTime === 0) {clickTime = now} else {if (now - clickTime < 800) {createHeart(e)clickTime = 0} else {clickTime = now}}
}const createHeart = (e) => {const rect = container.value.getBoundingClientRect()const xInside = e.clientX - rect.leftconst yInside = e.clientY - rect.topconst id = Date.now()hearts.value.push({ id, x: xInside, y: yInside })likes.value++setTimeout(() => {hearts.value = hearts.value.filter((h) => h.id !== id)}, 1000)
}const imageUrl ='https://images.unsplash.com/photo-1504215680853-026ed2a45def?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=334&q=80'onMounted(() => {const fontLink = document.createElement('link')fontLink.href = 'https://fonts.googleapis.com/css?family=Oswald'fontLink.rel = 'stylesheet'document.head.appendChild(fontLink)const faLink = document.createElement('link')faLink.href = 'https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.14.0/css/all.min.css'faLink.rel = 'stylesheet'faLink.crossOrigin = 'anonymous'document.head.appendChild(faLink)
})
</script>
样式部分 <style scoped>
<style scoped>
.heart-anim {position: absolute;animation: grow 0.6s linear;transform: translate(-50%, -50%) scale(0);
}@keyframes grow {to {transform: translate(-50%, -50%) scale(10);opacity: 0;}
}
</style>
🔍 重点效果实现
✅ 双击事件判断
通过记录点击时间戳来判断是否为双击行为:
const now = new Date().getTime()
if (now - clickTime < 800) {createHeart(e)clickTime = 0
} else {clickTime = now
}
这是模拟原生 dblclick
事件的一种方式,同时保留了对单击行为的控制。
💡 动态生成爱心图标
每次双击会根据点击坐标生成一个爱心图标:
hearts.value.push({ id, x: xInside, y: yInside })
并在一秒后自动从数组中移除,以实现动画结束后的清理。
🎨 动画设计
使用 CSS 关键帧实现放大并透明消失的效果:
@keyframes grow {to {transform: translate(-50%, -50%) scale(10);opacity: 0;}
}
配合 Tailwind 的 absolute
定位,实现了视觉上“从点击点飞出”的效果。
🎨 TailwindCSS 样式重点讲解
类名 | 作用 |
---|---|
min-h-screen , flex-col , items-center , justify-center | 居中布局 |
font-[Oswald] , text-white | 字体与文字颜色 |
relative , absolute | 心形图标的绝对定位 |
h-[440px] w-[300px] | 固定图片容器大小 |
bg-cover bg-center | 设置背景图片居中覆盖 |
cursor-pointer | 鼠标悬停为手型 |
overflow-hidden | 防止爱心动画溢出容器 |
shadow-lg | 添加阴影提升层次感 |
text-red-600 | 爱心颜色设置为红色 |
这些类帮助我们快速构建了一个美观、互动性强的点赞组件。
📁 常量定义 + 组件路由
constants/index.js
添加组件预览常量:
{id: 29,title: 'Double Click Heart',image: 'https://50projects50days.com/img/projects-img/29-double-click-heart.png',link: 'DoubleClickHeart',},
router/index.js
中添加路由选项:
{path: '/DoubleClickHeart',name: 'DoubleClickHeart',component: () => import('@/projects/DoubleClickHeart.vue'),},
🏁 总结
基于 Vue 3 和 TailwindCSS 的双击点赞动画组件不仅实现了基本的交互功能,它非常适合用于社交平台、图片浏览、内容互动等需要增强用户体验的场景。
你可以进一步扩展此组件的功能包括:
- ✅ 添加音效反馈(如“滴”一声)
- ✅ 支持移动端触摸双击识别
- ✅ 支持本地存储点赞数(使用 localStorage)
- ✅ 添加粒子爆炸或其他动画效果
- ✅ 将组件封装为
<DoubleHeartImage />
可复用组件
👉 下一篇,我们将完成AutoTextEffect
组件,一个类似打字机的组件,可以调节速度。🚀
感谢阅读,欢迎点赞、收藏和分享 😊