
鸿蒙5 状态管理基础:@State与@Link装饰器的深度解析
@State:组件内部状态管理
@State用于声明组件的内部状态,当状态变化时自动触发UI更新。适用场景:组件私有状态、不需要与父组件通信的简单状态。
基本用法:
@Entry
@Component
struct CounterPage {
// 声明内部计数状态
@State count: number = 0
build() {
Column() {
Text(当前计数: ${this.count}
)
.fontSize(20)
Button('+1')
.onClick(() => {
this.count += 1 // 修改状态自动更新UI
})
}
}
}
嵌套组件使用场景:
@Component
struct ToggleSwitch {
@State isActive: boolean = false
build() {
Toggle({ type: ToggleType.Switch })
.isOn(this.isActive)
.onChange(value => {
this.isActive = value
})
}
}
@Entry
@Component
struct SettingsPage {
build() {
Column() {
Text(‘WiFi设置’).fontSize(18)
ToggleSwitch() // 独立状态组件
}
}
}
@Link:父子组件双向绑定
@Link用于实现父子组件间的双向数据绑定,适用场景:父组件需要控制子组件状态、子组件需要向父组件反馈状态变化。
基本用法:
// 子组件
@Component
struct BrightnessSlider {
@Link @Watch(‘onBrightnessChange’)
brightness: number
// 监听变化触发额外操作
onBrightnessChange() {
console.log(亮度值更新: ${this.brightness}
)
}
build() {
Slider({ value: this.brightness, min: 0, max: 100 })
.onChange(value => {
this.brightness = value
})
}
}
// 父组件
@Entry
@Component
struct ControlPanel {
@State brightnessValue: number = 50 // 统一状态源
build() {
Column() {
Text(当前亮度: ${this.brightnessValue}%
)
BrightnessSlider({ brightness: $this.brightnessValue })
Button('恢复默认')
.onClick(() => {
this.brightnessValue = 50 // 父组件修改影响子组件
})
}
}
}
核心差异对比
特性 @State @Link
作用范围 组件内部 父子组件之间
数据流向 单向(组件内部) 双向(父子相互影响)
初始化 组件内初始化 必须从父组件初始化
适用场景 简单组件/独立状态 表单控件/复杂交互组件
语法 @State value: T = … @Link value: T
组合使用实战:电商购物车
// 购物车子项组件
@Component
struct CartItem {
@Link @Watch(‘onCountChange’)
count: number
onCountChange() {
if (this.count < 0) this.count = 0 // 数据校验
}
build() {
Row() {
Text(‘商品名称’)
Button(‘-’)
.onClick(() => this.count–)
Text(${this.count}
)
Button(‘+’)
.onClick(() => this.count++)
}
}
}
// 购物车父组件
@Entry
@Component
struct ShoppingCart {
@State totalCount: number = 0
@State itemCounts: number[] = [1, 2, 0] // 各商品数量
build() {
Column() {
ForEach(this.itemCounts, (item, index) => {
CartItem({ count: $this.itemCounts[index] })
})
Divider()
Text(`总计: ${
this.itemCounts.reduce((sum, count) => sum + count, 0)
}件商品`)
Button('清空购物车')
.onClick(() => {
this.itemCounts = [0, 0, 0]
})
}
}
}
使用误区与避坑指南
初始化问题:
@State必须初始化,@Link禁止初始化
错误:@Link value: number = 0
引用类型注意事项:
// 数组类型需要整体修改才能触发更新
@State items: string[] = [‘a’, ‘b’]
// 错误:不会触发更新
this.items.push(‘c’)
// 正确:创建新数组
this.items = […this.items, ‘c’]
性能优化:
// 复杂组件添加状态变更日志
@State @Watch(‘onPositionChange’)
position: number = 0
onPositionChange() {
console.debug(位置更新: ${this.position}
)
}
进阶技巧:状态分层设计
在大型项目中推荐分层管理状态:
UI组件层:使用@State管理视觉状态(展开/折叠)
功能组件层:使用@Link连接业务组件
全局状态层:使用AppStorage全局状态管理
// 全局状态定义
AppStorage.SetOrCreate(‘userMode’, ‘light’)
@Component
struct ThemeButton {
@StorageLink(‘userMode’) mode: string
build() {
Button(this.mode === ‘light’ ? ‘🌞’ : ‘🌙’)
.onClick(() => {
this.mode = this.mode === ‘light’ ? ‘dark’ : ‘light’
})
}
}
掌握@State和@Link的本质区别,能够让你在鸿蒙应用开发中:
构建高内聚低耦合的组件体系
实现数据流向可控的复杂交互
避免不必要的组件渲染,提升性能
为后续进阶状态管理打下坚实基础
