📅 我们继续 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>
<!-- 图片容器 -->
<div
class="relative h-[440px] w-[300px] cursor-pointer overflow-hidden bg-cover bg-center shadow-lg"
:style="{ backgroundImage: `url(${imageUrl})` }"
@click="handleClick"
ref="container">
<i
v-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 = 0
const 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.left
const yInside = e.clientY - rect.top
const 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
组件,一个类似打字机的组件,可以调节速度。🚀
感谢阅读,欢迎点赞、收藏和分享 😊