1. 程式人生 > 實用技巧 >H5九宮格抽獎,親測可用

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>