title: Vue JS: Prop's property change is not detected inside sub-components
body: <p>I'm building a simple media player app. This is the simplified app structure:</p>
  
  <pre><code>|-- app.vue
  |-- components
  |   |-- main-wrapper
  |   |   |-- index.vue
  |   |   |-- main-content
  |   |   |   |-- albums.vue
  |   |   |   |-- artists.vue
  |   |   |   |-- index.vue
  |   |   |   |-- songs.vue
  |   |   `-- sidebar
  |   |       `-- playlists.vue
  |   |-- shared
  |       `-- song-item.vue
  `-- main.js
  </code></pre>
  
  <p>The song list is fetched from the top level <code>app.vue</code> and subsequently passed down as <code>props</code> to <code>components/main-wrapper/index.vue</code>,  <code>components/main-wrapper/main/content/index.vue</code>, and <code>components/main-wrapper/main/content/songs.vue</code>, in that order. All <code>props</code> are defined as dynamic – e.g. <code>:list="songs"</code> – and registered in the child components – e.g. <code>props: ['list']</code> and such. </p>
  
  <p>Now in the <code>songs.vue</code> subcomponent I have this code:</p>
  
  <pre><code>&lt;template&gt;
      &lt;tbody&gt;
          &lt;tr is="song-item" v-for="song in list" track-by="id" :song="song"&gt;&lt;/tr&gt;
      &lt;/tbody&gt;
  &lt;/template&gt;
  
  &lt;script&gt;
      import songItem from '../../shared/song-item.vue';
  
      export default {
          props: ['list'], // register the prop from parent, as said above
          replace: false,
          components: { songItem }
      };
  &lt;/script&gt;
  </code></pre>
  
  <p>Each <code>songItem</code> is a component instance (?) that has its own status set by checking <code>song.playing</code>, i.e. to highlight the text if it's being played.</p>
  
  <pre><code>&lt;style&gt;.playing { color: #f00; }&lt;/style&gt;
  
  &lt;template&gt;
      &lt;tr :class="{ 'playing': song.playing }"&gt;
          &lt;td class="title"&gt;{{ song.title }}&lt;/td&gt;
          &lt;td class="controls"&gt;
              &lt;i v-show="!song.playing" class="fa fa-play-circle" @click="play"&gt;&lt;/i&gt;
              &lt;i v-show="song.playing" class="fa fa-pause-circle" @click="pause"&gt;&lt;/i&gt;
          &lt;/td&gt;
      &lt;/tr&gt;
  &lt;/template&gt;
  
  &lt;script&gt;
      export default {
          props: ['song'], // again, register the prop from parent
  
          methods: {
              play() {
                  this.$root.play(this.song);
              }
          }
      }
  &lt;/script&gt;
  </code></pre>
  
  <p>Now, <code>this.$root.play(this.song)</code> will set the current song's <code>playing</code> property to <code>false</code>, replace it with the newly provided <code>this.song</code> parameter, and set this new song's <code>playing</code> to <code>true</code>.</p>
  
  <p>With this approach, I'd expect that every time a new song is played, its component's <code>&lt;tr&gt;</code> will be highlighted with <code>.playing</code> class activated, when those of others will be dimmed due to <code>.playing</code> class removed. Sadly, it's not the case. Apparently the songs' <code>playing</code> property is not watched at all, so even though it's changed in every <code>Song</code> object, the CSS class is never toggled.</p>
  
  <p>What am I doing wrong here?</p>