【鸿蒙开发】第三十六章 状态管理 - V1V2混用和迁移指导
目录
1 自定义组件混用场景指导
1.1 概述
1.2 状态管理装饰器总览
状态管理V1的装饰器
状态管理V2的装饰器
状态管理装饰器支持的数据类型总览
1.3 限制条件
1.3.1 V1和V2的装饰器不允许混用
1.V1的自定义组件中不可以使用V2的装饰器
2.V2的自定义组件中不可以使用V1的装饰器
3. 多个装饰器不允许装饰同一个变量(@Watch、@Once、@Require除外)
2 混用场景介绍
2.1 V1和V2类相关装饰器混用
1. V1的自定义组件中使用被@ObservedV2装饰的类对象
2. V2的自定义组件中使用被@Observed装饰的类对象
2.2 不存在变量传递时,V1和V2的自定义组件混用
1. V1中使用V2的自定义组件
2. V2中使用V1的自定义组件
2.3 存在变量传递时,V1和V2的自定义组件数据混用
1. V1->V2:V1的普通变量传递给V2的自定义组件
2. V1->V2:V1的状态变量传递给V2的自定义组件
3. V2->V1:V2的普通变量传递给V1的自定义组件
4. V2->V1:V2的状态变量传递给V1的自定义组件
2.4 混用场景总结
3 V1->V2迁移指导
3.1 概述
3.2 V1V2使用指引
3.3 迁移指南的目的
3.4 V1V2能力对比及迁移简表
3.5 各装饰器迁移示例
@State->@Local
@Link -> @Param/@Event
@Prop -> @Param
@ObjectLink/@Observed/@Track -> @ObservedV2/@Trace
@Provide/@Consume -> @Provider/@Consumer
@Watch -> @Monitor
@Computed
LocalStorage->全局@ObservedV2/@Trace
AppStorage->AppStorageV2
Environment->调用Ability接口直接获取系统环境变量
PersistentStorage->PersistenceV2
1 自定义组件混用场景指导
1.1 概述
状态管理V1与V2的混用规则可以概括为:
-
V1的自定义组件中不可以使用V2的装饰器,否则编译报错。
-
组件间不存在变量传递时,V1的自定义组件中可以使用V2的自定义组件,包括import第三方@ComponentV2装饰的自定义组件。
-
组件间存在变量传递时,V1的变量传递给V2的自定义组件,有如下限制:
- V1中未被装饰器装饰的变量(后称普通变量):V2只能使用@Param接收。
- V1中被装饰器装饰的变量(后称状态变量):V2存在只能通过@Param装饰器接收,且仅限于boolean、number、enum、string、undefined、null这些简单类型数据。
-
V2的自定义组件中不可以使用V1的装饰器,否则编译报错。
-
组件间不存在变量传递时,V2自定义组件可以使用V1的自定义组件,包括import第三方@Component装饰的自定义组件。
-
组件间存在变量传递时,V2的变量传递给V1的自定义组件,有如下限制:
- V2中未被装饰器装饰的变量(后称普通变量):若V1使用装饰器装饰接收的数据,只能通过@State、@Prop、@Provide。
- V2中被装饰器装饰的变量(后称状态变量):若V1使用装饰器装饰接收的数据,不支持内置类型数据:Array、Set、Map、Date。
1.2 状态管理装饰器总览
状态管理V1的装饰器
装饰器类别 | 装饰器 |
---|---|
组件内装饰器 | @State、@Prop、@Link、@ObjectLink、@Provide、@Consume、@StorageProp、@StorageLink、@LocalStorageProp、@LocalStorageLink、@Watch |
类相关装饰器 | @Observed、@Track |
状态管理V2的装饰器
装饰器类别 | 装饰器 |
---|---|
组件内装饰器 | @Local、@Param、@Provider、@Consumer、@Once、@Event、@Monitor、@Computed |
类相关装饰器 | @ObservedV2、@Trace、@Type |
状态管理装饰器支持的数据类型总览
状态管理能够支持的数据类型有:
数据类型 | 关键字 |
---|---|
简单类型数据 | boolean、number、enum、string、null、undefined |
function类型 | function(仅V2的@Event、@Monitor、@Computed支持) |
Object类型 | Object |
Class类型 | Class |
内置类型 | Array、Map、Set、Date |
1.3 限制条件
1.3.1 V1和V2的装饰器不允许混用
1.V1的自定义组件中不可以使用V2的装饰器
V2的组件内装饰器不允许在V1的自定义组件中使用,编译会报错。
@Local、@Param、@Event,@Provider、@Consumer、@Monitor、@Computed和示例代码中的装饰器表现一致。
2.V2的自定义组件中不可以使用V1的装饰器
V1的组件内装饰器不允许在V2的自定义组件中使用,编译会报错。
@ObjectLink、@Provide、@Consume、@StorageProp、@StorageLink、@LocalStorageProp、@LocalStorageLink和示例的装饰器表现一致。
3. 多个装饰器不允许装饰同一个变量(@Watch、@Once、@Require除外)
除了@Watch、@Once、@Require这些能力扩展装饰器可以配合其他装饰器使用外,其他装饰器不允许装饰同一个变量。
2 混用场景介绍
2.1 V1和V2类相关装饰器混用
1. V1的自定义组件中使用被@ObservedV2装饰的类对象
@ObservedV2的使用需要遵循如下规则:
- @ObservedV2只能装饰Class,@Trace、@Type只能装饰类属性,且只能在@ObservedV2中使用。
- @Track不可以在@ObservedV2中使用。
- 对于被@ObservedV2装饰的Class,不可以直接被V1的装饰器装饰,否则编译时报错。
- 示例中,开发者去掉报错的装饰器即可正常运行,被@Trace装饰的类属性变化时可以观察到变化,否则不可以观测到变化。
2. V2的自定义组件中使用被@Observed装饰的类对象
不建议开发者在V2中使用@Observed装饰的Class,因为@Observed和@Track仅能对类属性做区分,无观测能力,使用@Observed和@ObjectLink拆分嵌套数据才能够观测深层次数据,但@ObjectLink无法在V2的自定义组件中使用。
开发者在对V1的代码向V2迁移时,@Observed装饰的Class不建议在@ComponentV2中使用,无观测能力,如果一定要使用,则遵循以下规则:
- @Observed只能装饰Class,且@Trace不可以在@Observed中使用。
- @Observed和@Track无任何观测能力,只能用于防止Class中一个类属性改变而导致整个Class的刷新。
- 继承自@Observed的Class被V2装饰器装饰,V2的组件内装饰器无类属性观测能力,所以使用@Observed会无法观测到类属性变化。
- 示例中,开发者去掉报错的装饰器即可正常运行,由于无观测能力,所以不建议V2中使用@Observed。
2.2 不存在变量传递时,V1和V2的自定义组件混用
1. V1中使用V2的自定义组件
V1中使用V2的自定义组件,当不存在变量传递时无影响,若涉及变量传递,请见下一节V1和V2的数据混用。
2. V2中使用V1的自定义组件
2中使用V1的自定义组件,当不存在变量传递时无影响,若涉及变量传递,请见下一节V1和V2的数据混用。
2.3 存在变量传递时,V1和V2的自定义组件数据混用
1. V1->V2:V1的普通变量传递给V2的自定义组件
当V1的普通变量传递给V2的自定义组件时,有如下限制:
- V2的自定义组件必须通过@Param接收数据。
- 接收数据的观测能力为@Param能力,对于接收的Class,需要通过@ObservedV2和@Trace才能观察变化。
2. V1->V2:V1的状态变量传递给V2的自定义组件
当V1的状态变量给V2的自定义组件时,有如下规则:
仅支持简单类型变量,其余类型数据会在编译时报错。
示例中使用了@State装饰器,@Prop、@Link、@ObjectLink、@Provide、@Consume、@StorageProp、@StorageLink、@LocalStorageProp、@LocalStorageLink行为和@State保持一致。
3. V2->V1:V2的普通变量传递给V1的自定义组件
当V2的普通变量传递给V1自定义组件时:
V1可以不使用装饰器接收数据,接收过来的变量在V1组定义组件内也会是普通变量。
V1若使用装饰器接收数据,仅可通过@State、@Prop、@Provide接收。
4. V2->V1:V2的状态变量传递给V1的自定义组件
V2的状态变量传递给V1的自定义组件,存在如下限制:
V1可以不使用装饰器接收数据,接收过来的变量在V1组定义组件内也会是普通变量。
V1若使用装饰器接收数据,仅可通过@State、@Prop、@Provide接收。
V1若使用装饰器接收数据,不支持内置类型的数据。
2.4 混用场景总结
通过对V1和V2的混用场景详细梳理,可以看到,当V2的代码混用V1的代码时,即V1的组件或者类数据向V2进行传递,大部分V1的能力在V2都是被禁止的。而V1的代码去混用V2代码时,即V2的组件或者类数据向V1传递,做了部分功能开放,例如@ObservedV2和@Trace,这也是对V1嵌套类数据的观测能提供的最大的帮助。所以在代码开发时,不鼓励开发者使用V1和V2进行混用开发,但是对于代码迁移上,可以让V1的开发者逐步将代码向V2进行迁移,从而稳步替换V1的功能代码,并且十分不鼓励开发者在V2的代码架构上混用V1的代码。
3 V1->V2迁移指导
3.1 概述
ArkUI状态管理的主要职责是:负责将可观察数据的变化自动同步到UI界面,实现数据驱动的UI刷新,使开发者能更加够专注于UI界面的实现和设计。
在状态管理框架的演进过程中,先后推出了状态管理V1和V2两个版本。V1强调组件层级的状态管理,而V2则增强了对数据对象的深度观察与管理能力,不再局限于组件层级。通过V2,开发者能够更灵活地控制数据和状态,实现更高效的UI刷新。具体V1和V2的区别可以参见状态管理概述。
3.2 V1V2使用指引
- V2是V1的增强版本,为开发者提供更多功能和灵活性。
- 对于新开发的应用,建议直接使用V2版本范式来进行开发。
- 对于已经使用V1的应用,如果V1的功能和性能已能满足需求,则不必立即切换到V2。如果开发者在开发过程中受限于V1不能深度观察等特性,则建议开发者尽早规划向V2的迁移,以便未来实现平滑过渡和改进。
- 对于需要在现阶段混用V1和V2的场景,请参阅混用文档。编译器、工具链、IDE对某些不推荐的误用和混用场景会进行校验,虽然开发者可能可以通过特殊手段绕过这些校验,但还是强烈建议开发者遵循混用文档的指导,避免因双重代理等问题给应用带来不确定性。
3.3 迁移指南的目的
- 对希望将现有V1应用迁移到V2的开发者,提供系统化的模板和指导,帮助完成V1到V2的迁移。
- 对希望逐步将V1应用过渡到V2的开发者,提供参考,结合本迁移文档与混用文档,可以帮助开发者实现逐步改造。
- 尚未开始开发应用但已熟悉V1状态管理规则的开发者,可以参考本迁移文档及V2各个装饰器和接口的文档,开始使用V2进行应用开发。
3.4 V1V2能力对比及迁移简表
V1装饰器名 | V2装饰器名 | 说明 |
---|---|---|
@Observed | @ObservedV2 | 表明当前对象为可观察对象。但两者能力并不相同。 @Observed可观察第一层的属性,需要搭配@ObjectLink使用才能生效。 @ObservedV2本身无观察能力,仅代表当前class可被观察,如果要观察其属性,需要搭配@Trace使用。 |
@Track | @Trace | V1装饰器@Track为精确观察,不使用则无法做到类属性的精准观察。 V2@Trace装饰的属性可以被精确跟踪观察。 |
@Component | @ComponentV2 | @Component为搭配V1状态变量使用的自定义组件装饰器。 @ComponentV2为搭配V2状态变量使用的自定义组件装饰器。 |
@State | 无外部初始化:@Local 外部初始化一次:@Param@Once | @State和@Local类似都是数据源的概念,在不需要外部传入初始化时,可直接迁移。如果需要外部传入初始化,则可以迁移为@Param@Once,详情见@State->@Local。 |
@Prop | @Param | @Prop和@Param类似都是自定义组件参数的概念。当输入参数为复杂类型时,@Prop为深拷贝,@Param为引用。 |
@Link | @Param@Event | @Link是框架自己封装实现的双向同步,对于V2开发者可以通过@Param@Event自己实现双向同步。 |
@ObjectLink | @Param | 直接兼容,@ObjectLink需要被@Observed装饰的class的实例初始化,@Param没有此限制。 |
@Provide | @Provider | 兼容。 |
@Consume | @Consumer | 兼容。 |
@Watch | @Monitor | @Watch用于监听V1状态变量的变化,具有监听状态变量本身和其第一层属性变化的能力。状态变量可观察到的变化会触发其@Watch监听事件。 @Monitor用于监听V2状态变量的变化,搭配@Trace使用,可有深层监听的能力。状态变量在一次事件中多次变化时,仅会以最终的结果判断是否触发@Monitor监听事件。 |
LocalStorage | 全局@ObservedV2@Trace | 兼容。 |
AppStorage | AppStorageV2 | 兼容。 |
Environment | 调用Ability接口获取系统环境变量 | Environment获取环境变量能力和AppStorage耦合。在V2中可直接调用Ability接口获取系统环境变量。 |
PersistentStorage | PersistenceV2 | PersistentStorage持久化能力和AppStorage耦合,PersistenceV2持久化能力可独立使用。 |
3.5 各装饰器迁移示例
@State->@Local
迁移规则
在V1中,@State装饰器用于装饰组件内部的状态变量,在V2中提供了@Local作为其替代能力,但两者在观察能力和初始化规则上存在明显差异。针对不同的使用场景,迁移策略如下:
- 简单类型:对于简单类型的变量,可以直接将@State替换为@Local。
- 复杂类型:V1中的@State可以观察复杂对象的第一层属性变化,而V2中的@Local只能观察对象自身的变化。如果需要追踪对象内部的属性变化,可以结合使用@ObservedV2和@Trace。
- 外部初始化:V1中,@State支持从外部传递初始值,但在V2中,@Local禁止外部初始化。若需要从外部传递初始值,可以使用@Param和@Once装饰器来实现类似的效果。
@Link -> @Param/@Event
迁移规则
在V1中,@Link允许父组件和子组件之间进行双向数据绑定。迁移到V2时,可以用@Param和@Event模拟双向同步。@Param实现父到子的单向传递,子组件再通过@Event回调函数触发父组件的状态更新。
@Prop -> @Param
迁移规则
在V1中,@Prop装饰器用于从父组件传递参数给子组件,这些参数在子组件中可以被直接修改。在V2中,@Param取代了@Prop的作用,但@Param是只读的,子组件不能直接修改参数的值。因此,根据场景的不同,有几种迁移策略:
- 简单类型:对于简单类型的参数,可以直接将@Prop替换@Param。
- 复杂类型:如果传递的是复杂对象且需要严格的单向数据绑定,可以对对象进行深拷贝,防止子组件修改父组件的数据。
- 子组件修改变量:如果子组件需要修改传入的参数,可以使用@Once来允许子组件对在本地修改该变量。但需要注意,如果使用了@Once,则代表当前子组件只会被初始化一次,后续并没有父组件到子组件的同步能力。
复杂类型的单向数据传递
在V2中,传递复杂类型时,如果希望实现严格的单向数据绑定,防止子组件修改父组件的数据,需要在使用@Param传递复杂对象时进行深拷贝以避免传递对象的引用。
子组件修改变量
在V1中,子组件可以修改@Prop的变量,然而在V2中,@Param是只读的。如果子组件需要修改传入的值,可以使用@Param和@Once允许子组件在本地修改。
@ObjectLink/@Observed/@Track -> @ObservedV2/@Trace
迁移规则
在V1中,@Observed与@ObjectLink装饰器用于观察类对象及其嵌套属性的变化,但V1只能直接观察对象的第一层属性。对于嵌套对象的属性,必须通过自定义组件和@ObjectLink实现观察。此外,V1中提供了@Track装饰器来实现对属性级别变化的精确控制。
在V2中,@ObservedV2与@Trace结合使用,可以高效地实现类对象及其嵌套属性的深度观察,省去了对自定义组件的依赖,简化了开发流程。同时,@Trace装饰器还具备精确更新的能力,替代了V1中的@Track,从而实现更高效的UI刷新控制。根据不同的场景,有以下迁移策略:
- 嵌套对象的属性观察:V1中需要通过自定义组件和@ObjectLink观察嵌套属性,V2中则可以使用@ObservedV2和@Trace直接观察嵌套对象,简化了代码结构。
- 类属性的精确更新:V1中的@Track可以用V2中的@Trace取代,@Trace可以同时观察和精确更新属性变化,使代码更简洁高效。
嵌套对象属性观察方法
在V1中,无法直接观察嵌套对象的属性变化,只能观察到第一层属性的变化。必须通过创建自定义组件并使用@ObjectLink来实现对嵌套属性的观察。V2中使用@ObservedV2和@Trace,可以直接对嵌套对象的属性进行深度观察,减少复杂度。
类属性变化观测
在V1中,@Observed用于观察类实例及其属性的变化,@Track则用于对属性级别的变化优化,使得只有被@Track装饰的属性触发UI更新。在V2中,@Trace结合了观察和更新属性级别变化的能力,搭配@ObservedV2实现高效的UI更新。
@Provide/@Consume -> @Provider/@Consumer
迁移规则
V1的@Provide/@Consume和V2@Provider/@Consumer定位和作用大体类似,基本可以实现丝滑替换,但是有以下细微差距,开发者可根据自己代码实现来参考是否需要调整:
在V1中,@Provide和@Consume用于父子组件之间的数据共享,可以通过alias(别名)或属性名匹配,同时@Consume必须依赖父组件的@Provide,不允许本地初始化。而V2中,@Provider和@Consumer增强了这些特性,使数据共享更加灵活。根据不同的场景,有以下迁移策略:
- V1中@Provide/@Consume在没有指定alias的情况下,可以直接使用。V2中@Provider/@Consumer是标准装饰器,且参数可选,所以不管有无指定alias后面需要必须跟随“()”。
- alias和属性名匹配规则:V1中,@Provide和@Consume可以通过alias或属性名匹配;V2中,alias是唯一的匹配key,指定alias后只能通过alias匹配。
- 本地初始化支持:V1中,@Consume不允许本地初始化,必须依赖父组件;V2中,@Consumer支持本地初始化,当找不到对应的@Provider时使用本地默认值。
- 从父组件初始化:V1中,@Provide可以直接从父组件初始化;V2中,@Provider不支持外部初始化,需用@Param和@Once接受初始值并赋给 @Provider。
- 重载支持:V1中,@Provide默认不支持重载,需设置 allowOverride;V2中,@Provider默认支持重载,@Consumer会向上查找最近的@Provider。
@Watch -> @Monitor
迁移规则
在V1中,@Watch用于监听状态变量的变化,并在变量变化时触发指定回调函数。在V2中,@Monitor替代了@Watch,可以更灵活地监听变量的变化,并获取变量变化前后的值。具体的迁移策略如下:
- 单变量监听:对于简单的场景,可以直接用@Monitor替换@Watch,效果一致。
- 多变量监听:V1的@Watch无法获取变化前的值。在V2中,@Monitor支持同时监听多个变量,并可以访问变量变化前后的状态。
@Computed
迁移规则
V1中并没有提供计算属性的概念,所以对于UI中的冗余计算,并没有办法可以减少重复计算。V2针对该场景,提供了@Computed装饰器,可以帮助开发者减少重复计算。
LocalStorage->全局@ObservedV2/@Trace
迁移规则
LocalStorage的目的是为了实现页面间的状态变量共享。之所以提供这个能力,是因为V1状态变量和View层耦合,无法由开发者自主地实现页面间状态变量的共享。
对于状态管理V2,状态变量的观察能力内嵌到数据本身,不再和View层耦合,所以对于状态管理V2,不再需要类似LocalStorage的能力,可以使用全局@ObservedV2/@Trace,由开发者自己import和export,自己实现状态变量的页面间共享。
AppStorage->AppStorageV2
上一小节中,对于全局的@ObserveV2/@Trace的改造并不适合跨Ability的数据共享,该场景可以使用AppStorageV2来替换。
Environment->调用Ability接口直接获取系统环境变量
V1中,开发者可以通过Environment来获取环境变量,但Environment获取的结果无法直接使用,需要配合AppStorage才能得到对应环境变量的值。
PersistentStorage->PersistenceV2
V1中PersistentStorage提供了持久化UI数据的能力,而V2则提供了更加方便使用的PersistenceV2接口来替代它。
- PersistentStorage持久化的触发时机依赖AppStorage的观察能力,且与AppStorage耦合,开发者无法自主选择写入或读取持久化数据的时机。
- PersistentStorage使用序列化和反序列化,并没有传入类型,所以在持久化后,会丢失其类型,且对象的属性方法不能持久化。
对于PersistenceV2:
- 与PersistenceV2关联的@ObservedV2对象,其@Trace属性的变化,会触发整个关联对象的自动持久化。
- 开发者也可以调用PersistenceV2.save和PersistenceV2.connect接口来手动触发持久化写入和读取。
相关文章:
【鸿蒙开发】第三十六章 状态管理 - V1V2混用和迁移指导
目录 1 自定义组件混用场景指导 1.1 概述 1.2 状态管理装饰器总览 状态管理V1的装饰器 状态管理V2的装饰器 状态管理装饰器支持的数据类型总览 1.3 限制条件 1.3.1 V1和V2的装饰器不允许混用 1.V1的自定义组件中不可以使用V2的装饰器 2.V2的自定义组件…...

