父传子 单向 不加修饰符 1-无响应式、2-可以写默认值、3-可以改但是父覆盖
步骤1: 传 调用组件传递数据 自定义组件名({ 属性名:数据 }) 步骤2: 收 属性名:数据 步骤3: 用 this.属性名父传子 单向 @Prop 1-有响应式、不可以写默认值仅支持number/string/boolean
步骤1: 传 调用组件传递数据 自定义组件名({ 属性名:数据 }) 步骤2: 收 @Prop 属性名:数据 步骤3: 用 this.属性名父子双向 @Link 1-双向 子直接改父、2-支持对象
步骤1: 传 调用组件传递数据 自定义组件名({ 属性名:要把this.改成$ }) 步骤2: 收 @Link 属性名:数据 步骤3: 用 this.属性名子传父 调用父的方法 this指向
步骤1: 父定义方法 onUpdTile = (data:string) => {} 步骤2: 传递给子 Tabbar({ onUpdTile: this.onUpdTile }) 步骤3: 子收 onUpdTile: (data:string) => {} 步骤4: 子用 this.onUpdTile(数据)后代 1-双向、2-支持对象
步骤1:父 @Provide 状态:类型 = 数据 步骤2:子 @Consume 状态:类型
状态
原始类型
引用类型:修改二维的数据没有响应式 =》 解决修改一维的
@State arr: {num:number}[] = [
{num:1},
{num:2}
]
this.arr[0].num++
this.arr[0] = {num: this.arr[0].num+1}
状态比较推荐的类型限制写法(鸿蒙项目开发命名规范)
判断:让大家知道在build层也可以写判断
循环
ForEach(数组, (item:类型, i:number) => {
结构
})
一、@ObjectLink item双向
@ObjectLink和@Observed类装饰器用于在涉及嵌套对象和数组的场景中进行双向数据同步
-
被@Observed修饰的类,可以被观察到属性的变化
-
子组件中通过@ObjectLink装饰器装饰的状态变量用于接收@Observed装饰的类的实例
@Observed class Stu { name: string money: number constructor(name:string, money:number) { this.name = name this.money = money } } @Component struct Child { // @Prop item:Stu // @Link item:Stu @ObjectLink item:Stu build() { Column() { Row() { Text(`姓名-${this.item.name},`) Text(`资产-${this.item.money},`) Text(`+1 `).onClick(() => { this.item.money++ }) Text('删除') } } .width('100%') .padding(20) .margin({top:20}) .border({ width: 2, color: 'red', style: BorderStyle.Solid }) } } @Entry @Component struct Index { @State data1:Stu[] = [ new Stu('张三', 30), new Stu('李四', 40), new Stu('王五', 50), ] build() { Column() { Text('父组件') // Child( {data1:this.data1} ) Button('造人👶🏻') // 子也是非常复杂的布局 ForEach( this.data1, (item:Stu) => { // Child({ item:item }) Child({ item:item }) } ) // 父有很多其他代码 } .width('100%') .padding(20) .border({ width: 2, color: 'red', style: BorderStyle.Solid }) } }二、@Watch
@Watch用于监听状态变量的变化,当状态变量变化时,@Watch的回调方法将被调用。@Watch在ArkUI框架内部判断数值有无更新使用的是严格相等(===),遵循严格相等规范。当在严格相等为false的情况下,就会触发@Watch的回调。
- 建议开发者避免无限循环。循环可能是因为在@Watch的回调方法里直接或者间接地修改了同一个状态变量引起的。为了避免循环的产生,建议不要在@Watch的回调方法里修改当前装饰的状态变量;
- 不建议在@Watch函数中调用async await,因为@Watch设计的用途是为了快速的计算,异步行为可能会导致重新渲染速度的性能问题。
2.1 语法
@Prop @Wathc('onUpdMsg') msg:string
onUpdMsg = () => { 不行
onUpdMsg() {
}
2.2 案例
场景1: 百度搜索
@Entry
@Component
struct Index {
// @State num:number = 1
@State @Watch('onUpdNum') num:number = 1 // upd update
@State @Watch('onUpdContent') content:string = ''
@State mock:string[] = [
'abcdefg',
'aaaa123bbbb',
'cccc123',
'67898768dddddd'
]
// onUpdContent = () => {}
onUpdContent() {
// 定义临时数组 存放筛选后的数据
let temp: string[] = []
// 遍历数据 筛选 判断当前输入的内容是否在数组中
this.mock.forEach((item:string) => {
// 语法: 字符串1.includes('字符串2')
// 作用 :判断字符串2是否在字符串1中
// 返回: 布尔类型
if (item.includes(this.content)) { // 当前输入的字符串content 是否在item中
temp.push(item)
}
})
// 保存 页面展示最新数据
this.mock = temp
}
// onUpdNum = () => {
// }
onUpdNum() {
console.log('num数据变化啦:'+this.num)
}
build() {
Column() {
Text(this.num.toString()).fontSize(60)
Button('num++').onClick(() => this.num++)
/*
watch场景1 百度搜索
1 布局 上述输入框、下面展示数据
2 把【输入的数据】保存到【状态】里面
3 监控状态变化 =》 实战:去数据库获取数据 ,学习咱们就筛选
4 拿到数据保存到模型 页面展示
*/
TextInput({
placeholder:'请输入内容 实战去后端数据库获取,咱们这里准备一些假mock数据 筛选'
})
.onChange((content:string) => {
console.log('当前输入的内容:'+content)
// 实战:这边去后端数据库拿数据 根据用户输入的内容
// 学习:需求咱就假数据过滤
// 方案1:遍历mock数据,判断content 是否在里面 在就展示 不在就移除
// 方案2:先别写逻辑 按照之前写的思路 把数据保存起来 后面监控数据变化
// 思考🤔:上面哪个方案好呢
// 回答:方案2 1-这里数据保存了 后面如果要做添加功能,2-减少UI层/视图层代表量 尽量的不要在Build里面写太多逻辑
this.content = content
})
ForEach(
this.mock,
(item:string) => {
Text(String(item)).width('100%').fontSize(30).margin({top:20,bottom:20})
}
)
}
}
}