如何使用 Vue js 2 在组件子组件链上冒泡事件? [英] How to bubble events on a component subcomponent chain with Vue js 2?
问题描述
我的 vue 应用程序使用:
由component-child组成的component-parent组件
在父组件内部我有按钮,当有人点击一个按钮时,我想发出一个事件以便由 vue 处理并传递给另一个组件
到目前为止我做了什么:
var vm = new Vue({el: '#app',方法: {itemSelectedListener: 函数(item){console.log('itemSelectedListener', item);}}});Vue.component('component-child', {模板:' <span v-on:click="chooseItem(pty)" >Button </span>',方法: {选择项目:功能(pty){控制台日志(pty);this.$emit('itemSelected', {优先级":pty});}}});Vue.component('组件父', {模板:'<component-child v-for="q in items" ></component-child>'});
HTML:
<component-parent v-on:itemSelected="itemSelectedListener" ></component-parent>
它到达了我的 console.log(pty);
行,但似乎 this.$emit('itemSelected'
不会通过:
console.log('itemSelectedListener', item);//这不会被调用...
提示?
我应该从 child->parent->Vue-instance 冒泡事件吗?(我也试过了,但没有成功)
您的 component-parent
模板存在一个问题,因为它试图呈现多个子组件.Vue 通常需要在组件内部使用单个根 div,因此您需要将其包装在 div 或其他标签中.
<component-child v-for=q in items"></component-child>
要指出的第二件事是,您从 2 级以下的子组件发出一个事件,并在根中收听它.
Root//但是你在上面1级监听事件组件 1//你应该在这里监听事件组件 2//您尝试从这里发出它
这里有 2 个选项.从 component-child
发出,在 component-parent
中监听该事件,然后向上传播该事件.小提琴 https://jsfiddle.net/bjqwh74t/29/
第二个选项是注册一个所谓的全局 bus
,它是一个空的 vue 实例,当您想要在非子-父组件之间进行通信时,您可以将其用于这种情况.小提琴 https://jsfiddle.net/bjqwh74t/30/
通常在父组件和子组件之间,您通过从子组件发出并在父组件中使用 v-on:event-name="handler"
直接使用事件,但对于具有更多级别的情况在组件之间使用第二种方法.
第一种情况的文档链接:https://vuejs.org/v2/guide/components.html#Using-v-on-with-Custom-Events
第二种情况的文档链接:https://vuejs.org/v2/guide/components.html#Non-Parent-Child-Communication
PS:更喜欢使用 kebab-case 作为事件名称,这意味着您使用 -
而不是大写字母.使用大写字母书写可能会导致您的事件未在根中捕获的奇怪情况.
I have my vue application using:
component-parent component that is made of component-child
inside component-parent I have buttons, when someone click a button I want to emit an event in order to be handled by vue and passed to another component
What I did so far:
var vm = new Vue({
el: '#app',
methods: {
itemSelectedListener: function(item){
console.log('itemSelectedListener', item);
}
}
});
Vue.component('component-child', {
template: ' <span v-on:click="chooseItem(pty )" >Button </span>',
methods: {
chooseItem: function(pty){
console.log(pty);
this.$emit('itemSelected', {
'priority' : pty
});
}
}
});
Vue.component('component-parent', {
template: '<component-child v-for="q in items" ></component-child>'
});
HTML:
<component-parent v-on:itemSelected="itemSelectedListener" ></component-parent>
It reaches my console.log(pty);
line but it seems that this.$emit('itemSelected'
wont get through:
console.log('itemSelectedListener', item); // this is not going to be called...
an hint?
should I bubble up the event from child->parent->Vue-instance? ( I also tried that but with no success)
There is one issue with your component-parent
template as it tries to render multiple child components. Vue usually requires a single root div inside components therefore you need to wrap it in a div or other tag.
<div>
<component-child v-for="q in items"></component-child>
</div>
A second thing to point out is that you emit an event from a child component which is 2 levels down and you listen to it in the root.
Root //but you listen to the event up here 1 level above
Component 1 //you should listen to the event here
Component 2 //your try to emit it from here
You have 2 options here. Either emit from component-child
listen to that event in component-parent
then propagate that event upwards. Fiddle https://jsfiddle.net/bjqwh74t/29/
The second option would be to register a global so called bus
which is an empty vue instance that you can use for such cases when you want communication between non child-parent components. Fiddle https://jsfiddle.net/bjqwh74t/30/
Usually between parent and child components you use the events directly by emitting from child and listening in parent with v-on:event-name="handler"
but for cases where you have more levels between components you use the second approach.
Doc link for the first case: https://vuejs.org/v2/guide/components.html#Using-v-on-with-Custom-Events
Doc link for the second case: https://vuejs.org/v2/guide/components.html#Non-Parent-Child-Communication
PS: prefer using kebab-case for event names which means you write with -
instead of capital letters. Writing with capital letters can result in weird situations where your event is not caught in the root.
这篇关于如何使用 Vue js 2 在组件子组件链上冒泡事件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!