我正在使用 Vue 和 Vuex 构建一个简单的电影应用程序,并希望能够在单击按钮时将电影添加到收藏夹列表中。我正在将电影添加到商店,但我希望在添加电影后按钮上的文本从"添加到收藏夹"更改为"从收藏夹中删除"。我正在使用计算属性来读取 Vuex 商店,以根据电影是否在商店的收藏夹列表中来确定按钮上的文本。如果我重新加载页面,按钮上的文本会正确更改,但是当单击按钮添加/删除电影时,我无法更改文本。如何让计算的属性在 Vuex 存储中的更改时重新计算?
这是我的电影组件:
<template>
<div class="single-movie-page">
<img class="movie-img" :src="movie.img"></img>
<div class="single-movie-info">
<h1>{{movie.title}}</h1>
<h3>Rating: {{movie.stars}}</h3>
<h3>Released Date: {{movie.releaseDate}}</h3>
<p>{{movie.overview}}</p>
<button v-on:click="addRemoveFavourites" >{{ favourite }}</button>
</div>
</div>
</template>
<script>
export default {
props: ['movie'],
computed: {
favourite() {
return this.$store.state.favourites[this.movie.id] === undefined
? 'Add to Favourites'
: 'Remove from Favourites'
}
},
methods: {
addRemoveFavourites() {
this.$store.commit('changeFavourites', this.movie)
}
}
}
</script>
这是我的 Vuex 商店:
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export const store = new Vuex.Store({
state: {
favourites: {}
},
mutations: {
changeFavourites: (state, movie) => {
if (state.favourites[movie.id]) {
delete state.favourites[movie.id]
} else state.favourites[movie.id] = movie
}
}
})
我尝试在addRemoveFavorites 方法中使用this.$forceUpdate()
,但这也没有用。
Bert 有正确的答案,您通常不能从对象中添加/删除属性并让它们在 Vuejs 中是反应式的。
如果您希望它们具有响应性,则需要使用Vue.set
和Vue.delete
。
所以你的突变应该看起来像这样:
mutations: {
changeFavourites: (state, movie) => {
if (state.favourites[movie.id]) {
Vue.delete(state.favourites, movie.id)
} else {
Vue.set(state.favourites, movie.id, movie)
}
}
}