Vue.js方法未触发定时器倒计时问题技术问询
解决Vue组件倒计时定时器不工作的问题
你的问题核心出在setInterval回调函数里的this指向错误——在普通函数回调中,this不再指向Vue组件实例,所以你修改this.timeValue和this.showTimer根本不会更新组件的响应式数据,自然看不到倒计时效果。
下面给你三种可行的修复方案,选一种你习惯的就行:
方案1:提前保存组件实例的this
在setInterval外面把组件的this存到一个变量里,回调里用这个变量访问组件数据:
var timerArea = Vue.component('timer-area', { data: function () { return ({ timeValue: 6, showTimer: true }); }, methods: { countdownTimer: function () { const vm = this; // 保存组件实例的this var downloadTimer = setInterval(function () { vm.timeValue--; // 用vm代替this if (vm.timeValue <= 0) { clearInterval(downloadTimer); vm.showTimer = false; } }, 1000); } }, mounted() { // Vue 2.x+推荐用mounted代替ready钩子 this.countdownTimer(); }, template: `<div v-if="showTimer">{{ timeValue }}</div>` // 补全模板示例 });
方案2:使用箭头函数
箭头函数不会绑定自己的this,会继承外层作用域的this(也就是组件实例),代码更简洁:
var timerArea = Vue.component('timer-area', { data: function () { return ({ timeValue: 6, showTimer: true }); }, methods: { countdownTimer: function () { var downloadTimer = setInterval(() => { // 换成箭头函数 this.timeValue--; // 这里的this就是组件实例 if (this.timeValue <= 0) { clearInterval(downloadTimer); this.showTimer = false; } }, 1000); } }, mounted() { this.countdownTimer(); }, template: `<div v-if="showTimer">{{ timeValue }}</div>` });
方案3:用bind绑定this
给setInterval的回调函数绑定组件的this:
var timerArea = Vue.component('timer-area', { data: function () { return ({ timeValue: 6, showTimer: true }); }, methods: { countdownTimer: function () { var downloadTimer = setInterval(function () { this.timeValue--; if (this.timeValue <= 0) { clearInterval(downloadTimer); this.showTimer = false; } }.bind(this), 1000); // 绑定组件的this到回调函数 } }, mounted() { this.countdownTimer(); }, template: `<div v-if="showTimer">{{ timeValue }}</div>` });
另外补充个小提示:Vue 2.x开始已经不再推荐使用ready钩子,换成mounted更合适,它的触发时机是组件挂载到DOM后,更符合大多数场景的需求。
内容的提问来源于stack exchange,提问作者UncountedBrute
相关产品推荐
相关产品推荐

