如何修改不同组件中的数据?

时间:2016-11-14 22:28:31

标签: vue.js

我是Vue js的新手,并试图为自己构建一个简单的CRUD示例。

关于non parent child communication的文档,我想修改一个组件数据中的heading值,但要修改另一个组件的数据。

我设置a fiddle来展示我目前理解的相对功能,我们在这里有HTML:

<div id="app" v-cloak>
  <person-add></person-add>
  <person-list :list="people"></person-list>
</div>

<template id="person-add-template">
  <div>
    <h2>
      <span>{{ heading }}</span>
      Person
    </h2>
    <form @submit.prevent="handleFormSubmit">
      <input type="text" placeholder="Enter persons name" v-model="name" />
      <button type="submit" v-show="name">
        Add Person
      </button>
    </form>
  </div>
</template>

<template id="person-list-template">
  <div>
    <h2>People</h2>
    <table border="1">
      <tr>
        <th>Person</th>
        <th>Edit</th>
      </tr>
      <tr v-for="(person, key) in list">
        <td>{{ person.name }}</td>
        <td><button type="button" @click="editPerson(key)">Edit</button></td>
      </tr>
    </table>
  </div>
</template>

和JS:

// https://vuejs.org/v2/guide/components.html#Non-Parent-Child-Communication
var bus = new Vue();
// Add
Vue.component('person-add', {
  template: '#person-add-template',
  props: ['list'],
  data: function () {
    return {
      heading: 'Add',
      name: ''
    }
  },
  created: function () {
    bus.$on('toggle-heading', function (newHeading) {
      console.log(newHeading);
      this.heading = newHeading;
    });
  }
});
// List
Vue.component('person-list', {
  template: '#person-list-template',
  props: ['list'],
  methods: {
    editPerson: function (key) {
      console.log('fired');
      bus.$emit('toggle-heading', 'Edit');
    }
  }
});
// Vue
new Vue({
  el: '#app',
  data: {
    people: [
      { name: 'Bob' },
      { name: 'Frank' },
      { name: 'Mary' }
    ]
  }
});

正如您所看到的,它提供了一个以“添加人物”开头的简单表单,并列出了一些人以及每个人的编辑按钮:

Person List

我想要发生的是,当我点击人名旁边的编辑时,它会将另一个组件中的标题更改为“编辑人”,而不是默认的“添加人”。

在组件A的方法中,我有:

editPerson: function (key) {
  console.log('fired');
  bus.$emit('toggle-heading', 'Edit');
}

在组件B中创建的钩子中,我有:

created: function () {
  bus.$on('toggle-heading', function (newHeading) {
    console.log(newHeading);
    this.heading = newHeading;
  });
}

当我单击编辑时,在控制台中我看到日志fired然后Edit,因此事件似乎会跟随person-add组件,但我尝试分配新标题this.heading = newHeading;,标题不会改变,我正在努力理解为什么。

如果有人能够说明为什么会发生这种情况,我在这里出错了,或者如果这不是正确的方式应该怎么做,那么我们将非常感激。

非常感谢提前!

1 个答案:

答案 0 :(得分:1)

你的问题实际上与范围有关,而不是对Vue缺乏了解。您的代码是正确的,除非您尝试从创建自己的this上下文的函数内部访问this

无论何时以这种方式创建新函数,它都会创建自己的this,所以当你这样做时:

bus.$on('toggle-heading',  function(newHeading) {
    console.log(newHeading);
    // this refers to this anonymous function only 
    this.heading = newHeading;
});

this仅指函数本身,而不是Vue实例。

解决此问题的方法是使用arrow function,但不会创建自己的this

  bus.$on('toggle-heading',  (newHeading) => {
      console.log(newHeading);
      // No new 'this' context is created in an arrow function
      this.heading = newHeading;
    });

如果您不使用ECMAScript 2015,则需要在功能外设置this的引用:

  var self = this; // set a reference to "this"

  bus.$on('toggle-heading',  function(newHeading) {
      console.log(newHeading);
      // Now self refers to the view models `this`
      self.heading = newHeading;
    });

我已经更新了你的小提琴,向你展示了两种方法:

箭头功能:https://jsfiddle.net/abtgmx47/3/

使用var self=this参考:https://jsfiddle.net/abtgmx47/4/