Javascript Vue 相当于 setTimeout?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/38399050/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 21:25:40  来源:igfitidea点击:

Vue equivalent of setTimeout?

javascriptvue.js

提问by flurpleplurple

I'm making a shopping cart system with Laravel and Vue. When I add an item to the basket, I display a confirmation message by toggling a Vue variable being watched by a v-if:

我正在用 Laravel 和 Vue 制作购物车系统。当我将一个项目添加到购物篮时,我通过切换 v-if 正在监视的 Vue 变量来显示一条确认消息:

<div class="alert alert-success" v-if="basketAddSuccess" transition="expand">Added to the basket</div>

And the JS:

和JS:

addToBasket: function(){
                item = this.product;
                this.$http.post('/api/buy/addToBasket', item);
                this.basketAddSuccess = true;
            }

(And yes, I will be adding this in a then-catch shortly).

(是的,我很快就会在当时的情况下添加这个)。

This works fine and the message appears. However, I'd like the message to disappear again after a certain time, say a few seconds. How can I do this with Vue? I've tried setTimeOutbut Vue doesn't seem to like it, saying it's undefined.

这工作正常并显示消息。但是,我希望消息在一段时间后再次消失,比如几秒钟。我怎样才能用 Vue 做到这一点?我试过了,setTimeOut但 Vue 似乎不喜欢它,说它未定义。

EDIT: I was misspelling setTimeoutlike an idiot. However, it still doesn't work:

编辑:我setTimeout像个白痴一样拼错了。但是,它仍然不起作用:

My function is now:

我的功能现在是:

addToBasket: function(){
                item = this.photo;
                this.$http.post('/api/buy/addToBasket', item);
                this.basketAddSuccess = true;
                setTimeout(function(){
                    this.basketAddSuccess = false;
                }, 2000);
            }

回答by Samuel Bergstr?m

after encountering the same issue, I ended up on this thread. For future generation's sake: The current up-most voted answer, attempts to bind "this" to a variable in order to avoid changing the context when invoking the function which is defined in the setTimeout.

遇到同样的问题后,我结束了这个线程。为了后代:当前投票最多的答案尝试将“this”绑定到一个变量,以避免在调用 setTimeout 中定义的函数时更改上下文。

An alternate and more recommended approach(using Vue.JS 2.2 & ES6) is to use an arrow function in order to bind the context to the parent (Basically "addToBasket"'s "this" and the "setTimeout"'s "this" would still refer to the same object):

另一种更推荐的方法(使用 Vue.JS 2.2 和 ES6)是使用箭头函数将上下文绑定到父级(基本上是“addToBasket”的“this”和“setTimeout”的“this”仍然会引用同一个对象):

addToBasket: function(){
        item = this.photo;
        this.$http.post('/api/buy/addToBasket', item);
        this.basketAddSuccess = true;
        setTimeout(() => {
            this.basketAddSuccess = false;
        }, 2000);
    }

回答by g.annunziata

Arrow Function

箭头函数

The best and simplest way to solve this problem is by using an arrow function () => {}:

解决这个问题的最好和最简单的方法是使用箭头函数() => {}

    addToBasket() {
        var item = this.photo;
        this.$http.post('/api/buy/addToBasket', item);
        this.basketAddSuccess = true;
        // now 'this' is referencing the Vue object and not the 'setTimeout' scope
        setTimeout(() => this.basketAddSuccess = false, 2000);
    }

This works because the thisof arrow functions is bound to the thisof its enclosing scope- in Vue, that's the parent/ enclosing component. Inside a traditional function called by setTimeout, however, thisrefers to the windowobject(which is why you ran into errors when you tried to access this.basketAddSuccessin that context).

这是有效的,因为thisof 箭头函数绑定到this封闭范围的--- 在 Vue 中,这是父/封闭组件。setTimeout然而,thiswindow由 调用的传统函数中,引用了对象(这就是您尝试this.basketAddSuccess在该上下文中访问时遇到错误的原因)。

Argument Passing

