鸿蒙开发:this的指向问题

前言

"你开发的组件,明明我数据改变了,为什么却没有变化?"

"不对吧,你这个封装的不行,我在@Builder函数中获取外部的属性,总是为undefined?"

可以说,以上的反馈,无论是在工作之中,还是在外部的开源中,遇到了无数次,我的回答就一句话,那是你的this指向不对。

this,浅显易懂,就是指的自己,用于类中访问属性和方法,举一个很常见的一个案例,也是最简单的,通常我们给组件设置数据时,经常会用到this,如下所示,this就是指的当前组件Index。

TypeScript 复制代码
@Entry
@Component
struct Index {
  @State title: string = "标题"

  build() {
    Column() {
      Text(this.title)
    }
  }
}

如果是正常的组件引用,一般this不会出现大的问题,但是在自定义组件,用到了@BuilderParam装饰器,在需要外部传递@Builder函数的时候,问题就暴露出来了,我们还是来一个案例。

首先自定义一个组件,如下所示,接收一个外部传递组件layout。

TypeScript 复制代码
@Component
export struct Child {
  title: string = "我是Child"
  @BuilderParam layout: () => void

  build() {
    this.layout()
  }
}

我们把上述的自定义组件Child引用一下,然后自定义一个@Builder函数。

TypeScript 复制代码
@Entry
@Component
struct Index {
 title: string = "我是Index"

  build() {
    Child({
      layout: this.TextView
    })
  }

  @Builder
  TextView() {
    Column() {
      Text(this.title)
    }
  }
}

那么以上的案例,在运行之后,Text组件会显示 "我是Index" 还是 "我是 Child " 呢?

答案是 "我是Child"。


很多同学也会很懵,明明我在Index里调用的this,为什么不是显示Index里的 "我是Index" 数据呢?,哎,这就是this指向问题,也是很多同学在@Builder函数中一直困惑的问题。

this指向分析

以上的案例中,我们在使用自定义组件的时候,是直接通过this传递的,此时的this指向的是自定义组件Child,所以,在@Builder装饰器函数中,this获取的是自定义组件Child里的数据,如果自定义组件中未有定义,那么就为undefined,这也是前言中很多同学的反馈。

TypeScript 复制代码
Child({
      layout: this.TextView
    })

那么如何把this指向,修改宿主对象呢?也就是调用自定义组件的Index组件呢?很简单,只需要,修改为箭头函数即可。

TypeScript 复制代码
Child({
      layout: ()=>{
        this.TextView()
      }
    })

以上的案例,this指向的就是宿主对象,这样就解决了数据为什么为undefined,数据为什么无法更新的问题。

相关总结

所以,在以后遇到@Builder函数的时候,如果你要用到外部宿主的this,书写方式为箭头函数()=>{},在大括号里引用你定义的@Builder函数,切记,箭头函数的this才是指向的是宿主对象,否则指向的是自定义组件。

TypeScript 复制代码
()=>{
  //你定义的@Builder函数
}

所以啊,老铁们,你们在使用别人自定义的组件时,一定要注意到这个this指向问题,并不是别人封装的不对,而是我们使用的方式不对。

希望这个this,能打开你的新世界大门!

相关推荐
_瑞1 小时前
APM_函数调用栈展开
ios·编译原理
字节暗面2 小时前
四款 APP 加固强度测评:让 AI 拆了四个包,结果有点出乎意料
android·逆向工程·加固
YM52e2 小时前
鸿蒙 ArkTS 实战|网络常用漫剧主角名称分类表:26 位主角 8 大分类 + 搜索筛选
学习·华为·harmonyos
小雨青年2 小时前
【HarmonyOS 7 悬浮页签深度实战】02 从普通底栏到第一个悬浮页签
华为·harmonyos
网安蟹佬霸2 小时前
蓝队防御实战:SIEM与SOAR构建安全运营中心(万字详解+实战配置)
android·安全·web安全·网络安全·网安
whyutianict_vv2 小时前
从零到上架6款APP:AI鸿蒙全栈智能体开发5个月实战复盘(ArkTS/DevEco/AGC全流程)
人工智能·个人开发·harmonyos
敢敢のwings3 小时前
世界模型与FlashWorld:从“在梦中学习“到秒级3D场景生成
android·学习·3d
OH_TPC3 小时前
HarmonyOS APP开发---"启动秀"应用引导页App,需要用到这个库
harmonyos
Dovis(誓平步青云)4 小时前
牛奶不能减成负数:冰箱库存的筛选、去重与不可变更新
android·java·开发语言
Awna4 小时前
MySQL 存储空间与索引运维实战:从空间排查到在线扩容
android·运维·mysql