鸿蒙API18~26新增V2组件全解析
鸿蒙API18~26新增V2组件全解析
一、为什么值得关注这批组件
HarmonyOS 的系统预置 UI 组件库(@kit.ArkUI 里的 advanced 组件)过去长期基于状态管理 V1 实现:页面用 @Component + @State,组件内部状态与外部数据的联动要经过多层复制与同步。从 API 18(HarmonyOS 5.1.0) 开始,官方正式提供了一批基于状态管理 V2 实现的预置组件——它们内部用 @ComponentV2 / @ObservedV2 / @Trace 搭建,能直接吃下页面里的 V2 状态对象,实现属性级精准刷新。到 API 26(26.0.0,语义化版本号时代的第一个大版本),第二批 V2 组件落地,这个家族正式覆盖了弹窗、进度、分段、标签、步进器、气泡、下拉刷新、树形视图等高频场景。
对开发者的直接收益有三点:
- 状态外置、深度观测:V2 组件的入参大多是
@Param引用传递,配合@ObservedV2 + @Trace的数据类,深层数据变化能精准驱动组件刷新,不需要深拷贝。 - 与
@ComponentV2页面无缝衔接:新页面直接用 V2 范式开发,这批组件开箱即用,不必再为用 V1 组件而回退到@Component。 - 官方标准交互,零定制成本:下载按钮、分段选择、标签筛选这些高频交互直接用官方组件,风格与系统一致。
本文把 API 18 → API 26 之间新增的全部 V2 组件逐一列出,标注使用方法,并给出可直接运行的关键示例。
背景补充:同一时期 ArkUI 还在 API 26 引入了组件级沉浸光感(通用属性
systemMaterial),那部分内容此前已有专文讲解,本文聚焦状态管理 V2 组件线。
二、V2 组件的四个共性规则
学具体组件之前,先记住这批组件共同的「游戏规则」,能避免绝大多数踩坑:
1. 全部由 @ComponentV2 实现,宿主页面也应是 V2 范式。 V2 组件内部只能搭配 @Local、@Param、@Event 等 V2 装饰器。如果你的页面还是 @Component + @State,要么迁移页面,要么把传给组件的数据抽成 @ObservedV2 类。
2. 输入输出契约清晰:@Param 进、@Event 出。 属性大多标记 @Require @Param(必传)或 @Param(可选),回调统一是 @Event。需要双向同步时用 !! 语法糖,例如 selectedIndex: this.segIndex!!——组件内部改选中的页签,你的 @Local 变量会同步更新。
3. 不要给 V2 组件设置通用属性/通用事件。 这是官方文档反复强调的坑:如果对这类组件设置 .width()、.onClick() 等通用属性,编译工具链会额外生成一个 __Common__ 节点并把属性挂上去,而不是挂在组件本身,结果就是「设了不生效」。正确做法是宽高、外边距、点击都包在外层容器上。
4. 模型与设备限制。 全部仅支持 Stage 模型;API 18 批次从 API 18 起支持(大部分同时支持元服务),API 26 批次从 26.0.0 起支持(设备需升到 HarmonyOS 7 对应版本);多数组件在 Wearable 设备上调用会运行异常。
三、API 18 批次(HarmonyOS 5.1.0)
3.1 DialogV2 弹窗全家桶(7 个)
一次给出七种标准模态弹窗,全部 @ComponentV2 实现,配合 this.getUIContext().getPromptAction().openCustomDialog 拉起:
| 组件 | 适用场景 |
|---|---|
TipsDialogV2 | 带图形的重要提示(如卸载确认) |
SelectDialogV2 | 单选列表弹窗(选语言、选地区) |
ConfirmDialogV2 | 确认弹窗,可带 checkbox |
AlertDialogV2 | 警告弹窗 |
LoadingDialogV2 | 加载中弹窗 |
CustomContentDialogV2 | 自定义内容弹窗 |
PopoverDialogV2 | 气泡弹窗 |
七个弹窗共享同一套基础契约(title/content + primaryButton/secondaryButton 双按钮),差异化体现在各自的专属属性上:
| 差异点 | 说明 |
|---|---|
| 图形区 | TipsDialogV2 独有 imageRes/imageSize/imageBorderColor,可给提示配图形 |
| 勾选框 | TipsDialogV2 与 ConfirmDialogV2 支持 checkTips + checked + onCheckedChange,「不再提示」类需求零成本 |
| 单选列表 | SelectDialogV2 独有 radioContent(SheetInfo[])+ selectedIndex |
| 自定义内容 | CustomContentDialogV2 允许在弹窗内塞自定义内容区 |
import { SelectDialogV2, TipsDialogV2, AdvancedDialogV2Button } from '@kit.ArkUI';
@Entry
@ComponentV2
struct DialogDemo {
@Local formatIndex: number = 0;
// 单选列表弹窗:标准「标题 + 单选列表 + 确认按钮」布局
@Builder
selectBuilder(): void {
SelectDialogV2({
title: '选择导出格式',
selectedIndex: this.formatIndex,
radioContent: [
{ title: 'Markdown', action: () => { this.formatIndex = 0; } },
{ title: 'PDF', action: () => { this.formatIndex = 1; } },
{ title: 'HTML', action: () => { this.formatIndex = 2; } }
],
confirm: new AdvancedDialogV2Button({ content: '确定', action: () => {} })
})
}
build() {
Button('选择导出格式')
.onClick(() => {
this.getUIContext().getPromptAction().openCustomDialog({
builder: () => { this.selectBuilder() }
})
})
}
}
要点:
- 列表项
radioContent是SheetInfo[],每项的action回调里自己维护选中索引(@Param只读,选中态由你驱动); - 按钮
AdvancedDialogV2Button统一描述content+action; - 与 V1 的
CustomDialogController相比,官方更推荐 V2 场景使用openCustomDialog。注意调用入口与重载选择:openCustomDialog/closeCustomDialog挂在UIContext.getPromptAction()返回的PromptAction上(UIContext本身没有这两个方法)。openCustomDialog直传 builder 的重载返回Promise<void>,而传{ builder: () => { this.xxx() } }选项对象的重载返回Promise<number>(dialogId),需要程序化关弹窗时用后者,把返回的 dialogId 传给closeCustomDialog(dialogId)。
▶ 运行效果(图1):三种弹窗实体对比——TipsDialogV2「已保存」(纯提示 + 确定按钮)、ConfirmDialogV2「删除所选文件?」(勾选框「同时删除云端副本」+ 取消/删除双按钮)、AlertDialogV2「网络连接失败」(警告 + 取消/重试),家族共性(标题/正文/双按钮)与各自专属属性一图看全。

