source

Vuex - 변환 핸들러 외부의 vuex 저장소 상태 변환 안 함

factcode 2022. 8. 11. 21:54
반응형

Vuex - 변환 핸들러 외부의 vuex 저장소 상태 변환 안 함

다음 오류가 표시되는 이유:

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

그것은 무엇을 뜻하나요?

편집 입력 파일을 입력하려고 하면 발생합니다.

pages/todos/index.vue

<template>
  <ul>
    <li v-for="todo in todos">
      <input type="checkbox" :checked="todo.done" v-on:change="toggle(todo)">
      <span :class="{ done: todo.done }">{{ todo.text }}</span>
      <button class="destroy" v-on:click="remove(todo)">delete</button>

      <input class="edit" type="text" v-model="todo.text" v-todo-focus="todo == editedTodo" @blur="doneEdit(todo)" @keyup.enter="doneEdit(todo)" @keyup.esc="cancelEdit(todo)">

    </li>
    <li><input placeholder="What needs to be done?" autofocus v-model="todo" v-on:keyup.enter="add"></li>
  </ul>
</template>

<script>
import { mapMutations } from 'vuex'

export default {
  data () {
    return {
      todo: '',
      editedTodo: null
    }
  },
  head () {
    return {
      title: this.$route.params.slug || 'all',
      titleTemplate: 'Nuxt TodoMVC : %s todos'
    }
  },
  fetch ({ store }) {
    store.commit('todos/add', 'Hello World')
  },
  computed: {
    todos () {
      // console.log(this)
      return this.$store.state.todos.list
    }
  },
  methods: {
    add (e) {

      var value = this.todo && this.todo.trim()
      if (value) {
        this.$store.commit('todos/add', value)
        this.todo = ''
      }

    },
    toggle (todo) {
      this.$store.commit('todos/toggle', todo)
    },
    remove (todo) {
      this.$store.commit('todos/remove', todo)
    },

    doneEdit (todo) {
      this.editedTodo = null
      todo.text = todo.text.trim()
      if (!todo.text) {
        this.$store.commit('todos/remove', todo)
      }
    },
    cancelEdit (todo) {
      this.editedTodo = null
      todo.text = this.beforeEditCache
    },
  },
  directives: {
    'todo-focus' (el, binding) {
      if (binding.value) {
        el.focus()
      }
    }
  },
}
</script>

<style>
.done {
  text-decoration: line-through;
}
</style>

stores/todos.js

export const state = () => ({
  list: []
})

export const mutations = {
  add (state, text) {
    state.list.push({
      text: text,
      done: false
    })
  },
  remove (state, todo) {
    state.list.splice(state.list.indexOf(todo), 1)
  },
  toggle (state, todo) {
    todo.done = !todo.done
  }
}

이걸 어떻게 고칠지 생각나는 거 없어?

Vuex에 속한 상태에서 v-model을 사용하는 것은 조금 까다로울 수 있습니다.

사용하신 적이 있다v-modeltodo.text 삭제:

<input class="edit" type="text" v-model="todo.text" v-todo-focus="todo == editedTodo" @blur="doneEdit(todo)" @keyup.enter="doneEdit(todo)" @keyup.esc="cancelEdit(todo)">

:value를 읽다v-on:input ★★★★★★★★★★★★★★★★★」v-on:change 변환 합니다.

이 문제는 https://vuex.vuejs.org/en/forms.html 에서 처리됩니다.

안녕하세요. 같은 문제를 찾아서 다음 중 하나를 사용하여 내 개체를 복제하여 해결합니다.

{ ...obj} //spread syntax 
Object.assign({}, obj)
JSON.parse(JSON.stringify(obj))

당신의 코드에 대해서는 이 부품을 교체해야 할 것 같습니다.

computed: {
  todos () {
    // console.log(this)
    return this.$store.state.todos.list
  }
}

이와 함께.

computed: {
  todos () {
    // console.log(this)
    return {...this.$store.state.todos.list}
  }
}

이것이 최선의 방법인지는 모르겠지만, 같은 문제를 안고 있는 다른 사람들에게 도움이 되길 바랍니다.

lodash를 사용할 수 있다면 두통은 없습니다.