轮子项目--消息队列的实现(3)
上一篇文章中我把一些关键的类以及表示出来,如何对这些类对应的对象进行管理呢?管理分为硬盘和内存上,硬盘又分为数据库(管理交换机,队列和绑定)和文件(管理消息),本文就…...

一文深入了解DeepSeek-R1:模型架构
本文深入探讨了 DeepSeek-R1 模型架构。让我们从输入到输出追踪 DeepSeek-R1 模型,以找到架构中的新发展和关键部分。DeepSeek-R1 基于 DeepSeek-V3-Base 模型架构。本文旨在涵盖其设计的所有重要方面。 📝 1. 输入上下文长度 DeepSeek-R1的输入上下文长…...
秘密信息嵌入到RGB通道的方式:分段嵌or完整嵌入各通道
目录 1. 将秘密信息分为三部分的理由 (1)均匀分布负载 (2)提高鲁棒性 (3)容量分配 2. 不将秘密信息分为三部分的情况 (1)嵌入容量 (2)视觉质量 &#…...
Ai人工智能的未来:趋势、挑战与机遇
Ai人工智能的未来:趋势、挑战与机遇 引言 人工智能(AI)已经成为当代科技发展的核心驱动力,其影响力渗透到各个行业,并塑造了我们未来的社会结构。无论是在医疗、金融、制造业,还是在自动驾驶、智能客服、…...
理解WebGPU 中的 GPUDevice :与 GPU 交互的核心接口
在 WebGPU 开发中, GPUDevice 是一个至关重要的对象,它是与 GPU 进行交互的核心接口。通过 GPUDevice ,开发者可以创建和管理 GPU 资源(如缓冲区、纹理、管线等),并提交命令缓冲区以执行渲染和计算任…...

