vue 拼团秒杀多个倒计时实现 数据改变页面没有刷新
2019-10-09 本文已影响0人
真是个非常帅气的昵称呢
<template>
<div>
<div v-for="(item,index) in list" :key="index">
{{ item.showTime.s }}
</div>
</div>
</template>
<script>
// import child from "@/views/components/child";
export default {
name: "father",
data() {
return {
remainList: [{
remainTime: 6000
}],
list: [],
timer: null,
timeCountFun: null,
time: {
h: 0,
m: 0,
s: 0
},
interval: null,
tuanList: [{}],
};
},
mounted() {
// this.countDownList(this.remainList);
// this.count(50000)
this.countDown(this.remainList)
},
methods: {
countDown(list) {
clearInterval(this.timer);
this.timer = setInterval(
function () {
for (let i = 0; i < list.length; i++) {
var item = list[i]
var temp = item.remainTime / 1000;
if (temp > 0) {
--temp;
} else {
temp = 0;
}
item.remainTime = temp * 1000;
// 格式化
const h = Math.floor((temp / 60 / 60) % 24);
const m = Math.floor((temp / 60) % 60);
const s = Math.floor(temp % 60);
let obj = {};
obj.h = h > 9 ? h : "0" + h;
obj.m = m > 9 ? m : "0" + m;
obj.s = s > 9 ? s : "0" + s;
item.showTime = obj;
console.log("s", item.showTime.s);
}
console.log("tag", list);
this.list = [...list];
}.bind(this),
1000
);
},
count(sec) {
var now = new Date().getTime();
var end = new Date(now + sec).getTime();
var _this = this;
_this.timeCountFun = setInterval(function () {
var _sec = Math.floor((end - new Date().getTime()) / 1000);
if (_sec <= 0) {
clearInterval(_this.timeCountFun);
} else {
const h = Math.floor((_sec / 60 / 60) % 24);
const m = Math.floor((_sec / 60) % 60);
const s = Math.floor(_sec % 60);
_this.time.h = h > 9 ? h : "0" + h;
_this.time.m = m > 9 ? m : "0" + m;
_this.time.s = s > 9 ? s : "0" + s;
console.log(_this.time.s)
}
}, 1000);
},
format(time) {
var d = Math.floor(time / (24 * 60 * 60 * 1000))
var hdate = time - d * 24 * 60 * 60 * 1000
var h = Math.floor(hdate / (60 * 60 * 1000))
var mdate = hdate - h * 60 * 60 * 1000
var m = Math.floor(mdate / (60 * 1000))
var s = Math.floor((mdate - m * 60 * 1000) / 1000)
if (d < 10) {
d = '0' + d
}
if (h < 10) {
h = '0' + h
}
if (m < 10) {
m = '0' + m
}
if (s < 10) {
s = '0' + s
}
var _time=h+" : "+m+" : "+s
return _time
},
countDownList(list) {
var _this = this
clearInterval(_this.interval)
_this.interval = setInterval(function () {
for (let i = 0; i < list.length; i++) {
var item = list[i]
var time = item.remainTime
// console.log('remainTime', time)
if (time >= 1000) {
time = time - 1000
} else {
time = 0
}
item.remainTime = time
// console.log('remainTime', item.remainTime)
item.showTime = _this.format(time)
// console.log('remainTime', item.showTime)
}
// console.log('lisy', list)
_this.tuanList = [...list]
// _this.$forceUpdate();
}, 1000)
},
}
};
</script>
<style lang="scss" scoped>
</style>
刚开始我都是直接把list赋值给_this.tuanList,结果打印list时间是在1s 1s改变的,但是到了页面或者data上,数据一直保持不变,找了很久的原因,发现是因为改变的引用数据类型,所以只会在刚开始改变一次,之后就监听不到数据的改变。
对此有三种方法:
https://blog.csdn.net/tangdou5682/article/details/99946515
办法1,用 Object.assign
对象改变:oldObj = Object.assign({},newObj);
或者 es6 oldObj={...newObj}
oldArr=[...newArr]
办法2,用vue.set
this.$set(this,'oldObj',newObj);
this.$set(this,'oldArray',newArray);
例如要改变data中 some: { name: { a: 1, b: 3 } }里面b的值,可以这样
this.$set(this.some.name,‘b’,2)
Vue不允许在已经创建的实例上动态添加新的根级响应式属性,然而它可以使用vue.set方法将相应属性添加到嵌套的对象上。
办法3,使用update
this.$forceUpdate(),强制视图更新