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



倒计时计时器工作正常,但深度观察程序不工作。我让深度观察者将秒的新值记录到控制台,但它没有,尽管倒计时计时器一直在滴答作响。

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((函数更改了date_current的值,而不是单独更改date_current.seconds,所以深度观察程序不会被触发?

因为watchseconds,但秒不是data中的直接属性或计算属性,如果您想观察seconds上的更改,则需要在date_current上应用watch事件,并在watch函数内部获取date_current.seconds

<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只是丢失了对象引用,因为您为它设置了一个全新的对象,而vue使用代理作为反应属性。因此,它失去了以前的代理,并设置了一个新的代理,但不会触发更改。(也许设置immediate: true有帮助,但它不太适合这种情况。(

如果您观察date_current.seconds,那么您的观察者会观察一个基元值并检测到更改。(这是更好的方法。(

希望能有所帮助。

最新更新