title: Why does the conditional rendering of icons fail in this Vue 3 application?
body: <p>I am working on an <strong>audio player</strong> with Vue 3 and the Napster API.</p>
  <h3>Project details</h3>
  <p>There is a mute/unmute button and the method below:</p>
  <pre><code>toggleMute() {
    this.player.muted = !this.player.muted;
  }
  </code></pre>
  <p><div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="false">
  <div class="snippet-code">
  <pre class="snippet-code-js lang-js prettyprint-override"><code>const musicApp = {
    data() {
      return {
        player: new Audio(),
        trackCount: 0,
        tracks: []
      };
    },
    methods: {
      async getTracks() {
        try {
          const response = await axios
            .get(
              "https://api.napster.com/v2.1/tracks/top?apikey=ZTk2YjY4MjMtMDAzYy00MTg4LWE2MjYtZDIzNjJmMmM0YTdm"
            )
            .catch((error) =&gt; {
              console.log(error);
            });
          this.tracks = response;
          this.tracks = response.data.tracks;
        } catch (error) {
          console.log(error);
        }
      },
      nextTrack() {
        if (this.trackCount &lt; this.tracks.length - 1) {
          this.trackCount++;
          this.setPlayerSource();
          this.playPause();
        }
      },
      prevTrack() {
        if (this.trackCount &gt;= 1) {
          this.trackCount--;
          this.setPlayerSource();
          this.playPause();
        }
      },
      setPlayerSource() {
        this.player.src = this.tracks[this.trackCount].previewURL;
      },
      playPause() {
        if (this.player.paused) {
          this.player.play();
        } else {
          this.player.pause();
        }
      },
      toggleMute() {
        this.player.muted = !this.player.muted;
      }
    },
    async created() {
      await this.getTracks();
      this.setPlayerSource();
      this.playPause();
    },
    computed: {
      isPlaying() {
        return !this.player.paused;
      },
      isMuted() {
        return this.player.muted;
      }
    }
  };
  
  Vue.createApp(musicApp).mount("#audioPlayer");</code></pre>
  <pre class="snippet-code-css lang-css prettyprint-override"><code>html,
  body {
    margin: 0;
    padding: 0;
    font-size: 16px;
  }
  
  body * {
    box-sizing: border-box;
    font-family: "Montserrat", sans-serif;
  }
  
  .player-container {
    display: flex;
    justify-content: center;
    align-items: center;
    min-height: 100vh;
    background-color: #2998ff;
    background-image: linear-gradient(62deg, #2998ff 0%, #5966eb 100%);
  }
  
  #audioPlayer {
    width: 300px;
    height: 300px;
    border-radius: 8px;
    position: relative;
    overflow: hidden;
    background-color: #00ca81;
    background-image: linear-gradient(160deg, #00ca81 0%, #ffffff 100%);
    box-shadow: 0 0.125rem 0.25rem rgba(0, 0, 0, 0.075);
    display: flex;
    flex-direction: column;
    align-items: center;
  }
  
  .volume {
    color: #ff0057;
    opacity: 0.9;
    font-size: 20px;
    position: absolute;
    top: 5px;
    right: 6px;
    cursor: pointer;
  }
  
  .album {
    width: 100%;
    flex: 1;
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    align-items: center;
  }
  
  .album-items {
    padding: 0 10px;
    text-align: center;
  }
  
  .cover {
    width: 150px;
    height: 150px;
    margin: auto;
    box-shadow: 0px 5px 12px 0px rgba(0, 0, 0, 0.17);
    border-radius: 50%;
    background: url("https://www.udiscovermusic.com/wp-content/uploads/2017/08/The-Smashing-Pumpkins-Mellon-Collie-and-the-Infinite-Sadness.jpg")
      center top transparent;
    background-size: cover;
  }
  
  .info {
    width: 100%;
    padding-top: 5px;
    color: #000;
    opacity: 0.85;
  }
  
  .info h1 {
    font-size: 11px;
    margin: 5px 0 0 0;
  }
  
  .info h2 {
    font-size: 10px;
    margin: 3px 0 0 0;
  }
  
  .to-bottom {
    width: 100%;
    margin-top: auto;
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
  }
  
  .track {
    background-color: #ff0057;
    opacity: 0.9;
    height: 3px;
    width: 100%;
  }
  
  .controls {
    width: 150px;
    display: flex;
    height: 60px;
    justify-content: space-between;
    align-items: center;
  }
  
  .controls .navigate {
    display: flex;
    box-shadow: 1px 2px 7px 2px rgba(0, 0, 0, 0.09);
    width: 33px;
    height: 33px;
    line-height: 1;
    color: #ff0057;
    cursor: pointer;
    background: #fff;
    opacity: 0.9;
    border-radius: 50%;
    text-align: center;
    justify-content: center;
    align-items: center;
  }
  
  .controls .navigate.disabled {
    pointer-events: none;
    color: #606060;
    background-color: #f7f7f7;
  }
  
  .controls .navigate.navigate-play {
    width: 38px;
    height: 38px;
  }
  
  .navigate-play .fa-play {
    margin-left: 3px;
  }</code></pre>
  <pre class="snippet-code-html lang-html prettyprint-override"><code>&lt;link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet" /&gt;
  &lt;script src="https://unpkg.com/axios@0.22.0/dist/axios.min.js"&gt;&lt;/script&gt;
  &lt;script src="https://unpkg.com/vue@next"&gt;&lt;/script&gt;
  &lt;link href="https://fonts.googleapis.com/css2?family=Montserrat:wght@300;500&amp;display=swap" rel="stylesheet"&gt;
  
  &lt;div class="player-container"&gt;
    &lt;div id="audioPlayer"&gt;
      &lt;span class="volume" @click="toggleMute"&gt;
        &lt;i v-show="!isMuted" class="fa fa-volume-up"&gt;&lt;/i&gt;
        &lt;i v-show="isMuted" class="fa fa-volume-off"&gt;&lt;/i&gt;
      &lt;/span&gt;
      &lt;div class="album"&gt;
        &lt;div class="album-items"&gt;
          &lt;div class="cover"&gt;&lt;/div&gt;
          &lt;div class="info"&gt;
            &lt;h1&gt;{{tracks[trackCount].name}}&lt;/h1&gt;
            &lt;h2&gt;{{tracks[trackCount].artistName}}&lt;/h2&gt;
          &lt;/div&gt;
        &lt;/div&gt;
      &lt;/div&gt;
  
      &lt;div class="to-bottom"&gt;
        &lt;div class="track"&gt;&lt;/div&gt;
        &lt;div class="controls"&gt;
          &lt;div class="navigate navigate-prev" :class="{'disabled' : trackCount == 0}" @click="prevTrack"&gt;
            &lt;i class="fa fa-step-backward"&gt;&lt;/i&gt;
          &lt;/div&gt;
          &lt;div class="navigate navigate-play" @click="playPause"&gt;
            &lt;i v-if="isPlaying" class="fa fa-pause"&gt;&lt;/i&gt;
            &lt;i v-else class="fa fa-play"&gt;&lt;/i&gt;
          &lt;/div&gt;
          &lt;div class="navigate navigate-next" :class="{'disabled' : trackCount == tracks.length - 1}" @click="nextTrack"&gt;
            &lt;i class="fa fa-step-forward"&gt;&lt;/i&gt;
          &lt;/div&gt;
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;</code></pre>
  </div>
  </div>
  </p>
  <h3>The problem</h3>
  <p>Depending on the state of the player (muted or unmuted), I want to display either the volume-up or the volume-off icon. For this purpose, I use the <code>isMuted</code> <em>computed property</em> in the template:</p>
  <pre><code>&lt;span class=&quot;volume&quot; @click=&quot;toggleMute&quot;&gt;
    &lt;i v-show=&quot;!isMuted&quot; class=&quot;fa fa-volume-up&quot;&gt;&lt;/i&gt;
    &lt;i v-show=&quot;isMuted&quot; class=&quot;fa fa-volume-off&quot;&gt;&lt;/i&gt;
  &lt;/span&gt;
  </code></pre>
  <p>The player is correctly muted and unmuted but <em>the icon does not change</em> accordingly.</p>
  <h4>What am I doing wrong?</h4>