vue3专题1------父组件中更改子组件的属性

理解 Vue 3 中父组件如何引用子组件的属性是一个很重要的概念。 这里涉及到 defineExpose 和 ref 这两个关键点。

方法:使用 defineExpose 在子组件中暴露属性,然后在父组件中使用 ref 获取子组件实例并访问暴露的属性。

下面我将详细解释这个过程:

1. 子组件 (Child Component):

  • 创建 Ref: 首先,在子组件中使用 ref 创建你想要暴露的属性。
  • 使用 defineExpose 暴露: 使用 defineExpose 显式声明你想让父组件访问的属性。只有通过 defineExpose 暴露的属性才能被父组件访问。
// ChildComponent.vue<template><div><p>子组件 Count: {{ count }}</p><button @click="increment">Increment</button></div>
</template><script setup>
import { ref } from 'vue';const count = ref(0);const increment = () => {count.value++;
};// 暴露 count 和 increment 方法给父组件defineExpose({count,increment
})</script>

说明:

  • defineExpose 接受一个对象,该对象包含你想暴露给父组件访问的属性和方法。
  • 在上面的例子中,我们通过defineExpose 暴露了 count (ref 对象) 和 increment 方法,否则父组件也无法访问它。

2. 父组件 (Parent Component):

  • Template Ref: 在父组件的模板中,使用 ref 特殊 attribute 给子组件命名,以便稍后获取子组件的实例。
  • 获取子组件实例: 在父组件中,创建一个与模板中 ref 特殊 attribute 同名的 ref。 当组件挂载后,这个 ref 将会持有子组件的实例。
  • 访问暴露的属性: 在 onMounted 生命周期钩子中,访问子组件实例上的暴露属性。 需要在组件挂载后才能访问子组件的实例。
