首页 > 解决方案 > Vue.js:在点击时响应式更新组件

问题描述

我有一个用于在收藏夹中添加/删除项目的组件。它工作得很好,但用户看不到他/她是否将项目添加到收藏夹中(如果项目被收藏,我会显示一个星形图标,如果不是,我会显示一个空图标)。我怎样才能被动地做到这一点?如果用户单击它,我希望我的图标更改其类别。

这是我的代码:

零件:

<template>
 <span :class="isFavorite
            ? 'mdi mdi-star favorite'
            : 'mdi mdi-star-outline'"
    class="favorite-item-icon"
    @click="isFavorite ? deleteFromFavoriteItems(itemId) : addToFavoriteItems(itemId)">
 </span>
</template>

<script>
 export default {
  import { mapGetters, mapActions } from 'vuex';

  props: ['itemId', 'isFavorite'],
  methods: {
    ...mapActions(['addToFavoriteItems', 'deleteFromFavoriteItems']),
  },
};
</script>

v-for 中的组件的父组件列表:

...
 <favorite-label :itemId="item.id" :isFavorite="item.is_favourite" />
...

在我的商店:

addToFavoriteItems({ commit }, itemId) {
  http
    .post(`${config.api}api/v1/items/favourite-save`, {
      item_id: itemId,
    });
deleteFromFavoriteItems({ commit }, itemId) {
  http
    .post(`${config.api}api/v1/items/favourite-delete`, {
      item_id: itemId,
    });

标签: javascriptvue.jsreactive-programming

解决方案


您需要将item服务器(更新后)的 分配给商店,例如:

$post(..., { item_id: itemId }).then(function(response) {
  this.$store.commit('items/SET_ITEM', response.data)
})

items/SET_ITEM突变循环当前数组中的项目并在匹配时更新项目id

let itemToUpdate = this.items.forEach(function(i) {
  if (i.id === item.id) {
    i = item
  }
})

isFavorite然后它应该正确地改变 store 调度 prop 更新并导致视图在新计算到位的情况下重新渲染。

或者,如果itemId可以使用您传递的 ,则服务器没有理由更改任何内容,只需将其传递,例如:

$post(..., { item_id: itemId }).then(function() {
  this.$store.commit('items/UPDATE_FAVORITE', { item: itemId })
})

现在您可以添加一个切换收藏夹的突变,基本上:

this.items.forEach(function(i) {
  if (i.id === item) {
      i.is_favorite = !i.is_favorite
  }
})

推荐阅读