当前位置 主页 > 网站技术 > 代码类 >

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

    栏目:代码类 时间:2019-10-16 15:05

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

           实现思路:

    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 
          class="wheel-list"
          :
          :class="transition">
         <li v-for="(prize,index) in slotPrizes"
           :
           v-bind:key="index">
          <div class="fan-item"
             ></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>