Vue JS:在子组件内部未检测到 Prop 的 属性 更改

Vue JS: Prop's property change is not detected inside sub-components

我正在构建一个简单的媒体播放器应用程序。这是简化的应用程序结构:

|-- 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.vuecomponents/main-wrapper/main/content/index.vuecomponents/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参数,并设置这个新歌的 playingtrue

通过这种方法,我希望每次播放一首新歌时,其组件的 <tr> 将突出显示并激活 .playing class,而其他组件将被激活由于 .playing class 被移除而变暗。可悲的是,事实并非如此。显然歌曲的 playing 属性 根本没有被观看,所以即使它在每个 Song 对象中都发生了变化,CSS class 也从未被切换。

我做错了什么?

您可以尝试将 属性(例如 playingSong)添加到 app.vue 并将其作为 synced property 传递给 song-item 模板。

那么,您应该设置 this.playingSong = this.song

而不是 this.$root.play(this.song)

然后,创建一个计算属性来检查歌曲

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

希望对您有所帮助。