参数传递

Another way of doing this would be passing thisas an arg to your function through setTimeout's prototypeusing its setTimeout(callback, delay, arg1, arg2, ...)form:

这样做的另一种方法是使用其形式this通过setTimeout的原型作为参数传递给您的函数setTimeout(callback, delay, arg1, arg2, ...)

    addToBasket() {
        item = this.photo;
        this.$http.post('/api/buy/addToBasket', item);
        this.basketAddSuccess = true;
        //Add scope argument to func, pass this after delay in setTimeout
        setTimeout(function(scope) {
             scope.basketAddSuccess = false;
        }, 2000, this);
    }

(It's worth noting that the arg passing syntax is incompatible with IE 9 and below, however.)

(值得注意的是,arg 传递语法与 IE 9 及以下版本不兼容。)

Local Variable

局部变量

Another possible, but less eloquent and less encouraged, way is to bind thisto a var outside of setTimeout:

另一种可能的,但不太雄辩且不太受鼓励的方法是绑定this到 之外的 var setTimeout

    addToBasket() {
        item = this.photo;
        this.$http.post('/api/buy/addToBasket', item);
        this.basketAddSuccess = true;
        //Declare self, which is accessible inside setTimeout func
        var self = this;
        setTimeout(function() {
             self.basketAddSuccess = false;
        }, 2000);
    }

Using an arrow function would eliminate the need for this extra variable entirely however, and really should be used unless something else is preventing its use.

然而,使用箭头函数将完全消除对这个额外变量的需要,并且真的应该使用,除非其他东西阻止它的使用。

回答by Kevin Muchwat

Add bind(this) to your setTimeout callback function

将 bind(this) 添加到您的 setTimeout 回调函数中

setTimeout(function () {
    this.basketAddSuccess = false
}.bind(this), 2000)

回答by u10350822

ES6 can bind 'this'

ES6 可以绑定'this'

setTimeout(() => {

 },5000);

回答by mohamad

vuejs 2

Vuejs 2

first add this to methods

首先将其添加到方法中

methods:{
    sayHi: function () {
      var v = this;
      setTimeout(function () {
        v.message = "Hi Vue!";
    }, 3000);
   }

after that call this method on mounted

之后在mounted上调用这个方法

mounted () {
  this.sayHi()
}

回答by Samundra Khatri

You can use Vue.nextTick

你可以使用 Vue.nextTick

addToBasket: function(){
                item = this.photo;
                this.$http.post('/api/buy/addToBasket', item);
                this.basketAddSuccess = true;
                Vue.nextTick(() =>{
                    this.basketAddSuccess = false;
                });
            }

回答by Wouter Schoofs

If you want to use the this keyword in your function, you need to write the setTimeout function in ES6

如果你想在你的函数中使用 this 关键字,你需要在 ES6 中编写 setTimeout 函数

setTimeout(() => {
   this.filters.max_budget_gt_eq = this.budgetHigherValue;
}, 1000);

回答by Peter

Kevin Muchwat above has the BEST answer, despite only 10 upvotes and not selected answer.

上面的 Kevin Muchwat 给出了最佳答案,尽管只有 10 票赞成并且没有选择答案。

setTimeout(function () {
    this.basketAddSuccess = false
}.bind(this), 2000)

Let me explain WHY.

让我解释一下为什么。

"Arrow Function" is ECMA6/ECMA2015. It's perfectly valid in compiled code or controlled client situations (cordova phone apps, Node.js), and it's nice and succinct. It will even probably pass your testing!

“箭头函数”是 ECMA6/ECMA2015。它在编译代码或受控客户端情况(cordova 手机应用程序、Node.js)中完全有效,而且非常简洁。它甚至可能会通过您的测试!

However, Microsoft in their infinite wisdom has decided that Internet Explorer WILL NOT EVER SUPPORT ECMA2015!

然而,微软以其无穷的智慧决定 Internet Explorer 将永远不支持 ECMA2015!

Their new Edge browser does, but that's not good enough for public facing websites.

他们的新 Edge 浏览器可以,但这对于面向公众的网站来说还不够好。

Doing a standard function(){} and adding .bind(this) however is the ECMA5.1 (which IS fully supported) syntax for the exact same functionality.

执行标准 function(){} 并添加 .bind(this) 是 ECMA5.1(完全支持)语法,用于完全相同的功能。

This is also important in ajax/post .then/else calls. At the end of your .then(function){}) you need to bind(this) there as well so: .then(function(){this.flag = true}.bind(this))

这在 ajax/post .then/else 调用中也很重要。在你的 .then(function){}) 的末尾,你也需要在那里绑定(this): .then(function(){this.flag = true}.bind(this))

