source

vuej + vuex 폼 처리의 올바른 방법은 무엇입니까?

factcode 2022. 8. 13. 12:07
반응형

vuej + vuex 폼 처리의 올바른 방법은 무엇입니까?

나는 한 페이지에 제출해야 할 큰 양식이 있다.

<container>
  <formA>
  <formB>
  <formC>
  <submitButton>
<container>

겉보기엔 이렇게 생겼고 모든 양식 데이터를 저장하는 가게가 있어요사용자가 제출 버튼을 클릭하면 vuex 스토어를 사용하여 모든 양식 데이터를 수집합니다.

문제는 매장에 있는 양식 데이터를 매번 업데이트해야 한다는 것입니다.

vue 컴포넌트에서는 이렇게 하겠습니다.

 watch: {
   userInput (val) {
     this.updateState(val)
 }

폼 데이터(v-model과 함께 적용됨)를 확인하여 입력이 변경될 때 상태를 업데이트합니다.

또는 vuex 문서에 기재되어 있는 것과 같습니다.

  userInput: {
    get () {
      return this.$store.state.userInput
    },
    set (val) {
      this.updateState(val)
    }
  }

음.. 이건 좋은 생각이 아닌 것 같아.vuex로 처리하는 더 좋은 방법이 있나요?

Vuex의 폼 처리를 훨씬 쉽게 하는 작은 툴을 만들었습니다.vuex-map-fields

가게

import Vue from 'vue';
import Vuex from 'vuex';

// Import the `getField` getter and the `updateField`
// mutation function from the `vuex-map-fields` module.
import { getField, updateField } from 'vuex-map-fields';

Vue.use(Vuex);

export default new Vuex.Store({
  state: {
    fieldA: '',
    fieldB: '',
  },
  getters: {
    // Add the `getField` getter to the
    // `getters` of your Vuex store instance.
    getField,
  },
  mutations: {
    // Add the `updateField` mutation to the
    // `mutations` of your Vuex store instance.
    updateField,
  },
});

요소

<template>
  <div id="app">
    <input v-model="fieldA">
    <input v-model="fieldB">
  </div>
</template>

<script>
import { mapFields } from 'vuex-map-fields';

export default {
  computed: {
    // The `mapFields` function takes an array of
    // field names and generates corresponding
    // computed properties with getter and setter
    // functions for accessing the Vuex store.
    ...mapFields([
      'fieldA',
      'fieldB',
    ]),
  },
};
</script>

vuex-map-fields에 대한 자세한 내용은 다음 블로그를 참조하십시오.Vue, Vuex 및 vuex-map-field를 사용한 복수행 폼 처리 방법

이를 위해 딥워치를 사용하고 오브젝트 내의 모든 필드를 갖습니다.데이터를 저장하기 위해 여러 접근 방식을 사용할 수 있습니다.오브젝트 상에서 반복할 수 있습니다.각 필드를 폼 오브젝트에 변수 이름과 함께 저장하거나 필요한 경우 전체 양식을 저장합니다.

또,v-model.lazy="form.myfield"사용자가 필드를 떠난 후에만 바인딩을 갱신하는 것을 나타냅니다.

폼 컴포넌트

<template>
    <div>
        <!-- You can optionally use v-model.lazy="form.field1" to only update once user has exited the field or pressed enter -->
        <input v-model="form.field1" />
        <input v-model.lazy="form.field2" />
    </div>
</template>

<script>
    export default {
        props: ['value'],

        data: function () {
            return {
                internalForm: {
                    field1: null,
                    field2: null
                }
            }
        },

        watch: {
            internalForm: {
                handler: function (newValue) {
                // Emit new form object to parent component so we can use v-model there
                this.$emit('input', this.form)
                // Or save form data
                this.handleFormSave(this.form)
                },
                // Tell vue to do a deep watch of entire form object to watch child items in the object
                deep: true
            }
        }
    }
</script>

상위 컴포넌트

<template>
    <form-component v-model="forms.form1" />
    <submit-button @click="saveAllFormData" />
</template>

<script>
    export default {
        data: function () {
            return {
                forms: {
                    form1: null // This will be updated when 'input' is emitted 
                }
            }
        },

        watch: {
            forms: {
                handler: function (newValue) {
                    if (allFormsValid && readyToSave)
                        saveAllFormData(newValue);
                },
                deep: true
            }
        }
    }
</script>

나는 이 문제에 대해 두통이 있었다.

Vuex 문서에서는 모든 필드에 대해 스토어를 업데이트해야 한다고 설명합니다.타이핑하는 걸 왜 좋아해?

델은 효과적인 솔루션을 1개 만듭니다.스토어 오브젝트를 로컬 오브젝트로 복제하는 것을 기반으로 합니다.

  //We are passing (vuexstore) 'item' object from parent component:
  //<common-item v-bind:item="item" ....
  props: ['item'],

  // create localItem - this is reactive object for vuex form
  data: () => {
    return {
      localItem: null
    }
  },

  // make clone on created event
  created: function() {
    this.localItem =  this._clone(this.item)
  },

  // watch vuexstore 'item' for changes
  watch: {
    item: function(val) {
      this.localItem = this._clone(this.item)
    }
  },

  // map mutations and update store on event
  methods: {
     ...mapMutations([
      'editItem'
    ]),
    updateItemHandler: function() {
      this.editItem({ item: this._clone(this.localItem) })
    },
    _clone: function(o){
      return JSON.parse(JSON.stringify(o))
    }
  },

내부 양식 사용:

 <input v-model="localItem.text" @keyup="updateItemHandler" type="text" class="form-control"></input>

나는 이것이 단지 vuex의 부족이라고 생각한다.훨씬 더 짧고 내장된 솔루션이 있어야 합니다.

언급URL : https://stackoverflow.com/questions/44780768/what-is-sane-way-in-vuejs-vuex-form-handling

반응형