vue实现抽奖
Vue 实现抽奖功能
基本抽奖逻辑
创建一个Vue组件,包含奖品列表、抽奖按钮和结果显示区域。使用随机数生成器选择奖品。
<template>
<div>
<h2>抽奖活动</h2>
<button @click="startLottery" :disabled="isDrawing">开始抽奖</button>
<div v-if="result">恭喜获得: {{ result }}</div>
</div>
</template>
<script>
export default {
data() {
return {
prizes: ['一等奖', '二等奖', '三等奖', '参与奖'],
isDrawing: false,
result: null
}
},
methods: {
startLottery() {
this.isDrawing = true
this.result = null
setTimeout(() => {
const randomIndex = Math.floor(Math.random() * this.prizes.length)
this.result = this.prizes[randomIndex]
this.isDrawing = false
}, 2000)
}
}
}
</script>
动画效果增强
添加转盘动画效果,使抽奖过程更生动。使用CSS过渡和Vue的过渡组件。
<template>
<div>
<transition name="rotate">
<div class="prize-wheel" :style="{ transform: `rotate(${rotation}deg)` }">
<div v-for="(prize, index) in prizes" :key="index" class="prize-item">
{{ prize }}
</div>
</div>
</transition>
<button @click="spinWheel">旋转转盘</button>
</div>
</template>
<script>
export default {
data() {
return {
prizes: ['奖品1', '奖品2', '奖品3', '奖品4'],
rotation: 0,
isSpinning: false
}
},
methods: {
spinWheel() {
if (this.isSpinning) return
this.isSpinning = true
const spins = 5 // 旋转圈数
const targetAngle = 360 * spins + Math.floor(Math.random() * 360)
this.rotation = 0
setTimeout(() => {
this.rotation = targetAngle
setTimeout(() => {
const prizeIndex = Math.floor((targetAngle % 360) / (360 / this.prizes.length))
alert(`恭喜获得: ${this.prizes[prizeIndex]}`)
this.isSpinning = false
}, 5000) // 动画持续时间
}, 50)
}
}
}
</script>
<style>
.prize-wheel {
width: 300px;
height: 300px;
border-radius: 50%;
position: relative;
transition: transform 5s cubic-bezier(0.17, 0.67, 0.12, 0.99);
background: conic-gradient(
red 0% 25%,
blue 25% 50%,
green 50% 75%,
yellow 75% 100%
);
}
.prize-item {
position: absolute;
width: 100%;
text-align: center;
transform-origin: center;
color: white;
font-weight: bold;
}
</style>
概率控制
实现不同奖品的中奖概率控制,使用权重随机算法。
methods: {
weightedRandom() {
const weights = [10, 20, 30, 40] // 对应奖品的权重
const total = weights.reduce((a, b) => a + b, 0)
const random = Math.random() * total
let current = 0
for (let i = 0; i < weights.length; i++) {
current += weights[i]
if (random <= current) {
return this.prizes[i]
}
}
return this.prizes[0] // 默认返回第一个奖品
}
}
服务器交互
从后端API获取奖品列表和中奖结果,增加真实性。
methods: {
async fetchPrizes() {
try {
const response = await axios.get('/api/prizes')
this.prizes = response.data
} catch (error) {
console.error('获取奖品失败:', error)
}
},
async drawPrize() {
try {
const response = await axios.post('/api/draw')
this.result = response.data.prize
} catch (error) {
console.error('抽奖失败:', error)
}
}
}
防止重复抽奖
添加抽奖次数限制,使用localStorage记录抽奖状态。
methods: {
checkDrawLimit() {
const today = new Date().toDateString()
const lastDraw = localStorage.getItem('lastDrawDate')
const drawCount = localStorage.getItem('drawCount') || 0
if (lastDraw === today && drawCount >= 3) {
alert('今日抽奖次数已达上限')
return false
}
return true
},
updateDrawRecord() {
const today = new Date().toDateString()
const lastDraw = localStorage.getItem('lastDrawDate')
let drawCount = localStorage.getItem('drawCount') || 0
if (lastDraw === today) {
drawCount++
} else {
drawCount = 1
}
localStorage.setItem('lastDrawDate', today)
localStorage.setItem('drawCount', drawCount)
}
}






