【问题标题】:change parent props from child component in vuejs2从 vuejs2 中的子组件更改父道具
【发布时间】:2018-08-06 21:33:23
【问题描述】:

我想从子组件中更改父级道具的值。这在 vuejs 1 中效果很好,但在 vue 2 中效果不佳(我想在 vue.js 2 中使用它)。

这是一个小例子:

HTML

<div id="app">
   <parent :content="{value:'hello parent'}"><</parent>
</div>

JavaScript

var parent = {
  template: '<child :content="content"></child>',
  props: ['content'],
};

var child = {
  template: '<div>{{ content.value }}<button @click="change">change me</button></div>',
  props: ['content'],
  methods: {
    change() {
      this.content.value = "Value changed !";
    }
  }
};

Vue.component('child', child);
Vue.component('parent', parent);

new Vue({
  el: '#app',
});

https://jsfiddle.net/f5gt94f2/

【问题讨论】:

    标签: javascript vue.js vuejs2


    【解决方案1】:

    tl;dr:在 vue2 中,你需要使用.sync modifier


    在父级的 data (see reason here) 中创建 content 属性的本地副本。

    var parent = {
      ...
      data() {
        return {
          localContent: this.content // creating a local copy, so we can mutate and react to it
        }
      }
    };
    

    现在,将 localContent 传递给孩子,而不是 content。还有pass it using .sync so it can be updated

    var parent = {
      template: '<div><child :content.sync="localContent"></child></div>',
      ...                     //     ^^^^^^^^^^^^^^^^^^^^-- changed here
    

    现在,在孩子中,不要分配给this.content.value,而是发出更新事件:

    var child = {
        ...
        change() {
          this.$emit('update:content', {value: "Value changed !"})
        }
      }
    };
    

    这个带有新值的事件将被父级接收,并将更新其localContent,这也将因此更新子级的content 属性。

    下面的最终运行代码。

    var parent = {
      template: '<div><child :content.sync="localContent"></child><br>At parent: {{ localContent }}</div>',
      props: ['content'],
      data() {
        return {
          localContent: this.content
        }
      }
    };
    
    var child = {
      template: '<div>At child: {{ content.value }}<button @click="change">change me</button></div>',
      props: ['content'],
      methods: {
        change() {
          this.$emit('update:content', {value: "Value changed !"})
        }
      }
    };
    
    Vue.component('child', child);
    Vue.component('parent', parent);
    
    new Vue({
      el: '#app'
    });
    <script src="https://unpkg.com/vue@2.5.13/dist/vue.js"></script>
    
    <div id="app">
      <parent :content="{value:'hello parent'}"></parent>
    </div>

    【讨论】:

    • 太棒了!我不知道 .sync 又回来了,我也可以使用 this.content.value = "helloooo"; 而不是 this.$emit('update:content', {value: "Value changed !"}) 并且它可以工作
    • 你可以,但你不应该,这是一种不好的做法。它之所以有效,是因为value 是一个嵌套属性,并且因为它是反应性的(因为它是父级中的data 属性)。例如,到达parentcontent 不是响应式的,因为它是通过文字&lt;parent :content="{value:'hello parent'}"&gt; 传递的。但是,无论如何,如果您知道缺点,但认为直接更改是值得的(我可以理解),那么您可以使用它,或者当然。
    【解决方案2】:

    你必须为此使用发射事件

    家长:

    <child :content="content" @updateParent="updateValue"></child>
    
    methods: {
      updateValue (value) {
        // Your code here
      }
    }
    

    孩子:

    props: ['content'],
    methods: {
      change () {
        this.$emit('updateParent', value)
      }
    }
    

    https://vuejs.org/v2/guide/components.html#Custom-Events

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-07-08
      • 1970-01-01
      • 2019-11-26
      • 2019-08-27
      • 1970-01-01
      • 1970-01-01
      • 2019-04-06
      • 2020-09-01
      相关资源
      最近更新 更多