Gec*_*o29 6 vue.js vuex vuetify.js
我在我的应用程序中遇到了一些有关反应性的问题。
我有一个 Vuex 商店,其中有一个对象“歌曲”,其中包含“歌曲”对象,其中键是它们的 ID。对于其中的每个歌曲对象,我都有各种属性,有问题的属性是“播放”一个布尔值。
例如
songs = {
2: {playing: false},
7: {playing: true)
}
Run Code Online (Sandbox Code Playgroud)
在我的应用程序中,我有一个列表,对所有这些歌曲使用 v-for,并通过一个按钮切换歌曲的播放属性。当按下按钮时,我会发送我创建的动作,传入与按下的按钮相关联的歌曲 ID
this.$store.dispatch('toggleSongPlaying', {songid: songid})
Run Code Online (Sandbox Code Playgroud)
根据歌曲是否正在播放,我希望显示适当的图标。
我的问题的简化 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
};
Run Code Online (Sandbox Code Playgroud)
设置功能工作正常,问题在于反应性。按下切换按钮时,不会发生图标更改。然而,触发重新渲染会导致图标发生变化。在我的组件中,我像这样使用 mapGetters:
computed: {
...mapGetters({
songs: "getSongs"
})
}
Run Code Online (Sandbox Code Playgroud)
为了使反应性与此嵌套对象正常工作,我是否缺少某些东西?
感谢您的任何建议!
编辑 - 列表和图标的模板代码
<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>
Run Code Online (Sandbox Code Playgroud)
methods: {
toggleSongPlaying(songid) {
this.$store.dispatch('toggleSongPlaying', {songid: songid})
}
},
Run Code Online (Sandbox Code Playgroud)
EDIT2 在创建的单独组件中,我用这样的歌曲填充歌曲对象
created() {
var songid = "12"
var song = {
length: ...,
playing: false,
}
var payload = {
song: song,
songid: songid
}
this.$store.dispatch('addSong', payload)
},
Run Code Online (Sandbox Code Playgroud)
在 Vuex 中
行动:
addSong({ commit }, payload) {
commit("add_song", payload);
}
Run Code Online (Sandbox Code Playgroud)
突变体:
add_song(state, payload) {
state.songs[payload.songid] = payload.song
},
Run Code Online (Sandbox Code Playgroud)
您将歌曲分配到您的状态的方式不是被动的
Vue 无法检测属性添加或删除
更改您的add_song
突变以用songs
新的(包括新歌曲)替换state 属性。这被视为songs
不可变的
add_song: (state, { songid, song }) => {
state.songs = {
...state.songs,
[ songid ]: { ...song } // break any object references, thank me later
}
},
Run Code Online (Sandbox Code Playgroud)
现在您不需要使用,Vue.set
因为该payload
属性已被被动添加。你update_song_playing
可以简单地
update_song_playing: (state, { songid }) => {
const song = state.songs[songid];
if (song) {
song.playing = !song.playing;
}
}
Run Code Online (Sandbox Code Playgroud)
您也可以Vue.set
在您的add_song
突变中使用,但我一直觉得基于 Flux 的存储最适合使用不可变数据。
归档时间: |
|
查看次数: |
4929 次 |
最近记录: |