programing

Vuex에서 계산된 속성을 사용하여 돌연변이가 등록되지 않음

closeapi 2023. 6. 25. 20:06
반응형

Vuex에서 계산된 속성을 사용하여 돌연변이가 등록되지 않음

저는 많은 양식 구성요소를 사용하여 입력된 정보를 기반으로 뷰를 실시간으로 업데이트하는 시스템을 보유하고 있습니다.앱을 처음 구축했을 때는 주로 v-model, 로컬 구성 요소 데이터 및 vue save 상태를 사용하여 데이터를 로컬 스토리지에 보관하여 페이지를 다시 로드할 때 지속되도록 했습니다.

그러나 프로그램이 확장됨에 따라 vuex로 이동했을 때, 이것은 그리 간단하지 않았기 때문에 50개 이상의 입력에 대해 변경 함수에 쓸 필요가 없도록 게터와 세터를 사용하여 계산된 속성을 가진 v-model을 사용하기로 결정했습니다.또한 v-model을 사용하여 다음과 같이 개체에 대한 하나의 계산 변수를 생성하고 해당 개체의 속성을 업데이트할 수 있습니다.

  <div v-for="prof in info.profs">
  <textarea v-model="prof.name" class="code-input uk-input" rows="1" cols="20"></textarea>
  <textarea v-model="prof.email" class="code-input uk-input" rows="1" cols="25"></textarea>
  <textarea v-model="prof.office" class="code-input uk-input" rows="1" cols="50"></textarea> <br>
  </div>

info: {
  get () {
    return this.$store.getters.getInfo
  },
  set (payload) {
    this.$store.commit('updateInfo', payload)
  }
},

이는 스토어가 개별적으로 계산된 변수를 생성할 필요 없이 각 속성에 대한 데이터를 업데이트하는 방식으로 완벽하게 작동합니다.그러나 어떤 이유에서인지 vuechrome 개발 도구에 커밋된 변환 "updateInfo"로 표시되지 않으며 vuex-persisted 상태 또는 vuex-persist와 같은 vuex용 로컬 스토리지 플러그인을 사용하면 정상적으로 구성된 다른 변환을 커밋할 때까지 로컬 스토리지 데이터가 변경되지 않습니다.현재 해결 방법은 구성 요소에 속성의 로컬 복사본을 생성한 다음 해당 속성의 변경 사항을 확인하고 저장소에 커밋하는 것입니다. 그러면 구성 요소 수준의 로컬 스토리지 믹스를 다시 사용할 수 있습니다.하지만 저는 이 애플리케이션에서 꽤 장황할 것이기 때문에 정보의 각 속성에 대한 변경 함수나 계산 변수를 작성하지 않는 더 나은 방법이 필요하다고 생각합니다.

data () {
return {
  info: this.$store.getters.getInfo
 }
},
watch: {
info: function(payload){
  this.$store.commit('updateInfo', payload)
 }
},

사실, 두 가지 방법 모두 틀렸습니다.더하다strict: true두 경우 모두 오류가 발생하는 것을 볼 수 있습니다.

두 가지 대안 모두에서profname,email그리고.office특성은 직접 수정됩니다(이는 모든 변화가 돌연변이를 통해 발생해야 한다는 Vuex 원칙에 위배됨).

마찬가지로, 수정하지 않기 때문에 계산된 세터(첫 번째 사례)나 감시자(두 번째 사례)가 트리거되지 않습니다.item깊이 내포된 특성(예:name).


믹스인을 계속 사용할 수 있는 가장 간단한 해결책은 도랑을 제거하는 것입니다.v-model다음을 사용합니다.:value그리고.@input예:

<textarea :value="prof.name" @input="updateProf(prof, 'name', $event)" >

를 한다는 점에 하세요.updateProf변환(아래 참조)을 수행하고 혼합에 들어가는 방법입니다.

이런 식으로 모든 수정은 돌연변이 내에서 이루어집니다.마지막 메모 하나, 만약 당신이 사용을 정당화한다면.:value그리고.@input자세한 내용은 사용자 지정 지시문을 생성하여 처리할 수 있습니다.