Java 设计模式之桥接模式
文章目录 Java 设计模式之桥接模式概述UML代码实现 Java 设计模式之桥接模式 概述 桥接模式(Bridge):将抽象部分与它的实现部分分离,使它们都可以独立地变化。通过桥接模式,可以避免类爆炸问题,并提高系统的可扩展性。 UML 核心…...

机器学习(李宏毅)——GAN
一、前言 本文章作为学习2023年《李宏毅机器学习课程》的笔记,感谢台湾大学李宏毅教授的课程,respect!!! 不得不说GAN真是博大精深! 二、大纲 GAN问世基本思想原理剖析Tips of GANGAN的应用Cycle GANEva…...
QT无弹窗运行和只允许运行一个exe
最近做一个小功能,需要后台运行QT程序,无弹窗,并且只允许一个exe运行,不关闭程序,无法2次启动。 main.cpp #include "deleteshotcurveflie.h" #include <QApplication> #include <QSharedMemory&…...

C++ STL 容器
C 的 STL(Standard Template Library) 提供了多种容器,分为以下几类: 序列容器(Sequence Containers)关联容器(Associative Containers)无序关联容器(Unordered Associa…...
开源赋能,智造未来:Odoo+工业物联网,解锁智能工厂新范式——以真实案例解读制造业数字化转型的降本增效密码
工业物联网的机遇与挑战:为什么企业需要Odoo? 《中国智能制造发展研究报告2023》指出,85%的制造企业已启动数字化转型,但超60%面临“数据孤岛、系统割裂、成本高企”的痛点[1]。传统ERP系统难以实时对接产线设备,而定…...
CTF-WEB: 利用iframe标签利用xss,waf过滤后再转换漏洞-- N1ctf Junior display
核心逻辑 // 获取 URL 查询参数的值 function getQueryParam(param) { // 使用 URLSearchParams 从 URL 查询字符串中提取参数 const urlParams new URLSearchParams(window.location.search); // 返回查询参数的值 return urlParams.get(param); } // 使用 DOMPuri…...

K8s组件
一、Kubernetes 集群架构组件 K8S 是属于主从设备模型(Master-Slave 架构),即有 Master 节点负责集群的调度、管理和运维,Slave 节点是集群中的运算工作负载节点。 主节点一般被称为 Master 节点,master节点上有 apis…...
python面试题
以下是一些Python面试题: 一、基础语法 Python中的列表(list)和元组(tuple)有什么区别? 答案: 可变性:列表是可变的,可以修改列表中的元素、添加或删除元素;元组是不可变的,一旦创建就不能修改。语法:列表使用方括号[]定义,元组使用圆括号()定义(单个元素的元组…...
AOS安装及操作演示
文章目录 一、安装node1.1 在 macOS 上管理 Node版本1.1.1 安装 nvm1.1.2 验证 nvm 是否安装成功1.1.3 使用 nvm 安装/切换 Node.js 版本1.1.4 卸载 Node.js 版本 1.2 在 windows 上管理 Node版本1.2.1 安装 nvm-windows1.2.2 安装 Node.js 版本1.2.3 切换 Node.js 版本1.2.4 卸…...
蓝桥杯单片机组第十三届初赛试题-程序题(第2批)
题目到官网看即可,有点久了有些细节记不清了,可能以前发的帖子解释详细一点。 这是我单片机初学的时候写的,像代码结构什么的肯定有可以提升的地方,多多包涵,将就看一下。 i2c文件使用官方的,pcf8591函数…...

企业级高可用 Kubernetes 实践:基于青云 LB 搭建容灾与负载均衡集群全攻略
一、前言 在企业生产环境,k8s高可用是一个必不可少的特性,其中最通用的场景就是如何在 k8s 集群宕机一个节点的情况下保障服务依旧可用。部署高可用k8s集群对于企业级云平台来说是一个根本性的原则,容错、服务可用和数据安全是高可用基础设施的关键。本文是在青云上利用青云…...

Python Pandas(11):Pandas 数据可视化
数据可视化是数据分析中的重要环节,它帮助我们更好地理解和解释数据的模式、趋势和关系。通过图形、图表等形式,数据可视化将复杂的数字和统计信息转化为易于理解的图像,从而便于做出决策。Pandas 提供了与 Matplotlib 和 Seaborn 等可视化库…...
【练习】图论
F. Friendly Group 图中选择一个点-1 边两端点都选择1 边一个端点选择-1 添加链接描述 #include<iostream> using namespace std; #include<vector> #include<cstring> const int N300010; int n,m; vector<int> G[N]; int temp1,temp2; bool vis[N…...

【RAG落地利器】Weaviate、Milvus、Qdrant 和 Chroma 向量数据库对比
什么是向量数据库? 向量数据库是一种将数据存储为高维向量的数据库,高维向量是特征或属性的数学表示。每个向量都有一定数量的维度,根据数据的复杂性和粒度,可以从数十到数千不等。 向量通常是通过对原始数据(如文本、图像、音频、视频等)…...
生成xcframework
打包 XCFramework 的方法 XCFramework 是苹果推出的一种多平台二进制分发格式,可以包含多个架构和平台的代码。打包 XCFramework 通常用于分发库或框架。 使用 Xcode 命令行工具打包 通过 xcodebuild 命令可以打包 XCFramework。确保项目已经配置好需要支持的平台…...

定时器任务——若依源码分析
分析util包下面的工具类schedule utils: ScheduleUtils 是若依中用于与 Quartz 框架交互的工具类,封装了定时任务的 创建、更新、暂停、删除等核心逻辑。 createScheduleJob createScheduleJob 用于将任务注册到 Quartz,先构建任务的 JobD…...

【单片机期末】单片机系统设计
主要内容:系统状态机,系统时基,系统需求分析,系统构建,系统状态流图 一、题目要求 二、绘制系统状态流图 题目:根据上述描述绘制系统状态流图,注明状态转移条件及方向。 三、利用定时器产生时…...
TRS收益互换:跨境资本流动的金融创新工具与系统化解决方案
一、TRS收益互换的本质与业务逻辑 (一)概念解析 TRS(Total Return Swap)收益互换是一种金融衍生工具,指交易双方约定在未来一定期限内,基于特定资产或指数的表现进行现金流交换的协议。其核心特征包括&am…...
根据万维钢·精英日课6的内容,使用AI(2025)可以参考以下方法:
根据万维钢精英日课6的内容,使用AI(2025)可以参考以下方法: 四个洞见 模型已经比人聪明:以ChatGPT o3为代表的AI非常强大,能运用高级理论解释道理、引用最新学术论文,生成对顶尖科学家都有用的…...
大语言模型(LLM)中的KV缓存压缩与动态稀疏注意力机制设计
随着大语言模型(LLM)参数规模的增长,推理阶段的内存占用和计算复杂度成为核心挑战。传统注意力机制的计算复杂度随序列长度呈二次方增长,而KV缓存的内存消耗可能高达数十GB(例如Llama2-7B处理100K token时需50GB内存&a…...

打手机检测算法AI智能分析网关V4守护公共/工业/医疗等多场景安全应用
一、方案背景 在现代生产与生活场景中,如工厂高危作业区、医院手术室、公共场景等,人员违规打手机的行为潜藏着巨大风险。传统依靠人工巡查的监管方式,存在效率低、覆盖面不足、判断主观性强等问题,难以满足对人员打手机行为精…...
第八部分:阶段项目 6:构建 React 前端应用
现在,是时候将你学到的 React 基础知识付诸实践,构建一个简单的前端应用来模拟与后端 API 的交互了。在这个阶段,你可以先使用模拟数据,或者如果你的后端 API(阶段项目 5)已经搭建好,可以直接连…...
文件上传漏洞防御全攻略
要全面防范文件上传漏洞,需构建多层防御体系,结合技术验证、存储隔离与权限控制: 🔒 一、基础防护层 前端校验(仅辅助) 通过JavaScript限制文件后缀名(白名单)和大小,提…...

Axure零基础跟我学:展开与收回
亲爱的小伙伴,如有帮助请订阅专栏!跟着老师每课一练,系统学习Axure交互设计课程! Axure产品经理精品视频课https://edu.csdn.net/course/detail/40420 课程主题:Axure菜单展开与收回 课程视频:...