ajax九宫格抽奖源代码,vue抽奖组件之九宫格

写在前面

本人自从事前端工作以来,每每遇到技术问题后,都是向百度/谷歌求教,久而久之便养成了伸手即来的‘本领’。。。可能是出于‘懒’的原因(没错,就是因为懒),从未发表过技术文章或开发经验,深感惭愧,故洗心革面,决心分享一些东西。

本文所述仅冰山一角,欢迎大家留言宝贵经验~。

1.需求

页面属于活动页面

a.进入页面会请求后台接口,拉取当前用户抽奖剩余次数

b.点击九宫格开始按钮,开始转动,并请求后台接口

c.接口请求成功,根据接口返回的停留位置停止转动

d.可连续抽奖,直至抽奖次数为0

大致展示效果如下

ajax九宫格抽奖源代码,vue抽奖组件之九宫格_第1张图片

2.组件源码

template部分

  • {{item.info}}

  • 按钮

您有{{luckyTimes}}次抽奖机会

script部分

1.接口说明:如果本地localhost启动,可以用setTimeout模拟post请求

2.函数说明:

move函数 为100ms转动,切最小转动次数为12(一圈半,也就是防止接口返回太快,刚开始转就停止),当接口返回成功后,记录当前index及服务器的返回停止位置stopIndex,并执行enter函数;

enter函数 100ms转动,接受参数,计算当前index与stopIndex的差值,如果>4,就可以执行递减,===4时;<=4,再次判断是否>-4(这个判断是为了计算多转几次),执行stop函数;

stop函数 为300ms转动,只转4次,然后完成整个流程;

3.对于setInterval,当组件销毁时,要清除定时器

import { post } from '@common/js/ajax';

import { deepQuery } from '@mfw/trans-core';

export default {

data() {

return {

// 奖单

list: [

{ img: 'https://n3-q.mafengwo.net/s12/M00/43/1C/wKgED1v__MqAPEuxAABG61CRQek46.jpeg', info: '谢谢参与', active: false },

{ img: 'https://b1-q.mafengwo.net/s12/M00/43/1C/wKgED1v__MqATFWOAAA8r6he_a471.jpeg', info: '北京-东京往返机票', active: false },

{ img: 'https://n3-q.mafengwo.net/s12/M00/42/2C/wKgED1v__AyAGkNKAAA33_Ke5y444.jpeg', info: '50元代金券', active: false },

{ img: 'https://n3-q.mafengwo.net/s12/M00/43/1C/wKgED1v__MqAPEuxAABG61CRQek46.jpeg', info: '马蜂窝护照包', active: false },

{ img: 'https://b1-q.mafengwo.net/s12/M00/43/1C/wKgED1v__MqATFWOAAA8r6he_a471.jpeg', info: '谢谢参与', active: false },

{ img: 'https://n3-q.mafengwo.net/s12/M00/42/2C/wKgED1v__AyAGkNKAAA33_Ke5y444.jpeg', info: '北京-札幌往返机票', active: false },

{ img: 'https://b1-q.mafengwo.net/s12/M00/43/1C/wKgED1v__MqATFWOAAA8r6he_a471.jpeg', info: '蚂蜂窝旅行箱', active: false },

{ img: 'https://n3-q.mafengwo.net/s12/M00/42/2C/wKgED1v__AyAGkNKAAA33_Ke5y444.jpeg', info: '马蜂窝日历', active: false },

],

// 上次停留位置 index

lastIndex: 0,

// 服务器返回停留位置 index

stopIndex: 0,

// 正常转动动画

timer1: null,

// 进入低速转动动画

timer2: null,

// 低速转动动画

timer3: null,

// 正在执行动画

isMoving: false,

// 转动次数 最小12次(一圈半) 防止转动时间过短

times: 0,

// 接口成功返回停止stopIndex 标识

ajaxEnd: false,

// 进入低速转动动画 标识

timerEnd: false,

// 用户抽奖次数(实际应该是后台返回的次数)

luckyTimes: 5,

};

},

watch: {

times(val) {

// 如果计数过程中,ajax未成功

if (!this.ajaxEnd) {

return false;

}

if (val >= 12) {

this.timerEnd = true;

}

},

},

methods: {

getStopIndex() { // 获取服务器返回的index

post('/lottery')

.then((res) => {

if (deepQuery(res, 'data', 'success')) {

this.stopIndex = deepQuery(res, 'data', 'data');

if (this.lastIndex !== this.stopIndex || this.lastIndex === this.stopIndex) {

this.ajaxEnd = true;

}

} else {

return Promise.reject(deepQuery(res, 'data', 'message'));

}

})

.catch((err) => {

// 初始化数据

clearInterval(this.timer1);

this.list.map((e) => {

e.active = false;

});

this.lastIndex = 0;

this.isMoving = false;

this.lastIndex = 0;

this.times = 0;

const errMsg = typeof err === 'string' ? err : '服务器繁忙,请稍后重试';

this.showToast(errMsg);

});

},

move() { // 点击开始游戏按钮

if (!this.luckyTimes) {

console.error('没有抽奖次数了');

return false;

}

if (this.isMoving) {

return false;

}

this.isMoving = true;

this.ajaxEnd = false;

this.timerEnd = false;

this.times = 0;

console.error('上次停止位置: ', this.lastIndex);

let i = this.lastIndex;

// 执行ajax请求数据

this.getStopIndex();

// 执行动画

this.timer1 = setInterval(() => {

this.times++;

i++;

if (i === 8) {

i = 0;

}

this.list.map((e) => {

e.active = false;

});

this.$set(this.list[i], 'active', true);

// 当获取到服务器数据 index

if (this.timerEnd) {

console.log('服务器返回的停止位置: ', this.stopIndex);

clearInterval(this.timer1);

this.enter(i, this.stopIndex);

}

}, 100);

},

enter(cur, stop) { // 计算需要停止的index

console.log(cur, stop);

let count = stop - cur;

if (count <= 4) {

count = count > -4 ? count + 8 : count + 16;

}

let i = cur;

this.timer2 = setInterval(() => {

count--;

i++;

if (i === 8) {

i = 0;

}

this.list.map((e) => {

e.active = false;

});

this.$set(this.list[i], 'active', true);

if (count === 4) {

clearInterval(this.timer2);

this.stop(i, stop);

}

}, 100);

},

stop(cur, stop) { // 计算需要停止的index

let count = 0;

let i = cur;

this.timer3 = setInterval(() => {

count++;

i++;

if (i === 8) {

i = 0;

}

this.list.map((e) => {

e.active = false;

});

this.$set(this.list[i], 'active', true);

if (count === 4) {

clearInterval(this.timer3);

this.isMoving = false;

this.lastIndex = this.stopIndex;

this.luckyTimes--;

}

}, 300);

},

showToast(err) { // toast 提示

alert(err);

},

},

beforeDestroy() { // 组件销毁前

// 清除定时器

clearInterval(this.timer1);

clearInterval(this.timer2);

clearInterval(this.timer3);

},

};

