vue实现抽奖
Vue 实现抽奖功能
基本抽奖逻辑
使用 Vue 的响应式特性管理抽奖状态和数据。定义一个奖品数组,通过随机数生成器选中奖品。

data() {
return {
prizes: ['一等奖', '二等奖', '三等奖', '谢谢参与'],
isRolling: false,
result: ''
}
},
methods: {
startLottery() {
if (this.isRolling) return
this.isRolling = true
// 模拟抽奖过程
const rollInterval = setInterval(() => {
this.result = this.prizes[Math.floor(Math.random() * this.prizes.length)]
}, 100)
// 3秒后停止
setTimeout(() => {
clearInterval(rollInterval)
this.isRolling = false
this.showResult()
}, 3000)
},
showResult() {
alert(`恭喜获得: ${this.result}`)
}
}
转盘抽奖实现
使用 CSS 动画创建转盘效果,通过旋转角度决定中奖结果。

<template>
<div class="wheel-container">
<div
class="wheel"
:style="{ transform: `rotate(${rotateDegree}deg)` }"
@click="startSpin"
></div>
<div class="pointer"></div>
</div>
</template>
<script>
export default {
data() {
return {
sectors: [
{ text: '一等奖', color: '#FF0000', angle: 30 },
{ text: '二等奖', color: '#00FF00', angle: 90 },
// 更多奖品...
],
rotateDegree: 0,
isSpinning: false
}
},
methods: {
startSpin() {
if (this.isSpinning) return
this.isSpinning = true
const spinDuration = 3000 // 3秒
const targetRotation = 360 * 5 + this.getRandomPrizeAngle()
this.rotateDegree = 0
const startTime = Date.now()
const animate = () => {
const elapsed = Date.now() - startTime
const progress = Math.min(elapsed / spinDuration, 1)
const easeProgress = this.easeOut(progress)
this.rotateDegree = easeProgress * targetRotation
if (progress < 1) {
requestAnimationFrame(animate)
} else {
this.isSpinning = false
this.showResult()
}
}
animate()
},
getRandomPrizeAngle() {
// 根据概率返回对应奖品角度
return this.sectors[0].angle // 示例
},
easeOut(t) {
return 1 - Math.pow(1 - t, 3)
}
}
}
</script>
<style>
.wheel-container {
position: relative;
width: 300px;
height: 300px;
}
.wheel {
width: 100%;
height: 100%;
border-radius: 50%;
background: conic-gradient(
#FF0000 0 30deg,
#00FF00 30deg 120deg,
/* 更多颜色... */
);
transition: transform 3s cubic-bezier(0.17, 0.67, 0.21, 0.99);
}
.pointer {
position: absolute;
top: -20px;
left: 50%;
transform: translateX(-50%);
width: 0;
height: 0;
border-left: 15px solid transparent;
border-right: 15px solid transparent;
border-top: 30px solid #000;
}
</style>
九宫格抽奖
实现常见的九宫格跑马灯效果抽奖。
data() {
return {
gridItems: [
{ id: 1, text: '奖品1', active: false },
{ id: 2, text: '奖品2', active: false },
// 更多格子...
],
currentIndex: 0,
targetIndex: 5, // 中奖位置
speed: 100,
timer: null
}
},
methods: {
startGridLottery() {
this.resetGrid()
this.timer = setInterval(() => {
this.gridItems[this.currentIndex].active = false
this.currentIndex = (this.currentIndex + 1) % this.gridItems.length
this.gridItems[this.currentIndex].active = true
}, this.speed)
setTimeout(() => {
this.stopAtTarget()
}, 2000)
},
stopAtTarget() {
clearInterval(this.timer)
let steps = 0
const maxSteps = 8 // 最后跑几圈
const slowDown = () => {
steps++
this.gridItems[this.currentIndex].active = false
this.currentIndex = (this.currentIndex + 1) % this.gridItems.length
this.gridItems[this.currentIndex].active = true
if (steps < maxSteps) {
this.speed += 50
setTimeout(slowDown, this.speed)
} else {
this.finalizeResult()
}
}
setTimeout(slowDown, this.speed)
},
finalizeResult() {
// 高亮显示中奖格子
this.gridItems.forEach(item => item.active = false)
this.gridItems[this.targetIndex].active = true
}
}
概率控制
为不同奖品设置不同的中奖概率。
getRandomPrize() {
const probabilities = [
{ prize: '一等奖', chance: 0.01 },
{ prize: '二等奖', chance: 0.1 },
{ prize: '三等奖', chance: 0.2 },
{ prize: '谢谢参与', chance: 0.69 }
]
const random = Math.random()
let cumulative = 0
for (const item of probabilities) {
cumulative += item.chance
if (random <= cumulative) {
return item.prize
}
}
return '谢谢参与'
}
注意事项
- 抽奖动画需要考虑性能,使用 requestAnimationFrame 替代 setTimeout
- 移动端需要添加触摸事件支持
- 中奖概率应该在后端计算,前端仅做展示
- 重要抽奖需要记录日志并验证结果
- 添加开始/结束按钮的状态管理,防止重复点击