3.2 ProgressButtonV2 进度下载按钮
带进度填充的文字按钮,专为「下载/同步」场景设计。内部状态类 ProgressButtonV2Color 用 @ObservedV2 + @Trace 实现,改颜色属性即刷 UI。
import { LengthMetrics, ProgressButtonV2 } from '@kit.ArkUI';
@Entry
@ComponentV2
struct DownloadDemo {
@Local progress: number = 0;
@Local isDone: boolean = false;
private timerId: number = -1;
startDownload(): void {
if (this.isDone) {
this.progress = 0;
this.isDone = false;
}
this.timerId = setInterval(() => {
this.progress += 2;
if (this.progress >= 100) {
this.progress = 100;
this.isDone = true;
clearInterval(this.timerId);
}
}, 60);
}
build() {
Column() {
// 宽度设置在外层容器——不要直接给组件设通用属性
Column() {
ProgressButtonV2({
progress: this.progress, // 0~100,越界自动截断
content: this.isDone ? '重新下载' : '下载',
progressButtonWidth: LengthMetrics.vp(220), // 默认 44vp
onClicked: () => { this.startDownload(); },
isEnabled: true
})
}
.width('100%')
}
}
}
核心参数:progress、content、onClicked、isEnabled 均为必填;可选 progressButtonWidth(LengthMetrics)与 progressButtonRadius。
两个「调样式」的重要属性值得单独演示对比:
progressButtonRadius:默认值是高度的一半(标准胶囊),传小值可变成圆角矩形;colorOptions:ProgressButtonV2Color是@ObservedV2类,四个颜色属性(progressColor/borderColor/textColor/backgroundColor)都是@Trace,改一个就精准刷新——这正是「基于状态管理 V2 实现」的组件带来的能力:
import { ProgressButtonV2Color, ColorMetrics } from '@kit.ArkUI';
ProgressButtonV2({
progress: this.progress,
content: '开始下载',
progressButtonWidth: LengthMetrics.vp(200),
progressButtonRadius: LengthMetrics.vp(8), // 胶囊 → 圆角矩形
colorOptions: new ProgressButtonV2Color({ // 系统蓝 → 绿色主题
progressColor: ColorMetrics.resourceColor('#34C759'),
borderColor: ColorMetrics.resourceColor('#34C759'),
textColor: ColorMetrics.resourceColor('#1A7A37'),
backgroundColor: ColorMetrics.resourceColor('#EAF7EE')
}),
onClicked: () => { this.startDownload(); },
isEnabled: true
})
▶ 运行效果(图2 GIF):两个按钮共用同一进度值——上为默认胶囊样式(系统蓝),下为
progressButtonRadius: 8vp+ 绿色colorOptions,点击后进度从 0% 同步填充到 100%,圆角与配色差异全程可见。

