web-dev-qa-db-fra.com

Vue équivalente à setTimeOut?

Je fais un système de panier avec Laravel et Vue. Lorsque j'ajoute un élément au panier, j'affiche un message de confirmation en basculant une variable Vue surveillée par un v-if:

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

Et le JS:

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

(Et oui, j'ajouterai ceci dans une capture à venir).

Cela fonctionne bien et le message apparaît. Cependant, j'aimerais que le message disparaisse à nouveau après un certain temps, disons quelques secondes. Comment puis-je faire cela avec Vue? J'ai essayé setTimeOut mais Vue ne semble pas l'apprécier, affirmant que ce n'est pas défini.

EDIT: J'ai mal orthographié setTimeout comme un idiot. Cependant, cela ne fonctionne toujours pas:

Ma fonction est maintenant:

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

Vous pouvez essayer ce code:

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

Mini-explication: la fonction interne appelée par setTimeout this n'est PAS l'objet VueJs (est l'objet global setTimeout), mais self, également appelé après 2 secondes, est toujours un objet VueJs. 

42
g.annunziata

après avoir rencontré le même problème, je me suis retrouvé sur ce fil. Pour les générations futures: La réponse actuelle la plus votée, tente de lier "ceci" à une variable afin d'éviter de modifier le contexte lors de l'appel de la fonction définie dans setTimeout.

Une autre approche plus recommandée (avec Vue.JS 2.2 & ES6) consiste à utiliser une fonction de flèche afin de lier le contexte au parent (essentiellement "addToBasket" est "this" et "setTimeout" est "this" se réfère toujours au même objet):

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

Ajouter une liaison (this) à votre fonction de rappel setTimeout

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

Vous pouvez utiliser Vue.nextTick

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

ES6 peut lier 'ceci'

setTimeout(() => {

 },5000);

2
陈奕璇

vuejs 2

d'abord ajouter ceci aux méthodes

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

après cet appel cette méthode sur monté

mounted () {
  this.sayHi()
}
2
mohamad

Kevin Muchwat ci-dessus a la MEILLEURE réponse, malgré seulement 10 votes positifs et la réponse non choisie.

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

Laissez-moi expliquer POURQUOI.

"Fonction de flèche" est ECMA6/ECMA2015. Il est parfaitement valide dans les situations de code compilé ou de clients contrôlés (applications de téléphonie Cordova, Node.js). Il est simple et concis. Il passera probablement vos tests!

Cependant, Microsoft dans leur sagesse infinie a décidé qu'Internet Explorer NE SUPPORTERA JAMAIS ECMA2015!

Leur nouveau navigateur Edge le fait, mais ce n’est pas suffisant pour les sites Web publics.

Faire une fonction standard () {} et ajouter .bind (this) est cependant la syntaxe ECMA5.1 (qui IS est entièrement prise en charge) pour une fonctionnalité identique.

Ceci est également important dans les appels ajax/post .then/else. À la fin de votre .then (fonction) {}), vous devez également lier (ceci) ainsi: .then (fonction () {this.flag = true} .bind (this))

J'aurais ajouté ceci comme commentaire à la réponse de Kevin, mais pour une raison quelconque, il faut moins de points pour poster des réponses que pour commenter les réponses.

NE FAITES PAS LA MÊME ERREUR QUE J'AI FAIT!

Je code sur un Mac, et utilise le commentaire de 48 points voté qui fonctionne très bien! Jusqu'à ce que certains scripts échouent et que je ne comprenne pas pourquoi. Je devais revenir en arrière et mettre à jour des dizaines d'appels de la syntaxe arrow à la syntaxe function () {}. Bind (this).

Heureusement, j'ai retrouvé ce fil et obtenu la bonne réponse. Kevin, je suis toujours reconnaissant.

Selon la "réponse acceptée", d'autres problèmes potentiels pourraient survenir lors de l'utilisation de bibliothèques supplémentaires (problèmes d'accès/de mise à jour corrects des propriétés/fonctions de Vue)

1
Peter

utiliser this.animationStop, pas utiliser this.animationStop  ()

animationRun(){
    this.sliderClass.anim = true;
    setTimeout(this.animationStop, 500);
},
0
Pax Exterminatus

Si vous souhaitez utiliser le mot-clé this dans votre fonction, vous devez écrire la fonction setTimeout dans ES6.

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