I would have added this as a comment to Kevin's response, but for some silly reason it takes less points to post replies than to comment on replies

我会将此作为评论添加到凯文的回复中,但出于某种愚蠢的原因,发布回复比评论回复所需的分数要少

DO NOT MAKE THE SAME MISTAKE I MADE!

不要犯和我一样的错误!

I code on a Mac, and used the 48 points upvoted comment which worked great! Until I got some calls on my scripts failing and I couldn't figure out why. I had to go back and update dozens of calls from arrow syntax to function(){}.bind(this) syntax.

我在 Mac 上编码,并使用了 48 点赞的评论,效果很好!直到我接到一些关于我的脚本失败的电话,我不知道为什么。我不得不回去更新几十个从箭头语法到 function(){}.bind(this) 语法的调用。

Thankfully I found this thread again and got the right answer. Kevin, I am forever grateful.

谢天谢地,我再次找到了这个线程并得到了正确的答案。凯文,我永远心存感激。

As per the "Accepted answer", that has other potential issues dealing with additional libraries (had problems properly accessing/updating Vue properties/functions)

根据“接受的答案”,还有其他潜在的问题来处理额外的库(正确访问/更新 Vue 属性/函数时出现问题)

回答by Armin

There's no need for bind(this)when you are using arrow functions:

bind(this)使用箭头函数时不需要:

  setTimeout( ()=> {
    // some code
   }, 500)

回答by zcoop98

Arrow Function

箭头函数

The best and simplest way to solve this problem is by using an arrow function () => {}:

解决这个问题的最好和最简单的方法是使用箭头函数() => {}

    addToBasket() {
        var item = this.photo;
        this.$http.post('/api/buy/addToBasket', item);
        this.basketAddSuccess = true;
        // now 'this' is referencing the Vue object and not the 'setTimeout' scope
        setTimeout(() => this.basketAddSuccess = false, 2000);
    }

This works because the thisof arrow functions is bound to the thisof its enclosing scope- in Vue, that's the parent/ enclosing component. Inside a traditional function called by setTimeout, however, thisrefers to the windowobject(which is why you ran into errors when you tried to access this.basketAddSuccessin that context).

这是有效的,因为thisof 箭头函数绑定到this封闭范围的--- 在 Vue 中,这是父/封闭组件。setTimeout然而,thiswindow由 调用的传统函数中,引用了对象(这就是您尝试this.basketAddSuccess在该上下文中访问时遇到错误的原因)。

Argument Passing

参数传递

Another way of doing this would be passing thisas an arg to your function through setTimeout's prototypeusing its setTimeout(callback, delay, arg1, arg2, ...)form:

这样做的另一种方法是使用其形式this通过setTimeout的原型作为参数传递给您的函数setTimeout(callback, delay, arg1, arg2, ...)

    addToBasket() {
        item = this.photo;
        this.$http.post('/api/buy/addToBasket', item);
        this.basketAddSuccess = true;
        //Add scope argument to func, pass this after delay in setTimeout
        setTimeout(function(scope) {
             scope.basketAddSuccess = false;
        }, 2000, this);
    }

(It's worth noting that the arg passing syntax is incompatible with IE 9 and below, however.)

(值得注意的是,arg 传递语法与 IE 9 及以下版本不兼容。)