V2装饰器@local的使用
【高心星出品】
概念
组件内部状态管理 @Local是专为@ComponentV2组件设计的装饰器,用于声明组件私有状态。被装饰的变量必须在组件内部初始化,禁止从父组件外部传入初始值(如Child({count: 10})
的写法会报错),确保状态封装性。
观测能力
-
支持类型:基本类型(number、string、boolean)、Object、class、Array、Set、Map、Date等内嵌类型,以及联合类型1。
-
变化触发机制:
- 简单类型(如number):赋值操作触发UI刷新(如
this.count++
)。 - 对象类型:仅整体赋值时触发(如替换整个对象
this.obj = new MyClass()
)。 - 数组/集合类型:整体赋值或调用特定API(如
push()
、set()
)时触发。
- 简单类型(如number):赋值操作触发UI刷新(如
与@State的对比
特性 | @Local(V2) | @State(V1) |
---|---|---|
初始化 | 强制内部初始化 | 允许外部传入覆盖初始值 |
作用域 | 组件内部私有 | 可跨组件传递 |
性能优化 | 更精细的观测,减少不必要刷新 | 可能因外部修改导致过度渲染 |
适用版本 | API 12+,ComponentV2组件 | 旧版本组件体系 |
使用场景
基本状态管理:
Button绑定local装饰的变量count,count值改变引起button刷新。
less
@Entry
@ComponentV2
struct Index {
@Local count: number = 1;
build() {
Column(){
Button('点击次数:'+this.count)
.width('60%')
.onClick(()=>{
this.count+=1
})
}
.height('100%')
.width('100%')
.justifyContent(FlexAlign.Center)
}
}
装饰数组的情况:
button绑定数据源datas的长度,list绑定数据源datas,当数据源调用push api或者元素更新的时候会引起UI刷新。
scss
@Entry
@ComponentV2
struct Localpage {
@Local datas:number[]=[1,2,3,4,5,6,7,8,9,10]
build() {
Column({space:20}){
Button('列表长度:'+this.datas.length)
.width('60%')
.onClick(()=>{
// 调用api会被观察
// this.datas.push(this.datas.length+1)
// 更新数组项也会被观察
this.datas[this.datas.length-1]=0
})
List(){
Repeat<number>(this.datas).each((item:RepeatItem<number>)=>{
ListItem(){
Text('列表项:'+item.item)
.fontSize(30)
.fontWeight(FontWeight.Bolder)
.padding(10)
.textAlign(TextAlign.Center)
}
})
}
.width('100%')
.divider({strokeWidth:2})
}
.height('100%')
.width('100%')
}
}
不可以从父组件向子组件传值
scss
@ComponentV2
struct child {
@Local count: number = 10
build() {
Column() {
Button('child count: ' + this.count)
.width('60%')
.onClick(() => {
this.count += 1
})
}
.width('100%')
.padding(20)
}
}
@Entry
@ComponentV2
struct Localpage1 {
@Local count: number = 11
build() {
Column() {
// 有问题不能外部传值
// child({count:11})
// child({count:this.count})
// 没问题
child()
}
.justifyContent(FlexAlign.Center)
.height('100%')
.width('100%')
}
}