如何将 Vue.js 事件向上传播到组件链?
How to propagate a Vue.js event up the components chain?
我确实有三个组成部分。
我对 Datatable
组件的作用没有任何影响,因为我从 npm 获得了它。
现在我想将一个事件从 EditButton
发送到我的 Zonelist
。
Zonelist
分量:
<template>
<datatable :columns="table_columns" :data="table_rows" filterable paginate v-on:remove="removeItem"></datatable>
</template>
<script>
import datatable from 'vuejs-datatable';
import moment from 'moment';
export default {
data() {
return {
table_columns: [
{label: "Zone", component: 'ZoneLink'},
{label: "Last updated", callback (row) {
let locale = $('html').closest('[lang]').attr('lang') || 'en';
moment.locale(locale);
return moment(row.last_updated).format('D. MMM YYYY');
}},
{label: '', component: 'EditButton'}
],
table_rows: [
{
"name": "xyz.de",
"last_updated": "2017-10-21 17:29:50"
}
],
form: {
name: '',
errors: []
}
};
},
components: {
datatable
},
methods: {
removeItem (item) {
this.table_rows.forEach((value, index, array) => {
if (value.name === item) {
Vue.delete(array, index);
}
});
}
}
}
</script>
现在我的 EditButton
组件 $emit()
是带有参数的 remove
事件。
但是没有任何反应。所以我认为vue是无法定位监听器的。
(我在这里使用的是 ES6 的方法缩写)
如果不通过 EditButton
中的 this.$parent.$parent
改变 Zonelist
的状态,我如何正确地做到这一点?
Non parent-child communication 在 Vue 中通常通过事件总线或状态管理系统处理。
在这种情况下,除非您的应用程序更复杂,否则事件总线可能就是您所需要的。由于您使用的是单文件组件,您可能需要在 window 上声明总线,可能在您的主脚本中。
window.bus = new Vue()
然后在您的 EditButton
中,您可以发出事件
bus.$emit('some-event', someData)
并且在您的 ZoneList
中您可以收听它。
bus.$on('some-event', someData => this.doSomething(someData))
另一种选择是要求 DataTable
通过向其添加 v:on="$listeners"
属性来向上传递所有事件。
有关更详细的说明,请参阅 。
编辑:
一个更安全的选择是简单地监听父事件 class 并将其传递给...
<ancestor @message="console.log($event)"> <!-- cute trick see * -->
...
<parent @message="$emit('message', $event)"> <!-- passes it on -->
...
<child @click="$emit('Hello World')"> <!-- creates the event -->
* computed: {'console' : () => console}
默认情况下,如果 Vue 组件中只有一个节点(即没有子节点),那么您从父节点附加到它的所有事件都会像常规事件一样触发 HTML元素。
但是如果你有一个有子节点的子节点怎么办?在这种情况下,您想使用 v-on="$listeners"
示例:
<template>
<div v-on="$listeners">
<button>Hello world</button>
</div>
</template>
文档:https://vuejs.org/v2/guide/components-custom-events.html#Binding-Native-Events-to-Components
我确实有三个组成部分。
我对 Datatable
组件的作用没有任何影响,因为我从 npm 获得了它。
现在我想将一个事件从 EditButton
发送到我的 Zonelist
。
Zonelist
分量:
<template>
<datatable :columns="table_columns" :data="table_rows" filterable paginate v-on:remove="removeItem"></datatable>
</template>
<script>
import datatable from 'vuejs-datatable';
import moment from 'moment';
export default {
data() {
return {
table_columns: [
{label: "Zone", component: 'ZoneLink'},
{label: "Last updated", callback (row) {
let locale = $('html').closest('[lang]').attr('lang') || 'en';
moment.locale(locale);
return moment(row.last_updated).format('D. MMM YYYY');
}},
{label: '', component: 'EditButton'}
],
table_rows: [
{
"name": "xyz.de",
"last_updated": "2017-10-21 17:29:50"
}
],
form: {
name: '',
errors: []
}
};
},
components: {
datatable
},
methods: {
removeItem (item) {
this.table_rows.forEach((value, index, array) => {
if (value.name === item) {
Vue.delete(array, index);
}
});
}
}
}
</script>
现在我的 EditButton
组件 $emit()
是带有参数的 remove
事件。
但是没有任何反应。所以我认为vue是无法定位监听器的。
(我在这里使用的是 ES6 的方法缩写)
如果不通过 EditButton
中的 this.$parent.$parent
改变 Zonelist
的状态,我如何正确地做到这一点?
Non parent-child communication 在 Vue 中通常通过事件总线或状态管理系统处理。
在这种情况下,除非您的应用程序更复杂,否则事件总线可能就是您所需要的。由于您使用的是单文件组件,您可能需要在 window 上声明总线,可能在您的主脚本中。
window.bus = new Vue()
然后在您的 EditButton
中,您可以发出事件
bus.$emit('some-event', someData)
并且在您的 ZoneList
中您可以收听它。
bus.$on('some-event', someData => this.doSomething(someData))
另一种选择是要求 DataTable
通过向其添加 v:on="$listeners"
属性来向上传递所有事件。
有关更详细的说明,请参阅
编辑:
一个更安全的选择是简单地监听父事件 class 并将其传递给...
<ancestor @message="console.log($event)"> <!-- cute trick see * -->
...
<parent @message="$emit('message', $event)"> <!-- passes it on -->
...
<child @click="$emit('Hello World')"> <!-- creates the event -->
*
computed: {'console' : () => console}
默认情况下,如果 Vue 组件中只有一个节点(即没有子节点),那么您从父节点附加到它的所有事件都会像常规事件一样触发 HTML元素。
但是如果你有一个有子节点的子节点怎么办?在这种情况下,您想使用 v-on="$listeners"
示例:
<template>
<div v-on="$listeners">
<button>Hello world</button>
</div>
</template>
文档:https://vuejs.org/v2/guide/components-custom-events.html#Binding-Native-Events-to-Components