65

I define the timer in each my-progress, used to update the value of view, but the console shows the value of the constant changes, and the value of view is still not changed, how can I do in the timer to change the value of view

Vue.component('my-progress', {
    template: '\
            <div class="progress progress-bar-vertical" data-toggle="tooltip" data-placement="top">\
                <div class="progress-bar" role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100" :style="{height: pgvalue}">{{pgvalue}}\
                </div>\
            </div>\
        ',
    data : function(){  

        return {
            pgvalue : '50%',
            intervalid1:'',
        }
    },
    computed:{

        changes : {
            get : function(){
                return this.pgvalue;
            },
            set : function(v){
                this.pgvalue =  v;
            }
        }
    },
    mounted : function(){

        this.todo()     
    },
    beforeDestroy () {

       clearInterval(this.intervalid1)
    },
    methods : {

        todo : function(){          
            this.intervalid1 = setInterval(function(){
                this.changes = ((Math.random() * 100).toFixed(2))+'%';
                console.log (this.changes);
            }, 3000);
        }
    },
})

here is the link: jsbin.com/safolom

Alexey
  • 1,366
  • 1
  • 13
  • 33
A_Wen
  • 783
  • 2
  • 6
  • 8

3 Answers3

89

this is not pointing to the Vue. Try

todo: function(){           
    this.intervalid1 = setInterval(function(){
        this.changes = ((Math.random() * 100).toFixed(2))+'%';
        console.log (this.changes);
    }.bind(this), 3000);
}

or

todo: function(){  
    const self = this;          
    this.intervalid1 = setInterval(function(){
        self.changes = ((Math.random() * 100).toFixed(2))+'%';
        console.log (this.changes);
    }, 3000);
}

or

todo: function(){  
    this.intervalid1 = setInterval(() => {
        this.changes = ((Math.random() * 100).toFixed(2))+'%';
        console.log (this.changes);
    }, 3000);
}

See How to access the correct this inside a callback?

Bert
  • 80,741
  • 17
  • 199
  • 164
  • 1
    For clarification, the first example uses `function(){}.bind()` to re-assign `this` the second uses a local `self` variable assigned to the correct `this`, and the third uses lambda `() => {}` syntax which automatically binds `this`. I believe the third option is preferred. – Nathan Goings Mar 27 '22 at 20:00
7

check this example:

Vue.component('my-progress-bar',{
 template:
`<div class="progress">
 <div
  class="progress-bar"
  role="progressbar"
  :style="'width: ' + percent+'%;'"
  :aria-valuenow="percent"
  aria-valuemin="0"
  aria-valuemax="100">
  {{ percent }}%
 </div>
</div>`,
 props: { percent: {default: 0} }
});


new Vue({
 el: '#app',
 data: {p: 50},
 created: function() {
  var self = this;
  setInterval(function() {
        if (self.p<100) {
             self.p++;
         }
    }, 100);
 }
});
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" rel="stylesheet">

<div id='app'>
  <my-progress-bar :percent.sync='p'>
  </my-progress-bar>
  <hr>
  <button @click='p=0' class='btn btn-danger bt-lg btn-block'>
  Reset Bar Progress
  </button>
</div>
fitorec
  • 4,257
  • 2
  • 24
  • 18
0

created : {

  window.setInterval(() => {
    getList(); // call any function or end point
  }, 1000); // interval set to one sec. 

}


const getList = () => {
    console.log('foo')
};
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>