Vue.js实现大转盘抽奖总结及实现思路

 大家好!先上图看看本次案例的整体效果。

Vue.js实现大转盘抽奖总结及实现思路

       实现思路:

Vue component实现大转盘组件,可以嵌套到任意要使用的页面。

css3 transform控制大转盘抽奖过程的动画效果。

抽奖组件内使用钩子函数watch监听抽奖结果的返回情况播放大转盘动画并给用户弹出中奖提示。

中奖结果弹窗,为抽奖组件服务。

       实现步骤如下:

 构建api奖品配置信息和抽奖接口,vuex全局存放奖品配置和中奖结果数据信息。

api:

export default {
 getPrizeList () {
  let prizeList = [
   {
    id: 1,
    name: \'小米8\',
    img: \'https://i1.mifile.cn/f/i/g/2015/cn-index/m8-140.png\'
   },
   {
    id: 2,
    name: \'小米电视\',
    img: \'https://i1.mifile.cn/f/i/g/2015/TV4A-43QC.png\'
   }, {
    id: 3,
    name: \'小米平衡车\',
    img: \'https://i1.mifile.cn/f/i/g/2015/cn-index/scooter-140!140x140.jpg\'
   }, {
    id: 4,
    name: \'小米耳机\',
    img: \'https://c1.mifile.cn/f/i/g/2015/video/pinpai140!140x140.jpg\'
   }
  ]
  return prizeList
 },
 lottery () {
  return {
   id: 4,
   name: \'小米耳机\',
   img: \'https://c1.mifile.cn/f/i/g/2015/video/pinpai140!140x140.jpg\'
  }
 }
}

store:

