Forms 什么是vuejs中的“理智之路”+;vuex表单处理?

Forms 什么是vuejs中的“理智之路”+;vuex表单处理?,forms,vue.js,vuex,Forms,Vue.js,Vuex,我有一个大的表格提交在单页 <container> <formA> <formB> <formC> <submitButton> <container> 通过查看表单数据(与v-model绑定)更新输入更改时的状态 或者像vuex文档中记录的那样 userInput: { get () { return this.$store.state.userInput }, s

我有一个大的表格提交在单页

<container>
  <formA>
  <formB>
  <formC>
  <submitButton>
<container>
通过查看表单数据(与v-model绑定)更新输入更改时的状态

或者像vuex文档中记录的那样

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

嗯。。我认为这不是个好主意。有没有更好的方法来处理vuex?

关于这个问题,我很头痛

Vuex文档描述了我们需要为每个字段更新存储。 这是一份打字的战利品,有什么用

我们提出了一个可行的解决方案。 它基于将存储对象克隆到本地对象

  //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))
    }
  },
//我们正在从父组件传递(vuexstore)'item'对象:
// {
返回{
localItem:null
}
},
//在创建的事件上进行克隆
已创建:函数(){
this.localItem=this.\u克隆(this.item)
},
//查看vuexstore“项”的更改
观察:{
项目:功能(val){
this.localItem=this.\u克隆(this.item)
}
},
//映射突变并在事件上更新存储
方法:{
…地图突变([
“编辑项”
]),
updateItemHandler:函数(){
this.editItem({item:this.\u clone(this.localItem)})
},
_克隆:功能(o){
返回JSON.parse(JSON.stringify(o))
}
},
内部表格用途:

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


我认为这只是缺少vuex。应该有更简短和内置的解决方案。

我会使用深度观察程序,并在一个对象中包含所有字段,您可以使用多种方法保存数据,迭代object.keys,将每个字段及其变量名存储在表单对象中,或者存储整个表单,无论您需要什么

您还可以使用
v-model.lazy=“form.myfield”
指示您只希望在用户离开该字段后更新绑定

表单组件

导出默认值{
道具:['value'],
数据:函数(){
返回{
内部形式:{
字段1:null,
字段2:空
}
}
},
观察:{
内部形式:{
处理程序:函数(newValue){
//将新表单对象发射到父组件,以便在那里使用v-model
this.$emit('input',this.form)
//或保存表单数据
this.handleFormSave(this.form)
},
//告诉vue对整个表单对象进行深度监视,以监视对象中的子项
深:是的
}
}
}
父组件

导出默认值{
数据:函数(){
返回{
表格:{
form1:null//当发出“input”时,此值将被更新
}
}
},
观察:{
表格:{
处理程序:函数(newValue){
如果(allFormsValid&&readyToSave)
saveAllFormData(newValue);
},
深:是的
}
}
}

我制作了一个小工具,使Vuex的表单处理变得更加简单:

例子 商场 组成部分

从“vuex映射字段”导入{mapFields};
导出默认值{
计算:{
//“mapFields”函数接受
//字段名并生成相应的
//使用getter和setter计算属性
//用于访问Vuex存储的函数。
…地图字段([
“菲尔达”,
“fieldB”,
]),
},
};

你可以在我的博客上阅读更多关于vuex地图字段的信息:

那些想法不好怎么办?我遇到了类似的问题。在每次输入时更新存储是没有意义的。在我看来,存储应该只接收提交的表单数据。因此,请在表单组件中保留表单数据的本地副本,并在成功提交后,使用表单数据向存储区提交。@RoyJ代码是多余的,监视每个输入对性能没有好处。@EricGuan我需要从表单组件获取最新数据。这就是我每次存储数据的原因。如果可以的话,您会更喜欢它吗?或者使用
change
事件而不是
input
事件来更新变量和存储?我也不得不依赖类似的东西。但是,也在尝试将本地副本放在存储中(尽管将本地数据放在全局存储中听起来很混乱)。这是因为只有在对保存的表单数据的api调用(vuex操作)完成后,我才能从组件(例如,在创建中)同步创建克隆副本。伙计,您的“小工具”节省了很多程序员,感谢您的奉献该项目对整体存储性能有何影响?它仅仅是绑定属性的一种语法糖,还是它还能够减轻频繁的存储访问?
 <input v-model="localItem.text" @keyup="updateItemHandler" type="text" class="form-control"></input>
<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>
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>