vue 实现红包雨
实现红包雨的基本思路
红包雨是一种常见的互动效果,通常在节日或促销活动中使用。Vue.js 可以通过结合 CSS 动画和 JavaScript 逻辑来实现这一效果。
创建红包雨组件
在 Vue 中创建一个红包雨组件,用于管理红包的生成、动画和交互逻辑。

<template>
<div class="red-packet-rain">
<div
v-for="(packet, index) in packets"
:key="index"
class="red-packet"
:style="{
left: `${packet.left}px`,
top: `${packet.top}px`,
animationDuration: `${packet.duration}s`,
}"
@click="handleClick(packet)"
>
{{ packet.amount }}
</div>
</div>
</template>
定义红包数据结构
红包数据包含位置、下落速度和金额等信息。
<script>
export default {
data() {
return {
packets: [],
maxPackets: 50, // 最大红包数量
raining: false,
};
},
methods: {
startRain() {
this.raining = true;
this.generatePackets();
},
generatePackets() {
if (!this.raining || this.packets.length >= this.maxPackets) return;
const packet = {
left: Math.random() * window.innerWidth,
top: -50,
duration: Math.random() * 3 + 2, // 下落时间
amount: Math.floor(Math.random() * 100) + 1, // 随机金额
};
this.packets.push(packet);
setTimeout(() => {
this.generatePackets();
}, 200); // 生成间隔
},
handleClick(packet) {
alert(`恭喜获得 ${packet.amount} 元红包!`);
this.packets = this.packets.filter((p) => p !== packet);
},
},
};
</script>
添加红包样式
通过 CSS 实现红包的下落动画和样式。

<style>
.red-packet-rain {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
pointer-events: none;
overflow: hidden;
}
.red-packet {
position: absolute;
width: 50px;
height: 60px;
background: url('red-packet.png') no-repeat;
background-size: contain;
pointer-events: auto;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
color: gold;
font-weight: bold;
animation: fall linear;
}
@keyframes fall {
to {
transform: translateY(100vh);
}
}
</style>
控制红包雨的开始和结束
在父组件中控制红包雨的启动和停止。
<template>
<div>
<button @click="startRain">开始红包雨</button>
<button @click="stopRain">停止红包雨</button>
<RedPacketRain ref="redPacketRain" />
</div>
</template>
<script>
import RedPacketRain from './RedPacketRain.vue';
export default {
components: { RedPacketRain },
methods: {
startRain() {
this.$refs.redPacketRain.startRain();
},
stopRain() {
this.$refs.redPacketRain.raining = false;
this.$refs.redPacketRain.packets = [];
},
},
};
</script>
优化性能
对于大量红包,可以使用 requestAnimationFrame 优化动画性能。
methods: {
animate() {
if (!this.raining) return;
this.packets.forEach((packet) => {
packet.top += 2; // 下落速度
if (packet.top > window.innerHeight) {
this.packets = this.packets.filter((p) => p !== packet);
}
});
requestAnimationFrame(this.animate);
},
startRain() {
this.raining = true;
this.animate();
this.generatePackets();
},
}
注意事项
- 红包图片需提前准备好,或使用纯色背景代替。
- 移动端需调整红包大小和点击区域。
- 可根据需求调整红包数量、下落速度和金额范围。