import lotteryApi from \'../../api/lottery.api.js\'
const state = {
 prizeList: [],
 lotteryResult: {}
}
const getters = {
 prizeList: state => state.prizeList,
 lotteryResult: state => state.lotteryResult
}
const mutations = {
 SetPrizeList (state, { prizeList }) {
  state.prizeList = prizeList
 },
 SetLotteryResult (state, { lotteryResult }) {
  state.lotteryResult = lotteryResult
 }
}
const actions = {
 getPrizeList ({ commit }) {
  let result = lotteryApi.getPrizeList()
  commit(\'SetPrizeList\', { prizeList: result })
 },
 lottery ({ commit }) {
  let result = lotteryApi.lottery()
  commit(\'SetLotteryResult\', { lotteryResult: result })
 }
}

export default {
 state,
 getters,
 mutations,
 actions,
 namespaced: true
}

编写抽奖组件,为保证通用性,组件只负责播放抽奖结果。接收两个数据和一个方法,如下:

数据一:预置的奖品列表数据(轮播奖品需要)

数据二:抽奖结果,播放抽奖动画和弹出中奖结果需要

方法:抽奖动作,返回的抽奖结果数据即为数据二,响应式传递给组件

大概代码思路如下(仅供参考,不可运行)

<template>
 <section>
  <div class=\"lucky-item\">
   <img src=\"//www.cnblogs.com/images/cnblogs_com/codeon/878827/o_backImage.jpg\"
      alt>
   <div class=\"lucky-box\">
    <img src=\"//www.cnblogs.com/images/cnblogs_com/codeon/878827/o_circle.jpg\"
       alt>
    <ul id=\"wheel\"
      class=\"wheel-list\"
      :style=\"wheelStyle\"
      :class=\"transition\">
     <li v-for=\"(prize,index) in slotPrizes\"
       :style=\"{transform: \'rotate(\'+index*45+\'deg)\'}\"
       v-bind:key=\"index\">
      <div class=\"fan-item\"
         style=\"transform: rotate(15deg) skewY(45deg);\"></div>
      <div class=\"lucky-prize\">
       <h3>{{prize.name}}</h3>
      </div>
     </li>
    </ul>
    <div class=\"wheel-btn\"
       @click=\"$emit(\'lottery\')\">
     <a>
      <img src=\"//images.cnblogs.com/cnblogs_com/codeon/878827/o_go.jpg\"
         alt>
     </a>
    </div>
   </div>
   <prize-pop :prize=\"lotteryResult\"
         v-if=\"showPrize\"
         @closeLotteryPop=\"showPrize=false\" />
  </div>
 </section>
</template>
<script>
import PrizePop from \'./common/prize-pop.vue\'
export default {
 name: \'BigTurntable\',
 data () {
  return {
   isStart: false,
   showPrize: false,
   wheelStyle: { \'transform\': \'rotate(0deg)\' },
   transition: \'transitionclear\',
   playTurns: 5 // 默认先旋转5圈
  }
 },
 components: {
  PrizePop
 },
 props: {
  prizes: {
   type: Array,
   required: false
  },
  lotteryResult: {
   type: Object,
   default: () => { }
  }
 },
 computed: {
  slotPrizes () {
   var self = this
   console.log(self.prizes)
   let prizeList = []
   prizeList.push({ ...self.prizes[0], slotIndex: 1 })
   prizeList.push({ name: \'谢谢参与\', slotIndex: 2 })
   prizeList.push({ ...self.prizes[1], slotIndex: 3 })
   prizeList.push({ name: \'谢谢参与\', slotIndex: 4 })
   prizeList.push({ ...self.prizes[2], slotIndex: 5 })
   prizeList.push({ name: \'谢谢参与\', slotIndex: 6 })
   prizeList.push({ ...self.prizes[3], slotIndex: 7 })
   prizeList.push({ name: \'谢谢参与\', slotIndex: 8 })
   console.log(prizeList)
   return prizeList
  }
 },
 methods: {
  /**
   * 执行抽奖动画
   */
  playWheel (index) {
   
  },
   /**
   * 获取中奖结果所在奖品列表中的索引,以确定抽奖动画最终落在哪个奖品
  */
  getPrizeIndex (prizeId) {
  
  }
 },
 watch: {
/**
   * 监听抽奖结果,一旦有中奖信息就开始执行抽奖动画
   */
  lotteryResult (newVal, oldVal) {
   var self = this
   if (newVal.id && newVal.id > 0) {
    let index = self.getPrizeIndex(newVal.id)
    self.playWheel(index)
   }
  }
 }
}
</script>

弹出中奖结果组件,依附于抽奖组件,在上一步的执行抽奖结果动画结束后执行。

<template>
<div class=\"subject-pop\" style=\"z-index: 10;\" v-if=\"prize.id>0\">
   <div class=\"subject-pop-mask\"></div>
   <div class=\"subject-pop-box\">
    <h3>恭喜您</h3>
    <p>
     <img :src=\"prize.img\" alt>
    </p>
    <h4>获得
     <span></span>
     <span>{{prize.name}}</span>
    </h4>
    <div class=\"subject-pop-footer\">
     <a href=\"javascript:;\" rel=\"external nofollow\" class=\"november-btn1\" @click=\"closeLotteryEmit\">知道了</a>
    </div>
   </div>
  </div>
</template>
<script>
export default {
 props: {
  prize: {
   type: Object,
   default: () => {
    return {
     id: 0
    }
   }
  }
 },
 methods: {
  closeLotteryEmit () {
   this.$emit(\'closeLotteryPop\')
  }
 }
}
</script>

抽奖组件运用在需要使用的页面中,此页面需要为抽奖组件提前准备好预置奖品列表和中奖结果信息,并提供好抽奖方法供子组件(抽奖组件)触发,触发完更改抽奖结果响应式传入到抽奖组件中。

<template>
 <section>
  <div style=\"width:100%;text-align:center;margin:2rem 0;\">您有一次抽奖机会,祝君好运~~~</div>
  <BigTurntable :prizes=\"prizeList\"
         :lotteryResult=\"lotteryResult\"
         @lottery=\"lottery\" />
 </section>
</template>

<script>
import { mapGetters, mapActions } from \'vuex\'
import BigTurntable from \'@/components/bigTurntable.vue\'
export default {
 name: \'BigTurntableRun\',
 created () {
  var self = this
  self.getPrizeList()
 },
 components: {
  BigTurntable
 },
 computed: {
  ...mapGetters({
   prizeList: \'lottery/prizeList\',
   lotteryResult: \'lottery/lotteryResult\'
  })
 },
 methods: {
  ...mapActions({
   getPrizeList: \'lottery/getPrizeList\',
   lottery: \'lottery/lottery\'
  })
 }
}
</script>

以上所述是小编给大家介绍的Vue.js实现大转盘抽奖总结及实现思路,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对网站的支持!
如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容