Katinka Hesselink
Katinka Hesselink

Reputation: 4173

change css while vue is calculating

On user-click some potentially heavy calculations ('set-selection' below) get made, so I want to show the user that the app is busy, while it is calculating. I've tried the following:

data() {
    return {
      isWaiting: false,
    };
},

methods: {
handleClick(node) {
  this.cursorWait();
  this.$nextTick()
      .then(this.$emit("set-selectie", node))
      .then(this.cursorClear);
},
cursorWait() {
  this.isWaiting = true;
},
cursorClear() {
  this.isWaiting = false;
}

The $emit takes some time, so I want vue to show a simple css change (cursor) based on the this.isWaiting data. However, it looks like what vue is actually doing is not responding to the change in this.isWaiting until the calculation is done.

As you can see I've tried $nextTick, but I have also tried lifecycle methods and this.$forceUpdate(). They don't work either.

How do I get this to work?

Upvotes: 0

Views: 718

Answers (2)

Katinka Hesselink
Katinka Hesselink

Reputation: 4173

It looks like browsers are very inconsistent in how they handle cursor changes through CSS.

We did get the following working (within the handleClick method above):

    let _this = this;
    window.requestAnimationFrame(function() {
      document.getElementById("treemain").style.background = "#ccc";
      document.getElementById("treemain").style.color = "#666";
      window.requestAnimationFrame(function() {
        _this.$emit("set-selectie", node);
        document.getElementById("treemain").style.background = "#fff";
        document.getElementById("treemain").style.color = "#011d47;";
      });
    });

So we're basically getting outside of Vue to solve this with basic javascript.

Upvotes: 0

Satyam Pathak
Satyam Pathak

Reputation: 6912

Assuming this an issue, "On user-click some potentially heavy calculations get made, so I want to show the user that the app is busy, while it is calculating."

I want to put what I have tried to fixed such situation :

Let the calculation is asynchronous and you never know when it get finished or a function which take some time to get executed.

new Vue({
  el:"#app",
  data : {
    text: "",
    inProgress : false
  },
  methods : {
  	calculate : function(){
    	this.inProgress = true;
    	  new Promise((resolve,reject)=>{
      	  setTimeout(function(){
        	resolve('I am done')
        },3000)
      }).then(e=>{
      	   this.text = e;
           this.inProgress = false;
      })
    }
  }
})
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<div id="app">
  <button @click="calculate()"> click me</button>
  <p>{{text}}</p>
  <div v-show="inProgress">
    loading...
  </div>
</div>

I have just tried a way to do that as I was not able to reproduce same situation due to lack of code information.

I hope this might help to get you through.

Upvotes: 1

Related Questions