Programing

Vue 및 Vuex: 상태를 변경할 때 계산된 속성이 호출되지 않음

c10106 2022. 4. 20. 21:39
반응형

Vue 및 Vuex: 상태를 변경할 때 계산된 속성이 호출되지 않음

나는 Vue와 Vuex가 처음이라 조금만 참아줘.

계산된 기능을 만들고 싶다.versions()내가 바뀔 때 부름을 받다.state.template, 그러나 나는 그렇게 하지 못하고 있다.좀 더 구체적으로, 언제state.template.versions변화들

이 구성 요소는 다음에 다시 렌더링할 구성 요소의 일부임state.template.versions변화들계산된 속성을 볼 수도 있다.versions()내가 부르고 싶은 것은:

    <el-dropdown-menu class="el-dropdown-menu--wide"
      slot="dropdown">
      <div v-for="version in versions"
        :key="version.id">
           ...
      </div>
    </el-dropdown-menu>
    ...
    computed: {
      ...mapState('documents', ['template', 'activeVersion']),
      ...mapGetters('documents', ['documentVersions', 'documentVersionById', 'documentFirstVersion']),
    versions () {
       return this.documentVersions.map(function (version) {
          const v = {
            id: version.id,
            name: 'Draft Version',
            effectiveDate: '',
            status: 'Draft version',
          }
          return v
        })
    },

바로 이겁니다.getter:

  documentVersions (state) {
    return state.template ? state.template.versions : []
  },

바로 이겁니다.action:

  createProductionVersion (context, data) {
    return new Promise((resolve, reject) => {
      documentsService.createProductionVersion(data).then(result => {
        context.state.template.versions.push(data)  // <-- Here I'm changing state.template. I would expect versions() to be called
        context.commit('template', context.state.template)

        resolve(result)
      })

바로 이겁니다.mutation:

  template (state, template) {
    state.template = template
  },

나는 Vue가 배열로 만들어진 체인을 감지하지 못하는 경우가 있다고 읽었지만,.push()발각된 것 같다.출처: https://vuejs.org/v2/guide/list.html#Caveats

업데이트할 때 계산된 속성이 호출되지 않는 이유에 대한 아이디어context.state.template.versions?

그 문제는 아마도 에서 비롯되었을 것이다.state.template = template.반응도 문제라는 것을 정확하게 짐작하셨는데, 어레이 반응도 문제가 아니라template이의를 제기하다

Vue는 속성 추가 또는 삭제를 감지할 수 없음.여기에는 자산에 대한 복잡한 객체에 영향을 주는 것이 포함된다.그것을 위해서는, 당신은 사용할 필요가 있다.Vue.set.

그래서 당신의 돌연변이는 다음과 같아야 한다.

template (state, template) {
  Vue.set(state, "template", template)
},

https://vuejs.org/v2/guide/reactivity.html#Change-Detection-Caveats

이 방법이 잘못되었기 때문에 당신의 기능이 호출되지 않을 것이다.

context.state.template.versions.push(data) 
context.commit('template', context.state.template)

context.state물체는 단지 당신의 현재 상태를 가리키기만 할 뿐이다.

내가 제안하는 해결책은 다음과 같다.

  1. 먼저 스토어 상태를 올바르게 선언해야 함

    state: {
       template: {
          versions: []
       }
    }
    
  2. 불필요한 조건 없이 이렇게 보이도록 getter를 업데이트해야 한다.

    documentVersions: state => return state.template.versions,

  3. 새로운 돌연변이를 추가하다

     ADD_VERSION: (state, version) => {
       state.template = {
         ...state.template,
         versions: [...state.template.versions, version]
        };
      }
    
  4. 이제 다음과 같은 조치를 취하십시오.

       createProductionVersion({commit}, data) {
           return new Promise((resolve, reject) => {
             documentsService.createProductionVersion(data).then(result => {
               commit('ADD_VERSION', data);
               resolve(result);
             });
           });
         }
    
  5. 구성 요소에서 계산된 속성을 함수에 포함된 개체로 변경하십시오.get그리고set방법(methods)set선택사항)

    versions: {
      get() {
        return this.documentVersions.map(function (version) {
          const v = {
            id: version.id,
            name: 'Draft Version',
            effectiveDate: '',
            status: 'Draft version',
          }
          return v
        })
      }
    },
    

내 생각에 이 오류는 네가 매장 상태를 정확하게 선언하지 않아서 발생한 것 같아.확실히 해두시오.versions당신의 소유물.template이의를 제기하다

state: {
  template: {
    versions: []
  }
}

이렇게 하면, 어떤 변화도versionsvue에 의해 속성이 탐지될 것이다.

참조URL: https://stackoverflow.com/questions/63299620/vue-and-vuex-computed-property-isnt-called-when-changing-state

반응형