【问题标题】:Vue JS: Prop's property change is not detected inside sub-componentsVue JS:在子组件内未检测到 Prop 的属性更改
【发布时间】:2018-09-09 05:43:32
【问题描述】:

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

|-- 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 参数,并将这首新歌曲的playing 设置为true

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

我在这里做错了什么?

【问题讨论】:

  • 你能提供一个jsfiddle吗?
  • 我不确定一个简单的小提琴是否可以处理这个问题。如上所述,这是应用程序的简化(非常简化)版本,实际上现在有大约 50 个文件,并且有一个 PHP 后端。

标签: vue.js


【解决方案1】:

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

那么,你应该设置this.playingSong = this.song,而不是this.$root.play(this.song)

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

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

希望对你有帮助。

【讨论】:

  • 这行得通,尽管有点繁琐——还有比这样传递currentSong 更好的方法吗?
  • 也许你可以像这样访问它this.$root.playingSong
  • 好吧,我试试这个。谢谢!
猜你喜欢
  • 2021-02-08
  • 1970-01-01
  • 2018-09-14
  • 1970-01-01
  • 2018-07-25
  • 1970-01-01
  • 2020-08-14
  • 2011-12-10
  • 1970-01-01
相关资源
最近更新 更多