17 Vue3中的emit传值

概述

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() 来为该组件声明反应式数据消息。

相关推荐
zhanghaisong_20151 分钟前
Caused by: org.attoparser.ParseException:
前端·javascript·html·thymeleaf
Eric_见嘉4 分钟前
真的能无限试(白)用(嫖)cursor 吗?
前端·visual studio code
DK七七34 分钟前
多端校园圈子论坛小程序,多个学校同时代理,校园小程序分展示后台管理源码
开发语言·前端·微信小程序·小程序·php
老赵的博客1 小时前
QSS 设置bug
前端·bug·音视频
Chikaoya1 小时前
项目中用户数据获取遇到bug
前端·typescript·vue·bug
南城夏季1 小时前
蓝领招聘二期笔记
前端·javascript·笔记
Huazie1 小时前
来花个几分钟,轻松掌握 Hexo Diversity 主题配置内容
前端·javascript·hexo
NoloveisGod1 小时前
Vue的基础使用
前端·javascript·vue.js
GISer_Jing1 小时前
前端系统设计面试题(二)Javascript\Vue
前端·javascript·vue.js
海上彼尚2 小时前
实现3D热力图
前端·javascript·3d