概述
We have already seen that props are used to pass data from a parent component to a child component. To pass data from a child component back to a parent component, Vue offers custom events.
我们已经看到,道具用于将数据从父组件传递到子组件。为了将数据从子组件传递回父组件,Vue 提供了自定义事件。
In a component, we can emit an event using the e m i t m e t h o d ; w i t h t h i s . emit method; with this. emitmethod;withthis.emit('eventName', payload) within <script>
; or just with $emit within the template section.
在组件中,我们可以使用 e m i t 方法、在 ' < s c r i p t > ' 中使用 t h i s . emit 方法、在 `<script>` 中使用 this. emit方法、在'<script>'中使用this.emit('eventName', payload) 或在模板部分使用 $emit 来发射事件。
Assuming we have got a reactive instance property, this.message, we could emit a send event with the message value in the script section using this.$emit. This could be the basis for a MessageEditor component:
假设我们已经有了一个反应式实例属性 this.message,我们就可以在脚本部分使用 this.$emit 发送一个带有消息值的发送事件。这可以作为 MessageEditor 组件的基础:
html
<script>
export default {
data () {
return {
message: null
}
},
methods: {
send() {
this.$emit('send', this.message);
}
}
}
</script>
In the same scenario, we could trigger a send event from the template section as follows:
在同样的情况下,我们可以从模板部分触发发送事件,如下所示:
html
<template>
<div>
<input v-model="message" />
<button @click="$emit('send', message)">Emit inline</button>
</div>
</template>
From a parent component, we can use v-on:event-name or the shorthand @event-name. event-name must match the name passed to $emit. Note eventName and event-name are not equivalent.
在父组件中,我们可以使用 v-on:event-name 或快捷方式 @event-name。event-name 必须与传递给 $emit 的名称一致。请注意,eventName 和 event-name 并不等同。
For instance, in the parent component we want to listen to the send event and modify some data accordingly. We bind @send with some event handler logic, which can be a JavaScript expression or a method declared using methods.
例如,在父组件中,我们要监听发送事件并相应地修改一些数据。我们将 @send 与一些事件处理逻辑绑定,这些逻辑可以是 JavaScript 表达式,也可以是使用 methods 声明的方法。
Vue will trigger this event handler and pass the event's payload object to it when applicable. You can use $event in the JavaScript expression of the template as the payload, as shown in the following example of the template section in App:
Vue 将触发该事件处理程序,并在适用时将事件的有效载荷对象传递给它。您可以在模板的 JavaScript 表达式中使用 $event 作为有效载荷,如以下 App.Vue 中模板部分的示例所示:
html
<template>
<div id="app">
<p>Message: {{ parentMessage }}</p>
<MessageEditor @send="parentMessage = $event" />
<button @click="parentMessage = null">Reset</button>
</div>
</template>
We can also extract the JavaScript expression to a component's updateParentMessage method and bind it as follows:
我们还可以将 JavaScript 表达式提取到组件的 updateParentMessage 方法中,并将其绑定如下:
html
<template>
<div id="app">
<p>Message: {{ parentMessage }}</p>
<MessageEditor @send="updateParentMessage" />
<button @click="parentMessage = null">Reset</button>
</div>
</template>
<script>
import MessageEditor from './components/MessageEditor.vue'
export default {
components: {
MessageEditor
},
data() {
return {
parentMessage: null
}
},
methods: {
updateParentMessage(newMessage) {
this.parentMessage = newMessage
}
}
}
</script>
Custom events support passing any JavaScript type as the payload. The event name, however, must be a String.
自定义事件支持传递任何 JavaScript 类型作为有效载荷。不过,事件名称必须是字符串。
在setup中使用事件
If you use <script setup>
, since there is no component's options object, we can't define custom events using the emits field. Instead, we use the defineEmits() function from the vue package and pass all the relevant events' definitions to it.
如果使用 <script setup>
,由于没有组件的选项对象,我们就无法使用 emits 字段定义自定义事件。相反,我们可以使用 vue 软件包中的 defineEmits() 函数,并将所有相关事件的定义传递给它。
For example, in the MessageEditor component, we can rewrite the event-registering functionality with defineEmits() as follows:
例如,在 MessageEditor 组件中,我们可以使用 defineEmits() 重写事件注册功能如下:
html
<template>
<div>
<input v-model="message"/>
<!--点击的适合,手动传递值-->
<button @click="$emit('send', message)">Emit inline</button>
</div>
</template>
<script setup>
import {defineEmits, ref} from 'vue'
const message = ref(null)
// 定义事件
const emits = defineEmits(['send'])
// 通过事件向父组件传递值
emits('send', message.value);
</script>
defineEmits() returns a function that we can trigger in the same concept with this.$emits. We will certainly need to use ref() to declare a reactive data message for this component, the usage.
defineEmits()会返回一个函数,我们可以用与 this.$emits 相同的概念来触发它。我们肯定需要使用 ref() 来为该组件声明反应式数据消息。