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

 更新时间:2019年10月09日 09:10:32   作者:码上组合  
这篇文章主要介绍了 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实现大转盘抽奖总结及实现思路,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对脚本之家网站的支持!
如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!

相关文章

  • vue组件中的数据传递方法

    vue组件中的数据传递方法

    这篇文章主要介绍了vue组件中的数据传递方法,非常不错,具有一定的参考借鉴价值,需要的朋友参考下吧
    2018-05-05
  • vue中定义全局声明vscode插件提示找不到问题解决

    vue中定义全局声明vscode插件提示找不到问题解决

    这篇文章主要为大家介绍了vue中定义全局声明vscode插件提示找不到问题解决,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-05-05
  • Vue实现二维码的展示及下载功能

    Vue实现二维码的展示及下载功能

    这篇文章主要介绍了Vue实现二维码的展示及下载功能,其中downloadQRCode()函数中的url为要下载的文件的路径,本文通过实例代码给大家介绍的非常详细,感兴趣的朋友跟随小编一起看看吧
    2024-05-05
  • Vue项目之学生管理系统实例详解

    Vue项目之学生管理系统实例详解

    这篇文章主要为大家详细介绍了Vue项目之学生管理系统实例,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助
    2022-03-03
  • Vue-cli Eslint在vscode里代码自动格式化的方法

    Vue-cli Eslint在vscode里代码自动格式化的方法

    本篇文章主要介绍了Vue-cli Eslint在vscode里代码自动格式化的方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-02-02
  • Vue.js最佳实践(五招助你成为vuejs大师)

    Vue.js最佳实践(五招助你成为vuejs大师)

    这篇文章主要介绍了Vue.js最佳实践,本文主要面向对象是有一定vue.js 编辑经验的开发者,需要的朋友可以参考下
    2018-05-05
  • 详解vue微信网页授权最终解决方案

    详解vue微信网页授权最终解决方案

    这篇文章主要介绍了 详解vue微信网页授权最终解决方案,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2019-06-06
  • 解决vue-element-admin中配置跨域出现的问题

    解决vue-element-admin中配置跨域出现的问题

    这篇文章主要介绍了解决vue-element-admin中配置跨域出现的问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-07-07
  • 解决iview打包时UglifyJs报错的问题

    解决iview打包时UglifyJs报错的问题

    下面小编就为大家分享一篇解决iview打包时UglifyJs报错的问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-03-03
  • vue路由中前进后退的一些事儿

    vue路由中前进后退的一些事儿

    这篇文章主要给大家介绍了关于vue路由中前进后退的一些事儿,文中通过示例代码介绍的非常详细,对大家学习或者使用vue路由具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
    2019-05-05

最新评论