Vue 3 组件通信教程

Vue 3 组件通信教程

1. Props 父传子

1.1 基础用法

在 Vue 3 中,我们使用 defineProps 来声明组件的 props:

<!-- 子组件 ChildComponent.vue -->
<script setup>
const props = defineProps({message: String,count: {type: Number,required: true,default: 0},items: {type: Array,default: () => []}
})
</script><template><div><p>{{ message }}</p><p>Count: {{ count }}</p></div>
</template>

父组件中使用:

<!-- 父组件 ParentComponent.vue -->
<script setup>
import { ref } from 'vue'
import ChildComponent from './ChildComponent.vue'const parentMessage = ref('Hello from parent')
const parentCount = ref(42)
</script><template><ChildComponent :message="parentMessage":count="parentCount"/>
</template>

1.2 Props 验证

Props 可以设置详细的验证规则:

<script setup>
const props = defineProps({// 基础类型检查propA: Number,// 多种类型propB: [String, Number],// 必填字段propC: {type: String,required: true},// 带有默认值propD: {type: Number,default: 100},// 带有默认值的对象propE: {type: Object,default: () => ({ message: 'hello' })},// 自定义验证函数propF: {validator(value) {return ['success', 'warning', 'danger'].includes(value)}}
})
</script>

2. Emits 子传父

2.1 基础用法

使用 defineEmits 声明事件:

<!-- 子组件 ChildComponent.vue -->
<script setup>
const emit = defineEmits(['update', 'delete'])const handleClick = () => {emit('update', { id: 1, data: 'new value' })
}
</script><template><button @click="handleClick">更新数据</button>
</template>

父组件中接收事件:

<!-- 父组件 ParentComponent.vue -->
<script setup>
import ChildComponent from './ChildComponent.vue'const handleUpdate = (payload) => {console.log('收到更新:', payload)
}
</script><template><ChildComponent @update="handleUpdate" />
</template>

2.2 带验证的 Emits

<script setup>
const emit = defineEmits({// 不带验证函数click: null,// 带验证函数submit: (payload) => {if (!payload.email) {return false}return true}
})
</script>

3. v-model 双向绑定

3.1 基础用法

<!-- 子组件 CustomInput.vue -->
<script setup>
defineProps(['modelValue'])
const emit = defineEmits(['update:modelValue'])
</script><template><input:value="modelValue"@input="emit('update:modelValue', $event.target.value)"/>
</template>

父组件中使用:

<script setup>
import { ref } from 'vue'
import CustomInput from './CustomInput.vue'const text = ref('')
</script><template><CustomInput v-model="text" /><p>输入的内容:{{ text }}</p>
</template>

3.2 多个 v-model 绑定

<!-- 子组件 UserForm.vue -->
<script setup>
defineProps(['firstName', 'lastName'])
const emit = defineEmits(['update:firstName', 'update:lastName'])
</script><template><input:value="firstName"@input="emit('update:firstName', $event.target.value)"/><input:value="lastName"@input="emit('update:lastName', $event.target.value)"/>
</template>

父组件使用:

<script setup>
import { ref } from 'vue'
import UserForm from './UserForm.vue'const firstName = ref('')
const lastName = ref('')
</script><template><UserFormv-model:firstName="firstName"v-model:lastName="lastName"/>
</template>

4. provide/inject 依赖注入

4.1 基础用法

<!-- 父组件提供数据 -->
<script setup>
import { provide, ref } from 'vue'const theme = ref('dark')
provide('theme', theme)
</script><!-- 子组件注入数据 -->
<script setup>
import { inject } from 'vue'const theme = inject('theme', 'light') // 第二个参数是默认值
</script>

4.2 响应式数据注入

<!-- 父组件 -->
<script setup>
import { provide, ref, readonly } from 'vue'const count = ref(0)
const incrementCount = () => {count.value++
}// 提供只读值和修改方法
provide('count', readonly(count))
provide('increment', incrementCount)
</script><!-- 子组件 -->
<script setup>
import { inject } from 'vue'const count = inject('count')
const increment = inject('increment')
</script><template><button @click="increment">{{ count }}</button>
</template>

5. EventBus 事件总线

虽然 Vue 3 移除了内置的事件总线,但我们可以使用第三方库或自己实现一个简单的事件总线:

// eventBus.js
import mitt from 'mitt'
export default mitt()

使用示例:

<!-- 组件 A -->
<script setup>
import eventBus from './eventBus'const sendMessage = () => {eventBus.emit('custom-event', { message: 'Hello!' })
}
</script><!-- 组件 B -->
<script setup>
import { onMounted, onUnmounted } from 'vue'
import eventBus from './eventBus'const handleEvent = (data) => {console.log(data.message)
}onMounted(() => {eventBus.on('custom-event', handleEvent)
})onUnmounted(() => {eventBus.off('custom-event', handleEvent)
})
</script>

