2015-11-28 4 views
1

Я создаю приложение для простого медиаплеера. Это упрощенная структура приложения:Vue JS: изменение свойств Prop не обнаружено внутри подкомпонентов

|-- 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 

песня список извлекается из верхнего уровня app.vue, а затем передается в props к components/main-wrapper/index.vue, components/main-wrapper/main/content/index.vue и components/main-wrapper/main/content/songs.vue, в таком порядке. Все props определяются как динамические. :list="songs" - и зарегистрировано в дочерних компонентах - например, props: ['list'] и тому подобное.

Сейчас в songs.vue подкомпоненте У меня есть этот код:

<template> 
    <tbody> 
     <tr is="song-item" v-for="song in list" track-by="id" :song="song"></tr> 
    </tbody> 
</template> 

<script> 
    import songItem from '../../shared/song-item.vue'; 

    export default { 
     props: ['list'], // register the prop from parent, as said above 
     replace: false, 
     components: { songItem } 
    }; 
</script> 

Каждый songItem является компонентом экземпляра, который имеет свой собственный статус, установленный проверкой song.playing, то есть, чтобы выделить текст, если он воспроизводится (?).

<style>.playing { color: #f00; }</style> 

<template> 
    <tr :class="{ 'playing': song.playing }"> 
     <td class="title">{{ song.title }}</td> 
     <td class="controls"> 
      <i v-show="!song.playing" class="fa fa-play-circle" @click="play"></i> 
      <i v-show="song.playing" class="fa fa-pause-circle" @click="pause"></i> 
     </td> 
    </tr> 
</template> 

<script> 
    export default { 
     props: ['song'], // again, register the prop from parent 

     methods: { 
      play() { 
       this.$root.play(this.song); 
      } 
     } 
    } 
</script> 

Теперь this.$root.play(this.song) установит playing свойства текущей песни в false, заменить его вновь при условии this.song параметра, и установить этот новый Сонг playing к true.

При таком подходе, я бы ожидать, что каждый раз, когда новая песня играет, его компонента <tr> будет выделена .playing класса активированной, когда те, остальные будут потускнели из-за .playing класс удален. К сожалению, это не так. По-видимому, свойство «playing» песен вообще не просматривается, поэтому, хотя он изменяется в каждом объекте Song, класс CSS никогда не переключается.

Что я здесь делаю неправильно?

+0

Не могли бы вы предоставить jsfiddle? –

+0

Я не уверен, может ли простая скрипка справиться с этим. Как уже упоминалось выше, это упрощенная (очень упрощенная) версия приложения, которая на самом деле имеет ~ 50 файлов и имеет бэкэнд PHP. –

ответ

2

Вы можете попробовать добавить свойство (например playingSong) в app.vue и передать его в качестве synced property к song-item шаблона.

Тогда вместо this.$root.play(this.song) следует установить this.playingSong = this.song

И затем, создать вычисляемое свойство, чтобы проверить песню

computed: { 
    playing() { 
     return this.playingSong === this.song 
    } 
} 

Надеется, что это помогает.

+0

Это работает, хотя и немного опрятно - есть ли лучший способ, чем прохождение «currentSong» вокруг? –

+0

Возможно, вы могли бы получить доступ к этому как это 'this. $ Root.playingSong' –

+0

Правильно, я попробую это. Благодаря! –

Смежные вопросы