3.3 SegmentButtonV2 分段按钮(3 个子组件)
| 子组件 | 形态 |
|---|---|
TabSegmentButtonV2 | 页签型 |
CapsuleSegmentButtonV2 | 单选胶囊型 |
MultiCapsuleSegmentButtonV2 | 多选胶囊型 |
数据类 SegmentButtonV2Items(@ObservedV2)承载选项,支持文本、图标、Symbol 及图文混合。三个子组件的选中属性不同:页签型与单选胶囊型用 selectedIndex(number),多选胶囊型用 selectedIndexes(number 数组),都推荐用 !! 双向绑定接住点选结果:
import { SegmentButtonV2Items, TabSegmentButtonV2, CapsuleSegmentButtonV2, MultiCapsuleSegmentButtonV2 } from '@kit.ArkUI';
@Entry
@ComponentV2
struct SegmentDemo {
@Local tabItems: SegmentButtonV2Items =
new SegmentButtonV2Items([{ text: '手机' }, { text: '平板' }, { text: 'PC/2in1' }]);
@Local tabIndex: number = 0;
@Local rangeItems: SegmentButtonV2Items =
new SegmentButtonV2Items([{ text: '日' }, { text: '周' }, { text: '月' }]);
@Local rangeIndex: number = 1;
@Local switchItems: SegmentButtonV2Items =
new SegmentButtonV2Items([{ text: 'Wi-Fi' }, { text: '蓝牙' }, { text: '定位' }]);
@Local switchIndex: Array<number> = [0, 1];
build() {
Column({ space: 12 }) {
// ① 页签型:selectedIndex 单选,!! 双向绑定回写点选结果
TabSegmentButtonV2({ items: this.tabItems, selectedIndex: this.tabIndex!! })
// ② 单选胶囊型:属性契约与页签型一致,形态不同
CapsuleSegmentButtonV2({ items: this.rangeItems, selectedIndex: this.rangeIndex!! })
// ③ 多选胶囊型:selectedIndexes 是数组,可默认多项选中
MultiCapsuleSegmentButtonV2({ items: this.switchItems, selectedIndexes: this.switchIndex!! })
Text(`页签:${this.tabIndex} 区间:${this.rangeIndex} 开关:${JSON.stringify(this.switchIndex)}`)
}
}
}
▶ 运行效果(图3):自上而下对应示例代码 ①②③——页签型
selectedIndex单选(选中「概述」)、单选胶囊(默认选中「周」)、多选胶囊selectedIndexes默认选中 Wi-Fi + 蓝牙,选中态样式由子组件形态决定。

