IT이야기

Vue 필터 및 "변환 핸들러 외부의 vuex 저장소 상태 변환 안 함"

cyworld 2022. 6. 4. 08:14
반응형

Vue 필터 및 "변환 핸들러 외부의 vuex 저장소 상태 변환 안 함"

아직 Vue를 배우고 있는데 왜 이 오류가 발생하는지 이해할 수 없습니다.

오류: [vuex] 변환 핸들러 외부의 vuex 저장소 상태를 변환하지 않습니다.

코드는 다음과 같습니다.

const DATE_FORMAT = "DD-MM-YYYY";

Vue.filter("formatDate", function(value, dateFormat) {
  dateFormat = dateFormat ? dateFormat : DATE_FORMAT;
  if (value) {
    return moment(String(value)).format(dateFormat);
  }
});

Vue.component('list-component', {
  props: ['projects'],
  template: 
`
<div>
  <ul v-for="project in projects" :key="project.id">
    <li v-for="(value, key) in project" :key="key">
      {{ key }}: {{ value }}
    </li>
    <hr />
  </ul>
</div>
`
});

const store = new Vuex.Store({
  state: {
    projects: [{
      id: 1,
      name: "super project",
      startDate: "2014-09-01T08:18:28+02:00"
    }, {
      id: 2,
      name: "extra project",
      startDate: "2017-12-20T07:28:23.133+01:00"
    }, {
      id: 3,
      name: "small project",
      startDate: "2017-12-20T07:28:23.133+01:00"
    }]
  },
  getters: {
    allProjects: state => state.projects
  },
  strict: true
});

new Vue({
  el: '#app',
  computed: {
    formattedProjects() {
      var project = store.getters.allProjects;
      project.forEach(project => {
        project.startDate = this.$options.filters.formatDate(project.startDate);
      });
      return project;
    }
  }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.20.1/moment.js"></script>
<script src="https://unpkg.com/vuex@3.0.1/dist/vuex.js"></script>
<script src="https://unpkg.com/vue@2.5.13/dist/vue.js"></script>
<div id="app">
  <list-component :projects="formattedProjects"></list-component>
</div>

https://jsfiddle.net/9sn78n1h/2/

속성 이름이 다를 수 있으므로 구성 요소에서 필터를 사용할 수 없습니다.위의 예에서는startDate그러나 다른 데이터에서는addDate,endDate기타. vuex 스토어에서 필요한 것은startDate변형시키고 싶지 않아요Vuex에 다른 getter를 쓰는 게allProjectsWithFormatedDate좋은 방법이긴 하지만 그래도 변종점에 대해 큰소리를 지르고 있습니다.

그래서 로컬 변수를 만듭니다.project내가 계산한 방법으로는formattedProjects()값을 변경했는데 왜 이런 오류가 발생했는지 모르겠어요.

이 문제를 이해하고 해결할 수 있는 올바른 방법을 보여 줄 수 있는 사람이 있나요?

내가 할 수 있다는 걸 알아strict에의 모드.false이 에러를 뮤트 하는 것(그리고 실가동하고 있는 것)을 위해서입니다만, 이 문제를 해결할 수 있는 더 좋은 방법이 있다고 생각합니다.

문제는 에러 메시지에 나타나 있다.Vuex에는 단방향 플로우가 있습니다.이것에 주의해 주세요.상태에 대한 모든 변경은 돌연변이 섹션에서만 수행해야 합니다.그래서 실수로 아래 라인에 있는 오브젝트를 변환하고 있습니다.

project.startDate = this.$options.filters.formatDate(project.startDate);

스토어 항목의 startDate 속성을 추가/업데이트(변환)합니다.project이것이 문제의 근본 원인입니다.Vuex가 더 나은 방법을 가지고 있을 거예요.계산된 속성 자체에서 처리하려면 다음과 같이 할 수 있습니다.

formattedProjects() {
  var clonedProject = []
  var project = store.getters.allProjects;
  project.forEach(project => {
    clonedProject.push({
      ...project,
      startData: this.$options.filters.formatDate(project.startDate)
    })
  });
  return clonedProject;
}

여기 바이올린 링크가 있습니다.

아주 단순하게 당신이 직접 상태를 수정하고 있기 때문에dispatch또는mutations.

상세한 것에 대하여는, 이 페이지를 참조해 주세요.

위의 예에서는 다음과 같은 항목을 추가할 수 있습니다.

mutations: {
  updateProject (state, obj) {
    // Use state, get the project then set startDate.
    // You can use obj.projectId and obj.startDate
  }
}

다음으로 루프를 변경하려면 다음과 같이 하십시오.

this.$store.commit('updateProject', {
  projectId: project.id, 
  startDate: this.$options.filters.formatDate(project.startDate)
})

Vue 인스턴스를 수행하는 를 추가하면 경고 없이 상태를 업데이트할 수 있습니다.

상태 크기와 앱의 복잡도에 따라 모듈 사용을 고려할 수 있습니다.

코멘트에 따라 스토어를 업데이트하지 않을 경우 데이터를 새 개체로 반환하십시오.

formattedProjects() {
  var project = store.getters.allProjects;
  var clone = []
  project.forEach(project => {
    clone.push({
      ...project,
      startData: this.$options.filters.formatDate(project.startDate)
    })
  });
  return clone;
}

이렇게 하면 새 개체가 반환되고 저장소 값이 변환되지 않습니다.데이터를 반환하는 더 짧은 방법이 있을 수 있지만.map테스트했을 때 문제가 발생했지만, 당신은 알 수 있을 것입니다.

주의: 컴포넌트 상태를 루프하여 컴포넌트 HTML 내에서 필터링하는 것도 생각할 수 있습니다.계산된 프로펠러를 사용하여 필터링할 필요가 있는 이유는 잘 모르겠습니다.

업데이트된 예:

const DATE_FORMAT = "DD-MM-YYYY";

Vue.filter("formatDate", function(value, dateFormat) {
  dateFormat = dateFormat ? dateFormat : DATE_FORMAT;
  if (value) {
    return moment(String(value)).format(dateFormat);
  }
});

Vue.component('list-component', {
  props: ['projects'],
  template: 
`
<div>
  <ul v-for="project in projects" :key="project.id">
    <li v-for="(value, key) in project" :key="key">
      {{ key }}: {{ value }}
    </li>
    <hr />
  </ul>
</div>
`
});

const store = new Vuex.Store({
  state: {
    projects: [{
      id: 1,
      name: "super project",
      startDate: "2014-09-01T08:18:28+02:00"
    }, {
      id: 2,
      name: "extra project",
      startDate: "2017-12-20T07:28:23.133+01:00"
    }, {
      id: 3,
      name: "small project",
      startDate: "2017-12-20T07:28:23.133+01:00"
    }]
  },
  getters: {
    allProjects: state => state.projects
  },
  strict: true
});

new Vue({
  el: '#app',
  computed: {
    formattedProjects() {
      var project = store.getters.allProjects;
      var clone = []
      project.forEach(project => {
        clone.push({
          ...project,
          startData: this.$options.filters.formatDate(project.startDate)
        })
      });
      return clone;
    }
  }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.20.1/moment.js"></script>
<script src="https://unpkg.com/vuex@3.0.1/dist/vuex.js"></script>
<script src="https://unpkg.com/vue@2.5.13/dist/vue.js"></script>
<div id="app">
  <list-component :projects="formattedProjects"></list-component>
</div>

언급URL : https://stackoverflow.com/questions/47992120/vue-filter-and-the-do-not-mutate-vuex-store-state-outside-mutation-handlers

반응형