鸿蒙5 状态管理基础:@State与@Link装饰器的深度解析

暗雨OL
发布于 2025-6-27 21:14
浏览
0收藏

@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的本质区别,能够让你在鸿蒙应用开发中:

构建高内聚低耦合的组件体系
实现数据流向可控的复杂交互
避免不必要的组件渲染,提升性能
为后续进阶状态管理打下坚实基础

分类
标签
收藏
回复
举报
回复
    相关推荐