6. refs 直接访问

6.1 模板引用

<!-- 父组件 -->
<script setup>
import { ref, onMounted } from 'vue'
import ChildComponent from './ChildComponent.vue'const childRef = ref(null)onMounted(() => {// 访问子组件的方法或属性childRef.value.someMethod()
})
</script><template><ChildComponent ref="childRef" />
</template><!-- 子组件 -->
<script setup>
// 需要显式暴露方法给父组件
defineExpose({someMethod() {console.log('方法被调用')}
})
</script>

最佳实践建议

  1. 优先使用 props 和 emits 进行父子组件通信
  2. 对于跨多层组件的通信,考虑使用 provide/inject
  3. 对于全局状态管理,使用 Vuex 或 Pinia
  4. 避免过度使用 EventBus,它可能导致维护困难
  5. 谨慎使用 refs 直接访问子组件,这可能破坏组件封装性

注意事项

  1. Props 是只读的,不要在子组件中直接修改
  2. 使用 v-model 时注意命名冲突
  3. provide/inject 的响应式数据建议使用 readonly 包装
  4. 在组件卸载时记得清理事件监听器
  5. 使用 TypeScript 时,建议为 props 和 emits 添加类型声明

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

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

相关文章

MySQL更新JSON字段key:value形式

MySQL更新JSON字段key:value形式 1. 介绍 ‌MySQL的JSON数据类型‌是MySQL 5.7及以上版本中引入的一种数据类型&#xff0c;用于存储JSON格式的数据。使用JSON数据类型可以自动校验文档是否满足JSON格式的要求&#xff0c;优化存储格式&#xff0c;并允许快速访问文档中的特定…

javax.xml.ws.soap.SOAPFaultException: ZONE_OFFSET

javax.xml.ws.soap.SOAPFaultException 表示 SOAP 调用过程中发生了错误&#xff0c;并且服务端返回了一个 SOAP Fault。 错误信息中提到的 ZONE_OFFSET 可能指的是时区偏移量。在日期和时间处理中&#xff0c;时区偏移量是指格林威治标准时间 (GMT) 的偏移量。如果服务期望特…

软路由设置ip地址实现一机一IP

软路由作为一种灵活且强大的网络设备&#xff0c;越来越受到家庭和小型企业用户的青睐。通过软路由配置代理IP&#xff0c;不仅可以提升网络性能&#xff0c;还能保护隐私和实现更多高级功能。本文将详细介绍如何在软路由中配置代理IP&#xff0c;帮助你轻松实现更高效的网络管…

介绍一下strupr(arr);(c基础)

hi , I am 36 适合对象c语言初学者 strupr(arr)&#xff1b;函数是把arr数组变为大写字母 格式 #include<string.h> strupr(arr); 返回值为arr 链接分享一下arr的意义(c基础)(必看)(牢记)-CSDN博客 #define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #incl…

【VRChat 全身动捕】VIVE 手柄改 tracker 定位器教程,低成本光学动捕解决方案(持续更新中2024.11.26)

更新 0.0.1&#xff08;2024/11/26&#xff09;&#xff1a; 1.解决了内建蓝牙无法识别、“steamVR 蓝牙不可用” 的解决方案 2.解决了 tracker 虽然建立了连接但是在 steamVR 界面上看不到的问题 3.解决了 VIVE 基站1.0 无法被蓝牙识别 && 无法被 steamVR 搜索到 &…

C++设计模式之组合模式中如何实现同一层部件的有序性

在组合模式中&#xff0c;为了实现同一层上部件的有序性&#xff0c;可以采取以下几种设计方法&#xff1a; 1. 使用有序集合 使用有序集合&#xff08;如 std::list、std::vector 或其他有序容器&#xff09;来存储和管理子部件。这种方法可以确保子部件按照特定顺序排列&am…

Web 端语音对话 AI 示例:使用 Whisper 和 llama.cpp 构建语音聊天机器人

大语言模型&#xff08;LLM&#xff09;为基于文本的对话提供了强大的能力。那么&#xff0c;能否进一步扩展&#xff0c;将其转化为语音对话的形式呢&#xff1f;本文将展示如何使用 Whisper 语音识别和 llama.cpp 构建一个 Web 端语音聊天机器人。 系统概览 如上图所示&…

网络地址转换

NAT概述 解决公有地址不足&#xff0c;并且分配不均匀的问题 公有地址&#xff1a;由专门的机构管理、分配&#xff0c;可以在因特网上直接通信 私有地址&#xff1a;组织和个人可以任意使用&#xff0c;只能在内网使用的IP地址 A、B、C类地址中各预留了一些私有IP地址 A&…

电脑无互联网连接怎么解决?分享5种解决方案

