Vue3——父子组件通信

news2025/5/18 22:35:12

    在Vue开发中,组件通信是核心概念之一。良好的组件通信机制能让我们的应用更加清晰、可维护。

父传子defineProps

    defineProps是一个编译时宏,仅在内部可用,不需要显式导入。声明的 props 会自动暴露给模板。 还返回一个对象,其中包含传递给组件的所有 props,以便我们可以根据需要在 JavaScript 中访问它们:<script setup>defineProps(在一个组件中仅可使用一次)

    在使用前先准备两个父子关系的组件:

<script setup>
import Son from './components/Son.vue';
</script>

<template>
  <div>
    我是父组件App.vue
    <Son></Son>
  </div>
</template>

<style scoped></style>
<script setup>

</script>

<template>
  <div>
    我是子组件Son.app
  </div>
</template>

<style scoped></style>

当前的效果为:

     想要实现父传子的效果,首先要在父组件中定义好数据,在子组件的标签中通过绑定自定义属性的方式,给定一个值;在子组件中使用defineProps函数接收,这其中有很多种情况。

    defineProps()内可使用数组语法或对象语法接收:

数组语法:

  • 使用中括号接收[]
  • 仅声明传递数据的名称,不需要指定类型或其他配置

对象语法:

  • 使用大括号接收{}
  • 需指定传递类型,可指定是否必填,默认值,自定义校验函数等。

注:父组件的中的子标签自定义属性必须与defineProps接收的名称保持一致,或者父组件中使用HTML特性规范,子组件中使用小驼峰命规范 


传递静态数据

数组接收

<script setup>
import Son from './components/Son.vue';
</script>

<template>
  <div>
    我是父组件App.vue
    <Son :props-a="666"></Son>
  </div>
</template>

<style scoped></style>

使用时可直接使用{{propsA}}或{{b.propsA}} 

<script setup>
const b = defineProps(["propsA"])
</script>

<template>
  <div>
    父组件传的值为--{{ b.propsA }}
  </div>
</template>

<style scoped></style>
<script setup>
const b = defineProps(["propsA"])
</script>

<template>
  <div>
    父组件传的值为--{{ propsA }}
  </div>
</template>

<style scoped></style>

<script setup>
import Son from './components/Son.vue';
</script>

<template>
  <div>
    我是父组件App.vue
    <Son :props-a="666" :props-num="'Stringa'"></Son>
  </div>
</template>

<style scoped></style>
<script setup>
const b = defineProps(["propsA","propsNum"])
</script>

<template>
  <div>
    父组件传的值为--{{ propsA }}{{ b.propsNum }}
  </div>
</template>

<style scoped></style>

 对象接收

<script setup>
const b = defineProps({"propsA":Number,"propsNum":String})
</script>

<template>
  <div>
    父组件传的值为--{{ propsA }}{{ b.propsNum }}
  </div>
</template>

<style scoped></style>

传递对象数据

一般情况下传递的值都是响应式的:

<script setup>
import Son from './components/Son.vue';
import { ref } from 'vue';

const str = ref("AppString")
const obj = ref({
  msg:"ObjectMsg",
  massage:"ObjMassage"
})
</script>

<template>
  <div>
    我是父组件App.vue
    <Son :props-a="str" :props-num="obj"></Son>
  </div>
</template>

<style scoped></style>

数组接收

<script setup>
const b = defineProps(["propsA","propsNum"])
</script>

<template>
  <div>
    父组件传的值为--{{ propsA }}{{ b.propsNum }}
  </div>
</template>

<style scoped></style>

这里可以直接使用b.propsNum.msg,不需要.value(在script也是一样),因为父组件在传递整个ref对象时会自动解包,传递ref对象的某个属性时也一样:

<script setup>
const b = defineProps(["propsA","propsNum"])
console.log(b.propsNum);


</script>

<template>
  <div>
    父组件传的值为--{{ propsA }}-{{ b.propsNum }}
  </div>
</template>

<style scoped></style>

对象接收 

使用对象接收时要理清楚接收的类型,传递对象时可直接使用一个大括号

