当前位置: 首页 > news >正文

Vue3.0组合式API:使用defineEmits()实现子组件向父组件传递数据

1、使用 defineEmits() 函数

父组件通过使用 Prop 为子组件传递数据,但如果子组件要把数据传递回去,就需要使用自定义事件来实现。父组件可以通过 v-on 指令(简写形式“@”)监听子组件实例的自定义事件,而子组件可以通过调用内建的 defineEmits() 函数并传入事件名称来触发自定义事件。

使用 <script setup> 语法糖,<script setup> 是在单文件组件 (SFC) 中使用组合式 API 的编译时语法糖。在 Vue3.2 中只需要在 script 标签上加上 setup 属性,无需 return,template 便可直接使用。相比于普通的 <script> 语法,它具有更多优势。

Vue3.0组合式API,组件之间的数据传递:

父传子:使用 defineProps() 函数。

子传父:使用 defineEmits()​ 函数。

为了在声明 props 和 emits 选项时获得完整的类型推导支持,我们可以使用 defineProps() 函数  和 defineEmits() 函数 API,它们将自动地在 <script setup> 中可用:

<script setup>
//父传子
const props = defineProps({foo: String
})//子传父
const emit = defineEmits(['change', 'delete'])
// setup 代码
</script>
  1. defineProps() 函数 和 defineEmits() 函数 都是只能在 <script setup> 中使用的编译器宏。他们不需要导入,且会随着 <script setup> 的处理过程一同被编译掉。
  2. defineProps() 函数 接收与 props 选项相同的值,defineEmits() 函数 接收与 emits 选项相同的值。
  3. defineProps() 函数 和 defineEmits() 函数 在选项传入后,会提供恰当的类型推导。
  4. 传入到 defineProps() 函数 和 defineEmits() 函数 的选项会从 setup 中提升到模块的作用域。因此,传入的选项不能引用在 setup 作用域中声明的局部变量。这样做会引起编译错误。但是,它可以引用导入的绑定,因为它们也在模块作用域内。

defineEmits()​ 函数的语法格式如下:

defineEmits( eventName, […args] )

参数说明:

eventName:传入事件的名称。

 […args]:触发事件传递的参数,该参数是非必选。

【实例】在 <script setup> 语法糖中,使用 defineEmits() 函数,实现子组件向父组件传递数据。

(1)创建 ParentComponent.vue 父组件

<template><fieldset><legend>父组件</legend><h3>父组件接收到子组件传递的数据:</h3><p>博客信息:{{ blogInfo.blogName }}</p><p>博客信息:{{ blogInfo.blogUrl }}</p><!-- 使用组件 --><ChildComponent @receiverData="getBlogInfo" /></fieldset>
</template><!-- 使用 <script setup> 语法糖 -->
<script setup>
import { reactive } from 'vue';//导入组件:使用 <script setup> 语法糖,导入的组件会自动执行注册
import ChildComponent from '@/components/ChildComponent.vue'// 使用 reactive 创建响应式的对象
const blogInfo = reactive({});// 核心代码:接收子组件传递数据的方法
function getBlogInfo(blogName, blogUrl) {blogInfo.blogName = blogName;blogInfo.blogUrl = blogUrl;
}</script>

(2)创建 ChildComponent.vue 子组件

<template><fieldset><legend>子组件</legend><button @click="sendData">传递数据给父组件</button></fieldset>
</template><!-- 使用 <script setup> 语法糖 -->
<script setup>
import { reactive } from 'vue';// 使用 reactive 创建响应式的对象
const blogInfo = reactive({blogName: '您好,欢迎访问 pan_junbiao的博客',blogUrl: 'https://blog.csdn.net/pan_junbiao'
});//核心代码
const emit = defineEmits(['receiverData']);function sendData() {//核心代码:触发自定义事件,传递数据个父组件emit('receiverData', blogInfo.blogName, blogInfo.blogUrl);
}</script>

 (3)在 App.vue 根组件中,引入父组件

<template><!-- 使用组件 --><ParentComponent />
</template><script setup>
//导入组件:使用 <script setup> 语法糖,导入的组件会自动执行注册
import ParentComponent from '@/components/ParentComponent.vue';</script>

执行结果:

2、组件事件配合 v-model 指令

如果是在子组件中用户输入数据,我们希望在获取数据的同时发生数据给父组件,这是可以配合 v-model 指令使用。

【实例】子组件中用户输入数据,在父组件中实时获取数据。

(1)修改 ParentComponent.vue 父组件

<template><fieldset><legend>父组件</legend><!-- 使用组件 --><ChildComponent @searchEvent="getSearch" /><h3>父组件接收到子组件传递的数据:</h3>接收到的搜索关键字:<input type="text" v-model="search" /></fieldset>
</template><!-- 使用 <script setup> 语法糖 -->
<script setup>
import { ref } from 'vue';//导入组件:使用 <script setup> 语法糖,导入的组件会自动执行注册
import ChildComponent from '@/components/ChildComponent.vue'// 使用 ref 创建响应式的对象
const search = ref('');// 核心代码:接收子组件传递数据的方法
function getSearch(keyword) {search.value = keyword;
}</script><style>
input {width: 300px;padding: 3px;font-size: 16px;
}
</style>

(2)修改 ChildComponent.vue 子组件

<template><fieldset><legend>子组件</legend>搜索:<input type="text" v-model="search" /></fieldset>
</template><!-- 使用 <script setup> 语法糖 -->
<script setup>
import { ref, watch } from 'vue';// 使用 ref 创建响应式的对象
const search = ref('');//核心代码
const emit = defineEmits(['searchEvent']);//watch监听器
watch(search, (newValue, oldValue) => {//核心代码:触发自定义事件,传递数据个父组件emit('searchEvent', newValue);
});</script>

执行结果:


http://www.mrgr.cn/news/30165.html

相关文章:

  • 【论文笔记】Wings: Learning Multimodal LLMs without Text-only Forgetting
  • Python 基础语法 二维列表
  • 游戏开发--C#面试题
  • 【SpringMVC】记录一次Bug——mvc:resources设置静态资源不过滤导致WEB-INF下的资源无法访问
  • 启动软件是用例吗
  • 单臂路由技术,eNSP实验讲解
  • 【Vue】VueRouter路由
  • Docker本地部署Chatbot Ollama搭建AI聊天机器人并实现远程交互
  • 学习Stable Diffusion使用 Roop插件轻松换脸(附插件)
  • 数据结构(十四)——HashMap与HashSet(OJ题)
  • G - Merchant Takahashi
  • 自动泊车系统中的YOLOv8 pose关键点车位线检测
  • 如何预防云服务器被勒索攻击
  • Unity教程(十五)敌人战斗状态的实现
  • vulnhub(10):W34KN3SS(很小的信息都不能放过)
  • 波分技术基础 -- WDM/OTN介绍
  • Java中线程的状态
  • 【深度学习】(2)--PyTorch框架认识
  • 电池曲线测试(TODO)
  • 两个字符串的最长公共子序列(Longest Common Subsequence, LCS)、荷兰国旗问题、合并两个有序数组、约瑟夫环
  • 【TabBar嵌套Navigation案例-关于页面 Objective-C语言】
  • 便捷数据检索与下载,拟合曲线预测趋势 轻松管理多个项目,实现在线监测
  • 生成式AI:ChatGPT及其在各行业的应用前景
  • aperiodic CSI-RS for tracking for fast SCell activation
  • ERP顾问退休?不存在的!
  • Flink 与 Kubernetes (K8s)、YARN 和 Mesos集成对比