programing

템플릿이 계산된 속성에 바인딩되어 업데이트되지 않는 이유는 무엇입니까?

firstcheck 2022. 8. 2. 23:11
반응형

템플릿이 계산된 속성에 바인딩되어 업데이트되지 않는 이유는 무엇입니까?

on on on on that that 에 의존하는 에 템플릿HTML이 되어 있는 .HTML html html html html html html html html html html html html html 。computedVuex terter getter 。알 수 속성의 을 템템 a a, a는 a a a a a a a a a a a로 .<p>를 달다{{ getNumSets }}.

하면, 「」로 갱신합니다.UPDATE_EXERCISE_SETS devtools에서 할 수 만, 은 Vue 되지 않습니다.<p> {{ getNumSets }} </p>★★★★★★ 。

템플릿 HTML:

<template>
...
<v-text-field
   v-model="getNumSets"
   placeholder="S"
   type="number"
   outlined
   dense
></v-text-field>
<p>{{ getNumSets }}</p>
...
</template>

컴포넌트 로직:

<script>
...
computed: {
   getNumSets: {
      get() {
         var numSets = this.$store.getters['designer/getNumSetsForExercise']({id: this.id, parent: this.parent})
         return numSets
      },
      set(value) {  // This correctly updates the state as seen in the Vue DevTools
        this.$store.commit('designer/UPDATE_EXERCISE_SETS', {
                    id: this.exerciseId,
                    parentName: this.parent,
                    numSets: parseInt(value),
                    date: this.date
                })
      }

}
...
</script>

Vuex 스토어 논리:

...
state: {
  designerBucket: []
},
getters: {
  getNumSetsForExercise: (state) => (payload) => {
    var numSets = 0
    for (var i = 0; i < state.designerBucket.length; i++) {
      if (state.designerBucket[i].id == payload.id) {
        numSets = state.designerBucket[i].numSets
      }
    }
    return numSets
  }
},
mutations: {
  UPDATE_EXERCISE_SETS(state, payload) {
    state.designerBucket.forEach(exercise => {
       if (exercise.id == payload.id) {
          exercise.numSets = payload.numSets
       }
    })
   }
}

어떤 통찰이라도 감사합니다!

저도 PS를해 본 적이 있습니다.for (var i=0...), 「」, 「」를 사용합니다.Vue.set()값을 설정합니다.이렇게 하면 저장소의 값도 업데이트되었지만 계산된 속성이 여전히 템플릿을 업데이트하지 않습니다.

이것은 다소 장황한 답변으로 바뀌었지만, 조금만 참아주세요.

Vuex getter에서 함수를 반환하기 때문에 Vue에서 반환된 값이 변경되더라도 함수는 변경되지 않으므로 Vue는 상태 변경 시 계산된 속성을 업데이트하지 않습니다.이것은 계산된 속성의 캐싱 메커니즘에 영향을 줍니다.


Arrow 함수 게터의 반응성


다음과 같은 게터를 작성할 때 유의해야 할 사항 중 하나는 화살표 함수를 반환하는 것입니다.

getNumSetsForExercise: (state) => (payload) => {
    var numSets = 0
    for (var i = 0; i < state.designerBucket.length; i++) {
        if (state.designerBucket[i].id == payload.id) {
        numSets = state.designerBucket[i].numSets
        }
    }
    return numSets
}

...게터로부터 더 이상 실제 상태 데이터를 반환하지 않는다는 것입니다.

컴포넌트의 로컬 데이터에 의존한 상태를 끌어내기 위해 이 기능을 사용하면 매우 편리합니다.변경을 검출하기 위해 Vue가 필요한 것은 아니지만 현재 상태에 액세스하기 위한 기능만 있으면 됩니다.

그러나 실제로는 업데이트되지 않은 상태에서 상태를 업데이트해야 한다고 생각하는 함정으로 이어질 수도 있습니다.이것은 이 getter를 예시와 같이 계산 속성에 사용하려고 할 때에만 매우 중요합니다.그 이유는 다음과 같습니다.computed속성은 종속성을 추적하고 데이터를 캐시합니다.

계산 캐싱 및 의존관계 검출


부에computed을 사용하다결과를 캐시하고 캐시를 비활성화할 시기를 알기 위해 의존하는 반응 값을 등록 및 추적합니다.

Vue는 계산된 속성의 값을 계산하는 즉시 이 값을 내부에 저장하므로 종속성을 변경하지 않고 속성을 다시 호출하면 속성이 캐시된 값을 다시 계산하는 대신 반환할 수 있습니다.

여기서 중요한 것은 의존관계 검출입니다.게터에는 Vue가 검출하는3가지 의존관계가 있습니다.

get() {
    var numSets = this.$store.getters['designer/getNumSetsForExercise']({id: this.id, parent: this.parent})
    return numSets
},
  1. 취득자:this.$store.getters['designer/getNumSetsForExercise']
  2. this.id
  3. this.parent

값들은 다음 경우 변경되지 않습니다.<v-text-field>셋터를 호출합니다.

즉, Vue는 종속성 변경을 감지하지 않고 다시 계산하는 대신 캐시된 데이터를 반환합니다.

수정 방법


일반적으로 이러한 의존성 문제에 직면하게 되면 더 많은 데이터를 상태로 이동하거나 어떤 방식으로 재구성함으로써 상태 설계가 개선될 수 있기 때문입니다.

이 경우, 꼭 필요한 경우가 아니라면 designerBucket정렬을 위한 배열이 되기 위해서는 세트가 저장되는 객체 대신 그것을 제안합니다.id이렇게 하면 루프를 제거함으로써 구현이 단순해지고 getter가 완전히 필요하지 않게 됩니다.

...
state: {
  designerBucket: {}
},
mutations: {
  UPDATE_EXERCISE_SETS(state, payload) {
    // Need to use $set since we're adding a new property to the object
    Vue.set(state.designerBucket, payload.id, payload.numSets);
  }
}

이제, getter를 호출하는 대신, 그냥 당기고designerBucket주(州)에서 접근하여this.id직접:

<script>
...
computed: {
    getNumSets: {
    get() {
        return this.$store.state.designerBucket[this.id];
    },
    set(value) {
        this.$store.commit('designer/UPDATE_EXERCISE_SETS', {
            id: this.exerciseId,
            parentName: this.parent,
            numSets: parseInt(value),
            date: this.date
        });
    }
}
...
</script>

이렇게 하면 Vue가 지금 변경 사항을 올바르게 감지하고 이전부터 오래된 캐시 문제를 방지할 수 있습니다.

편집: 먼저 mapGetters를 스크립트 태그 상단에 있는 'vuex'에서 가져옵니다.

import { mapGetters } from "vuex"

다음으로 계산 객체에서 mapGetters를 추가하고 다음과 같이 get() 메서드 내의 getter 메서드에 인수를 전달합니다.

computed: {
   ...mapGetters('designer',['getNumSetsForExercise']),
   getNumSets: {
      get() {
         var numSets = this.getNumSetsForExercise({id: this.id, parent: this.parent})
         return numSets
      },
      set(value) {  // This correctly updates the state as seen in the Vue DevTools
        this.$store.commit('designer/UPDATE_EXERCISE_SETS', {
                    id: this.exerciseId,
                    parentName: this.parent,
                    numSets: parseInt(value),
                    date: this.date
                })
      }

}

효과가 있는지 한번 봅시다.

언급URL : https://stackoverflow.com/questions/68167246/why-wont-my-template-update-with-it-being-bound-to-a-computed-property

반응형