<script setup>
const b = defineProps({
  "propsA":String ,
  "propsNum":{
  }
})


</script>

<template>
  <div>
    父组件传的值为--{{ propsA }}-{{ b.propsNum }}
  </div>
</template>

<style scoped></style>

 不过应该指定其它的类型Object:

<script setup>
const b = defineProps({
  "propsA":String ,
  "propsNum":Object
})


</script>

<template>
  <div>
    父组件传的值为--{{ propsA }}-{{ b.propsNum }}
  </div>
</template>

<style scoped></style>

 

注意:如果父组件直接传递一个响应式数据,那么子组件可以直接修改父组件的值。

<script setup>
import Son from './components/Son.vue';
import { ref } from 'vue';

const str = ref("AppString")
const obj = ref({
  msg:"ObjectMsg",
  massage:"ObjMassage",
  num:88
})
</script>

<template>
  <div>
    我是父组件App.vue{{ obj.msg }}
    <Son :props-a="str" :props-num="obj"></Son>
  </div>
</template>

<style scoped></style>
<script setup>
const b = defineProps({
  "propsA":String ,
  "propsNum":Object
})
const ad =()=>{
  b.propsNum.msg = "ooooo"
}

</script>

<template>
  <div>
    父组件传的值为--{{ propsA }}-{{ b.propsNum.msg }}
    <button @click="ad">修改值</button>
  </div>
</template>

<style scoped></style>

此时点击修改值,会直接修改父组件中的值:

如果传递的是响应式对象的属性,则子组件不能修改其值。

 

 props 展开

    当父组件向子组件传递数据时,如果直接使用 v-bind="object" 而不指定具体属性名,这称为 "props 展开" 或 "对象绑定"。这种方式会将对象的所有属性自动展开为单独的 props。

注:在子组件接收时,属性名和父组件中的属性值要一致

<script setup>
import Son from './components/Son.vue';
import { ref } from 'vue';

const obj = ref({
  msg:"ObjectMsg",
  massage:"ObjMassage",
  num:88
})
</script>

<template>
  <div>
    我是父组件App.vue{{ obj.msg }}
    <Son :="obj"></Son>
  </div>
</template>

<style scoped></style>
<script setup>
const b = defineProps({
  msg:String,
  massage:String,
  num:Number
})

</script>

<template>
  <div>
    父组件传的值为--{{b.msg}}
  </div>
</template>

<style scoped></style>

 在子组件中接收时缺少属性时不会报错,添加属性时,可以使用default给它默认值:

<script setup>
const b = defineProps({
  msg:String,
  massage:String,
  num:Number,
  aa:{
    type:Number,
    required:true,
    default:200
  }
})

</script>

<template>
  <div>
    父组件传的值为--{{b.msg}}{{ b.aa }}
  </div>
</template>

<style scoped></style>

子传父defineEmits

defineEmits 用于声明组件可以触发的自定义事件(子组件向父组件通信)

使用步骤:

  1. 用defineEmits定义事件名,得到emits对象
  2. 用emits函数指定事件名,并传递数据
  3. 父组件接收时,在子组件标签中触发子组件定义的事件,触发的函数的参数就是传递过来的值

<script setup>
import { reactive } from 'vue';
const emit = defineEmits(['e_app'])

const data = reactive({
  msg:""
})

const btn = ()=>{
  emit('e_app',data)
}
</script>

<template>
  <div>
    <input type="text" v-model="data.msg">
    <button @click="btn">提交给父组件</button>
  </div>
</template>

<style scoped></style>
<script setup>
import Son from './components/Son.vue';
import { ref } from 'vue';

const app =(data) =>{
  console.log(data.msg);
  massage.value = data.msg
}

const massage = ref("")
</script>

<template>
  <div>
    我是父组件
    {{ massage }}
    <Son @e_app="app"></Son>
  </div>
</template>

<style scoped></style>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2378826.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

游戏引擎学习第276天:调整身体动画

