programing

Vuex, 어레이에 있는 개체의 속성을 업데이트하면 여러 변환 방법이 발생합니다.

firstcheck 2022. 7. 29. 22:45
반응형

Vuex, 어레이에 있는 개체의 속성을 업데이트하면 여러 변환 방법이 발생합니다.

이런 가게가 있다고 칩시다.또한 컴포넌트를 선택하여car소품으로 전달되는 목록에서 다른 컴포넌트로 전송되며 여기서 다양한 속성을 편집할 수 있습니다.car물건.

만약 자동차 물체가 더 많은 성질을 가지고 있다면brand,weight기타. 다음 중 하나를 수행해야 합니다.

  • 모든 속성에 대해 새로운 돌연변이를 생성한다. 이것은 엄청난 양의 돌연변이를 발생시키는 단점을 가지고 있으며, 내 생각에는 스토어 파일을 매우 읽을 수 없게 만들 이다.

  • 개체, 필드 및 값을 사용하는 범용 변환을 생성하여 할당합니다.이것은 하나의 일반 돌연변이만 발생한다는 장점이 있습니다.하지만 중첩된 개체를 처리할 수 없다는 단점이 있습니다.

  • 컴포넌트에 새 개체를 생성하여 필드별 상태의 개체를 바꿉니다.이것은 깨끗한 솔루션처럼 느껴지지만, 객체를 복사하여 가변성을 제거해야 하며, 이는 덜 깨끗한 느낌입니다.그리고 많이 쓰면 앱 속도도 늦춰야 할 것 같아요.

제 프로젝트에서는 혼돈스럽게 느껴지는 여러 가지 옵션이 혼재되어 있습니다.

그럼, 이것보다 더 좋은 패턴은 없을까?그렇지 않은 경우 베스트 프랙티스로 간주됩니다.나는 이것에 대한 답을 오랫동안 찾아봤지만 좋은 설명을 찾지 못했다.

state: {
    cars: [
        {id: 1, color: "blue"},
        {id: 2, color: "blue"},
        {id: 3, color: "blue"},
    ]
},
mutations: {
    setColor(state, {car, color}){
        car.color = color;
    }
},
getters: {
    allCars(state){
        return state.cars;
    }
},

deepMerge 함수를 사용합니다.

export const mutations = {
  setCarProperties(state, car) {
    const index = state.cars.findIndex((item) => item.id === car.id);

    Vue.set(state.cars, index, deepMerge(state.cars[index], car));
  }
};

따라서 속성을 변경하고 추가할 수 있습니다(네스트된 경우에도 마찬가지).

updateCarType() {
  const car = {
    id: 2,
    type: {
      engine: "electric",
    },
  };
  this.$store.commit("setCarProperties", car);
},

Vue를 사용하고 있습니다.돌연변이를 일으키다왜 평소처럼 상태를 바꾸지 않는지 궁금할 수도 있습니다.

state.cars[index] = deepMerge(state.cars[index], car));

하지만 그건 반응하지 않을 거야, Vue.set가 필요합니다.https://vuejs.org/v2/api/ #Vue-set

데모 확인: https://codesandbox.io/s/questions-69864025-vuex-update-property-of-object-in-array-causes-many-mutation-methods-sq09z?file=/pages/index.vue

저는 이 주제에 대한 제 의견을 공유하겠습니다.솔직히 저는 베스트 프랙티스를 모르며, 같은 접근방식의 변형도 몇 가지 있습니다.

기본적으로는 말씀하신 두 번째 원칙만 적용되며 전체 업데이트 사이클 동안 반응성이 유지됩니다.

스토어에서 일반 돌연변이를 만듭니다.

mutations: {
    setItem(state, item) {
      let idx = state.items.findIndex((i) => i.id === item.id);
      Vue.set(state.items, idx, item);
    }
}

구성 요소에서 상태 항목을 계산된 속성에 매핑하고 편집된 항목에 대해 다른 항목을 만듭니다.

computed: {
    ...mapGetters({ allItems: "allItems" }),
    localItem: {
      get() {
        return this.allItems[0];
      },
      set(val) {
        this.setItem(val);
      },
    },
},
methods: {
    ...mapMutations(["setItem"])
}

그리고 까다로운 부분은 로컬 항목을 업데이트하십시오.

methods: {
    ...mapMutations(["setItem"]),
    changeItem() {
      this.$set(this, "localItem", { ...this.localItem, color: "red" });
    },
}

개체 속성을 직접 업데이트하지 않고 개체 전체를 할당하여 계산된 세터가 트리거되고 변경 내용이 경고 없이 저장되도록 합니다.

코드앤드박스

변경된 속성과 함께 전체 자동차 객체를 작업으로 전달할 수 있습니다.

async carUpdate({ commit }, car) {
  await // some axios or fetch call...
  commit('updateCar', car);
},

다음으로 다음과 같은 돌연변이를 커밋합니다.

updateCar(state, car) {
  state.cars = [
    ...state.cars.map((item) =>
      item.id !== car.id
        ? item
        : {
            ...item,
            ...car,
          }
    ),
  ];
},

언급URL : https://stackoverflow.com/questions/69864025/vuex-update-property-of-object-in-array-causes-many-mutation-methods

반응형