我开始玩vuejs(2.0)。 我构建了一个包含一个组件的简单页面。 该页面有一个带有数据的Vue实例。 在那个页面上,我注册并将组件添加到html中。 组件有一个输入[type=text]。我希望该值反映在父实例(主Vue实例)上。

如何正确地更新组件的父数据? 从父对象传递绑定道具是不好的,会向控制台抛出一些警告。他们的文件里有一些东西,但不管用。


当前回答

双向绑定在Vue 2.0中已弃用,转而使用事件驱动的体系结构。一般来说,孩子不应该改变它的道具。相反,它应该$emit事件并让父进程响应这些事件。

在您的特定情况下,您可以使用带有v-model的自定义组件。这是一种特殊的语法,它允许一些接近双向绑定的东西,但实际上是上面描述的事件驱动体系结构的简写。你可以在这里阅读-> https://v2.vuejs.org/v2/guide/components.html#Form-Input-Components-using-Custom-Events。

这里有一个简单的例子:

Vue.component('child', { template: '#child', //The child has a prop named 'value'. v-model will automatically bind to this prop props: ['value'], methods: { updateValue: function (value) { this.$emit('input', value); } } }); new Vue({ el: '#app', data: { parentValue: 'hello' } }); <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.13/vue.js"></script> <div id="app"> <p>Parent value: {{parentValue}}</p> <child v-model="parentValue"></child> </div> <template id="child"> <input type="text" v-bind:value="value" v-on:input="updateValue($event.target.value)"> </template>


文档中说

<custom-input v-bind:value="something" v-on:input="something = arguments[0]"></custom-input>

等于

<custom-input v-model="something"></custom-input>

这就是为什么子对象上的道具需要命名为value,以及为什么子对象需要$emit一个名为input的事件。

其他回答

在子组件中:

this.$emit('eventname', this.variable)

在父组件中:

<component @eventname="updateparent"></component>

methods: {
    updateparent(variable) {
        this.parentvariable = variable
    }
}

在孩子身上

 <input
            type="number"
            class="form-control"
            id="phoneNumber"
            placeholder
            v-model="contact_number"
            v-on:input="(event) => this.$emit('phoneNumber', event.target.value)"
    />

data(){
    return {
      contact_number : this.contact_number_props
    }
  },
  props : ['contact_number_props']

在父

<contact-component v-on:phoneNumber="eventPhoneNumber" :contact_number_props="contact_number"></contact-component>


 methods : {
     eventPhoneNumber (value) {
      this.contact_number = value
    }

当我们想要将数据传递给父组件以及当前子组件的另一个嵌套子组件时,使用data属性将非常有用,如下面的示例所示。

例子: 像这样从父组件调用子组件。

父组件:

<template>
  <TodoItem :todoParent="todo" />
</template>

<script>
export default {
  data() {
    return {
      todo: {
        id:1,
        task:'todo 1',
        completed:false
      }
    };
  }
}
</script>

子组件:

<template>
  <div class="todo-item" v-bind:class="{'is-completed':todo.completed}">
    <p>
      <input type="checkbox" @change="markCompleted" />
      {{todo.task}}
      <button class="del">x</button>
    </p>
  </div>
</template>

<script>
export default {
  name: "TodoItem",
  props: ["todoParent"],
  data() {
    return {
      todo: this.todoParent,
    };
  },
  methods: {
    markCompleted() {
      this.todo.completed = true
    },
  },
};
</script>

即使你可以将这个属性传递给嵌套的子组件,它也不会给出这个错误/警告。

当您只需要在父组件和子组件之间同步此属性时的其他用例。可以使用Vue中的同步修改器来实现。v型模型也很有用。在这个问题中还有许多其他的例子。

Example2:使用组件事件。 我们可以从子组件发出事件,如下所示。

父组件:

<template>
  <TodoItem :todo="todo" @markCompletedParent="markCompleted" />
</template>

<script>
export default {
  data() {
    return {
      todo: {
        id:1,
        task:'todo 1',
        completed:false
      }
    };
  },
  methods: {
    markCompleted() {
      this.todo.completed = true
    },
  }
}
</script>

子组件:

<template>
  <div class="todo-item" v-bind:class="{'is-completed':todo.completed}">
    <p>
      <input type="checkbox" @change="markCompleted" />
      {{todo.task}}
      <button class="del">x</button>
    </p>
  </div>
</template>

<script>
export default {
  name: "TodoItem",
  props: ["todo"],
  methods: {
    markCompleted() {
      this.$emit('markCompletedParent', true)
    },
  }
};
</script>

我同意上述事件发射和v模型的答案。但是,我认为我应该发布我所发现的关于具有多个表单元素的组件,这些元素想要发射回它们的父元素,因为这似乎是谷歌返回的第一批文章之一。

我知道这个问题指定了单个输入,但这似乎是最接近的匹配,并且可以为使用类似vue组件的人节省一些时间。此外,还没有人提到.sync修饰符。

据我所知,v模型解决方案只适合一个输入返回到它们的父。我花了一些时间寻找它,但Vue(2.3.0)文档确实展示了如何将发送到组件中的多个道具同步回父组件(当然是通过emit)。

它被恰当地称为.sync修饰符。

以下是文档的内容:

在某些情况下,我们可能需要对道具进行“双向绑定”。 不幸的是,真正的双向绑定会产生维护问题, 的源可以使父组件发生变异 这种突变在父母和孩子身上都很明显。 这就是为什么我们建议以模式发出事件的原因 更新:myPropName。例如,在一个假设的组件中 标题道具,我们可以传达分配新值的意图 :

this.$emit('update:title', newTitle)

然后家长就可以听了 并更新本地数据属性(如果需要的话)。为 例子:

<text-document   
 v-bind:title="doc.title"  
 v-on:update:title="doc.title = $event"
></text-document>

为了方便起见,我们用.sync修饰符提供了这种模式的简写:

<text-document v-bind:title.sync="doc.title"></text-document>

你也可以通过一个对象同时同步多个对象。在这里查看文档

子组件

使用这个。$emit('event_name')向父组件发送一个事件。

父组件

为了在父组件中监听该事件,我们执行v-on:event_name,并在该事件发生时执行一个方法(例如handleChange)

:完成)