$emit an event from child to parent in vue.js, es6 语法
Posted
技术标签:
【中文标题】$emit an event from child to parent in vue.js, es6 语法【英文标题】:$emit an event from child to parent in vue.js, es6 syntax 【发布时间】:2017-03-11 02:00:41 【问题描述】:我是 Vue.js 的新手,我使用 ES6 语法和 vue-class-component
。我在尝试从孩子向其父母发出事件时遇到问题。
我遵循了默认 Vue.js 语法的逻辑,但我的父母似乎无法捕捉到孩子发出的事件。代码:
子组件
我在每个<li>
上附加了一个单击事件侦听器,它调用了一个发出事件的函数。事件监听器是在父级上定义的。
export default class HorizontalNavigation
handleClick (e)
e.preventDefault();
// console.log(e.target.dataset.section);
this.$emit('ChangeView', e.target.dataset.section);
render (h)
return (
<div class= style.horizontalNavigation >
<div class='sections-wrapper'>
<div class= style.sections >
<ol>
<li><a on-click= this.handleClick href='#1' data-section='1' class='selected'>We are</a></li>
<li><a on-click= this.handleClick href='#2' data-section='2'>Services</a></li>
<li><a on-click= this.handleClick href='#3' data-section='3'>Cases</a></li>
<li><a on-click= this.handleClick href='#4' data-section='4'>Studio</a></li>
<li><a on-click= this.handleClick href='#5' data-section='5'>Career</a></li>
<li><a on-click= this.handleClick href='#6' data-section='6'>Contact</a></li>
</ol>
<span class='filling-line' aria-hidden='true'></span>
</div>
</div>
</div>
);
父组件
export default class ViewsContainer
ChangeView (data)
console.log(data);
render (h)
return (
<div class= style.restrictOverflow >
<HorizontalNavigation />
<main class= style.viewsContainer on-ChangeView= this.ChangeView >
<SingleView dataSection='weare' id='1' class='selected' />
<SingleView dataSection='services' id='2' />
<SingleView dataSection='cases' id='3' />
<SingleView dataSection='studio' id='4' />
<SingleView dataSection='career' id='5' />
<SingleView dataSection='contact' id='6' />
</main>
</div>
);
按照 vue.js 语法,我应该能够通过从元素发出事件来监听来自父级的子事件,但父级似乎没有捕获该事件。
我哪里错了?
【问题讨论】:
【参考方案1】:您需要在要接收$emit
的视图模型上使用$emit
,使用bus
或使用https://vuex.vuejs.org/。
直接发送给父级
最简单的方法,就是简单的$emit
从子组件直接到父组件:
this.$parent.$emit('ChangeView', e.target.dataset.section);
这是好的,但是如果您有一个长链组件,您需要将$emit
连接到链中的每个$parent
。
通过事件总线发射
您可以使用 Vue 非常简单地创建全局事件总线。您在主组件中创建一个 Vue 实例,然后应用程序中的所有其他组件可以emit
向它发送事件,并使用on
对这些事件做出反应。
var bus = new Vue();
var vm = new Vue(
methods:
changeView()
bus.$emit('ChangeView', e.target.dataset.section);
);
也可以发送到$root
,但不建议这样做。但是,如果您的 app
确实变得非常复杂,您可能需要考虑使用 Vues 自己的状态管理系统 vuex。
监听事件
您可以使用$on
在视图模型中侦听$emit
并侦听特定事件:
var vm = new Vue(
created()
this.$on('ChangeView', section =>
console.log(section);
);
);
如果您使用的是总线,这也类似,但您只需引用总线:
bus.$on('ChangeView', ...);
您也可以使用v-on
直接在您的html中使用它:
<div v-on:ChangeView="doSomething"></div>
【讨论】:
谢谢克雷格!但是你怎么听父母的,我什么都听不懂…… 非常感谢克雷格!我也犯了一个错误,将 on-ChangeView 侦听器放在父级而不是实例本身上。所以解决我的问题的方法是:ChangeView
是什么?
这是救生员。感谢您的信息。【参考方案2】:
在 Vue 中,您可以通过发出事件从子组件到父组件进行通信。 子组件 “发出”一个带有 $emit
和 父组件 “监听”的事件 像这样:
子组件:
<template>
<div>
<button @click="this.handleClick">Click me!</button>
</div>
</template>
<script>
export default
name: "BaseButton",
methods:
handleClick: function()
this.$emit("clickFromChildComponent");
;
</script>
<style scoped>
</style>
父组件:
<template>
<div class="home">
<h1>Passing a event from child up to parent!</h1>
<BaseButton @clickFromChildComponent="handleClickInParent"/>
</div>
</template>
<script>
import BaseButton from "./BaseButton";
export default
components:
BaseButton
,
name: "Home",
methods:
handleClickInParent: function()
alert('Event accessed from parent!');
;
</script>
<style scoped>
</style>
您可以找到一个工作示例代码实现 here并在您自己的上下文中使用它。
【讨论】:
【参考方案3】:除非我遗漏了某些东西(很可能),否则在像这样的简单示例中,您只需要在组件中侦听 emit
ted 事件即可。例如,在您的父元素中,您将拥有:
<HorizontalNavigation v-on:ChangeView=this.ChangeView />
然后在您的子 (HorizontalNavigation
) 组件中,您将 emit
'ChangeView' 事件:
this.$emit('ChangeView', e.target.dataset.section);
根据您对@craig_h 的回答所做的评论,我自己在类似的代码中尝试了这个,这正是我所需要的。我不需要 emit
给父母,也不需要使用公共汽车或 vuex。
【讨论】:
花括号在我的代码中产生问题。如果你最终在这里寻找 Vue 3 脚本设置
使用defineEmits 声明发射然后使用返回的函数发射是一种很好的可读性做法
子组件:
<template>
<div>
<button @click="handleClick">Increment</button>
</div>
</template>
<script setup>
const emit = defineEmits(['custom'])
const handleClick = () =>
emit('custom')
</script>
父组件:
<template>
<h1> counter </h1>
<Button @custom="handleCustom"/>
</template>
<script setup>
import ref from 'vue'
import Button from './components/Button.vue'
const counter = ref(0)
const handleCustom = () =>
counter.value++
</script>
Here is 工作实现
【讨论】:
以上是关于$emit an event from child to parent in vue.js, es6 语法的主要内容,如果未能解决你的问题,请参考以下文章
$emit,$broadcast,$on用法,来源于http://www.tuicool.com/articles/qIBNve
How to Distinguish a Physical Disk Device from an Event Message