另外,从 API 23 起 TabSegmentButtonV2 / CapsuleSegmentButtonV2 还提供了 backgroundSystemMaterial(系统 API)配置系统材质背景,可与沉浸光感体系组合使用。
四、API 26 批次(26.0.0)
4.1 ChipGroupV2 / ChipV2 标签组
单选或多选的操作块群组,适合分类、筛选、标签选择。ChipGroupV2Items 同样是 @ObservedV2 数据类,对象属性的内部变化也能被监听。
import { ChipGroupV2, ChipGroupV2Items, ChipGroupV2ItemStyle, ChipV2Size } from '@kit.ArkUI';
@Entry
@ComponentV2
struct ChipDemo {
// items 持有在 @Local 中,配合 !! 双向绑定,组件内删标签会同步收缩
@Local chipItems: ChipGroupV2Items = new ChipGroupV2Items([
{ label: { text: '全部' }, allowClose: true }, // allowClose: true → 标签右侧渲染 ×
{ label: { text: '文档' }, allowClose: true },
{ label: { text: '图片' }, allowClose: false }, // false 或缺省 → 不显示关闭图标
{ label: { text: '视频' }, allowClose: true }
]);
@Local selected: Array<number> = [0];
build() {
Column() {
ChipGroupV2({
items: this.chipItems!!,
itemStyle: new ChipGroupV2ItemStyle({ size: ChipV2Size.SMALL }),
selectedIndexes: this.selected,
multiple: false,
onChange: (activated: Array<number>) => {
this.selected = activated;
}
})
Text(`当前标签数:${this.chipItems.length}`)
}
}
}
每个 item 支持 prefixIcon / prefixSymbolIcon / suffixIcon / suffixSymbolIcon / allowClose 等配置。其中 allowClose: true 会在标签右侧渲染一个 × 关闭图标,点击后该项从 items 中移除——前提是把 items 持有在 @Local 中并用 !! 双向绑定传给组件,删除结果才能回传到你的数据源并驱动 Text 等关联视图刷新;allowClose: false(默认值)则不显示关闭图标。注意:传入 suffixIcon 或 suffixSymbolIcon 时 allowClose 不生效(后缀位置被自定义图标占用)。另外,multiple: true 时 selectedIndexes 是索引数组;$selectedIndexes 回调可实现选中索引的双向绑定;suffix 参数可在群组最右侧挂自定义组件(官方提供 ChipGroupV2IconGroupSuffix)。
▶ 运行效果(图4 GIF):上组单选 + SMALL + 全部可关闭——依次点掉「文档」「视频」后「当前标签数」从 5 变 3;下组多选 + NORMAL +
allowClose混合(红色/蓝色无 ×,绿色/黄色有 ×),多选索引随点选实时变化。

4.2 CounterV2 步进器(4 种形态)
CounterV2Type | 形态 | 配套样式参数 |
|---|---|---|
LIST | 列表型 | numberOptions |
COMPACT | 紧凑型 | numberOptions |
INLINE | 数值内联型 | inlineOptions |
INLINE_DATE | 日期内联型 | dateOptions |
import { CounterV2Component, CounterV2Type, CounterV2DateData } from '@kit.ArkUI';
@Entry
@ComponentV2
struct CounterDemo {
@Local count: number = 5;
@Local dateText: string = '';
build() {
Column({ space: 12 }) {
CounterV2Component({
options: {
type: CounterV2Type.INLINE,
inlineOptions: {
value: this.count,
min: 0,
max: 99,
step: 1,
onChange: (value: number) => { this.count = value; }
}
}
})
CounterV2Component({
options: {
type: CounterV2Type.INLINE_DATE,
dateOptions: {
year: 2026, month: 11, day: 10,
onDateChange: (date: CounterV2DateData) => {
// date.toString() 返回 "YYYY-MM-DD"
this.dateText = date.toString();
}
}
}
})
Text(`数量:${this.count} 日期:${this.dateText}`)
}
}
}
数值型共用 value/min/max/step/onChange 契约;日期型回调返回 CounterV2DateData,自带 toString()。
形态与属性的组合关系值得记住:LIST/COMPACT 走 numberOptions,比 INLINE 多一个 label 说明文本;step 步长(≥1 整数,默认 1)在日期内联型上不生效;value 越过 min/max 时自动截断。把四种形态摆在一起看差异最直观:
// LIST 列表型:带 label 说明文本,适合表单里的独立一行
CounterV2Component({
options: { type: CounterV2Type.LIST, numberOptions: { label: '价格', value: 5, min: 0, max: 10 } }
})
// COMPACT 紧凑型:同样有 label,尺寸更小,step: 10 大步长演示
CounterV2Component({
options: { type: CounterV2Type.COMPACT, numberOptions: { label: '数量', value: 10, min: 0, max: 100, step: 10 } }
})
▶ 运行效果(图5):四宫格对照——左上 LIST 列表型(「价格」label + 大按钮)、右上 COMPACT 紧凑型(「数量」label、step: 10)、左下 INLINE 数值内联型(上下箭头步进)、右下 INLINE_DATE 日期内联型(日期 2026/11/10 上下调节),底部一行实时回显当前值。

