【问题标题】:setInterval() in Vue makes my this-variable undefinedVue 中的 setInterval() 使我的 this 变量未定义
【发布时间】:2020-09-30 18:56:41
【问题描述】:

你好,所以我在 Vue 中制作了一个基本时钟,出于某种原因,我使用此代码将初始时间值输入到 bazinga,但一旦更新它就表明它是未定义的。如果我也在 setInterval() 函数中定义 now 和其他变量,我设法“让它工作”,但这似乎不是一个好的选择。 this.bazinga 怎么会在第一次迭代后变得未定义?

<template>
    <div id="clock">
        <h2>The time is now</h2>
        <p>{{ bazinga }}</p>
        
    </div>
</template>

<style>

</style>

<script>
export default {
    data(){
        const now = new Date()
        const hours = now.getHours()
        const minutes = now.getMinutes()
        const seconds = now.getSeconds()
        return{
            bazinga: now
        }
    },
    created() {
         setInterval(() => {
            console.log(this.bazinga)
            this.bazinga = this.now
            console.log(this.bazinga)
        }, 1000)
    },
    destroyed() {
        clearInterval(this.now)
    }
}
</script>

【问题讨论】:

  • this.now 未定义,因为您没有在 datacomputed 属性中包含此属性,这就是为什么 this.bazinga = this.now 将使 this.bazinga 未定义。

标签: vue.js


【解决方案1】:

data 属性中的所有const 变量都没有注册为组件的数据,它们只是在data 块中可访问的变量。

我假设您想在每次致电 this.now 时获得更新的 new Date()

我会建议类似的东西:

<script>
export default {
    data(){
        return{
            now: new Date();
        }
    },
    computed {
      hours: function() {
          return this.now.getHours()
      }
      minutes: function() {
          return this.now.getMinutes()
      },
      seconds: function() {
          return this.now.getSeconds()
      }
    },
    created() {
         setInterval(() => {
            console.log(this.bazinga)
            this.updateNow()
            console.log(this.bazinga)
        }, 1000)
    },
    updateNow() {
       this.now = new Date()
    }
    destroyed() {
        clearInterval(this.now)
    }
}
</script>

每次调用updateNow() 都会得到一个新的日期,并更新所有计算的日期。 :)

【讨论】:

  • 好的,谢谢!为什么变量没有注册为我的组件的数据,即使它们在 data()-block 中?数据块中定义的变量和数据块中的组件数据有什么区别?
  • data 属性是一个函数,它应该返回一个对象,其中包含您在组件中需要的所有属性(及其初始值)。从您的代码中,您只返回了一个带有 bazinga 作为属性的对象,所以它是唯一注册的对象!
  • 除了语法错误,您需要将 updateNow() 定义为一个方法,然后它才能工作
  • 哦,是的,对不起。我习惯了基于 Typescript 类的组件,所以我不需要指定 methods 对象。对不起!
【解决方案2】:
<template>
    <div id="clock">
        The Time is Now {{bazinga}}
    </div>

</template>

<script>
export default {
    data(){
        return {
            hours: 0,
            minutes: 0,
            seconds: 0,
            hoursDisplay: 0,
            secondIterator: 1000,
            hourTime: 12,
        }
    },
    mounted() {
        this.$options.timer = window.setTimeout(this.updateDateTime, this.secondIterator);
    },
    destroyed() {
        window.clearTimeout(this.$options.timer);
    },
    methods: {
        updateDateTime() {
            const now = new Date();
            this.hours = now.getHours();
            this.minutes = this.zeroPad(now.getMinutes());
            this.seconds = this.zeroPad(now.getSeconds());
            this.hoursDisplay = this.hours % this.hourTime || this.hours;
            this.$options.timer = window.setTimeout(this.updateDateTime, this.secondIterator);
        },
        zeroPad: function (time) {
            return (parseInt(time, 10) >= 10 ? '' : '0') + time;
        }
    },
    computed: {
        amPm: function () {
            if (this.hours) {
                return this.hours >= 12 ? 'PM' : 'AM';
            }
        },
        bazinga: function () {
            if (this.amPm) {
                return [this.hoursDisplay, this.minutes, this.seconds].join(':') + ' ' + this.amPm;
            }

        },
    }
}
</script>

我在这里制作了一个时钟组件,但基本上你总是希望在组件中使用数据道具并通过 this.someproperty 访问它们。您还可以使用观察者或计算属性来返回它们,就像我在这里所做的那样。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-01-02
    • 1970-01-01
    • 2020-02-15
    • 1970-01-01
    • 1970-01-01
    • 2017-01-20
    • 2019-03-12
    • 2021-03-26
    相关资源
    最近更新 更多