将数据发送到嵌套自定义输入组件的正确方法

时间:2017-08-18 22:27:57

标签: javascript vue.js vuejs2

我正在从React迁移到Vue,我只是喜欢Vue提供的v-model事物。现在我处于这种情况,并且无法找出这样做的最佳方式。

以下是我的组件树的样子:

- FormContainer
  -FormView
    - CustomInput
      - input

我在FormContainer中有我的州,让我们称之为姓名和年龄。我希望避免编写自定义setter方法,就像我通常使用v-model一样,我怎样才能将数据传递给输入组件。

目前我正在做这样的事情:

// in my container
<form-view :name="name" :age="age" />

// in my form view I am doing something like
<custom-input v-model="age"/>
<input v-model="name" />

它们都不起作用,我收到以下错误Avoid mutating a prop directly

我应该可以做像

这样的事情
<form-view @age="age" :age="age" @name="name" :name="name"/>

或类似的东西。如果您需要更多详细信息,请与我们联系。

1 个答案:

答案 0 :(得分:1)

我已经两次回答过这个问题了,虽然我的回答很有道理,但我认为他们没有针对你的问题,所以我已经删除了它们。

从根本上说,你希望事件能够起泡&#34;从发生事件的元素到拥有数据项的Vue。 Vue事件不会冒泡,但是本机事件会发生,所以如果您在层次结构底部生成了本机input事件,则可以在任何组件中使用@input.native来捕获它。那里的树。

对于您提供的示例,如果nameage数据项位于顶级Vue中,则最外层组件可以将其作为.sync modifier的道具。这意味着组件中的任何update:nameupdate:age事件都将导致数据项更新。到目前为止一切都很好。

form-view组件内移动,我们有一个原生输入元素。通常,它会发出本机input事件。我们希望那些事件成为update:name事件,所以我们这样处理:

 <input :value="name" @input="$emit('update:name', $event.target.value)">

现在这里有趣的部分:在form-view组件中,我们有custom-input组件。在它的核心(我们并不真正关心它可能有多远),它会生成一个本机输入事件。我们可以让它自然地冒出来并在custom-input组件的根部捕获它,然后发出所需的update:age事件,而不是在每个级别捕获并冒泡它们。

<custom-input :value="age" @input.native="$emit('update:age', $event.target.value)">

总而言之,我们有两个变量通过组件传递给input元素,两个input事件处理程序,没有计算。

&#13;
&#13;
new Vue({
  el: '#app',
  data: {
    name: 'Jerry',
    age: 21
  },
  components: {
    formView: {
      props: ['age', 'name'],
      components: {
        customInput: {
          props: ['value']
        }
      }
    }
  }
});
&#13;
<script src="//cdnjs.cloudflare.com/ajax/libs/vue/2.4.2/vue.min.js"></script>
<div id="app">
  <div>Name: {{name}}</div>
  <div>Age: {{age}}</div>
  <form-view :name.sync="name" :age.sync="age" inline-template>
    <div>
      <custom-input :value="age" @input.native="$emit('update:age', $event.target.value)" inline-template>
        <div>
          Age: <input :value="value">
        </div>
      </custom-input>
      <div>Name: <input :value="name" @input="$emit('update:name', $event.target.value)"></div>
    </div>
  </form-view>
</div>
&#13;
&#13;
&#13;