4.3 PopupV2 气泡
用于提示、操作确认、信息通知的气泡弹窗,@Builder 装饰,配合 getPromptAction().openCustomDialog 使用。气泡的精髓在于区别于普通模态弹窗的轻量感:居中悬浮但蒙层全透明(不压暗页面)、autoCancel 点气泡外任意区域即收、onClose 响应右上角 ×:
import { PopupV2, PopupV2Button, ImageModifier, TextModifier } from '@kit.ArkUI';
// 组件内
@Local dialogId: number = -1;
@Builder
popupBuilder(): void {
PopupV2({
icon: $r('sys.media.ohos_ic_public_ok'),
iconModifier: new ImageModifier().width(24).height(24).fillColor('#0A59F7'),
title: '轻提示气泡',
titleModifier: new TextModifier().fontSize(16).fontWeight(FontWeight.Bold).fontColor('#E6000000'),
message: '区别于普通弹窗:蒙层透明不压暗页面,点气泡外任意区域即可收起。',
messageModifier: new TextModifier().fontSize(13).fontColor('#99000000').lineHeight(18),
showClose: true,
maxWidth: 300,
onClose: () => { this.getUIContext().getPromptAction().closeCustomDialog(this.dialogId); },
buttons: [
{ text: '稍后再说', action: () => { this.getUIContext().getPromptAction().closeCustomDialog(this.dialogId); },
buttonTextModifier: new TextModifier().fontSize(14).fontColor('#99000000') },
{ text: '知道了', action: () => { this.getUIContext().getPromptAction().closeCustomDialog(this.dialogId); },
buttonTextModifier: new TextModifier().fontSize(14).fontWeight(FontWeight.Medium).fontColor('#0A59F7') }
] as [PopupV2Button | undefined, PopupV2Button | undefined]
})
}
// 触发:透明蒙层 + 居中悬浮;传选项对象的重载返回 dialogId。
// 注意:isModal: false 时没有蒙层可点,autoCancel 会失效;
// 用「模态 + maskColor 透明」的组合,才能既不压暗页面又支持点外部收起。
// this.getUIContext().getPromptAction().openCustomDialog({
// builder: () => { this.popupBuilder() },
// autoCancel: true,
// isModal: true,
// maskColor: Color.Transparent,
// alignment: DialogAlignment.Center
// }).then((id: number) => { this.dialogId = id; });
支持 icon/title/message、titleModifier/messageModifier/iconModifier/buttonTextModifier 微调样式、最多两个按钮(PopupV2Button)、onClose 关闭回调、direction 适配 RTL、maxWidth(默认 400vp)。TextModifier / ImageModifier 同样从 @kit.ArkUI 导入。注意:showClose 的 × 图标本身只是开关的呈现,真正的关闭逻辑要在 onClose 里自己调 closeCustomDialog(dialogId);不设置 onClose 时点 × 是没有反应的。
▶ 运行效果(图6 GIF):点击「气泡弹窗」——「轻提示气泡」轻悬浮在页面中间:蓝色对勾图标 + 标题 + × 关闭 + 「稍后再说/知道了」双按钮,全程没有黑色蒙层压暗页面,点气泡外任意区域即收起;与图1 的普通模态弹窗对比,轻量感一目了然。

4.4 SwipeRefresherV2 下拉刷新指示
极简的展示型组件,只有两个字段:content(加载文案,超宽截断)与 isLoading(必填开关,false 时不渲染)。两个字段的差异效果最直观——content 换文案不换布局,isLoading 直接控制组件生与死。通常嵌在自定义下拉刷新流程里,由你的状态控制显隐:
import { SwipeRefresherV2 } from '@kit.ArkUI';
@Entry
@ComponentV2
struct RefreshDemo {
@Local isLoading: boolean = true;
build() {
Column({ space: 12 }) {
// 同一个 isLoading 驱动两个实例,content 各自定制文案
SwipeRefresherV2({ content: '正在加载…', isLoading: this.isLoading })
SwipeRefresherV2({ content: '下拉刷新中,请稍候', isLoading: this.isLoading })
// 切到 false:两个实例同时消失(组件不渲染);切回 true 恢复
Button(this.isLoading ? '切到非加载态(isLoading: false)' : '切回加载态(isLoading: true)')
.onClick(() => { this.isLoading = !this.isLoading; })
}
}
}
▶ 运行效果(图7 GIF):点击「切到非加载态」——
isLoading: true时两条不同文案的加载指示同时出现,切到false全部消失(组件不渲染),再点「切回加载态」恢复;两个实例由同一个状态变量驱动,content各自定制文案。