运行游戏&#xff0c;演示我们遇到的拉伸问题&#xff0c;看起来不太好&#xff0c;并考虑切换到更顶视角的视角 我们开始讨论游戏开发中的一些美学决策&#xff0c;特别是在处理动画方面。虽然我们是游戏程序员&#xff0c;通常不负责设计或艺术部分&#xff0c;但因为这是一…

从开发者角度看数据库架构进化史:JDBC - 中间件 - TiDB

作者&#xff1a; Lucien-卢西恩 原文来源&#xff1a; https://tidb.net/blog/e7034d1b Java 应用开发技术发展历程 在业务开发早期&#xff0c;用 Java 借助 JDBC 进行数据库操作&#xff0c;虽能实现基本交互&#xff0c;但需手动管理连接、编写大量 SQL 及处理结果集&a…

Mipsel固件Fuzzing小记

Mipsel固件Fuzzing小记 0x01 准备 1.1 安装必要工具链 首先需要安装 MIPS 交叉编译工具链和相关依赖&#xff1a; sudo apt-get install -y gcc-mipsel-linux-gnu g-mipsel-linux-gnu binwalk qemu-user-static afl这些工具分别用于&#xff1a;交叉编译、固件解包、二进制…

本土DevOps革命:Gitee如何撬动中国企业的数字化转型新动能

在数字化浪潮席卷全球的背景下&#xff0c;中国企业正面临前所未有的转型压力与机遇。随着《数据安全法》和《个人信息保护法》的全面实施&#xff0c;以及信创产业政策的深入推进&#xff0c;研发工具链的自主可控已成为关乎企业核心竞争力的战略命题。在这一关键赛道上&#…

强化学习入门:马尔科夫奖励过程二

文章目录 前言1、动作2、策略总结 前言 最近想开一个关于强化学习专栏&#xff0c;因为DeepSeek-R1很火&#xff0c;但本人对于LLM连门都没入。因此&#xff0c;只是记录一些类似的读书笔记&#xff0c;内容不深&#xff0c;大多数只是一些概念的东西&#xff0c;数学公式也不会…

JVM 双亲委派机制

一、从 JDK 到 JVM&#xff1a;Java 运行环境的基石 在 Java 开发领域&#xff0c;JDK&#xff08;Java Development Kit&#xff09;是开发者的核心工具包。它不仅包含了编译 Java 代码的工具&#xff08;如 javac&#xff09;&#xff0c;还内置了 JRE&#xff08;Java Run…

uniapp -- uCharts 仪表盘刻度显示 0.9999999 这样的值问题处理。

