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(),强制视图更新

上一篇下一篇

猜你喜欢

热点阅读