computed: {
  ...mapState({
    todo: (state) => _.cloneDeep(state.todo)
  })
}

혹시라도 누군가 이 문제로 인해 문제가 생길까 봐 매장 상태를 복제/복제하여 코드를 작동시켰습니다.

당신의 경우, 이런 걸 시도해 보세요...

computed: {
  todos () {
    return [ ...this.$store.state.todos.list ]
  }
}

기본적으로는 todos.list 배열의 클론을 만드는 분산 연산자입니다.이를 통해 상태 값을 직접 변경하는 것이 아니라, 스토어에 돌연변이를 저장할 수 있도록 커밋을 잊지 마십시오.

오류는 개체를 얕게 복제했기 때문에 발생할 수 있습니다.
예: 카피하려고 했지만 오브젝트는 원시형이 아닙니다.String ★★★★★★★★★★★★★★★★★」Number이치
여기서는 오래된 개체를 참조하면서 하나의 개체를 다른 개체로 복제했다고 생각합니다.큰놈을 변종시키니까 경고 하나 제대로 받았네

여기 Vue3 문서의 GIF가 있습니다(이 사례에서는 아직 유효합니다).
왼쪽은 오브젝트(머그)가 올바르게 복제되지 않은 것을 나타내고 있습니다.>> > > > > > > > > > > > > > > > > > >
이치노> > > > 값으로 전달되었습니다.되지 않는다.


은, 「」를 사용하는 입니다.lodashNuxt에서 효율적으로 로드하는 방법은 다음과 같습니다.

  • lodash-es (예:yarn add lodash-es최적화된 트리 셰이크 가능한 Lodash ES 모듈입니다.
  • 당신은 또한 그것을 변환해야 할 수도 있습니다.nuxt.config.js다음과 같이
build: {
  transpile: ['lodash-es'],
}
  • 로딩하다.vue이와 같은 컴포넌트
<script>
import { cloneDeep } from 'lodash-es'

...
const properlyClonedObject = cloneDeep(myDeeplyNestedObject)
...
</script>

몇 가지 요점:

  • Lodash가 권장됩니다.JSON.parse(JSON.stringify(object))왜냐하면 그것은 몇몇 사건들을 처리해 주기 때문이다.
  • 이 셋업 덕분에 라이브러리 전체가 아닌 lodash에서 작은 기능만 로드하므로 성능 면에서는 불이익이 없습니다.
  • Lodash는 JS(핵심 라이브러리 없음)에는 크게 부족한 전투 테스트된 유용한 기능을 많이 가지고 있습니다.
export default new Vuex.Store({
    ...
    strict: true
})

「비판」이라고 코멘트하려고 하다.

Vuex 모듈을 사용 중인 경우 모듈이 다음 중 하나일 경우 이 오류가 발생할 수 있습니다.dataproperty는 객체를 반환하는 함수가 아닌 객체로, 이 모듈을 여러 Store 간에 공유하고 있습니다.

그래서 다음 대신:

// In stores/YourModule.js
export default {
  state: { name: 'Foo' },
}

변경 내용:

// In stores/YourModule.js
export default {
  state: () => {
    return { name: 'Foo' };
  },
}

이것은 실제로 여기에 기재되어 있습니다.

예를 들어 다음과 같이 모듈의 여러 인스턴스를 작성해야 할 수 있습니다.

동일한 모듈을 사용하는 여러 스토어 작성(예를 들어 runInNewContext 옵션이 false이거나 '1회'일 때 SSR에서 상태 저장 싱글톤을 열지 않도록 하기 위해). 같은 스토어에 동일한 모듈을 여러 번 등록합니다.플레인 객체를 사용하여 모듈 상태를 선언하면 해당 상태 객체가 참조에 의해 공유되고 변환 시 크로스 스토어/모듈 상태 오염이 발생합니다.

이것은 실제로 Vue 컴포넌트 내부의 데이터와 같은 문제입니다.따라서 솔루션도 동일합니다.모듈 상태를 선언하는 함수를 사용합니다(2.3.0+에서 지원).

언급URL : https://stackoverflow.com/questions/46044276/vuex-do-not-mutate-vuex-store-state-outside-mutation-handlers

반응형