4.5 TreeViewV2 树形视图
层级列表组件,适合备忘录、邮箱侧边栏等嵌套结构。核心是 TreeControllerV2 控制器:addNode 链式建树、buildDone 收尾,运行期支持 addNode/removeNode/modifyNode/refreshNode 动态改树;TreeListenerManagerV2 提供节点点击/增删/移动的监听。
import { TreeViewV2, TreeControllerV2 } from '@kit.ArkUI';
@Entry
@ComponentV2
struct TreeDemo {
treeController: TreeControllerV2 = new TreeControllerV2();
aboutToAppear(): void {
this.treeController
.addNode({ parentNodeId: -1, currentNodeId: 1, isFolder: true, primaryTitle: '文档', secondaryTitle: '2' })
.addNode({ parentNodeId: 1, currentNodeId: 2, isFolder: false, primaryTitle: '周报.md' })
.addNode({ parentNodeId: 1, currentNodeId: 3, isFolder: false, primaryTitle: '计划.md' })
.addNode({ parentNodeId: -1, currentNodeId: 4, isFolder: true, primaryTitle: '图片', secondaryTitle: '1' })
.addNode({ parentNodeId: 4, currentNodeId: 5, isFolder: false, primaryTitle: '截图.png' })
.buildDone();
}
build() {
Column() {
Column() {
TreeViewV2({ treeControllerV2: this.treeController })
}
.height(220)
.width('100%')
}
}
}
NodeParamV2 的几个关键属性决定了节点的形态差异:parentNodeId: -1 表示挂根节点,其余填父节点的 currentNodeId;isFolder 区分文件夹(可展开/折叠,带箭头)与文件节点;primaryTitle 是主标题、secondaryTitle 是右侧副标题(常用作未读数、数量角标);icon/selectedIcon 可选,配置节点前后的图标。currentNodeId 必须全局唯一,重复会导致节点构建异常。
与 V1 版 TreeView 相比,TreeViewV2 的节点数据与监听体系全面切换到 V2 范式(NodeParamV2、TreeListenerV2 等),节点数据的修改可直接驱动视图刷新。
▶ 运行效果(图8 GIF):点击「图片」文件夹——节点按压高亮后展开,展开箭头变为收起箭头(▼),露出子文件「截图.png」;
isFolder: true才可展开/折叠,secondaryTitle在右侧显示数量角标(2、1),文件节点不带箭头。

五、版本速查表
| 组件 | 导入自 | API | 一句话用途 |
|---|---|---|---|
| DialogV2 系列(7 个) | @kit.ArkUI | 18 | 提示/选择/确认/警告/加载/自定义内容/气泡 弹窗 |
| ProgressButtonV2 | @kit.ArkUI | 18 | 带进度的下载按钮 |
| SegmentButtonV2 系列(3 个) | @kit.ArkUI | 18 | 页签/单选/多选分段按钮 |
| ChipV2 / ChipGroupV2 | @kit.ArkUI | 26.0.0 | 单选/多选标签组 |
| CounterV2 | @kit.ArkUI | 26.0.0 | 数值/日期步进器(4 形态) |
| PopupV2 | @kit.ArkUI | 26.0.0 | 标准气泡提示 |
| SwipeRefresherV2 | @kit.ArkUI | 26.0.0 | 下拉刷新加载指示 |
| TreeViewV2 | @kit.ArkUI | 26.0.0 | 树形层级视图 |
配套的 V2 生态里程碑:API 18 起 WithTheme 支持 V2 组件;API 23 起 @ComponentV2 支持在 ArkTS 卡片中使用;API 26 起通用属性 systemMaterial 让所有组件可配置系统材质(沉浸光感)。
六、小结
API 18 → 26 两年间,官方把高频交互组件的 V2 化分成了清晰的两步:API 18 先解决「弹窗 + 进度 + 分段」三大件,API 26 补齐「标签、步进器、气泡、刷新、树形」这一批长尾场景。这些组件与 @ComponentV2 页面是天然一对:数据用 @ObservedV2 + @Trace 建模,页面用 @Local/@Param 管理状态,组件入参用 !! 双向绑定——整个链路没有深拷贝、没有 @State 代理的黑盒,刷新粒度精确到属性级。
落地时记住三条纪律:宿主页面用 V2 范式;通用属性包在外层容器而不是组件上;新项目从 @ComponentV2 起步。存量 V1 页面不必急着全量迁移,按「新模块用 V2 组件、老页面维持 V1」渐进过渡即可。
更多推荐



所有评论(0)