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.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
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
}
}
希望对您有所帮助。
我正在构建一个简单的媒体播放器应用程序。这是简化的应用程序结构:
|-- 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
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
}
}
希望对您有所帮助。