我是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' }
]
}
});
正如您所看到的,它提供了一个以“添加人物”开头的简单表单,并列出了一些人以及每个人的编辑按钮:
我想要发生的是,当我点击人名旁边的编辑时,它会将另一个组件中的标题更改为“编辑人”,而不是默认的“添加人”。
在组件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;
,标题不会改变,我正在努力理解为什么。
如果有人能够说明为什么会发生这种情况,我在这里出错了,或者如果这不是正确的方式应该怎么做,那么我们将非常感激。
非常感谢提前!
答案 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/