// ParentComponent.vue
<template><div><ChildComponent ref="childComponentRef" /><p>父组件 Count: {{ childCount }}</p><button @click="incrementChild">Increment Child</button></div>
</template><script>
import { ref, onMounted } from 'vue';
import ChildComponent from './ChildComponent.vue';const childComponentRef = ref(null); //  初始值必须为 null
const childCount = ref(0);onMounted(() => {// 确保 childComponentRef.value 存在if (childComponentRef.value) {// 访问子组件暴露的 count 属性childCount.value = childComponentRef.value.count.value;// 可以调用子组件暴露的方法} else {console.warn('Child component ref is not yet available.');}
});const incrementChild = () => {if (childComponentRef.value) {childComponentRef.value.increment(); // 调用子组件的方法childCount.value = childComponentRef.value.count.value; // 更新父组件的 count}
};</script>

说明:

  • childComponentRef 的初始值必须为 null
  • onMounted 钩子是至关重要的。在这个钩子被调用时,子组件已经被挂载,childComponentRef.value 将指向子组件的实例。
  • 通过 childComponentRef.value.count.value 访问子组件暴露的 count 属性。 注意,由于 count 本身是一个 ref,所以需要使用 .value 两次才能获取其值。
  • 通过 childComponentRef.value.increment() 调用子组件暴露的 increment 方法。
  • 在访问子组件的属性或方法之前,最好检查 childComponentRef.value 是否存在,以避免错误。

总结:

  1. 子组件: 使用 ref 创建响应式属性,并使用 defineExpose 暴露要给父组件访问的属性和方法。
  2. 父组件: 在模板中使用 ref 特殊 attribute 引用子组件,并在 setup 中创建同名的 ref。 在 onMounted 钩子中,通过 ref.value 访问子组件的实例,并访问暴露的属性和方法。

重要提示:

  • 单向数据流: 虽然可以从父组件访问子组件的属性,但应该尽量避免直接修改子组件的状态。 更好的做法是让子组件通过 emit 触发事件,父组件监听这些事件并做出相应的更新。 这有助于维护清晰的单向数据流。
  • 避免过度暴露: 只暴露父组件真正需要的属性和方法。 避免暴露不必要的内部状态,以保持子组件的封装性。

注意:在父组件修改子组件的属性时,通常推荐暴露方法,而不是直接暴露属性

理由:

1. 维护单向数据流:

  • 暴露属性 (不推荐): 直接暴露子组件的属性给父组件修改,容易打破单向数据流。 父组件可以随意更改子组件的状态,导致子组件的状态变化不可预测,增加了调试和维护的难度。 这就像父组件直接“篡改”了子组件的数据,子组件可能不了解发生了什么变化。

  • 暴露方法 (推荐): 通过暴露方法,子组件可以控制如何修改其内部状态。 父组件调用这些方法来请求子组件进行更新。 这种方式保持了清晰的数据流方向:父组件 "请求" 子组件修改数据,子组件 "响应" 请求并执行修改。 子组件可以验证传入的数据、执行一些副作用操作 (例如,在数据更改后更新本地存储) 等,从而更好地控制自身的状态。

2. 更好的封装性:

  • 暴露属性: 直接暴露属性会破坏子组件的封装性。 父组件需要了解子组件内部的属性结构和类型,这增加了父组件和子组件之间的耦合度。 如果子组件内部的属性发生变化,可能需要修改父组件的代码。

  • 暴露方法: 通过暴露方法,子组件可以隐藏其内部的实现细节。 父组件只需要知道如何调用这些方法,而不需要了解子组件内部是如何存储和处理数据的。 这样可以更容易地修改子组件的内部实现,而不会影响到父组件。

3. 更好的控制和验证:

  • 暴露属性: 父组件可以直接设置属性值,没有机会进行验证或控制。

  • 暴露方法: 子组件可以在方法内部对传入的参数进行验证,确保数据的有效性。 此外,子组件还可以在方法内部执行一些额外的逻辑,例如触发自定义事件或更新其他相关的状态。

示例:

假设子组件有一个 count 属性,父组件想要增加它的值。

推荐 (暴露方法):

// ChildComponent.vue
<script setup>
import { ref } from 'vue';const count = ref(0);const increment = (amount = 1) => {count.value += amount;
};defineExpose({increment, // 暴露 increment 方法
});</script>// ParentComponent.vue
<script setup>
import { ref, onMounted } from 'vue';
import ChildComponent from './ChildComponent.vue';const child = ref(null);
onMounted(() => {child.value.increment(5); // 调用子组件的 increment 方法
});</script>

总结:

在设计组件时,应该尽量遵循单向数据流的原则,提高组件的封装性和可维护性。 因此,在父组件需要修改子组件状态的情况下,推荐暴露方法 (actions),而不是直接暴露属性。 这使得子组件可以更好地控制其内部状态,并提供更大的灵活性。

当然,在非常简单的情况下,如果父组件只需要读取子组件的状态,并且不需要进行任何修改,那么暴露属性是可以接受的。 但总的来说,暴露方法是更安全、更灵活、更推荐的做法

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

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

相关文章

数据仓库分层架构解析:从理论到实战的完整指南​​

数据仓库分层是构建高效数据体系的核心方法论。本文系统阐述ODS、DWD、DWS、ADS四层架构的设计原理&#xff0c;结合电商用户行为分析场景&#xff0c;详解各层功能及协作流程&#xff0c;并给出分层设计的原则与避坑指南&#xff0c;帮助读者掌握分层架构的落地方法。 一、为什…

从零搭建一套前端开发环境

一、基础环境搭建 1.NVM(Node Version Manager)安装 简介 nvm&#xff08;Node Version Manager&#xff09; 是一个用于管理多个 Node.js 版本的工具&#xff0c;允许开发者在同一台机器上轻松安装、切换和使用不同版本的 Node.js。它特别适合需要同时维护多个项目&#xff…

计算机组成原理笔记(十六)——4.1基本算术运算的实现

计算机中最基本的算术运算是加法运算&#xff0c;加、减、乘、除运算最终都可以归结为加法运算。 4.1.1加法器 一、加法器的基本单元 加法器的核心单元是 全加器&#xff08;Full Adder, FA&#xff09;&#xff0c;而所有加法器都由 半加器&#xff08;Half Adder, HA&…

利用Qt创建一个模拟问答系统

界面&#xff1a; 添加了聊天显示区域&#xff08;QTextEdit&#xff09; 添加了发送按钮和清空对话按钮 优化了布局和窗口大小添加了时间戳显示 2、功能&#xff1a; 支持实时对话可以清空对话历史 支持按回车发送消息 添加了简单的关键词匹配响应系统 交互体验&#x…

神经光子渲染:物理级真实感图像生成——从麦克斯韦方程到深度学习

一、技术背景与核心突破 2025年&#xff0c;神经光子渲染&#xff08;Photonic Neural Rendering, PNR&#xff09;技术通过物理光学方程与神经辐射场的深度融合&#xff0c;在AIGC检测工具&#xff08;如GPTDetector 5.0&#xff09;的识别准确率从98%降至12%。该技术突破性地…

Linux中手动安装7-Zip软件文档

7zip位于EPEL源中&#xff0c;如果服务器可以联网或者配置了本地EPEL源则可以直接安装 yum install p7zip p7zip-plugins -y对于无法联网且没有配置本地EPEL源的服务器&#xff0c;可以通过官网下载安装包后&#xff0c;上传至服务器&#xff0c;手动安装 ## 下载地址&#x…

[密码学基础]GM/T 0018-2023 密码设备应用接口规范深度解析:技术革新与开发者实践

GM/T 0018-2023 密码设备应用接口规范深度解析&#xff1a;技术革新与开发者实践 GM/T 0018-2023《密码设备应用接口规范》是中国密码行业的重要标准&#xff0c;于2023年12月4日发布&#xff0c;2024年6月1日正式实施&#xff0c;替代了2012年版标准。该标准旨在规范密码设备…

8.QT-按钮类控件|Push Button|Radio Button|Check Box|Tool Button(C++)

Push Button 使⽤ QPushButton 表⽰⼀个按钮.这也是当前我们最熟悉的⼀个控件了. QPushButton 继承⾃ QAbstractButton .这个类是⼀个抽象类.是其他按钮的⽗类 在Qt Designer中也能够看到这⾥的继承关系 属性说明text按钮中的⽂本icon按钮中的图标iconSize按钮中图标的尺⼨sh…

CFIS-YOLO:面向边缘设备的木材缺陷检测轻量级网络解析

论文地址:https://arxiv.org/pdf/2504.11305 目录 一、论文核心贡献 二、创新点详解 2.1 CARAFE动态上采样 工作原理 优势对比 2.2 C2f_FNB轻量模块 计算效率 2.3 Inner-SIoU损失函数 三、实验验证 3.1 消融实验 3.2 对比实验 四、应用部署 4.1 边缘设备部署流程…

BUUCTF PWN刷题笔记(1-9)

才知道&#xff0c;由于栈对齐&#xff0c;直接动调看栈估计会错&#xff0c;用cyclic看 1.test_your_nc NC连接一下&#xff0c;这个网站似乎直接访问是不中的&#xff0c;怀疑是没开启web的端口。NC链接输入cat flag就OK了&#xff0c;应该只是让我这样的小菜鸟培养自信用的…

C#处理网络传输中不完整的数据流

1、背景 在读取byte数组的场景&#xff08;例如&#xff1a;读取文件、网络传输数据&#xff09;中&#xff0c;特别是网络传输的场景中&#xff0c;非常有可能接收了不完整的byte数组&#xff0c;在将byte数组转换时&#xff0c;因字符的缺失/增多&#xff0c;转为乱码。如下…

PostgreSQL 用户资源管理

PostgreSQL 用户资源管理 PostgreSQL 提供了多种机制来管理和限制用户对数据库资源的使用&#xff0c;以下是全面的资源管理方法&#xff1a; 1 连接限制 1.1 限制最大连接数 -- 在 postgresql.conf 中设置 max_connections 100 -- 全局最大连接数-- 为特定用户设置连接限…

新书速览|OpenCV计算机视觉开发实践:基于Qt C++

《OpenCV计算机视觉开发实践:基于Qt C》 本书内容 OpenCV是计算机视觉领域的开发者必须掌握的技术。《OpenCV计算机视觉开发实践:基于Qt C》基于 OpenCV 4.10与Qt C进行编写&#xff0c;全面系统地介绍OpenCV的使用及实战案例&#xff0c;并配套提供全书示例源码、PPT课件与作…

【上位机——MFC】消息映射机制

消息映射机制 Window消息分类消息映射机制的使用代码示例 MFC框架利用消息映射机制把消息、命令与它们的处理函数映射起来。具体实现方法是在每个能接收和处理消息的类中&#xff0c;定义一个消息和消息函数指针对照表&#xff0c;即消息映射表。 在不重写WindowProc虚函数的大…

docker学习笔记2-最佳实践

一、在容器中启动mysql的最佳实践 &#xff08;一&#xff09;查找目录 1、mysql的配置文件路径 /etc/mysql/conf.d 2、mysql的数据目录 /var/lib/mysql 3、环境变量 4、端口 mysql的默认端口3306。 &#xff08;二&#xff09;启动命令 docker run -d -p 3306:3306 …

Vue3核心源码解析

/packages/complier-core 定位​​&#xff1a;​​编译时核心​​&#xff0c;处理 Vue 模板的编译逻辑。​​核心功能​​&#xff1a; ​​模板解析​​&#xff1a;将 .vue 文件的模板语法&#xff08;HTML-like&#xff09;解析为 ​​抽象语法树 (AST)​​。​​转换优化…

n8n 中文系列教程_05.如何在本机部署/安装 n8n(详细图文教程)

n8n 是一款强大的开源工作流自动化工具&#xff0c;可帮助你连接各类应用与服务&#xff0c;实现自动化任务。如果你想快速体验 n8n 的功能&#xff0c;本机部署是最简单的方式。本教程将手把手指导你在 Windows 或 MacOS 上通过 Docker 轻松安装和运行 n8n&#xff0c;无需服务…

【python】pyCharm常用快捷键使用-(2)

pyCharm常用快捷键使用 快速导入任意类 【CTRLALTSPACE】代码补全【CTRLSHIFTENTER】代码快速修正【ALTENTER】代码调试快捷键

Docker 镜像、容器和 Docker Compose的区别

前言&#xff1a;Docker 的镜像、容器和 Docker Compose 是容器化技术的核心组件&#xff0c;以下是对它们的详细解析及使用场景说明。 ​​1、Docker 镜像&#xff08;Image&#xff09;​​ ​​定义​​&#xff1a; 镜像是只读模板&#xff0c;包含运行应用程序所需的代码、…

算法——背包问题(分类)

背包问题&#xff08;Knapsack Problem&#xff09;是一类经典的组合优化问题&#xff0c;广泛应用于资源分配、投资决策、货物装载等领域。根据约束条件和问题设定的不同&#xff0c;背包问题主要分为以下几种类型&#xff1a; 1. 0-1 背包问题&#xff08;0-1 Knapsack Probl…