H5九宫格抽奖,亲测可用
前提准备:scss 和 px2rem-loader 具体可以查看
一、新建抽奖组件 Lottery.vue
1、新components建文件夹lottery,包含src文件夹和index.js,src下面新建抽奖组件 Lottery.vue,lottery.scss
index.js
/** * {Array} prizesList : 抽奖图片数组 , 默认 [] * {Object} lotteryBtn : 抽奖按钮图片 , 默认 {img : ""} * {Number} prize : 中奖位置 , 默认 0 * {Number} speed : 速度 , 默认 100 * {Number} cycle : 转动次数 , 默认 20 * {Function} beforeLottery : 抽奖前处理函数 , 可用于发送请求获取结果 , 必须定义 * beforeLottery 需要引入两个参数 resolve 成功之后调用 , reject失败之后调用,可在reject里面写回调函数 * {Function} afterLottery : 抽奖结束回调函数 , 用于处理结果 */ export { default } from './src/Lottery.vue'
Lottery.vue
<template>
<div class="iv-lottery">
<ul>
<li class="row">
<div :class="['col-4' , {active : activeClass[index]}]"
v-for="(item,index) in lis1"
:key="index" class="prize">
<img :src="item.imgUrl">
<p class="prizeName">{{item.prizeName}}</p>
</div>
</li>
<li class="row">
<div :class="['col-4' , {active : activeClass[7]}]" class="prize">
<img :src="lis2Img.imgUrl">
<p class="prizeName">{{lis2Img.prizeName}}</p>
</div>
<div class="col-4"
@click="startLottery">
<div class="luck-btn">
<p class="luck-btn-txt">抽奖</p>
</div>
</div>
<div :class="['col-4' , {active : activeClass[3]}]" class="prize">
<img :src="lis3Img.imgUrl">
<p class="prizeName">{{lis3Img.prizeName}}</p>
</div>
</li>
<li class="row">
<div :class="['col-4' , {active : activeClass[6-index]}]"
v-for="(item,index) in lis4"
:key="index" class="prize">
<img :src="item.imgUrl">
<p class="prizeName">{{item.prizeName}}</p>
</div>
</li>
</ul>
</div>
</template>
<script type="text/javascript">
import './lottery.scss'
export default {
name: 'Lottery',
data () {
return {
activeClass: [false, false, false, false, false, false, false, false],
index: -1,
count: 8,
timer: null,
times: 0,
speedData: 100,
afterLotteryHandler: null
}
},
props: {
prizesList: {
type: Array,
default () {
return []
}
},
lotteryBtn: {
type: Object,
default () {}
},
beforeLottery: {
type: Function,
default () { throw new Error('you must define beforeLottery before draw a lottery ') }
},
afterLottery: {
type: Function,
// eslint-disable-next-line
default () { console.warn('you can use afterLottery after rolling'); }
},
prize: {
type: Number,
default: 0
},
speed: {
type: Number,
default: 100
},
cycle: {
type: Number,
default: 20
}
},
computed: {
lis1 () {
let list = []
this.prizesList.forEach(item => {
if ([1, 2, 3].includes(item.prizeNo)) {
list.push(item)
}
})
// 按照奖品序号排序
list.sort((a, b) => {
return a.prizeNo - b.prizeNo
})
return list
},
lis2Img () {
let row = {}
this.prizesList.forEach(item => {
if (item.prizeNo === 4) {
row.imgUrl = item.imgUrl
row.prizeName = item.prizeName
}
})
return row
},
lis3Img () {
let row = {}
this.prizesList.forEach(item => {
if (item.prizeNo === 5) {
row.imgUrl = item.imgUrl
row.prizeName = item.prizeName
}
})
return row
},
lis4 () {
let list = []
this.prizesList.forEach(item => {
if (item.prizeNo === 6) {
list[0] = item
}
if (item.prizeNo === 7) {
list[1] = item
}
if (item.prizeNo === 8) {
list[2] = item
}
})
return list
}
},
created () {
this.speedData = this.speed
this.afterLotteryHandler = this.afterLottery
},
beforeDestroy () {
this.afterLotteryHandler = () => { }
},
methods: {
startLottery () {
if (!this.lotteryBtn.lock) {
let promise = () => {
return new Promise((resolve, reject) => {
this.lotteryBtn.lock = true
this.beforeLottery(resolve, reject)
})
}
let start = async () => {
try {
await promise()
this.roll()
} catch (e) {
e()
}
}
start()
}
},
_rollHandler () {
var index = this.index
var count = this.count
for (let i = 0, len = this.activeClass.length; i < len; i++) {
this.activeClass[i] = false
}
index += 1
if (index > count - 1) {
index = 0
}
this.activeClass[index] = true
this.index = index
return false
},
roll () {
// eslint-disable-next-line
this.activeClass = this.activeClass.map(item => item = false);
this.times += 1
this._rollHandler()
if (this.times > this.cycle + 10 && this.prize === this.index) {
clearTimeout(this.timer)
setTimeout(
() => { this._showResult() }
, 1000)
this.lotteryBtn.lock = false
this.index = -1
this.count = 8
this.timer = null
this.speedData = this.speed
this.times = 0
} else {
if (this.times < this.cycle) {
this.speedData -= 2
} else {
if (this.times > this.cycle + 10 && ((this.prize === 0 && this.index === 7) || this.prize === this.index + 1)) {
this.speedData += 110
} else {
this.speedData += 20
}
}
if (this.speedData < 40) {
this.speedData = 40
}
this.timer = setTimeout(
() => { this.roll() }
, this.speedData)
}
return false
},
_showResult () {
this.afterLotteryHandler()
}
}
}
</script>
lottery.scss
.iv-lottery { ul { margin: 0 auto; padding:87px 0 0 50px; li { overflow:hidden; position: relative; margin-top:8px; } li div { width:177px; height:177px; position: relative; border-radius: 6px; float: left; margin-left:8px; text-align:center; // &.prize{ // background:#fffafa; // } &.active:before { content: ''; display: block; position: absolute; top: 0; left: 0; width: 100%; height: 100%; border-radius: 5px; background: rgba(255, 135, 46, 0.62); } } img{ width:102px; height:102px; margin-top:18px; &.img-btn{ width:209px; height:160px; position: absolute; left:50%; margin-left:-100px; // top:-10px; } } p{ &.prizeName{ color: #f15c38; font-size:22px; } &.gold{ line-height:28px; margin-top:-8px; } } .luck-btn{ margin-left:0; .luck-btn-txt{ font-size: 75px; color: #f87036; padding-top:20px; } .prizeName{ color: #d92a00; } } } }
二、引入抽奖组件
<template>
<div class="lottery-module">
<p>九宫格抽奖</p>
<lottery :beforeLottery="beforeLottery"
:lotteryBtn="lotteryBtn"
:prizesList="prizesList"
:prize="prize"
:afterLottery="afterLottery"></lottery>
</div>
</template>
<script>
import lottery from '@/components/lottery'
export default {
name: 'Lottery',
components: {
lottery
},
data () {
return {
prize: 0,
lotteryBtn: {
img: '',
lock: false
},
prizesList: [
{imgUrl: require('@/assets/logo.png'), prizeNo: 1, prizeName: '1'},
{imgUrl: require('@/assets/logo.png'), prizeNo: 2, prizeName: '2'},
{imgUrl: require('@/assets/logo.png'), prizeNo: 3, prizeName: '3'},
{imgUrl: require('@/assets/logo.png'), prizeNo: 4, prizeName: '4'},
{imgUrl: require('@/assets/logo.png'), prizeNo: 5, prizeName: '5'},
{imgUrl: require('@/assets/logo.png'), prizeNo: 6, prizeName: '6'},
{imgUrl: require('@/assets/logo.png'), prizeNo: 7, prizeName: '7'},
{imgUrl: require('@/assets/logo.png'), prizeNo: 8, prizeName: '8'}
],
count: 0
}
},
mounted () {
// this.getData()
},
methods: {
getData () {
// 请求接口开始----九宫格抽奖详情
// 次数为0,抽奖按钮置灰,不能抽奖
if (this.count === 0) {
this.lotteryBtn.lock = true
} else {
}
},
beforeLottery (resolve, reject) {
/*
* send ajax to get result and pass to child component
**/
// get result : this.prize
setTimeout(() => {
// 调用抽奖接口开始 ----------
console.log('抽奖开始===========')
// 中奖序号
this.prize = this.lotteryPrize(2)
// 抽奖开始
resolve()
}, 10)
},
// 抽奖九宫格抽奖位置
lotteryPrize (prizeNo) {
let prize
switch (prizeNo) {
case 1:
prize = 0
break
case 2:
prize = 1
break
case 3:
prize = 2
break
case 4:
prize = 7
break
case 5:
prize = 3
break
case 6:
prize = 6
break
case 7:
prize = 4
break
default:
prize = 5
}
return prize
},
// 抽奖结束
afterLottery () {
// 抽奖结果
alert(`恭喜抽中${this.prize}`)
}
}
}
</script>
<style scoped>
</style>

浙公网安备 33010602011771号