vue 实现红包雨
Vue 实现红包雨效果
红包雨是一种常见的互动效果,通常在节日或促销活动中使用。以下是使用 Vue 实现红包雨效果的方法。
准备工作
确保项目中已安装 Vue 2 或 Vue 3,并准备好相关依赖。如果使用 Vue 3,建议使用 Composition API 实现。
创建红包组件
创建一个红包组件,用于渲染单个红包。红包可以是图片或简单的 DOM 元素。

<template>
<div class="red-packet" :style="{ left: left + 'px', top: top + 'px' }">
<img src="@/assets/red-packet.png" alt="红包" />
</div>
</template>
<script>
export default {
props: {
left: Number,
top: Number,
},
};
</script>
<style scoped>
.red-packet {
position: absolute;
width: 50px;
height: 70px;
cursor: pointer;
animation: fall linear;
}
@keyframes fall {
to {
transform: translateY(100vh);
}
}
</style>
红包雨逻辑
在父组件中管理红包的生成、下落和点击事件。使用 setInterval 定时生成红包,并为每个红包设置随机位置和下落速度。
<template>
<div class="red-packet-rain">
<RedPacket
v-for="(packet, index) in packets"
:key="index"
:left="packet.left"
:top="packet.top"
@click="collectPacket(index)"
/>
</div>
</template>
<script>
import RedPacket from "./RedPacket.vue";
export default {
components: { RedPacket },
data() {
return {
packets: [],
interval: null,
};
},
mounted() {
this.startRain();
},
beforeUnmount() {
clearInterval(this.interval);
},
methods: {
startRain() {
this.interval = setInterval(() => {
this.packets.push({
left: Math.random() * (window.innerWidth - 50),
top: -70,
speed: 2 + Math.random() * 3,
});
}, 300);
},
collectPacket(index) {
this.packets.splice(index, 1);
// 处理红包点击逻辑,如增加积分或显示奖励
},
},
};
</script>
<style scoped>
.red-packet-rain {
position: relative;
width: 100vw;
height: 100vh;
overflow: hidden;
}
</style>
动画优化
为红包添加下落动画,可以通过 CSS 或 JavaScript 实现。CSS 动画性能更好,但 JavaScript 可以更灵活地控制速度。

.red-packet {
animation-duration: calc(1s * var(--speed));
}
在生成红包时动态设置 --speed:
this.packets.push({
left: Math.random() * (window.innerWidth - 50),
top: -70,
speed: 2 + Math.random() * 3,
style: `--speed: ${2 + Math.random() * 3}`,
});
点击事件处理
红包点击后移除红包并触发奖励逻辑。可以通过事件总线或 Vuex 管理全局状态。
collectPacket(index) {
const packet = this.packets[index];
this.packets.splice(index, 1);
this.$emit('collect', packet);
}
性能优化
大量红包可能导致性能问题,可以通过以下方式优化:
- 使用
requestAnimationFrame替代setInterval。 - 限制红包数量,移除超出屏幕的红包。
- 使用 CSS
will-change属性提升动画性能。
updatePackets() {
this.packets = this.packets.filter(packet => {
packet.top += packet.speed;
return packet.top < window.innerHeight;
});
requestAnimationFrame(this.updatePackets);
}
通过以上步骤,可以实现一个基本的红包雨效果,并根据需求进一步扩展功能。






