vue实现轮播抽奖
Vue 轮播抽奖实现方案
核心思路
- 使用 Vue 的
v-for渲染奖品列表 - 通过 CSS 动画实现滚动效果
- 利用 JavaScript 定时器控制停止逻辑
基础实现代码
<template>
<div class="lottery-container">
<div class="prize-list" :style="{ transform: `translateY(${offset}px)` }">
<div v-for="(prize, index) in prizes" :key="index" class="prize-item">
{{ prize.name }}
</div>
</div>
<button @click="startLottery">开始抽奖</button>
</div>
</template>
<script>
export default {
data() {
return {
prizes: [
{ name: '奖品1' },
{ name: '奖品2' },
{ name: '奖品3' },
{ name: '奖品4' },
{ name: '奖品5' }
],
offset: 0,
speed: 30,
timer: null,
targetIndex: 0
}
},
methods: {
startLottery() {
this.targetIndex = Math.floor(Math.random() * this.prizes.length)
this.roll()
},
roll() {
this.timer = setInterval(() => {
this.offset -= this.speed
if (this.offset % 60 === 0) {
this.checkStop()
}
}, 50)
},
checkStop() {
const currentIndex = Math.abs(this.offset / 60) % this.prizes.length
if (currentIndex === this.targetIndex && this.speed <= 1) {
clearInterval(this.timer)
this.$emit('finish', this.prizes[this.targetIndex])
} else if (currentIndex === this.targetIndex) {
this.speed *= 0.9
}
}
}
}
</script>
<style>
.lottery-container {
height: 60px;
overflow: hidden;
position: relative;
}
.prize-list {
transition: transform 0.1s ease-out;
}
.prize-item {
height: 60px;
display: flex;
align-items: center;
justify-content: center;
}
</style>
优化方案
-
添加缓动函数实现更自然的停止效果
// 在checkStop方法中修改减速逻辑 this.speed = Math.max(1, this.speed * 0.95) -
增加多轮循环效果
// 修改roll方法 const totalRounds = 3 // 旋转轮数 const totalItems = this.prizes.length * totalRounds + this.targetIndex if (Math.abs(this.offset / 60) >= totalItems) { clearInterval(this.timer) } -
使用 CSS transform 代替 top 属性提升性能
.prize-list { will-change: transform; }
完整组件封装建议
-
通过 props 接收奖品列表
props: { prizeList: { type: Array, default: () => [] } } -
添加回调函数处理抽奖结果
this.$emit('lottery-end', result) -
提供自定义样式插槽

<slot name="prize" :prize="currentPrize"></slot>
注意事项
- 移动端适配需要调整容器高度和动画速度
- 大量奖品时建议使用虚拟滚动技术
- 组件销毁前需清除定时器
beforeDestroy() { clearInterval(this.timer) }






