从子表单组件传递和检索数据的最佳方法是什么?

时间:2017-05-12 10:23:07

标签: javascript vue.js vuejs2

这是我目前的方法:

Parent.vue:

// Template

<form-child :schema="schema"><form-child>

// JS

data () {
  return {
    schema: [{ // name: '', value: '', type: '' }, { //etc ... }]
  }
}

FormChild.vue

// Template

<div v-for="field in schema">
  <input v-if="field.type === 'text'" @change="updateValue(field.name, field.value)">
  <textarea v-if="field.type === 'textarea'" @change="updateValue(field.name, field.value)">/textarea>
</div>

// JS

props: {
  schema: Arrary
}

methods: {
  updateValue (fieldName, fieldValue) {
    this.schema.forEach(field => {
      // this makes schema update in Parent.vue
      if (field.name === fieldName) field.value = fieldValue
    })
  }
}

这是最佳方式吗?或者使用emitv-model可能会更好? (如果是,您能提供示例代码吗?)

1 个答案:

答案 0 :(得分:1)

正确封装的子组件将与父数据结构分离。它需要typevalue作为单独的道具,加上一个不透明的id来告诉父母组件发出的值。

通过基于value参数计算可设置,组件可以在其表单元素上使用v-modelset函数会使用inputid发出newValue个事件,并且父级会从那里获取该事件。

更新:我觉得我不喜欢id去组件,所以我在输入处理程序中处理了这个问题:@input="updateField(index, $event)

&#13;
&#13;
new Vue({
  el: '#app',
  data: {
    schema: [{
        type: 'text',
        name: 'one',
        value: "1"
      },
      {
        type: 'textarea',
        name: 'two',
        value: "stuff in the textarea"
      }
    ]
  },
  methods: {
    updateField(index, newValue) {
      this.schema[index].value = newValue;
    }
  },
  components: {
    formInput: {
      props: ['type', 'value'],
      computed: {
        proxyValue: {
          get() { return this.value; },
          set(newValue) {
            this.$emit('input', newValue);
          }
        }
      }
    }
  }
});
&#13;
<script src="//cdnjs.cloudflare.com/ajax/libs/vue/2.3.3/vue.min.js"></script>
<div id="app">
  <div v-for="field in schema">
    {{field.name}} = {{field.value}}
  </div>
  <form-input inline-template v-for="field, index in schema" :type="field.type" :key="index" :value="field.value" @input="updateField(index, $event)">
    <div>
      <input v-if="type === 'text'" v-model="proxyValue">
      <textarea v-if="type === 'textarea'" v-model="proxyValue"></textarea>
    </div>
  </form-input>
</div>
&#13;
&#13;
&#13;