文章目录 🍉问题🍉解决方案🍉问题 在仪表盘上,23.8变成了 23.799999999999997 🍉解决方案 formatter格式化问题 1:在 config-ucharts.js 或 config-echarts.js 配置对应的 formatter 方法 formatter: {yAxisDemo1: function (

BGP团体属性

团体属性&#xff1a; 1、用于限制BGP路由的传递范围 2、类似于IGP协议中的tag值&#xff0c;用于对BGP路由实现标记。 团体属性的分类&#xff1a; 1、公共团体属性&#xff1a; Internet&#xff1a;默认所有路由都有该属性&#xff0c;具有该属性BGP路由发送给所有的BGP邻居…

Redis——三大策略

过期删除策略 Redis可以对key设置过期时间&#xff0c;因此需要有相应的机制将已过期的键值对删除 设置了过期时间的key会存放在过期字典中&#xff0c;可以用presist命令取消key过期时间 过期字典存储在redisDb结构中&#xff1a; typedef struct redisDb {dict *dict; …

Windows 操作系统使用 Tcping 命令检查目标主机端口是否开放

检查目标主机端口是否开放的方法已经很多了&#xff0c;网络上也有第三方网页版的检查工具&#xff0c;这篇文章给大家介绍一个实用小工具 Tcping 。 一、下载安装 Tcping 命令 Tcping 非 Windows 自带命令&#xff0c;我们需要下载 Tcping 可执行文件&#xff0c;然后将该文…

开源RTOS(实时操作系统):nuttx 编译

开源RTOS&#xff08;实时操作系统&#xff09;&#xff1a;nuttx 编译 手册&#xff1a;Installing — NuttX latest documentation 源码&#xff1a;GitHub - apache/nuttx: Apache NuttX is a mature, real-time embedded operating system (RTOS) Installing The fir…

python打包exe报错:处理文件时错误:Excel xlsx file; not supported

背景&#xff1a;最近用python写一个excel解析工具&#xff0c;然后打包成exe可执行文件的时候&#xff0c;遇到这样的问题 1.在我自己编译器运行是可以正常将上传后的excel进行解析&#xff0c;但是在打包成exe后&#xff0c;就无法正常解析excel 问题排查&#xff1a; 1.切换…

VUE3 -综合实践(Mock+Axios+ElementPlus)

目录 前言 目标 1.工程创建 2.Mock 2.1 配置Mock 扩 展 2.2 定义模拟数据 2.3 创建Mock服务器 3.导入ElementPlus 4.表格页面搭建 5.动态路由跳转 6.详情页面的制作 前言 基于前文 VUE3详细入门&#xff0c;我们对VUE3的基本使用有了初步的了解&#xff0c;下…

NDS3211HV单路H.264/HEVC/HD视频编码器

1产品概述 NDS3211HV单路高清编码器是一款功能强大的音/视频编码设备&#xff0c;支持2组立体声&#xff0c;同时还支持CC(CVBS)字幕。支持多种音频编码方式。该设备配备了多种音/视频输入接口&#xff1a;HD-SDI数字视频输入、HDMI高清输入&#xff08;支持CC&#xff09;、A…

LeetCode热题100--206.反转链表--简单

1. 题目 给你单链表的头节点 head &#xff0c;请你反转链表&#xff0c;并返回反转后的链表。 示例 1&#xff1a; 输入&#xff1a;head [1,2,3,4,5] 输出&#xff1a;[5,4,3,2,1] 示例 2&#xff1a; 输入&#xff1a;head [1,2] 输出&#xff1a;[2,1] 示例 3&…

来一个复古的技术FTP

背景 10年前的老代码&#xff0c;需要升级springboot框架&#xff0c;在升级过程中&#xff0c;测试业务流程里&#xff0c;有FTP的下载业务&#xff0c;不管测试环境如何测试&#xff0c;都没有成功&#xff0c;最后只能自己搭建一个FTP服务器&#xff0c;写一个ftp-demo来测试…

OpenWebUI新突破,MCPO框架解锁MCP工具新玩法

大家好&#xff0c;Open WebUI 迎来重要更新&#xff0c;现已正式支持 MCP 工具服务器&#xff0c;但 MCP 工具服务器需由兼容 OpenAPI 的代理作为前端。mcpo 是一款实用代理&#xff0c;经测试&#xff0c;它能让开发者使用 MCP 服务器命令和标准 OpenAPI 服务器工具&#xff…

TRTC实时对话式AI解决方案,助力人机语音交互极致体验

近年来&#xff0c;AI热度持续攀升&#xff0c;无论是融资规模还是用户热度都大幅增长。2023 年&#xff0c;中国 AI 行业融资规模达2631亿人民币&#xff0c;较2022年上升51%&#xff1b;2024年第二季度&#xff0c;全球 AI 初创企业融资规模为 240 亿美金&#xff0c;较第一季…

Linux安全篇 --firewalld

一、Firewalld 防火墙概述 1、Firewalld 简介 firewalld 的作用是为包过滤机制提供匹配规则(或称为策略)&#xff0c;通过各种不同的规则告诉netfilter 对来自指定源、前往指定目的或具有某些协议特征的数据包采取何种处理方式为了更加方便地组织和管理防火墙,firewalld 提供…

系分论文《论系统需求分析方法及应用》

系统分析师论文范文系列 【摘要】 2022年6月&#xff0c;我作为系统分析师参与了某金融机构“智能信贷风控系统”的建设项目。该系统旨在通过对业务流程的数字化重构&#xff0c;优化信贷审批效率并降低风险。项目涉及信贷申请、资质审核、风险评估、额度审批等核心流程&#x…