style部分

关于正方形布局,通过{width:100%;padding-bottom:100%;}实现

.v-common-com-lottery {

height: 100%;

font-size: .24rem;

color: #fff;

.list {

position: relative;

background: lightblue;

width: 100%;

padding-bottom: 100%;

}

.item {

width: 32%;

padding-bottom: 32%;

position: absolute;

background: lightgreen;

border-radius: .24rem;

overflow: hidden;

&.item0 {

left: 0;

top: 0;

}

&.item1 {

left: 34%;

top: 0;

}

&.item2 {

left: 68%;

top: 0;

}

&.item3 {

left: 68%;

top: 34%;

}

&.item4 {

left: 68%;

top: 68%;

}

&.item5 {

left: 34%;

top: 68%;

}

&.item6 {

left: 0;

top: 68%;

}

&.item7 {

left: 0;

top: 34%;

}

.icon {

position: absolute;

height: 100%;

width: 100%;

z-index: 1;

}

.info {

position: absolute;

left: 0;

bottom: 0;

background: linear-gradient(rgba(0, 0, 0, 0), rgba(0, 0, 0, .5));

height: .48rem;

width: 100%;

z-index: 2;

display: flex;

align-items: center;

justify-content: center;

}

.mask {

position: absolute;

left: 0;

top: 0;

z-index: 3;

width: 100%;

height: 100%;

background: rgba(0, 0, 0, .4);

opacity: 0;

}

&.active .mask{

opacity: 1;

}

}

.btn {

width: 32%;

padding-bottom: 32%;

background: lightsalmon;

position: absolute;

left: 34%;

top: 34%;

font-size: .72rem;

border-radius: .24rem;

overflow: hidden;

.text {

position: absolute;

height: 100%;

width: 100%;

display: flex;

align-items: center;

justify-content: center;

z-index: 2;

}

.mask {

position: absolute;

height: 100%;

width: 100%;

display: flex;

align-items: center;

justify-content: center;

z-index: 2;

}

}

.lucky-times {

color: #000;

font-size: .36rem;

}

}

@common/js/ajax源码如下

// https://github.com/axios/axios

const axios = require('axios');

// 超时 15秒

// axios.defaults.timeout = 15000;

// 允许发送cookie

axios.defaults.withCredentials = true;

/**

* get请求

* @param {string} url - 请求的路径

* @param {Object} params - 参数

* @return {Promise}

*/

export function get(url, params = {}) {

return axios.get(url, {

params,

});

}

/**

* post请求

* @param {string} url - 请求的路径

* @param {Object} data - 参数

* @param {Object} config - 原始配置

* @return {Promise}

*/

export function post(url, data = {}, config = {}) {

return axios.post(url, data, config);

}

deepQuery源码如下

/**

* 深度查询 deepQuery({},"a","b","c")

* @param {any} func 要查询的对象

* @return {boolean} true or false

*/

export function deepQuery(obj, ...args) {

return args.reduce((a, b) => (a ? a[b] : a), obj);

}

3.写在后面

欢迎各位大佬指正

后续会分享自定义日历组件/城市地点选择组件等等,欢迎大家一起讨论学习!

你可能感兴趣的:(ajax九宫格抽奖源代码)