Reputation: 4173
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
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
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