目录
1、父组件@State到子组件@Prop简单数据类型同步
2、父组件@State数组项到子组件@Prop简单数据类型同步
3、从父组件中的@State类对象属性到@Prop简单类型的同步
@Prop主要用用于父组件到子组件的数据级联更新,父组件的数据变化会影响到子组件的数据变化,但发过来子组件的数据变化则不会影响到父组件的更新。 被@Prop装饰的变量可以和父组件建立单向的同步关系。子组件中@Prop装饰的变量是可变的,但是变化不会同步回其父组件。
@Prop变量值初始化和更新机制:
@Entry
@Component
struct PropDemoPage {
@State message: string = '演示@Prop装饰器的使用:\n该装饰器用于实现修改父组件' +
'然后子组件自动更新的单向联动(子组件数据更新不会反馈到父组件中)'
@State index: number = 0
build() {
Row() {
Column() {
Text(this.message).letterSpacing(2)
Text(`${this.index}`)
.fontSize(48)
.fontColor(Color.Pink)
.padding(5)
.backgroundColor("#67c8ff")
.onClick(() => {
this.index++
})
Divider()
ChildView({ indexProp: this.index })
}
.width('100%')
}
.height('100%')
}
}
@Component
struct ChildView {
@Prop
indexProp: number
build() {
Row() {
Text(`${this.indexProp}`)
.fontSize(24)
.fontColor(Color.Pink)
.padding(8)
.backgroundColor("#8067c8ff")
.onClick(() => {
this.indexProp++
})
}
}
}
父组件中用@State修饰了变量index,通过“从父组件初始化”将其值赋值给子组件@Prop修饰的变量indexProp,同时在父组件和子组件中绑定了点击事件,表现如下:
@Entry
@Component
struct PropDemo2Page {
@State arr: number[] = [1, 2, 3];
build() {
Row() {
Column() {
Child({ value: this.arr[0] })
Child({ value: this.arr[1] })
Child({ value: this.arr[2] })
Divider().height(5)
ForEach(this.arr,
item => {
Child({ value: item })
},
item => JSON.stringify(item)
)
Text('replace entire arr')
.fontSize(50)
.onClick(() => {
// 两个数组都包含项“3”。
this.arr = this.arr[0] == 1 ? [3, 4, 5] : [1, 2, 3];
})
}
}
}
}
@Component
struct Child {
@Prop value: number;
build() {
Text(`${this.value}`)
.fontSize(50)
.onClick(() => {
this.value++
})
}
}
3个子组件都有从父组件的@State变量的拷贝,所以点击子组件,会发现上面的数字会变化,但是下面的数据不会变化(因为下面的数据位于父组件中)。
把上面三个数据都改为8 8 8,在点击下面的replace entire arr,会发现数据都变成了3 4 5;为什么呢?
当点击replace entire arr按钮的时候,由于子组件的数据变化不会反应到父组件中,虽然子组件显示8 8 8 ,但是父组件中的数据依然还是1 2 3,当点击事件发生的时候,依据判断条件就会把3 4 5赋值给数组,注意这里时发生在父组件中的赋值,其行为会反映到子组件中,所以会触发子组件的更新,也就时上面三个数据变成了3 4 5。
@Entry
@Component
struct PropDemo3Page {
@State book: Book = new Book('100 secrets of C++', 765);
build() {
Column() {
ReaderComp({ title: this.book.title, readIt: this.book.readIt })
ReaderComp({ title: this.book.title, readIt: this.book.readIt })
}
}
}
class Book {
public title: string;
public pages: number;
public readIt: boolean = false;
constructor(title: string, pages: number) {
this.title = title;
this.pages = pages;
}
}
@Component
struct ReaderComp {
@Prop title: string;
@Prop readIt: boolean;
build() {
Row() {
Text(this.title)
Text(`... ${this.readIt ? 'I have read' : 'I have not read it'}`)
.onClick(() => this.readIt = true)
}
}
}
如果图书馆有一本图书和两位用户,每位用户都可以将图书标记为已读,此标记行为不会影响其它读者用户。从代码角度讲,对@Prop图书对象的本地更改不会同步给图书馆组件中的@State图书对象。