HarmonyOS父子组件传递参数
1. 使用@State
和@Prop
进行父子组件传递———注意是单向同步
- 注意:只支持单向同步,同时也只能支持
string\number\boolean\enum
比较简单的类型。
代码
// 使用 props 进行父子组件传值
@Component
struct SonCom {
// 父子间传递过来的数据使用 @Prop 进行接受
@Prop sonCar: string
// 修改传递的参数
changeInfo = (info: string)=> {}
build() {
Column() {
Text(`这是子组件的盒子--- ${this.sonCar}`)
Button('子组件修改父组件的数据').onClick((event: ClickEvent) => {
this.changeInfo('吉利银河 L7 ----' + Math.ceil(Math.random() * 10))
})
}
.width('100%')
.height(100)
.backgroundColor(Color.Orange)
}
}
@Entry
@Component
struct PropsPage {
@State info: string = '比亚迪 宋'
changeInfo = (newInfo: string)=>{
this.info = newInfo
}
build() {
Column({space: 20}) {
Text(`这是父组件的盒子 ${this.info}`)
Button('修改父组件的数据').onClick((event: ClickEvent) => {
this.info = '领克 08---' + Math.ceil(Math.random() * 10)
})
// 这是子组件
SonCom({
sonCar: this.info,
changeInfo: this.changeInfo
})
}
.width('100%')
.height(300)
.backgroundColor(Color.Pink)
}
}
演示
2. @Link装饰器:父子双向同步
- 注意
// 子组件
@Component
struct ChildCom {
@Link list: number[]
build() {
Column() {
List({space: 10}) {
ForEach(this.list, (item: number, index) => {
ListItem() {
Text(item.toString())
.width('100%')
.padding(10)
.backgroundColor(Color.White)
}
})
}
}.onClick(() => {
this.list.push(this.list.length + 1)
})
}
}
// 父组件
@Entry
@Component
struct StateLink {
@State list: number[] = [1, 2, 3]
build() {
Column() {
ChildCom({
// 注意,这里调用时,使用$替换this,这是语法规定
list: $list
})
}
.width('100%')
.height('100%')
.backgroundColor(Color.Gray)
}
}
3. @Provide装饰器和@Consume装饰器:与后代组件双向同步
@Provide装饰器和@Consume装饰器:与后代组件双向同步
- 注意:
@Consume
装饰的变量通过相同的属性名绑定其祖先组件@Provide
装饰的变量,在这里就是SunziCom
中的@Consume listInfo: ListItemClass
与祖先组件ProvideConsume
中的@Provide listInfo: ListItemClass
属性名保持一致。
// 这是模拟的数据
@Observed
class ListItemClass {
name: string
likeNum: number
isLike: boolean
comment: string
constructor(name: string, likeNum: number, isLike: number, comment: string) {
this.name = name
this.likeNum = likeNum
this.isLike = isLike === 0 ? false : true
this.comment = comment
}
}
// 这是 孙子组件
@Component
struct SunziCom {
// 注意:这里的属性名要保持和 @Provide修饰的父组件属性名一致.
@Consume listInfo: ListItemClass
build() {
Column() {
Text(this.listInfo.name)
.fontSize(18)
.fontWeight(700)
.fontColor('#333')
.margin({
bottom: 10
})
Row() {
Text(this.listInfo.comment)
Row() {
Text(this.listInfo.likeNum.toString())
.fontColor(this.listInfo.isLike ? Color.Red : '#333')
}
.onClick(() => {
if (this.listInfo.isLike) {
this.listInfo.likeNum -= 1
} else {
this.listInfo.likeNum += 1
}
this.listInfo.isLike = !this.listInfo.isLike
})
}
.justifyContent(FlexAlign.SpaceBetween)
.width('100%')
}
.padding(10)
.borderRadius(10)
.alignItems(HorizontalAlign.Start)
.width('100%')
.backgroundColor(Color.White)
}
}
// 这是 儿子组件
@Component
struct ErziCom {
build() {
SunziCom()
}
}
@Entry
@Component
struct ProvideConsume {
@Provide listInfo: ListItemClass = new ListItemClass(`小火车况且况且-${Math.ceil(Math.random() * 10)}`, Math.ceil(Math.random() * 100), Math.floor(Math.random() * 2), `这是随机的评论--${Math.ceil(Math.random() * 1000)}`)
build() {
Column(){
ErziCom()
}
}
}
4. 使用@Observed装饰器和@ObjectLink装饰器:嵌套类对象属性变化,主要是可以处理Link
遇上ForEach
而导致一些奇怪的问题
@Observed装饰器和@ObjectLink装饰器:嵌套类对象属性变化
// 这是模拟的数据
@Observed
class ListItemClass {
name: string
likeNum: number
isLike: boolean
comment: string
constructor(name: string, likeNum: number, isLike: number, comment: string) {
this.name = name
this.likeNum = likeNum
this.isLike = isLike === 0 ? false : true
this.comment = comment
}
}
function createData() {
return [
new ListItemClass(`小火车况且况且-${Math.ceil(Math.random() * 10)}`, Math.ceil(Math.random() * 100), Math.floor(Math.random() * 2), `这是随机的评论--${Math.ceil(Math.random() * 1000)}`),
new ListItemClass(`小火车况且况且-${Math.ceil(Math.random() * 10)}`, Math.ceil(Math.random() * 100), Math.floor(Math.random() * 2), `这是随机的评论--${Math.ceil(Math.random() * 1000)}`),
new ListItemClass(`小火车况且况且-${Math.ceil(Math.random() * 10)}`, Math.ceil(Math.random() * 100), Math.floor(Math.random() * 2), `这是随机的评论--${Math.ceil(Math.random() * 1000)}`),
new ListItemClass(`小火车况且况且-${Math.ceil(Math.random() * 10)}`, Math.ceil(Math.random() * 100), Math.floor(Math.random() * 2), `这是随机的评论--${Math.ceil(Math.random() * 1000)}`)
]
}
// 子组件
@Component
struct ChildCom {
@ObjectLink listInfo: ListItemClass
build() {
Column() {
Text(this.listInfo.name)
.fontSize(18)
.fontWeight(700)
.fontColor('#333')
.margin({
bottom: 10
})
Row() {
Text(this.listInfo.comment)
Row() {
Text(this.listInfo.likeNum.toString())
.fontColor(this.listInfo.isLike ? Color.Red : '#333')
}
.onClick(() => {
if (this.listInfo.isLike) {
this.listInfo.likeNum -= 1
} else {
this.listInfo.likeNum += 1
}
this.listInfo.isLike = !this.listInfo.isLike
})
}
.justifyContent(FlexAlign.SpaceBetween)
.width('100%')
}
.padding(10)
.borderRadius(10)
.alignItems(HorizontalAlign.Start)
.width('100%')
.backgroundColor(Color.White)
}
}
// 父组件
@Entry
@Component
struct ObservedObjectLink {
@State list: ListItemClass[] = createData()
build() {
Column() {
List({
space: 10
}) {
ForEach(this.list, (item: ListItemClass, index: number) => {
ListItem() {
ChildCom({
listInfo: item
})
}
})
}
}
.padding(10)
.width('100%')
.height('100%')
.backgroundColor(Color.Gray)
}
}