【发布时间】:2020-12-26 08:43:27
【问题描述】:
我在我的应用程序中遇到了一些关于反应性的问题。
我有一个 Vuex 商店,我有一个对象“歌曲”,其中包含“歌曲”对象,其中键是它们的 id。对于其中的每个歌曲对象,我都有各种属性,其中一个正在“播放”一个布尔值。
例如
songs = {
2: {playing: false},
7: {playing: true)
}
在我的应用程序中,我有一个列表,对所有这些歌曲使用 v-for,并带有一个用于切换歌曲播放属性的按钮。当按下按钮时,我会发送我创建的动作,并传入与按下的按钮关联的 Songid
this.$store.dispatch('toggleSongPlaying', {songid: songid})
根据歌曲是否正在播放,我希望显示相应的图标。
我的问题的简化 vuex 存储包括以下内容:
const state = {
songs: {}
};
const mutations = {
update_song_playing(state, payload) {
var songObj = state.songs[payload.songid]
var playingBool = !songObj.playing
Vue.set(songObj, 'playing', playingBool)
}
};
const actions = {
toggleSongPlaying({ commit }, payload) {
commit("update_song_playing", payload)
}
};
const getters = {
getSongs: state => state.songs
};
设置功能工作正常,问题在于反应性。按下切换按钮时,不会发生图标更改。然而,触发重新渲染确实会导致图标发生变化。在我的组件中,我像这样使用 mapGetters:
computed: {
...mapGetters({
songs: "getSongs"
})
}
为了让反应性与此嵌套对象正常工作,我是否缺少一些东西?
感谢您的任何建议!
编辑 - 列表和图标的模板代码
<v-list dense>
<v-subheader>Songs List</v-subheader>
<v-list-item-group v-model="activeSong" color="primary">
<v-list-item
v-for="(song, songID) in songs"
:key="songID"
>
<v-icon class="mr-3" @click.stop="toggleSongPlaying(songID)">{{song.playing ? 'mdi-pause' : 'mdi-play'}}</v-icon>
// song details etc...
<v-list-item-content>
<v-list-item-title>
</v-list-item-title>
</v-list-item-content>
</v-list-item>
</v-list-item-group>
</v-list>
methods: {
toggleSongPlaying(songid) {
this.$store.dispatch('toggleSongPlaying', {songid: songid})
}
},
EDIT2 在创建的单独组件中,我用这样的歌曲填充歌曲对象
created() {
var songid = "12"
var song = {
length: ...,
playing: false,
}
var payload = {
song: song,
songid: songid
}
this.$store.dispatch('addSong', payload)
},
在 Vuex 中
行动:
addSong({ commit }, payload) {
commit("add_song", payload);
}
突变体:
add_song(state, payload) {
state.songs[payload.songid] = payload.song
},
【问题讨论】:
-
在组件内调用toggleSongPlaying动作。
-
我刚刚在底部添加了它。当我按下图标切换布尔变量时,不会发生任何变化。但是如果发生重新渲染,例如单击列表中的某个项目,则图标会发生变化
-
我也在 Vuetify 沙箱中尝试过,无法重现问题
-
嗯,这很奇怪。为了简单起见,我说过状态歌曲是用 2 个歌曲对象初始化的。在实践中,我在 created 钩子中设置歌曲,其中一个 setter 接受歌曲 id 和一个由各种道具(包括播放属性)组成的对象。会不会是这个问题?
-
请说明您如何将 song 对象分配给您的商店
标签: vue.js vuex vuetify.js