How can vue being reactive to Howlerjs's player status

315 views Asked by At

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

  1. when the player is first created. (As expected because this.player changed from null);
  2. 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 or pause method, the player is still the same player, only the result of playing 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.

0

There are 0 answers