programing

vuex - 권장되지 않는 경우에도 직접 상태를 변경할 수 있습니까?

prostudy 2022. 6. 5. 17:46
반응형

vuex - 권장되지 않는 경우에도 직접 상태를 변경할 수 있습니까?

문서에는 다음과 같이 기재되어 있습니다.

스토어 상태를 직접 변환할 수 없습니다.스토어 상태를 변경하는 유일한 방법은 돌연변이를 명시적으로 커밋하는 것입니다.

제 질문은 그게 좋은 관행인가요, 아니면 Vuex 주 내부가 그렇게 작동하는 건가요?즉, Vuex 상태는 Vue 데이터와 동일한 방식으로 반응합니까(JS 개체를 관찰 가능한 것으로 변환함) 아니면 다른 것입니까?

유사한 질문입니다. 돌연변이를 만드는 대신 동작의 상태를 직접 변경할 수 있습니까?이것이 나쁜 관행이고 규약을 따르는 것이 주는 추적성을 잃었다는 것을 알지만, 효과가 있을까요?

돌연변이를 일으키는 대신 동작의 상태를 직접 변경할 수 있습니까?이것이 나쁜 관행이고 규약을 따르는 것이 주는 추적성을 잃었다는 것을 알지만, 효과가 있을까요?

동작하지만 경고와 오류가 발생합니다.

vue.js:584 [Vue warn]: Error in callback for watcher "function () { return this._data.$$state }": "Error: [vuex] Do not mutate vuex store state outside mutation handlers."

   (found in <Component>)
   warn @ vue.js:584
   ...

vue.js:1719 Error: [vuex] Do not mutate vuex store state outside mutation handlers.
    at assert (VM260 vuex.js:103)

또 뭐가 망가질지 누가 알겠나?

직접 참조해 주세요(템플릿의 데이터 갱신에 주의해 주세요).

const store = new Vuex.Store({
strict: true,
  state: {
    people: []
  },
  mutations: {
    populate: function (state, data) {
      //Vue.set(state, 'people', data);
    }
  }
});
new Vue({
  store,
  el: '#app',
  mounted: function() {
    let self = this;
    this.$http.get('https://api.myjson.com/bins/g07qh').then(function (response) {
      // setting without commit
      Vue.set(self.$store.state, 'people', response.data); 
      //self.$store.commit('populate', response.data)
    }).catch(function (error) {
      console.dir(error);
    });
  },
  computed: {
    datadata: function() {
      return this.$store.state.people
    }
  },
})
<script src="https://unpkg.com/vue"></script>
<script src="https://unpkg.com/vuex"></script>
<script src="https://unpkg.com/vue-resource"></script>

<div id="app">
  Data: {{ datadata }}
</div>

Vue 데이터와 동일한 방식으로 반응하는 Vuex 상태(js 객체를 관찰 가능한 것으로 변환) 또는 다른 무엇일까?

네, 사실 Vue 자체가 스토어 오브젝트를 반응하게 만듭니다.Mutosues 공식 문서:

Vue의 반응성 규칙을 따르는 돌연변이

Vue에 의해 Vue 스토어 상태가 비활성화되므로 상태를 변환하면 상태를 감시하는 Vue 컴포넌트가 자동으로 업데이트됩니다.즉, 플레인 Vue를 사용할 때 Vuex 돌연변이가 동일한 반응성 경고를 받는다는 의미도 됩니다.

  1. 원하는 모든 필드를 미리 사용하여 스토어의 초기 상태를 초기화하십시오.

  2. 개체에 새 속성을 추가할 때 다음 중 하나를 수행해야 합니다.

    • Vue.set(obj, 'newProp', 123) 「」

    • 해당 개체를 새 개체로 바꿉니다.예를 들어 stage-3 객체 확산 구문을 사용하면 다음과 같이 쓸 수 있습니다.

      state.obj = { ...state.obj, newProp: 123 }
      

코드한 것을 덮어쓰거나 을 직접 않음)한Vue.set(obj, 'newProp', newValue)오브젝트는 반응하지 않습니다.


댓글의 질문(좋은 질문)을 폴로업합니다.

따라서 관찰 가능한 개체는 일반 Vue 데이터와 약간 다른 것 같습니다. 변경은 변환 핸들러에서만 허용됩니다.그래요?

그럴 수도 있지만, 난 그렇게 생각하지 않아.문서 및 증거(아래 참조)vm.$watch아래)와 정확히 같은 것을 가리키고 있습니다.data오브젝트, 적어도 반응/불안한 행동과 관련하여.

오브젝트는 다른 컨텍스트에서 변환된 것을 어떻게 알 수 있습니까?

좋은 질문입니다.바꿔 말하면:

전화하는 경우Vue.set(object, 'prop', data);Vue 내에서 예외 발생(위의 데모 참조), 호출하는 이유Vue.set(object, 'prop', data);그렇지 않다고 생각하시는 건가요?

은 의 코드 안에 있습니다.내부 함수를 통해 변환 코드를 실행합니다.

플래그를 설정하고 변환 코드를 실행하는 것(그리고 반환)이 전부입니다._committing로.false(예외 후)

그런 다음 Vuex 저장소는 상태 변수를 감시하고 플래그가 있는 동안 변수가 변경된 것을 감지하면(워처가 트리거함) 경고를 보냅니다.

(Bonus: vuex는 변수를 관찰하기 위해 -- Vue의 API 문서를 사용하고 있습니다.이것은, 상태의 오브젝트가 데이터 오브젝트와 같은 것을 암시합니다.Vue의 내부 오브젝트에 의존합니다).

이제 제 요점을 증명하기 위해 Vuex를 자신에게 설정하고 전화를 걸겠습니다.Vue.set()변이자 바깥에서요아래 그림과 같이 경고가 트리거되지 않습니다.터치.

const store = new Vuex.Store({
strict: true,
  state: {
    people: []
  },
  mutations: {
    populate: function (state, data) {
      //Vue.set(state, 'people', data);
    }
  }
});
new Vue({
  store,
  el: '#app',
  mounted: function() {
    let self = this;
    this.$http.get('https://api.myjson.com/bins/g07qh').then(function (response) {
      // trick the store to think we're using commit()
      self.$store._committing = true;
      // setting without commit
      Vue.set(self.$store.state, 'people', response.data); 
      // no warning! yay!
    }).catch(function (error) {
      console.dir(error);
    });
  },
  computed: {
    datadata: function() {
      return this.$store.state.people
    }
  },
})
<script src="https://unpkg.com/vue"></script>
<script src="https://unpkg.com/vuex"></script>
<script src="https://unpkg.com/vue-resource"></script>

<div id="app">
  Data: {{ datadata }}
</div>

간단하게 설명하겠습니다.

상태 개체가 이미 반응하므로 getter 및 돌연변이를 완전히 피할 수 있습니다.Vue의 모든 템플릿, 계산 템플릿, 감시 템플릿 등은 컴포넌트의 데이터를 사용하는 것과 동일하게 동작합니다.저장소의 상태는 공유 데이터 개체로 작동합니다.

단, 이렇게 하면 멤버의 명령어 설계 패턴과 캡슐화를 메서드로 회피할 수 있기 때문에 시간 이동 디버깅, 실행 취소/재실행 및 브레이크 포인트 설정을 구현할 수 없게 됩니다.

언급URL : https://stackoverflow.com/questions/49122648/vuex-is-it-possible-to-directly-change-state-even-if-not-recommended

반응형