数据传递
数组
简单类型数组
基础代码:
@Entry
@Component
struct Index {
@State
numArr: number[] = [100, 200, 300]
build() {
Column({ space: 10 }) {
ForEach(this.numArr, (item: number, index: number) => {
Button(item.toString())
.onClick(()=>{
})
})
}
.width("100%")
.height("100%")
.justifyContent(FlexAlign.Center)
}
}
错误写法:鸿蒙内部对于item可能常量形式声明,常量不能被修改
正确写法:
引用类型数组
基础代码:
import { promptAction } from '@kit.ArkUI'
interface IStar {
name: string
hot: number
}
@Entry
@Component
struct Index {
@State
starList: IStar[] = [{name: "周杰伦",hot: 100},{name: "费玉清",hot: 50},{name: "周华健",hot: 200},]
build() {
Column({ space: 10 }) {
ForEach(this.starList, (item: IStar, index: number) => {
Button(`${item.name} - ${item.hot}`)
.onClick(() => {
})
})
}
.width("100%")
.height("100%")
.justifyContent(FlexAlign.Center)
}
}
错误写法:如若数据是引用数据类型,常量 内存地址不能修改
错误写法:值改变,但UI不更新
正确写法:
单向->@Prop
@Prop可以实现父组件->子组件的单向数据传递,父组件数据改变,子组件数据随之改变;但子组件直接改变数据,父组件不会随之发生改变
简单类型数组-组件
基础代码:
@Component
struct MyButton {
@Prop
item: number
build() {
Column() {
Button(this.item.toString())
.onClick(() => {
})
}
}
}
@Entry
@Component
struct Index {
@State
numArr: number[] = [100, 200, 300]
build() {
Column({ space: 10 }) {
ForEach(this.numArr, (item: number, index: number) => {
MyButton({item})
})
}
.width("100%")
.height("100%")
.justifyContent(FlexAlign.Center)
}
}
错误写法:子组件设置点击事件,子组件的值改变,而父组件的值不随之改变
正确写法:
引用类型数组-组件
基础代码
interface IStar {
name: string
hot: number
}
@Component
struct MyButton {
@Prop
item: IStar
build() {
Column() {
Button(`${this.item.name} - ${this.item.hot}`)
.onClick(() => {
})
}
}
}
@Entry
@Component
struct Index {
@State
starList: IStar[] = [{name: "周杰伦",hot: 100},{name: "费玉清",hot: 50},{name: "周华健",hot: 200},]
build() {
Column({ space: 10 }) {
ForEach(this.starList, (item: IStar, index: number) => {
MyButton({ item: item })
})
}
.width("100%")
.height("100%")
.justifyContent(FlexAlign.Center)
}
}
错误写法:子组件中设置点击事件,点击使子组件中的hot数据直接自增,但可以观察到父组件中的hot数据并没有随之自增
正确写法:点击事件,点击使子组件中数据自增,父组件中的数据也随之自增
双向->@Link
单一的@Prop只能实现父组件->子组件的单向数据传递
配合:
const item = this.数组[index]
item.数组中某个元素属性++
this.数组.splice(index,1,item)
虽然可以实现双向数据传递,但避免不了一些弊端,如:上述过程会使得整个数组所有数据刷新,在这里体现的不是很明显,但如果是有图片的数据,会发现,每次点击的发生改变的时候,图片也会随之刷新
@Link可以实现父组件<->子组件的双向数据传递,父组件数据修改的同时,子组件数据也随之修改;子组件数据直接修改时,父组件数据也随之修改。避免上述过程中出现的整个刷新的问题
@Link修饰简单类型数据
@Component
struct son {
// @Prop //父->子单向 可以不赋初值
@Link // 父<=>子双向
snum:number
build() {
Button(`子组件 ${this.snum}`)
.onClick(()=>{
this.snum++
})
}
}
@Entry
@Component
struct Index {
@State
fnum:number = 100
build() {
Column({space:10}){
Button(`父组件 ${this.fnum}`)
.onClick(()=>{
this.fnum++
})
son({snum:this.fnum})
}
.width('100%')
.height('100%')
.justifyContent(FlexAlign.Center)
}
}
@Link修饰引用类型数据
interface IPerson{
age:number
}
@Component
struct son {
// @Prop //父->子单向 可以不赋初值
@Link // 父<=>子双向
sperson:IPerson
build() {
Button(`子组件 ${this.sperson.age}`)
.onClick(()=>{
this.sperson.age++
})
}
}
@Entry
@Component
struct Index {
@State
fperson:IPerson = {
age:100
}
build() {
Column({space:10}){
Button(`父组件 ${this.fperson.age}`)
.onClick(()=>{
this.fperson.age++
})
son({sperson:this.fperson})
}
.width('100%')
.height('100%')
.justifyContent(FlexAlign.Center)
}
}
@Link修饰深层次引用类型
@Link无法修饰深层次引用类型,过程中会导致子组件无法显示
import { promptAction } from '@kit.ArkUI'
interface IDog{
weight:number
}
interface IPerson{
dog:IDog
}
@Component
struct son {
// @Prop //父->子单向 可以不赋初值
@Link // 父<=>子双向
dog:IDog
build() {
Button(`子组件 ${this.dog.weight}`)
.onClick(()=>{})
}
}
@Entry
@Component
struct Index {
@State
fperson:IPerson = {
dog:{
weight:200
}
}
build() {
Column({space:10}){
Button(`父组件 ${this.fperson.dog.weight}`)
.onClick(()=>{
//鸿蒙没有对深层次的数据 做监听------
//UI不会更新
//数据是否发生变化?数据没有变化
//this.fperson.dog.weight++//无效
// 数组.splice
// this.list[index] = .....
// this.list.age++
const weight = this.fperson.dog.weight + 1
this.fperson.dog = { weight: weight }
promptAction.showToast({message:`${this.fperson.dog.weight}`})
})
son({dog:this.fperson.dog})//无效,子组件无法显示
}
.width('100%')
.height('100%')
.justifyContent(FlexAlign.Center)
}
}
@Link无法修饰被ForEach循环出来的item
使用@Link修饰被ForEach循环出来的item->子组件({item})报错,程序无法运行
则@Link无法修饰被ForEach循环出来的item
@Component
struct MyButton {
@Link
item: number
build() {
Column() {
Button(this.item.toString())
}
}
}
@Entry
@Component
struct Index {
@State
numArr: number[] = [100, 200, 300]
build() {
Column({ space: 10 }) {
ForEach(this.numArr, (item: number) => {
// 提示出错
MyButton({ item })
})
}
.width("100%")
.height("100%")
.justifyContent(FlexAlign.Center)
}
}