无互联网连接是指设备无法与互联网进行通信或连接失败。这可能会导致我们无法正常上网&#xff0c;给我们的日常生活和工作带来很大的不便。但请不要担心&#xff0c;下面将为您介绍一些解决无互联网连接问题的方法。 一、检查网络是否正常连接 首先&#xff0c;确保您的路由器…

使用 F5 TTS 文字转音频

F5 TTS 支持 ZeroShot 音频克隆&#xff0c;只有将需要音频传给模型&#xff0c;模型既可以生成以对应声音生成的音频&#xff0c;F5 最强大的地方就是可以使用定制的人声。F5 使用了 DIT 架构进行训练&#xff0c;结构如下&#xff1a; 本地使用 F5 TTS F5 使用很简单&#x…

【Redis】Redis 预备知识

目录 1. 基本全局命令 KEYS EXISTS DEL EXPIRE TTL TYPE 2. 数据结构和内部编码 3. 单线程架构 Redis 提供了5种数据结构&#xff0c;理解每种数据结构的特点对于 Redis 开发运维非常重要&#xff0c;同时掌握每种数据结构的常见命令&#xff0c;会在使用 Redis 的时…

【从零开始的LeetCode-算法】3304. 找出第 K 个字符 I

Alice 和 Bob 正在玩一个游戏。最初&#xff0c;Alice 有一个字符串 word "a"。 给定一个正整数 k。 现在 Bob 会要求 Alice 执行以下操作 无限次 : 将 word 中的每个字符 更改 为英文字母表中的 下一个 字符来生成一个新字符串&#xff0c;并将其 追加 到原始的…

云原生革命:构建未来应用的无限可能

在这个数字化飞速发展的时代&#xff0c;云原生技术如同一股不可阻挡的潮流&#xff0c;正深刻改变着软件开发和部署的方式。它不仅仅是一种技术变革&#xff0c;更是一场关于如何更高效、更灵活地构建和运行应用的革命。今天&#xff0c;我们就来深入探讨云原生的魅力所在&…

软件设计模式复习

一、软件生存周期 二、软件开发过程模型 瀑布模型 特征&#xff1a; 从上一阶段承接的成果物作为本阶段的工作对象&#xff1b; 对上一阶段成果实施本阶段的活动&#xff1b; 给出本阶段的成果&#xff0c;作为下一阶段的输入&#xff1b; 对本阶段的工作进行评审&#xff0c…

centos7 yum install 失败,mirrorlist.centos.org连接不上

由于centos7停止支持,导致mirrorlist.centos.orgdns解析都是失效啦,yum命令没法安装程序. 换一个镜像源就好 sudo cp /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.bak sudo curl -o /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/…

搭建文件服务器并使用Qt实现文件上传和下载(带账号和密码)

文章目录 0 背景1 搭建文件服务器2 代码实现文件上传和下载2.1 在pro文件中添加网络支持2.2 创建网络管理类2.3 文件上传2.4 文件下载 3 扩展&#xff08;其他方法实现文件上传和下载&#xff09;3.1 python3.2 npm3.3 ftp服务器 4 完整的代码 0 背景 因为需要使程序具备在远程…

JVM 常见面试题及解析(2024)

目录 一、JVM 基础概念 二、JVM 内存结构 三、类加载机制 四、垃圾回收机制 五、性能调优 六、实战问题 七、JVM 与其他技术结合 八、JVM 内部机制深化 九、JVM 相关概念拓展 十、故障排查与异常处理 一、JVM 基础概念 1、什么是 JVM&#xff1f;它的主要作用是…

自动化运维(k8s)之微服务信息自动抓取:namespaceName、deploymentName等全解析

前言&#xff1a;公司云原生k8s二开工程师发了一串通用性命令用来查询以下数值&#xff0c;我想着能不能将这命令写成一个自动化脚本。 起初设计的 版本一&#xff1a;开头加一条环境变量&#xff0c;执行脚本后&#xff0c;提示输入&#xff1a;需要查询的命名空间&#xff0c…

鸿蒙一次开发,多端部署,响应式布局

鸿蒙一次开发&#xff0c;多端部署&#xff0c;响应式布局 一、定义屏幕相关常量 BreakpointConstants.ets import BreakpointType from ../bean/BreakpointType export default class BreakPointConstants{/*** 小屏幕设备的Breakpoints 标记*/static readonly BREAKPOINT_…

ubuntu防火墙入门(一)——设置服务、关闭端口

本机想通过git clone gitgithub.com:skumra/robotic-grasping.git下载代码&#xff0c;firewall-config中需要为当前区域的防火墙开启SSH服务吗 是的&#xff0c;如果你想通过 git clone gitgithub.com:skumra/robotic-grasping.git 使用 SSH 协议从 GitHub 下载代码&#xff0…