programing

Vuex - 전체 어레이 업데이트

itsource 2022. 7. 21. 20:00
반응형

Vuex - 전체 어레이 업데이트

Vue.js 앱이 있어요.이 앱은 상태 관리에 Vuex를 사용하고 있습니다.저희 가게는 다음과 같습니다.

const store = new Vuex.Store({
    state: {
        items: []
    },

    mutations: {
        MUTATE_ITEMS: (state, items) => {
            state.items = items;
        }
    },

    actions: {
        loadItems: (context, items) => {
            context.commit('MUTATE_ITEMS', items);
        }
    }
  })
;

Vue 인스턴스에는 다음과 같은 방법이 있습니다.

loadItems() {

  let items = [];
  for (let I=0; I<10; I++) {
    items.push({ id:(I+1), name: 'Item #' + (I+1) });
  }
  this.$store.dispatch('loadItems', items);
},

이 작업을 실행하면 자식 구성 요소의 항목 목록이 업데이트되지 않습니다.이것은 Vue.js의 반응성 모델 때문이라고 생각합니다.그러나 전체 어레이를 어떻게 업데이트해야 할지 잘 모르겠습니다.또한, 이 기능을 사용할 필요가 있는지 잘 모르겠습니다.Vue.set내 스토어 변환, 스토어 액션 또는 Vue 인스턴스 메서드 자체.좀 헷갈리네요.

컴포넌트:

<template>
    <div>
        <h1>Items ({{ items.length }})</h1>
        <table>
            <tbody>
                <tr v-for="item in items" :key="item.id">
                    <td>{{ item.id }}</td>
                </tr>
            </tbody>
        </table>
    </div>
</template>

<script>
    import { mapState } from 'vuex';

    export default {
        computed: mapState({
            items: state => state.items
        })
    };
</script>

Vue.js 앱에서 Vuex에 중앙에서 저장된 어레이 전체를 업데이트하려면 어떻게 해야 합니까?

vue를 사용하다set기능.이렇게 하면 Vue의 반응성이 시작되고 필요한 개체가 업데이트됩니다.

import Vuex from 'vuex';
const store = new Vuex.Store({
    state: {
        items: []
    },

    mutations: {
        MUTATE_ITEMS: (state, items) => {
            Vue.set(state, 'items', items);
            // or, better yet create a copy of the array
            Vue.set(state, 'items', [...items]);
        }
    },

    actions: {
        loadItems: (context, items) => {
            context.commit('MUTATE_ITEMS', items);
        }
    }
  })
;

어레이나 오브젝트를 취급할 때는 보통 분산 연산자를 사용하여 하는 것과 같은 변경을 방지하는 것이 좋습니다.{...myObject}또는[..myArray]이렇게 하면 다른 소스에서 오브젝트를 변경하여 소스를 변경하는 것을 방지할 수 있으므로 getters에서도 구현하는 것이 좋습니다.


업데이트:

다음은 작업 예시를 제시하겠습니다.https://codesandbox.io/s/54on2mpkn (http://https://codesandbox.io/s/54on2mpkn (http://filecomponents를 1개 사용할 수 있습니다)

내가 깨달은 것은, 당신은 데이터를 얻는 데 도움이 되는 게 아무것도 없다는 것이다.가 없다는 것입니다.계산된 값을 직접 사용하거나 mapGetters를 사용하여 호출할 수 있지만 필수 사항은 아닙니다.다음은 데이터를 얻을 수 있는 세 가지 방법입니다.

<script>
import { mapGetters } from "vuex";
import Item from "./Item";

export default {
  name: "ItemList",
  components: {
    Item
  },
  computed: {
    ...mapGetters(["items"]), // <-- using mapGetters
    itemsGet() {    // <-- using getter, but not mapGetters
      return this.$store.getters.items;
    },
    itemsDirect() {  // <--no getter, just store listener
      return this.$store.state.items;
    }
  }
};
</script>

기능적인 관점에서 어떤 것을 선택했는지는 중요하지 않지만, getter를 사용하면 유지보수가 용이한 코드를 만들 수 있습니다.

다음과 같은 작업을 디스패치해야 합니다.

// dispatch with a payload
this.$store.dispatch('loadItems', {items})

// dispatch with an object
this.$store.dispatch({type: 'loadItems',items})

2021년에 이 답변에 도달하여 Vuex 4, Vue 3, Typescript, setup() 함수(Composition API라고도 함)를 사용하고 있다면 다음과 같은 방법으로 유사한 문제를 해결할 수 있습니다.

처음에는 비동기 작업을 통해 vuex 상태의 어레이를 변환했지만 UI 변경 사항이 표시되지 않았습니다.자, 여기 가식이 있습니다.

나는 이런 vuex 상태를 가지고 있다.

interface State {
  areas: Area[]
}

이와 같은 성분

export default {
   name: "Area",
   setup() {
      const store = UseStore();
      store.dispatch('fetchAreas');
      const areas = store.state.areas;
      return {
        store,
        areas,
      }
   }
}

그 액션을 위한 디스패치 기능은 다음과 같습니다.

async ['fetchAreas](context: ContextType<State>): Promise<void> {
   const areas = await getTheStuff();
   context.commit('setAreas', areas);
} 

그것은 가식이다.

내 문제는 'setAreas'의 변환 수신기에 있었다.

원래는 이렇게 생겼는데

['setAreas'](state: State, value: Area[]) {
  state.areas = value;
}

UI 업데이트를 트리거하지 못했습니다.이걸로 바꿨어요

['setAreas'](state: State, value: Area[]) {
   state.areas.splice(0, state.areas.length);
   value.forEach(v => state.areas.push(v));
}

UI 업데이트를 트리거했습니다. 왜요?

원래 어레이 전체를 오버라이드함으로써 반응성을 통한 vuex 변경 검출이 원래 어레이에 대한 참조를 잃었기 때문에 vuex가 새로운 어레이를 재등록하여 무효로 하는 동안 변경은 없었다고 생각합니다.

두 번째 방법에서는 어레이 방식을 사용하여 원래 어레이 참조를 그대로 유지하되 요소를 완전히 업데이트합니다.효율적이지는 않지만, 효과가 있고, 가끔은 그것만 바랄 수 있습니다.

그런 문제가 있어서 다음과 같이 해결했습니다. // 컴포넌트에서

계산: {

 data: {
     get() {
         this.$store.commit('updateData', this.$store.state.data)
         return this.$store.state.data;
     },
 }

} // 스토어 내

 mutations: {
      updateData(state,item){
          store.state.data = item;
      }
  }

네, 정말 놀랍습니다.

위의 솔루션 중 거의 아무 것도 기능하지 않았습니다(Vue2/Vuex3). 다만, 이하의 돌연변이는 필요에 따라서 동작합니다.어레이가 교환되어 반응성이 유지됩니다.

는 왜 헷갈렸다.Vue.set상태가 갱신되지만 뷰 갱신은 트리거되지 않습니다.

그 대신 아래는 업데이트를 트리거하는 액션에 대한 문서를 따르고 있었습니다.

https://vuejs.org/v2/guide/list.html#Mutation-Methods

SWAP_DATASET(state, dataset) {
    if (state.currentDataSets.length > 0) {
      state.currentDataSets.shift()
      state.currentDataSets.push(dataset)
    } else {
      state.currentDataSets.push(dataset)
    }
  },

언급URL : https://stackoverflow.com/questions/50767191/vuex-update-an-entire-array

반응형