So I need to play some mp3 audio using Howler.js, and want a minimal GUI for it. I created this component that is a button, which will show "play" or "pause" icon based on the status of the player. Here is the code:
<template>
<div><button class="ui icon button" @click="toggleAudioPlay">
<i v-if="isPlaying" class="pause icon"></i>
<i v-else class="play icon"></i>
</button>
<button @click="showDuration">Show</button>
</div>
</template>
<script lang="ts">
import { Howl } from 'howler'
export default {
props: ['audio'],
data: function () {
return {
player: null
}
},
computed: {
isPlaying () {
console.log('updating "isPlaying"')
return this.player && this.player.playing()
}
},
methods: {
toggleAudioPlay () {
if (!this.player) {
this.player = new Howl({
src: [this.audio]
})
}
if (this.isPlaying) {
this.player.pause()
} else {
this.player.play()
}
},
showDuration () {
console.log('Duration is:', this.player ? this.player.duration() : 0)
}
}
}
</script>
<style>
</style>
Here is a running example of above code on codesandbox.
It worked as expected. But after thinking about it, I started wondering why it worked: isPlaying
not only depends on the value of this.player
, it also depends on the internal status of this.player
, how does Vue know when to recalculate the computed property isPlaying
?
I added the logging statement in function isPlaying
to see when the property is updated. Testing shows that it's updated
- when the player is first created. (As expected because
this.player
changed fromnull
); - when the player starts or pauses, and at the end of play (??? How can Vue know that these are the moments that the property need to be recalculated? After calling the
play
orpause
method, the player is still the same player, only the result ofplaying
method changed).
Will Vue recheck the player status after any of the player's method is called?
I added the show
button, to call the duration
method of the player, which will not change the playing status of the player. Testing with this button shows that isPlaying
is not updated when duration
is called, so it looks like Vue knows exactly what methods of the player will change its status. This surprised me because technically any method could change the player's status, you have to read/analyze the code to determine whether it will change the player's status or not. As a matter of fact, the playing
method of the Howler.js player is quite complicate, not just querying a property of the player.
I checked Vue's document on Reactivity in Depth and couldn't find anything related to this.
Any explanation or references to related docs or codes of Vue are appreciated.