抛出一个事件来通知父组件做出改变
)v-on
或 @
来选择性地监听子组件上抛的事件
,就像监听原生 DOM 事件那样,当监听到子组件上抛出的事件时,就会执行对应事件绑定的监听函数
内置的 $emit 方法
,通过传入事件名称来抛出一个事件$event
作为事件参数emits 选项
来声明需要抛出的事件(emits声明选项不是必须的)
<template>
<div :style="{ fontSize: postFontSize + 'em' }">
<BlogPost
v-for="post in posts"
:key="post.id"
:title="post.title"
@enlarge-text="postFontSize += 0.1"/>
div>
template>
<script >
import BlogPost from './BlogPost.vue'
export default {
name: 'Blog',
components: {
BlogPost
},
data() {
return {
posts: [
{ id: 1, title: 'My journey with Vue' },
{ id: 2, title: 'Blogging with Vue' },
{ id: 3, title: 'Why Vue is so fun' }
],
postFontSize: 1
}
}
}
script>
<style lang="scss">style>
<template>
<div class="blog-post">
<h4>{{ title }}h4>
<button @click="$emit('enlarge-text')">Enlarge textbutton>
div>
template>
<script>
export default {
name: 'BlogPost',
props: ['title'],
// 这个emits声明选项不是必须的
emits: ['enlarge-text']
}
script>
<style lang="scss">style>
在组件的模板表达式中,可以直接使用 $emit 方法触发自定义事件
$emit() 方法在组件实例上也同样以 this.$emit() 的形式可用:
<templte>
<button @click="$emit('someEvent')">click mebutton>
template>
<script>
export default {
methods: {
submit() {
this.$emit('someEvent')
}
}
}
script>
父组件可以通过 v-on (缩写为 @) 来监听事件
组件的事件监听器也支持 .once 修饰符
- 触发事件时建议使用camelCase 形式
(驼峰命名,首字母小写),父组件监听是可以使用kebab-case 形式
(短横线分隔,推荐)
组件触发的事件没有冒泡机制,你只能监听直接子组件触发的事件
。
外部的事件总线
全局状态管理方案
。<MyComponent @some-event="callback" />
<MyComponent @some-event.once="callback" />
<template>
{{ count }}
<BlogPost @increase-by="(n) => count += n" />
<BlogPost @increase-by="increaseCount" />
template>
<script >
import BlogPost from './BlogPost.vue'
export default {
name: 'Blog',
components: {
BlogPost
},
data() {
return {
count: 0
}
},
methods: {
increaseCount(n,m,e) {
console.log(n,m,e); // 1, 2, PointerEvent {isTrusted: true, _vts: 1682821628803, pointerId: 1, width: 1, height: 1, …}
this.count += n
}
}
}
script>
<style lang="scss">style>
<template>
<div class="blog-post">
<button @click="$emit('increaseBy', 1, 2, $event)">
Increase by 1
button>
div>
template>
<script>
export default {
name: 'BlogPost',
}
script>
<style lang="scss">style>
<template>
<button v-on:click="$emit('doUpdate',$event,1,2)">触发doUpdate事件button> <br/>
<button v-on:click="$emit('refresh', {name:'zzhua',age:Math.floor(Math.random() * 20)})">触发refresh事件button>
子组件中person: {{ person }}<br/>
<button v-on:click.once="handleClick()">触发click事件button>
template>
<script lang="ts" setup>
import { ref,reactive,onUpdated } from 'vue'
/* 1. defineEmits() 宏不能在子函数中使用。它必须直接放置在