鸿蒙笔记--装饰器
这一节主要了解一下鸿蒙里的装饰器,装饰器是一种特殊的语法结构,用于装饰类、结构体、方法以及变量;
1 @Component在鸿蒙(HarmonyOS)开发中扮演着重要角色,主要用于定义可重用的UI组件,主要作用:1)组件化:@Component装饰的struct表示该结构体具有组件化能力,能够成为一个独立的组件。这使得开发者可以将UI界面拆分成多个可复用的部分,提高代码的可维护性和复用性。
2)生命周期管理:被@Component装饰的组件可以调用组件的生命周期函数,如aboutToAppear(组件即将出现时回调)和aboutToDisappear(组件即将销毁前回调),从而进行资源管理和状态更新。3)UI绘制:每个被@Component装饰的组件都必须包含一个build()函数,该函数用于绘制组件的UI界面。这体现了声明式UI的核心思想,即数据驱动页面更新。
import { Text, Button, Column } from '@ohos.agp.components'; // 使用@Component装饰struct定义计数器组件
@Component
struct Counter { @State private count: number = 0; // build函数用于绘制组件的UI界面 build() { Column() { // 显示计数值 Text(`${this.count}`).fontSize(24) // 增加计数值的按钮 Button('增加') .onClick(() => { this.count++; // 修改@State变量的值,触发UI更新 }) } }
} @Entry
@Component
struct App { build() { Column() { // 使用Counter组件 Counter() } }
}
2 @Entry在鸿蒙中扮演着至关重要的角色,主要用于标识页面的入口组件。主要作用:1)页面入口标识:@Entry装饰的自定义组件会被视为当前页面的默认入口组件。在鸿蒙应用中,每个页面都是由一系列组件组合而成的,而@Entry装饰的组件则是这些组件的根节点,负责页面的初始化和呈现。2)预览支持:在使用预览器(如Previewer)进行页面预览时,@Entry装饰的组件会被首先创建并呈现,方便开发者在开发过程中实时查看页面的效果。3)组件树结构:在鸿蒙的组件化开发模式中,页面由多个组件构成,这些组件之间形成了一种树状结构。@Entry装饰的组件位于这棵树的根部,是页面加载和渲染的起点。
import { TextInput, Button, Column } from '@ohos.agp.components';
@Entry
@Component
struct LoginPage { // build函数用于绘制登录页面的UI界面 build() { Column() { TextInput({ placeholder: '请输入用户名' }) TextInput({ placeholder: '请输入密码', type: TextInputType.Password }) // 登录按钮 Button('登录') .onClick(() => { // 在这里处理登录逻辑,比如验证用户名和密码 // ... }) } }
}
3 @State在鸿蒙中扮演着管理组件的状态信息的作用,主要作用:
1. 标记状态信息
@State装饰器的主要作用是标记一个类或对象的属性为状态信息,表示该属性会随着时间的推移而发生变化。这些状态信息通常与组件的UI渲染相关联,当状态发生变化时,组件的UI也会相应地更新。
2. 自动同步状态
当一个属性被@State装饰后,该属性的值会被自动同步到应用的状态管理中。这意味着,当属性值发生变化时,应用的状态也会相应地更新,并且这种更新能够触发UI的重新渲染。这种机制有助于开发者在应用的不同组件之间共享状态数据,并且能够方便地观察和响应这些状态的变化。
3. 响应式编程
@State装饰器是实现响应式编程的关键之一。在鸿蒙开发中,响应式编程是一种重要的编程范式,它允许开发者以声明式的方式编写代码,并通过状态的变化来驱动UI的更新。@State装饰器使得开发者可以轻松地定义状态变量,并在状态变化时自动触发UI的更新,从而简化了UI更新的逻辑。
4. 私有性和初始化
@State装饰的变量是私有的,只能从组件内部访问。这有助于封装组件的内部状态,防止外部代码直接修改状态变量,从而保证了组件的封装性和安全性。此外,@State装饰的变量必须初始化,不能为空。这确保了状态变量在使用前已经有一个明确的初始值,避免了因未初始化而导致的潜在问题。
5. 支持多种数据类型
@State装饰器可以作用到多种数据类型上,包括基本数据类型(如number、string、boolean等)和复杂数据类型(如Object、class、array等)。这使得开发者可以根据需要灵活地定义状态变量的类型,并在状态变化时更新相应的UI元素。
6. 生命周期管理
@State装饰的变量生命周期与其所属自定义组件的生命周期相同。当组件被销毁时,其内部的状态变量也会被销毁,从而避免了内存泄漏等问题。
4 @Prop在鸿蒙中主要用于定义组件的属性,并确保组件属性与父组件数据源之间的同步关系。主要作用:
1. 定义组件属性
@Prop装饰器用于在子组件中定义那些需要从父组件接收的属性。这些属性可以是基本数据类型(如string、number、boolean等),也可以是枚举类型(enum),但不支持any类型,也不允许使用undefined和null作为初始值。在父组件中,通过传递给子组件的构造参数来初始化这些@Prop装饰的属性。
2. 单向同步
@Prop装饰的变量与父组件之间建立的是单向同步关系。这意味着,当父组件中的数据源发生变化时,与之相关的@Prop装饰的变量会自动更新,以保持与父组件数据的一致性。然而,子组件中对@Prop装饰的变量所做的修改不会同步回父组件。这种单向同步机制有助于维护父子组件之间的数据流向清晰,避免数据混乱。
3. 初始化与修改
@Prop装饰的变量允许在子组件中进行本地初始化和修改。但是,需要注意的是,如果父组件中的数据源在子组件本地修改之后发生了变化,那么子组件本地对@Prop装饰的变量所做的修改将被覆盖。这是因为@Prop装饰的变量本质上是父组件数据源的副本,它们之间的同步关系是单向的。
4. 变量类型与深拷贝
@Prop装饰的变量在父子组件同步过程中会进行深拷贝。这意味着,除了基本类型、Map、Set、Date、Array等特定类型外,其他类型的数据在拷贝过程中可能会丢失其原有的类型信息。因此,在使用@Prop装饰器时,需要注意数据类型的问题,以避免因类型不匹配或丢失而导致的错误。
@Component
struct ChildComponent { @Prop childCount: number; build() { Text(`子组件计数: ${this.childCount}`).fontSize(24) }
} @Entry
@Component
struct ParentComponent { @State parentCount: number = 0; build() { Column() { Text(`父组件计数: ${this.parentCount}`).fontSize(24) Button('增加计数') .onClick(() => { this.parentCount++; }) // 将parentCount传递给子组件的childCount ChildComponent({ childCount: this.parentCount }) } }
}
5 @Provide在鸿蒙中主要用于实现跨层级组件间的数据共享和状态同步,一般与Consume配合使用,主要作用:
1. 数据提供与共享
@Provide装饰的变量被视为在组件树中向上提供的状态变量,这些变量自动对其所有后代组件可用。这意味着,在祖先组件中通过@Provide装饰的变量,可以被其所有后代组件通过@Consume装饰器来访问和绑定,从而实现跨层级的数据共享。
2. 跨层级状态同步
不同于@State和@Link等装饰器,@Provide和@Consume的组合允许在多层级的父子组件之间传递和同步状态。这种机制摆脱了参数传递机制的束缚,使得开发者可以更加方便地在复杂的组件树中管理和同步状态。
3. 双向数据同步
虽然@Provide本身主要用于数据提供,但与其配合使用的@Consume装饰器能够实现数据的双向同步。当@Provide装饰的变量在祖先组件中被更新时,所有绑定了该变量的后代组件也会自动更新其UI,反之亦然(尽管在实际应用中,后代组件通常不会直接修改@Provide的变量,而是通过事件或其他机制来请求祖先组件更新状态)。
4. 变量别名与绑定
@Provide装饰器允许开发者为提供的变量指定别名。这样,后代组件在通过@Consume装饰器绑定变量时,可以使用相同的变量名或别名来实现绑定。这种机制增加了灵活性,允许开发者在复杂的组件树中更容易地管理和识别状态变量。
5. 初始化与类型要求
@Provide装饰的变量必须指定初始值,这是确保状态变量在组件树中有效传递的前提。同时,@Provide和@Consume绑定的变量类型必须相同,以保证数据的正确性和一致性。
@Entry
@Component
struct CompA { @Provide reviewVotes: number = 0; build() { // ... }
} @Component
struct CompD { @Consume reviewVotes: number; build() { // 使用reviewVotes变量来更新UI }
}
6 @Observed 和 @ObjectLink 装饰器通常一起使用,以实现对象属性变化的观察和UI的自动更新。
1. 属性变化观察
@Observed装饰的类(class)会被自动观察其属性的变化。当类中的某个属性被修改时,鸿蒙框架能够感知到这种变化,并据此进行相应的响应。这种机制使得开发者可以方便地实现响应式编程,即根据数据的变化自动更新UI或其他状态。
2. 双向数据同步支持
虽然@Observed本身并不直接实现双向数据同步,但它与@ObjectLink等装饰器配合使用,可以支持在父子组件之间进行双向数据同步。在父组件中,使用@Observed装饰的类实例可以被传递给子组件,并通过@ObjectLink在子组件中接收,从而建立父子组件之间的双向数据绑定关系。
3. 嵌套对象与数组的支持
@Observed不仅支持对简单类型属性的观察,还支持对嵌套对象或数组等复杂数据结构的观察。这意味着,即使数据结构嵌套多层,只要使用@Observed进行装饰,鸿蒙框架都能够感知到其内部属性的变化,并作出相应的响应。
4. 改变类原型链
需要注意的是,使用@Observed装饰类会改变其原始的原型链。这种改变是为了实现属性的观察与响应机制,但也可能带来一些潜在的问题。因此,在使用@Observed时,需要谨慎考虑其可能带来的影响,并避免与其他类装饰器同时装饰同一个类,以免发生冲突。
@Observed
class Person { public name: string; public age: number; constructor(name: string, age: number) { this.name = name; this.age = age; }
}
// ParentComponent.ts
@Entry
@Component
struct ParentComponent { @State person: Person = new Person('Alice', 30); build() { // ... 传递person实例给子组件 }
}
// ChildComponent.ts
@Component
struct ChildComponent { @ObjectLink person: Person; build() { // 使用person实例的属性来更新UI }
}
7 @Builder在鸿蒙中提供了一种更轻量的UI元素复用机制。主要作用:
UI元素复用:通过@Builder装饰的函数,开发者可以将重复使用的UI元素抽象成一个方法,在build方法里进行调用,从而减少代码的冗余,提高开发效率。
封装复杂性:对于复杂的UI布局,使用@Builder可以将布局逻辑封装在自定义构建函数中,使得build方法更加简洁明了。
支持组件内和全局使用:@Builder装饰的函数既可以在自定义组件内部定义和使用,也可以定义为全局函数,供整个应用使用。
@Entry
@Component
struct MyComponent { build() { Column() { // 调用自定义构建函数 this.myCustomBuilder() } } @Builder myCustomBuilder() { Row() { Text('Hello, Builder!') } }
}
8 @Extend在ArkUI框架中用于扩展原生组件的样式和行为,主要作用:
行为封装:除了样式外,@Extend还可以封装组件的私有属性、私有事件和预定义的方法,使得组件的行为更加模块化和可重用。
全局定义:@Extend装饰的方法需要在全局范围内定义,不支持在组件内部定义,这有助于保持代码的整洁和一致性。
参数支持:@Extend装饰的方法支持参数,这使得它可以根据不同的需求动态地应用不同的样式或行为。
// 定义扩展样式
@Extend(Text)
function fancyText(fontSize: number, fontColor: Color) { .fontSize(fontSize) .fontColor(fontColor) .fontWeight(FontWeight.Bold) .fontStyle(FontStyle.Italic)
}
// 在组件中使用扩展样式
@Entry
@Component
struct MyComponent { @State label: string = 'Hello, Extend!'; build() { Column() { // 应用扩展样式 Text(this.label) .fancyText(24, Color.Red) .margin({ top: 10 }) } }
}
9 @CustomDialog在ArkUI框架中用于创建自定义对话框,主要作用:
自定义内容:@CustomDialog允许开发者在对话框中显示任何类型的内容,如文本、图像、表单、按钮等,从而满足多样化的交互需求。
高度可配置:通过@CustomDialog装饰的自定义对话框,开发者可以自定义对话框的标题、消息、按钮、图标等属性,以及对话框的样式和布局。
数据交互:自定义对话框还可以作为数据交互的桥梁,通过用户输入或选择的信息进行处理,并展示需要的信息给用户。
提升用户体验:@CustomDialog可以帮助开发者在用户操作过程中快速展示信息或选项,减少操作繁琐度和时间成本,从而提升用户体验。
@CustomDialog
struct CustomDialogExample { // 自定义对话框的控制器 controller: CustomDialogController build() { Column() { Text('我是内容') .fontSize(20) .margin({ top: 10, bottom: 10 }) // 添加按钮,并绑定点击事件 Flex({ justifyContent: FlexAlign.SpaceAround }) { Button('cancel') .onClick(() => { this.controller.close() if (this.cancel) { this.cancel() } }) .backgroundColor(0xffffff) .fontColor(Color.Black) Button('confirm') .onClick(() => { this.controller.close() if (this.confirm) { this.confirm() } }) .backgroundColor(0xffffff) .fontColor(Color.Red) } .margin({ bottom: 10 }) } }
}
// 在页面组件中使用自定义对话框
@Entry
@Component
struct CustomDialogUser { dialogController: CustomDialogController = new CustomDialogController({ builder: CustomDialogExample({ // 可以传入回调函数作为cancel和confirm属性的值 cancel: () => { console.info('Callback when the cancel button is clicked') }, confirm: () => { console.info('Callback when the confirm button is clicked') } }) }) build() { Column() { Button('click me') .onClick(() => { this.dialogController.open() }) .width('100%') .margin({ top: 5 }) } }
}
10 @Watch在ArkUI框架中主要用于监听状态变量的变化。当被@Watch装饰的状态变量发生变化时,会自动调用指定的回调函数,从而允许开发者执行相应的逻辑处理。主要作用:
状态监听:@Watch允许开发者监听指定状态变量的值的变化,当值发生变化时,执行特定的回调函数。
数据响应:在组件或页面的开发中,@Watch用于实现数据的响应式更新。当数据变化时,能够自动触发UI的重新渲染,保证界面与数据的同步。
性能优化:通过细粒度地控制哪些状态变量的变化需要触发UI更新,可以避免不必要的渲染,从而优化应用的性能。
@Component
struct TotalView {@Prop @Watch('onCountUpdated') count: number;@State total: number = 0;// @Watch 回调onCountUpdated(propName: string): void {this.total += this.count;}build() {Text(`Total: ${this.total}`)}
}@Entry
@Component
struct CountModifier {@State count: number = 0;build() {Column() {Button('add to basket').onClick(() => {this.count++})TotalView({ count: this.count })}}
}
相关文章:
鸿蒙笔记--装饰器
这一节主要了解一下鸿蒙里的装饰器,装饰器是一种特殊的语法结构,用于装饰类、结构体、方法以及变量; 1 Component在鸿蒙(HarmonyOS)开发中扮演着重要角色,主要用于定义可重用的UI组件,主要作用:1)组件化:Component装饰…...

不同环境下RabbitMQ的安装-3 操作RabbitMQ
前面两篇从不同环境下RabbitMQ的安装-1 为什么要使用消息服务 到同环境下RabbitMQ的安装-2 ARM架构、X86架构、Window系统环境下安装RabbitMQ介绍了关于如何在ARM架构、X86架构和Window系统下如何安装,各位小伙伴可以根据自己的实际开发场景参考安装。 到本篇是一些…...

postgregSQL配置vector插件
1.下载vector 下载vector:https://pgxn.org/dist/vector/0.5.1/ 放在:C:\Program Files\PostgreSQL\vector-0.5.1 2.安装Visual Studio 2022 下载:https://visualstudio.microsoft.com/zh-hans/downloads/ 安装Visual Studio是为了C编译环…...

PUMA论文阅读
PUMA: Efficient Continual Graph Learning with Graph Condensation PUMA:通过图压缩进行高效的连续图学习 ABSTRACT 在处理流图时,现有的图表示学习模型会遇到灾难性的遗忘问题,当使用新传入的图进行学习时,先前学习的这些模…...
算法学习day31(动态规划)
一、比特位计数 给你一个整数 n ,对于 0 < i < n 中的每个 i ,计算其二进制表示中 1 的个数 ,返回一个长度为 n 1 的数组 ans 作为答案。 输入:n 2 输出:[0,1,1] 解释:0 --> 0 1 --> 1 2 -…...

嵌入式学Day25---Linux软件编程---线程间通信
目录 编辑 一、线程的分离属性 1.1.什么是分离属性 1.2.分离属性相关函数接口 1.初始化线程属性-pthread_attr_init() 2.销毁线程属性-pthread_attr_destory() 3.设置线程属性-pthread_setdetachstate() 1.3.注意 二、互斥锁 2.1.资源 2.2.互斥锁 1.什么是互斥锁 2.互…...

【实现100个unity特效之17】在unity中使用shader和ShaderGraph分别实现模糊特定层,高斯模糊效果
最终效果 Unity通过Shader来模糊场景画面 参考:【游戏开发小技】Unity通过UI全屏图来模糊场景画面(Shader | 模糊 | 滤镜 | Blur) ShaderGraph实现图片的高斯模糊 参考:【游戏开发实战】Unity ShaderGraph实现图片的高斯模糊效…...

Unity补完计划 之 SpriteEditer Multiple
本文仅作笔记学习和分享,不用做任何商业用途 本文包括但不限于unity官方手册,unity唐老狮等教程知识,如有不足还请斧正 1. SpriteEditer Multiple Automatic slicing - Unity 手册 这是用于裁剪图集的模式 应用之后精灵编辑器会看到Slice亮…...

C++ IOStream
IOStream 类流特性 不可赋值和复制缓冲重载了<< >> 状态位 示例 状态位操作函数coutcin getget(s,n)/get(s,n,d):getline otherif(!fs)/while(cin) operator void*()与 operator!()代码示例 File Stream open 函数 文件打开方式 文件读写 读写接口 一次读一个字符…...
2024/8/8训练
A - 无线网络整点栅格统计 题目链接 算法:模拟 题目大意 给你一个n*m的网格,然后输出每一个点作为顶点能构成的正方形数量(可以为斜正方形). 算法思路 本身题目数据是很小的,可以通过n^2的时间复杂度枚举每一个顶点,然后再通过n平方的时间复杂度枚举出另一个对角顶点,判断…...
项目的小结
项目场景: 作业的发布,打回 。 学生端做作业 由作业的state来确定作业是否上交,批改,打回作业。 实体类的建立,还有各种成员变量的设计要满足需求 问题描述 问题: 在进行上传作业后,老师端…...

【目标检测实验系列】YOLOv5高效涨点:基于NAMAttention规范化注意力模块,调整权重因子关注有效特征(文内附源码)
1. 文章主要内容 本篇博客主要涉及规范化注意力机制,融合到YOLOv5(v6.1版本,去掉了Focus模块)模型中,通过惩罚机制,调整特征权重因子,使模型更加关注有效特征,助力模型涨点。 2. 简要概括 论文地址&#x…...

LSPatch制作内置模块应用软件无需root 教你制作内置应用
前言 LSPatch功能非常强大,它是一款基于LSPosed核心的免Root Xposed框架软件。这意味着用户无需进行手机root操作,即可轻松植入内置Xposed模块,享受更多定制化的功能和体验,比如微某内置模块版等,这为那些不想root手机…...
Java设计模式七大原则
本篇为七大原则概述,后面会有每个原则的介绍,喜欢的朋友可以蹲一下哦!!!! Java设计模式的七大原则一般是指“面向对象设计原则”,这些原则有助于在设计软件系统时提高代码的可维护性、可扩展性和…...

Copy as cURL 字段含义
当前端在开发过程中,遇到接口错误反馈给后端人员时,一般在此接口处右键复制为cURL。 格式如下: curl https://xxx.xxx.cn/xxx/xxx/management/record/list \-H accept: application/json, text/plain, */* \-H accept-language: zh-CN,zh;q0…...

mysql更改密码后,若依 后端启动不了解决方案
我原先的mysql 密码是 数字字符串 我想改成000 纯数字 改完之后,连接的数据库的代码 也更改后 ,后端启动不了 因为原先 密码数字字符串 不需要用引号" " 括起来 我改成纯数字 需要用 " " 括起来 如下图 然后就可以运行成功了...
Redis--缓存击穿、缓存穿透、缓存雪崩
缓存击穿 什么是缓存击穿呢? 在高并发的场景下,一个热点的缓存数据在redis中突然失效(过期或被删除时,所有的读请求都会直接落在数据库上,导致数据库瞬间压力剧增,严重时可能会造成数据库宕机。这种情况就是所谓的“缓存击穿”。(…...

10个理由告诉你,为什么鸿蒙是下一个职业风口!
在当今科技飞速发展的时代,新的技术和趋势不断涌现,为人们带来了前所未有的机遇和挑战。鸿蒙操作系统作为我国自主研发的创新成果,正逐渐成为科技领域的焦点,被认为是下一个职业风口。 10个理由告诉你,为什么鸿蒙是下一…...
Gitlab仓库的权限分配以及如何查看自己的权限
在GitLab中,权限分配和查看自己的权限可以通过以下步骤进行: ### 1. 查看自己的权限 要查看你在某个GitLab项目中的权限,可以按照以下步骤操作: 1. 登录到GitLab。 2. 进入你想查看权限的项目页面。 3. 在左侧菜单中,…...

职业本科大数据实训室
一、职业本科大数据实训室建设背景 在数字化浪潮汹涌澎湃的今天,大数据已跃升为引领社会进步和经济发展的新引擎。随着《中华人民共和国国民经济和社会发展第十四个五年规划和2035年远景目标纲要》的深入实施,数字化转型作为国家战略的重要组成部分&…...
Python训练营打卡Day46(2025.6.6)
知识点回顾: 不同CNN层的特征图:不同通道的特征图什么是注意力:注意力家族,类似于动物园,都是不同的模块,好不好试了才知道。通道注意力:模型的定义和插入的位置通道注意力后的特征图和热力图 i…...

网络安全逆向分析之rust逆向技巧
rust逆向技巧 rust逆向三板斧: 快速定位关键函数 (真正的main函数):观察输出、输入,字符串搜索,断点等方法。定位关键 加密区 :根据输入的flag,打硬件断点,快速捕获程序中对flag访问的位置&am…...
ABP VNext 与 Neo4j:构建基于图数据库的高效关系查询
ABP VNext 与 Neo4j:构建基于图数据库的高效关系查询 🚀 在社交网络、权限图谱、推荐系统等应用场景中,关系链深度和复杂度远超传统关系型数据库的表达能力。本文基于 ABP VNext 框架,集成 Neo4j 图数据库,构建一套高…...
AI问答-vue3+ts+vite:http://www.abc.com:3022/m-abc-pc/#/snow 这样的项目 在服务器怎么部署
为什么记录有子路径项目的部署,因为,通过子路径可以区分项目,那么也就可以实现微前端架构,并且具有独特优势,每个项目都是绝对隔离的。 要将 Vue3 项目(如路径为 http://www.abc.com:3022/m-saas-pc/#/sno…...
深入理解MySQL死锁:从原理、案例到解决方案
一、MySQL死锁的概念与定义 1. 死锁的基本定义 MySQL中的死锁是指两个或多个事务在同一资源上相互等待对方释放锁,导致这些事务都无法继续执行的情况。从本质上讲,死锁是多个事务形成了一个等待环路,每个事务都在等待另一个事务所持有的锁资…...
高考:如何合理选择学科、专业以及职业
如何合理选择学科、专业以及职业 一、自我认知:明确自身兴趣与优势(一)兴趣探索(二)能力评估(三)价值观与目标 二、外部调研:深入了解学科、专业与职业(一)学…...
Java八股文——集合「Map篇」
Map 面试官您好,关于 Java 中常见的 Map 集合,我可以从非线程安全和线程安全两个方面来介绍: 首先,我们来看一下非线程安全的 Map 实现,这些在单线程环境下性能通常更好,但在并发场景下需要外部同步&…...

API是什么意思?如何实现开放API?
目录 一、API 是什么 (一)API 的定义 (二)API 的作用 二、API 的类型 (一)Web API 1. RESTful API 2. SOAP API (二)操作系统 API (三)数据库 API …...
go语言学习 第6章:错误处理
第6章:错误处理 在任何编程语言中,错误处理都是一个至关重要的环节。Go语言以其简洁而强大的错误处理机制而闻名,这使得开发者能够以一种优雅且高效的方式处理程序中可能出现的错误情况。本章将深入探讨Go语言中的错误处理机制,包…...
FPGA没有使用的IO悬空对漏电流有没有影响
结论: 1.在FPGA中,没有使用的IO悬空确实是可能对漏电流和功耗产生一定的影响。 2.这种影响特别是在低功耗设计中或者电流敏感的应用中需要注意。 问题一:未连接 IO(Floating IO)会不会产生漏电流? 1.会有影…...