아래의 제이에스아이들 링크 또는 데모(동일 코드).

const store = new Vuex.Store({
  strict: true,
  state: {
    info: {
        profs: [
        {name: "Alice", email: "alice@example.com", office: "NY"},
        {name: "Bob", email: "bob@example.com", office: "CA"}
      ]
    }
  },
  mutations: {
    updateProf(state, {prof, prop, value}) {
        prof[prop] = value;
    }
  },
  getters: {
    getInfo: state => {
      return state.info
    }
  }
});
const mixin = {
  computed: {
    info() {
      return this.$store.getters.getInfo
    }
  },
  methods: {
    updateProf(prof, prop, e) {
        this.$store.commit('updateProf', {prof, prop, value: e.target.value})
    }
    }
}
new Vue({
  store,
  mixins: [mixin],
  el: '#app'
})
<script src="https://unpkg.com/vue"></script>
<script src="https://unpkg.com/vuex"></script>

<div id="app">
  {{ info }}
  <div v-for="prof in info.profs">
    <hr>
    name: <textarea :value="prof.name" @input="updateProf(prof, 'name', $event)" class="code-input uk-input" rows="1" cols="20"></textarea> <br>
    email: <textarea :value="prof.email" @input="updateProf(prof, 'email', $event)" class="code-input uk-input" rows="1" cols="25"></textarea> <br>
    office: <textarea :value="prof.office" @input="updateProf(prof, 'office', $event)" class="code-input uk-input" rows="1" cols="50"></textarea>
  </div>
</div>


가지고있는v-model

가능하다고 , 이 계속해서 할 수 한 v-model이 대안의 핵심은 딥 클로닝과 딥 동등한 기능을 수행하는 기능입니다.는 두 간단한한 구현을 했습니다. YMMV: YMMV: YMMV입니다.

제이에스아이들 링크.아래 데모(fiddle과 동일한 코드):

const store = new Vuex.Store({
  strict: true,
  state: {
    info: {
        profs: [
        {name: "Alice", email: "alice@example.com", office: "NY"},
        {name: "Bob", email: "bob@example.com", office: "CA"}
      ]
    }
  },
  mutations: {
    updateInfo(state, data) {
        state.info = data
    }
  },
  getters: {
    getInfo: state => {
      return state.info
    }
  }
});

// these two functions are key here
// consider using other implementations if you have more complicated property types, like Dates
function deepClone(o) { return JSON.parse(JSON.stringify(o)); }
function deepEquals(o1, o2) { return JSON.stringify(o1) === JSON.stringify(o2) }

const mixin = {
    data() {
    return {
      info: deepClone(this.$store.getters.getInfo),
    }
  },
  computed: {
    getInfo() {
      return this.$store.getters.getInfo;
    }
  },
  watch: {
    getInfo: {
        deep: true,
        handler(newInfo) {
        if (!deepEquals(newInfo, this.info)) { // condition to prevent infinite loops
                this.info = deepClone(newInfo);
        }
        }
    },
    info: {
        deep: true,
        handler(newInfo) {
            this.$store.commit('updateInfo', deepClone(newInfo))
        }
    }
    }
}
new Vue({
  store,
  mixins: [mixin],
  el: '#app'
})
<script src="https://unpkg.com/vue"></script>
<script src="https://unpkg.com/vuex"></script>

<div id="app">
  {{ info }}
  <div v-for="prof in info.profs">
    <hr>
    name: <textarea v-model="prof.name"  class="code-input uk-input" rows="1" cols="20"></textarea> <br>
    email: <textarea v-model="prof.email"  class="code-input uk-input" rows="1" cols="25"></textarea> <br>
    office: <textarea v-model="prof.office"  class="code-input uk-input" rows="1" cols="50"></textarea>
  </div>
</div>

언급URL : https://stackoverflow.com/questions/49565655/mutations-not-registering-using-computed-properties-in-vuex

반응형