@Stete numbe1:number=1;//或者是private定义的数据,
//父组件调用子组件
页面通用写法
- 每个页面或组件有且只有一个@Entry
- 页面是由一个或多个组件构成
- 其中组件只能export一个出去
- 建议组件写在前面,最后一个需要被渲染的组件作为@Entry出去,不然找不到组件
固定写法为:
//组件
@Entry//只有是页面或者组件作为最终渲染条件时才使用
@Component struct ComponmentName {
@State stateName:numbrt|string =value ;//定义的值
build(){
Column(){
//组件样式
}
}
}
@Style 可以定义当前页面或组件通用样式,不可export导出,然后引出给其他项目使用,定义的方法不可传递参数,并且只可定义通用样式,和方法,可以作为组件内定义时可以访问到组件常亮和状态变量,即this指向的数据
写法:
@Style function func (){ //定义的样式,或者方法 }
@Extend 仅可以定义当前组件或页面样式,不可export导出 ,定义的方法可以传递参数,具体参考ts 定义参数
写法:
@Extend (Text|Image|...UICompoment) funnction func (argument){
//定义的样式,可以接收参数
}
.stateStyle 几种操作方式的样式变化 正常态(normal)、获焦态(focused 不常用,可能电视端或者电脑端会使用,手机端鼠标模式才会有)按压态(pressed)、不可用态(disabled 不常用)
写法:
.stateStyle{
normal:{
//正常展示时展示的样式
} ,
pressed:{
//按压状态时展示的样式
} ,
focused:{
//指定元素获取焦点时展示的样式
},
disabled:{
//元素禁用时的状态
}
}
页面与组件的关系
-
一个页面只能有一个 @Entry 可以有多个@Component,
-
组件也可以同上方,然后通过export 导出
页面与组件周期
onPageShow 页面展示时
onpageHide 页面隐藏时,页面路由切换,路由列表还存在时也会触发
onBackPress 只用用户点击返回按钮时触发
aboutToAppear 组件出现时
aboutToDisappear 组件销毁时触发
@Builder
和组件build下写的方法同理,写在build定义之前的函数想要在build之后调用可以用这个方法,特点是可以同步 struct 定义的@State,即定义的值
@BuilderParam 引用@Builder函数
状态管理
状态变量 @State 会引起UI和数据源的改变
常规变量 private 不会引起UI更新
@Prop 只能接收来自父组件下发的状态,不能接收复杂数据类型,不能传值到父组件
@Prop 基本使用
父组件
@State numbe1:number=1;//或者是private定义的数据, //父组件调用子组件 Compoment1({number:numbe1})
子组件接受
@Prop number:number//即可接收来自父组件的传参
@Link 接收来自父组件的下发的状态,并且这个状态可以返回给父组件,也不能接收复杂数据类型
父组件
@State numbe1:number=1;//或者是private定义的数据, //父组件调用子组件 Compoment1({number:$numbe1})//这种方式可以将子组件修改的值重新返回给父组件
子组件
```
@Link number:number
//比如点击按钮执行数字加1
Button('+1').onClick(()=>{
this.number=this.number+1
})
```
@Provide 和 @Consume
他们可以全局去修改这个值,可以改变简单和复制数据类型
其中 @Provide可以等同于@State,即后续可以通过this去访问到定义的值
父组件
@Provide a:number=0;
@Provide obh_:object={a:1}
Text(JSON.stringify(this.a))//值会发生改变
Text(JSON.stringify(this.obh_))//对象数据也能改变
其他组件
@Consume a:number
@Consume('obh_') obj:object
Text('change')
.onClick(()=>{
this.a=this.a+1
let b:object=this.obj
b={a:this.a+1}
this.obj=b
})
@Observed 和 @ObjectLink
可以对定义的任意class类型值进行监听
其中,@Observed 为定义的构造对象 @ObjectLink 为监听定义构造函数的值,不允许赋值,可以监听@Observed 构造对象或者数组的值,也可以直接盖章对象或者数组的值,达到修改的目的
@ObjectLink 不能放在@Entry里面
所以如果要在入口组件上监听数据,可以将需要改变的数据先处理完,然后重构数据源,一维数组对象可以直接修改,通过@State处理,二维数据就可以通过上面方式
定义:
let NextId:number=1;
@Observed
class ClassA{
//定义构造对象ClassA ,其中id和c 是对象值,并且这个定义的构造对象可以被监听到
public id:number;
public c:number;
constructor(c:number) {
this.id=NextId++ this.c=c
}
}
@Observed class classB {
//classB为构造对象,也可以被监听到,即能被双向修改,同时继承了ClassA
public a:ClassA;//new classB 时,其数据上的a 为构造对象ClassA , //如定义一个变量objB =new classB();时objB.a=new ClassA()
constructor(a:ClassA) {
this.a=a
}
}
export {ClassA,classB},
监听
import { ClassA, classB } from './componment/observedUse' //要使用先引用
@Component//组件ViewA
struct ViewA {
label: string = 'ViewA1';
@ObjectLink a: ClassA;
build() {
Row() {
Button(`ViewA [${this.label}] this.a.c=${this.a.c} +1`)
//6.这里就是正常的引用监听变化改变数组,不会引起viewB的变化,
//尽管数据已经改变,但因为viewB不能监听到第二层,so...
.onClick(() => { this.a.c += 1; })
}
}
}
@Entry
@Component
struct viewB{
@State message: string = 'Hello World'
@State objB:classB=new classB(new ClassA(0))
//因为这里是@State定义的数据,它只能监听到一层数据变化。
//1.定义一个state,objB 并初始化为new ClassA(0),并且继承的ClassA初始值C赋值0
build() {
Row() {
Column() {
ViewA({ label: 'ViewA #111', a: this.objB.a })
ViewA({ label: 'ViewA #2', a: this.objB.a })
Text(this.message)
.fontSize(50)
.fontWeight(FontWeight.Bold)
Button(`ViewB: this.b.a.c+= 1`)
//4.因为这个操作是改变对象数据的第二层变化,
//所以不能在viewB上面监听到数据的变化
.onClick(()=>{ this.objB.a.c += 1 })
Button(`ViewB: this.b.a = new ClassA(0)`)
//3.因为这个操作能引起对象数据的第一层变化,
//所以此处点击时能引起viewB 上的数据更新,
//即下方2可以随构造对象值的变化而发生UI变化
.onClick(() => { this.objB.a = new ClassA(0); })
Button(`ViewB: this.b = new ClassB(ClassA(0))`)
//5.虽然改变了第二层数据的变化,但同时更新了第一层数据,
//可以监听和双向绑定数据
.onClick(() => {
this.objB.a.c +=1;
this.objB = new classB(new ClassA(this.objB.a.c));
})
Text(JSON.stringify(this.objB))
//2.此处可以查看定义的对象是否被监听到,即对象数据是否改变通过该处查看
} .width('100%')
}
.height('100%')
}
}
后续内容持续更新中。。。