'Vue 3 setInterval Methods behavior
Env
I have a Vue 3 Application which requires a constant setInterval() to be running in the background (Game Loop).
I put that in store/index.js and call it from views/Playground.vue on mounted().
When leaving Playground i call beforeUnmount(). Making sure that not multiple setInterval() are running.
// store/index.js
startGameLoop({ commit, dispatch, getters }) {
commit(
"setIntervalId",
setInterval(() => {
dispatch("addPower", getters["ship/getFuelPerSecond"]);
}, 1000)
);
},
// Playground.vue
beforeUnmount() {
clearInterval(this.intervalId);
}
In the top section of Playground.vue there is a score displayed and updated within the setInterval(). I use a library called gsap to make the changing numbers a bit pleasant for the eye.
<h2>Points: {{ tweened.toFixed(0) }}</h2>
watch: {
points(n) {
console.log("gsap");
gsap.to(this, { duration: 0.2, tweened: Number(n) || 0 });
},
},
Problem
methods from the Playground.vue are fired differently and i'm struggling to understand why that is the case.
gsap
the watch from the gsap is fired every second like i would expect from the setInterval() but...
Image
In the center of the Playground i display and image where the src part is v-bind to a method called getEnemyShipImage. In the future i would like to change the displayed enemie ship programmatically - but the method is called 34 times per second. Why is that?
<img
:class="{ flashing: flash }"
@click="fightEnemie()"
:src="getEnemyShipImage()"
alt=""
/>
getEnemyShipImage() {
console.log("image");
return require("@/assets/ships/ship-001.png");
}
Log (Browser)
Solution 1:[1]
moved it to a part without using a method and switch changing images to a watch.
data: () => {
return {
...
selectedImages: "",
images: [
require("@/assets/ships/ship-001.png"),
require("@/assets/ships/ship-002.png"),
require("@/assets/ships/ship-003.png"),
],
};
},
// initial value
mounted() {
this.selectedImages =
this.images[Math.floor(Math.random() * this.images.length)];
this.$store.dispatch("startGameLoop");
}
// watch score
watch: {
score() {
this.selectedImages =
this.images[Math.floor(Math.random() * this.images.length)];
},
}
it's not perfect but better as initialy.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Nick |
