繁体   English   中英

Vue Deep Watcher 不会在数据更改时触发

[英]Vue Deep Watcher doesnt trigger on data change

倒数计时器运行良好,但深度观察器不起作用。 我让深度观察者将新的秒值记录到控制台,但它没有,尽管倒计时计时器一直在滴答作响。

export default defineComponent({
  name: 'Countdown',
  data() {
    return {
      date_countdown: new Date('August 16, 2022').getTime(),
      date_current: {
        days: 0,
        hours: 0,
        minutes: 0,
        seconds: 0,
      },
      getDateDiff(date_countdown: number) {
        const date_current = new Date().getTime();
        const diff = date_countdown - date_current;
        const days = Math.floor(diff / (1000 * 60 * 60 * 24));
        const hours = Math.floor(
          (diff % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60)
        );
        const minutes = Math.floor((diff % (1000 * 60 * 60)) / (1000 * 60));
        const seconds = Math.floor((diff % (1000 * 60)) / 1000);
        return { days, hours, minutes, seconds };
      },
      timer() {
        return setInterval(() => {
          this.date_current = this.getDateDiff(this.date_countdown);
        }, 1000);
      },
    };
  },

  watch: {
    seconds: {
      deep: true,

      handler(newVal) {
        console.log(newVal); // to test the deep watcher; doesnt log tho
      },
    },
  },

  mounted() {
    this.timer();
  },

  beforeUnmount() {
    clearInterval(this.timer());
  },
});

我不确定,但也许因为 timer() function 改变了date_current的值而不是单独改变date_current.seconds ,所以深度观察器没有被触发?

那是因为您watch seconds ,但秒数不是data中的直接属性或计算属性,如果您想观察seconds的变化,您需要在date_currentwatch function get date_current.seconds上应用watch事件。

<script>
import { defineComponent } from "vue";
export default defineComponent({
  name: "Countdown",
  data() {
    return {
      date_countdown: new Date("August 16, 2022").getTime(),
      date_current: {
        days: 0,
        hours: 0,
        minutes: 0,
        seconds: 0,
      },
      getDateDiff(date_countdown) {
        const date_current = new Date().getTime();
        const diff = date_countdown - date_current;
        const days = Math.floor(diff / (1000 * 60 * 60 * 24));
        const hours = Math.floor(
          (diff % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60)
        );
        const minutes = Math.floor((diff % (1000 * 60 * 60)) / (1000 * 60));
        const seconds = Math.floor((diff % (1000 * 60)) / 1000);
        return { days, hours, minutes, seconds };
      },
      timer() {
        return setInterval(() => {
          this.date_current = this.getDateDiff(this.date_countdown);
        }, 1000);
      },
    };
  },

  watch: {
    date_current: {
      deep: true,
      handler(newVal) {
        console.log(newVal.seconds); // to test the deep watcher; doesnt log tho
      },
    },
  },

  mounted() {
    this.timer();
  },

  beforeUnmount() {
    clearInterval(this.timer());
  },
});
</script>

这是一个工作代码示例。

如果你做这种等式时我没记错的话;

this.date_current = this.getDateDiff(this.date_countdown);

watch 只是失去了 object 引用,因为你为它设置了一个全新的 object 并且 vue 使用代理来获取反应属性。 因此它会丢失之前的代理并设置一个新的代理,但不会触发更改。 (也许设置immediate: true有帮助,但它不太适合这种情况。)

如果您观看date_current.seconds那么您的观察者会观看原始值并检测到更改。 (这是一种更好的方法。)

希望能帮助到你。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM