programing

Vuex를 사용하여 항목이 개체 배열의 일부인 경우 어레이에서 항목을 제거하려면 어떻게 해야 합니까?

bestcode 2022. 7. 12. 22:37
반응형

Vuex를 사용하여 항목이 개체 배열의 일부인 경우 어레이에서 항목을 제거하려면 어떻게 해야 합니까?

라이브 데모 코드는, 다음과 같습니다.

https://codesandbox.io/s/vue-template-r26tg

다음과 같은 데이터를 가진 Vuex 스토어가 있다고 가정해 보겠습니다.

const store = new Vuex.Store({
  state: {
    categories: [
      {
        name: "Category A",
        items: [{ name: "Item 1" }, { name: "Item 2" }, { name: "Item 3" }]
      },
      {
        name: "Category B",
        items: [{ name: "Item A" }, { name: "Item B" }, { name: "Item C" }]
      },
      {
        name: "Category C",
        items: [{ name: "Item !" }, { name: "Item @" }, { name: "Item #" }]
      }
    ]
  }
});

그리고 저는...App.vue,Category.vue그리고.Item.vue다음과 같이 렌더링되도록 설정됩니다.

//App.vue
<template>
  <div id="app">
    <Category v-for="(category, index) in categories" :category="category" :key="index"/>
  </div>
</template>

<script>
  export default {
    components: { Category },

    computed: {
      ...mapState(["categories"])
    }
  };
</script>
//Category.vue
<template>
  <div class="category">
    <div class="header">{{ category.name }}</div>
    <Item v-for="(item, index) in category.items" :item="item" :key="index"/>
  </div>
</template>

<script>
  export default {
    components: { Item },

    props: {
      category: { type: Object, required: true }
    }
  };
</script>
//Item.vue
<template>
  <div class="item">
    <div class="name">{{ item.name }}</div>
    <div class="delete" @click="onDelete">&#10006;</div>
  </div>
</template>

<script>
  export default {
    props: {
      item: { type: Object, required: true }
    },

    methods: {
      onDelete() {
        this.$store.commit("deleteItem", this.item);
      }
    }
  };
</script>

바꿔 말하면App.vueVuex에서 카테고리 목록을 가져온 다음 에 전달합니다.Category.vue각 카테고리의 소품으로서Category.vue전해지다category.items로.Item.vue각 아이템의 소품으로서

항목 옆에 있는 삭제 버튼을 클릭하면 항목을 삭제해야 합니다.

여기에 이미지 설명 입력

단,Item.vue레벨, 나는 단지 에 액세스 할 수 있다.item단,category. 내가 보낸다면itemVuex에게, 나는 어느 것이 어떤 것인지 말할 방법이 없다.category그것은 소유물입니다.에 대한 참조를 얻으려면 어떻게 해야 합니까?categoryVuex를 사용하여 아이템을 삭제할 수 있습니까?

두 가지 방법을 생각할 수 있습니다.

  1. 부모 참조를 에 다시 추가합니다.category각각에 대해서item이것은 단지 내가 마사지를 해야 하기 때문에 바람직하지 않다.item또한 앱의 다른 부분에서는 다루지 않는 순환 참조를 도입하기 때문입니다.

  2. 이벤트를 내보내다Item.vue까지Category.vue그리고 렛Category.vueVuex 삭제 호출을 처리합니다.이렇게 하면 카테고리와 삭제할 항목이 모두 인식됩니다.

이런 종류의 삭제를 처리하는 더 좋은 방법이 있나요?

저는 (2)를 강력히 추천합니다.일반적으로 다른 부작용(API 호출, Vuex 돌연변이 등) 없이 소품을 사용하여 이벤트를 발생시키는 컴포넌트를 만들 수 있다면 그것이 올바른 경로입니다.이 경우 이벤트를 부모의 부모에게까지 푸시할 수도 있습니다.

공유 상태(Vuex)가 실제로 도움이 되는 것은 DOM 트리에서 서로 멀리 떨어져 있는 컴포넌트가 둘 이상 있는 경우입니다.예를 들어, 총 항목 수가 포함된 헤더를 상상해 보십시오.이 정도의 공간 구분은 앱에 존재할 수 있지만, 이 간단한 예에서는 그렇지 않습니다.

이벤트 전달의 또 다른 장점은 Vuex의 회피책 없이 스토리북 등의 툴을 쉽게 사용할 수 있다는 것입니다.

개인적으로는 2개(이벤트 출연)로 하겠습니다Item.vue까지Category.vue). 단, 가능성을 물었으므로 세 번째 방법이 있습니다.콜백 함수 전달입니다

예:

Category.vue:

<template>
  <div class="category">
    <div class="header">{{ category.name }}</div>
    <Item v-for="(item, index) in category.items" :item="item" :key="index"
     :on-delete="deleteItem"/>
  </div>
</template>

<script>
// ...
export default {
  // ...
  methods: {
    deleteItem(i) {
      console.log('cat', this.category.name, 'item', i)
      //this.$store.commit("deleteItem", this.item);
    }
  }
};
</script>

Item.vue:

<template>
  <div class="item">
    <div class="name">{{ item.name }}</div>
    <div class="delete" @click="() => onDelete(this.item)">&#10006;</div>
  </div>
</template>

<script>
export default {
  props: {
    item: { type: Object, required: true },
    onDelete: { type: Function }
  },
};
</script>

샌드박스를 갱신했습니다.이 경우 콜백은onDelete.

이것이 리액트라면 콜백은 확실히 좀 더 관용적인 방법이었다.Vue에서는 앞서 말한 것처럼 아이에게 이벤트를 방출하고 부모에게 이벤트를 처리하는 것을 찬성합니다.v-on를 참조해 주세요.

언급URL : https://stackoverflow.com/questions/57665858/using-vuex-how-do-i-remove-items-from-an-array-when-they-are-part-of-an-array-o

반응형