arkUI:自定义构建函数(参数的引用传递)

1 主要内容说明

一个程序由多个部分组成,我们先举个例子源码1,创建一个卡片效果以显示每个人的各项信息。有具体显示样式的函数方法Message_view,然后还有接口部分Message,以及一个入口文件。我们先把相关内容功能全部编写运行于一个文件内,先运行显示一下效果。然后将卡片显示样式的方法部分,和接口类型部分,拆分各放于其他文件中,再使用导入和导出的方式,再次运行程序呈现效果。程序运行的观看效果界面相同,只是呈现代码的方式不同。本文大目标仍是展示自定义构建函数的参数传递效果的。
我们都知道一个程序是多个功能组成的,每个文件配置相应功能的代码,更易于程序的维护和管理。往大了讲,一个项目多个组成部分,各个人在不同的地区编写各自的功能部分,最后再汇总组合运行,使得项目的完成更有灵活性。
关于人员的内容,我们本文是创建了一个对象数组aar,用于数据的导入显示。这里我们可以把数组arr理解成一个小数据库。可以类比,导入数据库的数据内容,是不是也可以在此设置相关的函数,用以数据库数据的导入,将数据设置相关显示样式,以呈现观察。

2 相关内容

我们创建一个用于显示人员卡片信息的程序。程序大的方向主要有三部分。

  • 第一部分,一个是程序的入口,在@Entry组件内,引用自定义构建函数的方法Message_view。
  • 第二部分,Message_view方法是显示单个卡片的具体样式,具体举例如下:
    在这里插入图片描述
  • 第三部分,创建接口类型Message,用于引用设置Message_view方法的各项参数。

我们在@Entry组件内,使用ForEach方法,将数组内的每个人的参数以第二部分卡片的形式各个显示出来。

2.1 自定义构建函数(引用传参)

2.1.1 源码1的相关说明

  • 定义数据接口:使用 Message 接口定义用户信息结构,包括姓名、年龄、身高、爱好和编号。

  • 状态变量:使用 @State 定义一个数组 arr,存储多个用户的数据。

  • 页面结构:在 build 函数中使用 ForEach 遍历 arr 数组,为每个用户调用 Message_view 组件,生成信息卡片。

  • 卡片显示:Message_view 组件中使用 Row 和 Column 布局,显示用户的姓名、年龄、编号、身高和爱好,设置样式使得信息整齐显示。

2.1.2 源码1 (push方法)

// 定义一个接口 Message 来描述用户信息
export interface Message {
  name: string;  // 姓名
  age: number;   // 年龄
  height: number; // 身高
  hobby: string; // 爱好
  num: number;   // 编号
}

// 引入 Message 接口和 Message_view 组件
// import { Message } from "../model/interface_massage"
// import { Message_view } from "../model/Message_view"

@Entry
@Component
struct PageFunction {

  // 定义一个状态变量 arr,其类型是 Message 数组,用来存储用户数据
  @State arr: Message[] = [
    {
      name: "阿桦",
      age: 20,
      height: 168,
      hobby: "篮球",
      num: 1
    },
    {
      name: "小魏",
      age: 22,
      height: 160,
      hobby: "排球",
      num: 2
    },
    {
      name: "基恩",
      age: 27,
      height: 164,
      hobby: "羽毛球",
      num: 3
    },
    {
      name: "诶安康",
      age: 23,
      height: 163,
      hobby: "足球",
      num: 4
    },
    {
      name: "蓝染",
      age: 18,
      height: 178,
      hobby: "游泳",
      num: 5
    },
    {
      name: "任丽君",
      age: 25,
      height: 166,
      hobby: "山地骑行",
      num: 6
    }
  ]

  // build 函数,生成页面结构
  build() {
    Column() {
      // 使用 ForEach 循环遍历 arr 数组,为每一个用户创建一个 Message_view 组件
      ForEach(
        this.arr,
        (item: Message) => {
          Message_view(item) // 调用 Message_view 组件,传入 item
        }
      )
    }
    .height('100%')
    .width('100%')
  }
}

// 定义一个名为 Message_view 的函数组件,用来显示每个用户的信息卡片
@Builder
function Message_view(mes: Message) {
  Column() {
    // 卡片上部分,显示姓名和年龄
    Row() {
      Text("姓名:")

      Text(mes.name)  // 显示用户的姓名
        .fontSize(20)
        .fontWeight(FontWeight.Bold)
        .fontColor("rgba(217, 18, 112, 1.00)")

      Blank() // 空格用于间隔

      Text("年龄:")

      Text(mes.age.toString())  // 显示用户的年龄
        .fontSize(20)
        .fontWeight(FontWeight.Bold)

      Blank()
    }
    .width("100%")
    .padding({ left: "2%", right: "2%" })

    // 卡片下部分,显示编号、身高和爱好
    Row() {
      Text("编号:")

      Text(mes.num.toString())  // 显示用户的编号
        .fontSize(15)
        .fontWeight(FontWeight.Bold)

      Blank()

      Text("身高:")

      Text(mes.height.toString())  // 显示用户的身高
        .fontSize(15)
        .fontWeight(FontWeight.Bold)
      Text("cm")

      Blank()

      Text("爱好:")
      Text(mes.hobby)  // 显示用户的爱好
        .fontSize(15)
        .fontWeight(FontWeight.Bold)
    }
    .width("100%")
    .padding({ left: "2%", right: "2%" })
  }
  .margin({ bottom: 20 })  // 每个卡片之间的底部间隔
  .padding({ left: "2%", right: "2%" })  // 卡片内容的左右内边距
  .backgroundColor("#ff25ffed")  // 卡片的背景颜色
  .height(80)  // 卡片高度
  .justifyContent(FlexAlign.SpaceEvenly)  // 控制子组件在卡片中的分布
  .width("90%")  // 卡片宽度
  .borderRadius("20")  // 圆角样式
}

2.1.3 源码1运行效果

在这里插入图片描述

2.2 源码1内容拆分,使用导入和导出方法显示程序效果

  • 文件路径关系如下
    在这里插入图片描述

2.2.1 源码2-1 @Entry入口文件

  • 文件名PageFunction.ets,在pages文件夹中

// 引入 Message 接口和 Message_view 组件
import { Message } from "../model/interface_massage"
import { Message_view } from "../model/Message_view"

@Entry
@Component
struct PageFunction {

  // 定义一个状态变量 arr,其类型是 Message 数组,用来存储用户数据
  @State arr: Message[] = [
    {
      name: "阿桦",
      age: 20,
      height: 168,
      hobby: "篮球",
      num: 1
    },
    {
      name: "小魏",
      age: 22,
      height: 160,
      hobby: "排球",
      num: 2
    },
    {
      name: "基恩",
      age: 27,
      height: 164,
      hobby: "羽毛球",
      num: 3
    },
    {
      name: "诶安康",
      age: 23,
      height: 163,
      hobby: "足球",
      num: 4
    },
    {
      name: "蓝染",
      age: 18,
      height: 178,
      hobby: "游泳",
      num: 5
    },
    {
      name: "任丽君",
      age: 25,
      height: 166,
      hobby: "山地骑行",
      num: 6
    }
  ]

  // build 函数,生成页面结构
  build() {
    Column() {
      // 使用 ForEach 循环遍历 arr 数组,为每一个用户创建一个 Message_view 组件
      ForEach(
        this.arr,
        (item: Message) => {
          Message_view(item) // 调用 Message_view 组件,传入 item
        }
      )
    }
    .height('100%')
    .width('100%')
  }
}

2.2.2 源码2-2 卡片显示样式方法(Message_view)

  • 文件名Message_view.ets,在model文件夹中
import {Message} from "../model/interface_massage"

// 定义一个名为 Message_view 的函数组件,用来显示每个用户的信息卡片
@Builder
export function Message_view(mes: Message) {
  Column() {
    // 卡片上部分,显示姓名和年龄
    Row() {
      Text("姓名:")

      Text(mes.name)  // 显示用户的姓名
        .fontSize(20)
        .fontWeight(FontWeight.Bold)
        .fontColor("rgba(217, 18, 112, 1.00)")

      Blank() // 空格用于间隔

      Text("年龄:")

      Text(mes.age.toString())  // 显示用户的年龄
        .fontSize(20)
        .fontWeight(FontWeight.Bold)

      Blank()
    }
    .width("100%")
    .padding({ left: "2%", right: "2%" })

    // 卡片下部分,显示编号、身高和爱好
    Row() {
      Text("编号:")

      Text(mes.num.toString())  // 显示用户的编号
        .fontSize(15)
        .fontWeight(FontWeight.Bold)

      Blank()

      Text("身高:")

      Text(mes.height.toString())  // 显示用户的身高
        .fontSize(15)
        .fontWeight(FontWeight.Bold)
      Text("cm")

      Blank()

      Text("爱好:")
      Text(mes.hobby)  // 显示用户的爱好
        .fontSize(15)
        .fontWeight(FontWeight.Bold)
    }
    .width("100%")
    .padding({ left: "2%", right: "2%" })
  }
  .margin({ bottom: 20 })  // 每个卡片之间的底部间隔
  .padding({ left: "2%", right: "2%" })  // 卡片内容的左右内边距
  .backgroundColor("#ff25ffed")  // 卡片的背景颜色
  .height(80)  // 卡片高度
  .justifyContent(FlexAlign.SpaceEvenly)  // 控制子组件在卡片中的分布
  .width("90%")  // 卡片宽度
  .borderRadius("20")  // 圆角样式
}

2.2.3 源码2-3 接口文件(interface Message)

  • 文件名interface_massage.ets,在model文件夹中
// 定义一个接口 Message 来描述用户信息
export interface Message {
  name: string;  // 姓名
  age: number;   // 年龄
  height: number; // 身高
  hobby: string; // 爱好
  num: number;   // 编号
}

2.2.4 源码2-1入口文件的运行效果

  • 和源码1的效果一样,且可以正常运行程序。
    在这里插入图片描述

3.结语

使用全局的函数,可以让代码更灵活。特别是在组件设置方式重复较多时,调用方法函数,让代码更简便。
由于笔者的能力有限,创作的内容有所不足在所难免,也敬请读者包涵和指出,万分感谢!

4.定位日期

2024-11-10;
21:52;

<think>嗯,我现在要解决这个关于ArkUI中私有自定义构建函数的选择题。首先,我需要回忆一下ArkUI的相关知识,特别是关于自定义构建函数的部分。题目给了四个选项,我需要逐一分析每个选项的正确性。 题目问的是正确的选项是哪一个。选项包括A、B、C、D四个。首先,我需要明确私有自定义构建函数的定义、作用域以及使用规则。根据之前学习的ArkUI框架,私有自定义构建函数通常是指使用@Builder装饰器定义的函数,只能在当前组件内使用,不能被外部组件调用。此外,构建函数内部如何访问组件状态变量,以及它们的作用域和调用限制也需要考虑。 先看选项A:“建议通过参数传递的方式访问组件的状态变量,而不是通过this”。根据ArkUI的最佳实践,构建函数中访问状态变量应该通过参数传递,而不是直接使用this,因为this可能指向不正确,尤其是在函数作用域变化时。这样可以确保数据的正确传递,避免副作用。所以A可能正确。 选项B:“在自定义函数体中,this指代当前所属组件,组件的状态变量可以在自定义构建函数内访问”。这里提到this指向当前组件,并且可以直接访问状态变量。但根据ArkUI的规则,在@Builder构建函数内部,直接使用this可能存在问题,尤其是在函数被其他作用域调用时,this可能不指向预期组件。正确的做法是通过参数传递状态变量,而不是依赖this。所以B可能是错误的。 选项C:“私有自定义构建函数只能在自定义组件外部定义”。这显然不正确。私有构建函数应该是在组件内部定义,只能在组件内部使用。如果在外部定义,那可能就不是私有的了,而是公共的。所以C错误。 选项D:“私有自定义构建函数不能在其他自定义构建函数中调用”。根据文档,私有构建函数(@Builder)可以在同一组件内的其他构建函数中被调用,但公共构建函数(@BuilderParam)可能有不同的规则。因此D的说法不正确,应该是可以调用的。所以D错误。 接下来需要确认各个选项的正确性。回忆ArkUI的官方文档,私有@Builder函数的作用域是组件内部,可以访问组件的状态变量,但推荐通过参数传递而不是直接使用this。所以选项A正确,B错误,因为this可能不可靠。C错误,因为私有构建函数在组件内部定义。D错误,因为它们可以在其他构建函数中被调用。 因此,正确的选项是A和B中的哪一个?这里可能存在混淆。需要更仔细核对。比如,选项B说this指代当前组件,是否允许在构建函数内访问状态变量?如果构建函数是私有的话,可能可以访问,但官方推荐的做法是参数传递。因此B的说法是否正确呢? 根据ArkUI的文档,@Builder函数内部确实可以访问组件内的状态变量,并且this指向当前组件。所以B的说法是正确的吗?或者是否有其他限制? 这个时候可能我的记忆有误。需要进一步分析。例如,在私有@Builder函数中,如果直接使用this,是否能正确访问状态变量?假设组件有一个状态变量@State count,那么在@Builder函数里使用this.count是否可行? 根据实际代码示例,私有@Builder函数可以直接访问组件内的状态变量,不需要通过参数传递,所以B选项的说法是正确的。而选项A的建议是否正确? 此时可能选项A和B存在矛盾。官方是否推荐使用参数传递而不是this? 查阅资料,ArkUI的@Builder函数中,如果构建函数是私有的(@Builder),可以直接访问组件的状态变量,此时this确实指向组件实例,所以B选项的描述是正确的。而选项A的说法是否正确呢?例如,虽然可以直接访问,但官方是否建议通过参数传递? 假设官方推荐使用参数传递而不是依赖this,那么选项A正确,而B的说法虽然技术上可能正确,但不符合最佳实践。例如,可能存在某些情况下this的作用域问题,导致访问状态变量不可靠,因此建议通过参数传递。 这时候需要判断题目中的正确选项是哪一个。比如,选项B是否正确?如果文档明确指出在自定义构建函数内可以通过this访问组件状态变量,则B正确。而选项A是否正确取决于是否建议这样做。 例如,假设文档指出:“在自定义构建函数中,应该通过参数传递的方式使用父组件的状态变量,而不是直接通过this引用”,那么选项A正确。否则,如果允许直接访问,则B正确。 这里可能需要更准确的回忆或资料。根据华为ArkUI的官方文档,私有@Builder函数可以访问组件内的状态变量,并且this指向当前组件。因此选项B是正确的。而选项A的说法是否正确呢? 如果选项A的说法是“建议通过参数传递”,而实际上直接访问是允许的,但推荐参数传递,那么可能A和B都存在正确部分,但需要看题目是否有多个正确选项。不过题目可能只允许一个正确选项。 但原题可能存在多个正确选项吗?题目选项可能设置为单选。这时候需要仔细看选项内容。 例如,选项B中的描述是否正确。假设this确实指向当前组件,并且可以访问状态变量,那么B是正确的。此时选项A的说法是否正确? 如果官方建议使用参数传递,而不是通过this访问,那么A的说法正确,而B的说法虽然可能技术上可行,但并不是建议的做法,所以选项A正确,而B不正确。但题目中的选项可能并不涉及建议,而是事实是否正确。 例如,选项B中的描述是否事实正确,即是否可以在构建函数内访问状态变量。如果是的话,那么B正确,而A可能是否正确取决于是否是“建议”。 此时,我需要重新考虑问题。题目中的选项B描述的是事实性的内容,而选项A描述的是建议性的内容。正确的答案可能同时存在,但根据实际文档,哪一个正确。 根据ArkUI的文档,私有@Builder函数可以访问组件的状态变量,并且this指向当前组件。因此选项B的说法是正确的。而选项A的说法是否正确呢? 假设官方推荐的做法是通过参数传递,而不是直接访问,那么A的说法正确,而B的说法虽然正确,但可能不是推荐方式。但题目问的是正确的选项,而不是最佳实践。因此如果B的说法在技术上是正确的,那么选项B正确,而A是否正确要看是否建议。 例如,题目中的选项B是否描述了正确的技术事实,而选项A则是一个建议。此时,选项B的说法正确,而选项A的说法是否错误? 例如,是否允许通过this访问,但建议使用参数传递?如果是的话,那么A的说法是建议,而B的说法是事实,那么两个选项可能都对。但题目可能只有一个正确选项,需要看选项是否互斥。 例如,如果选项B正确,那么选项A中的建议是否正确?例如,如果允许两种方式,但推荐参数传递,则A的说法正确,而B的说法也正确。但题目可能只有其中一个正确。 此时可能需要参考官方示例。例如,在ArkUI的文档中,私有@Builder函数的示例通常会直接访问组件的状态变量,而无需通过参数传递。例如: @State count: number = 0; @Builder myBuilder() { Text(`Count: ${this.count}`) } 这种情况下,this.count确实可以访问组件的状态变量,因此选项B的说法正确。而选项A的说法是否正确呢?如果是建议通过参数传递,可能在某些情况下更安全,但题目中的选项是否将建议作为正确选项? 因此,正确的选项应该是B,因为选项B的说法在技术上是正确的,而选项A的说法可能是一种推荐做法,但并非强制要求,因此题目可能选择B作为正确选项。 另外,关于选项D的说法:“私有自定义构建函数不能在其他自定义构建函数中调用”,是否正确?实际上,私有构建函数可以在同一组件内的其他构建函数中被调用,因此选项D错误。选项C错误,因为私有构建函数在组件内部定义。因此,正确的选项是B。 不过,这里可能存在混淆。例如,是否在函数体内可以访问状态变量?如果this指代当前组件,那么是的。所以选项B正确。</think>关于ArkUI中私有自定义构建函数的说法,正确选项为 **B**,具体分析如下: --- ### **选项分析** 1. **选项A** “建议通过参数传递的方式访问组件的状态变量,而不是通过`this`。” **错误**。 - 私有自定义构建函数(`@Builder`)可以直接通过`this`访问当前组件的状态变量,无需强制通过参数传递。 - 参数传递是推荐做法,但题目中“建议”一词属于实践指导,而非语法规则,因此选项A的表述不符合技术事实。 2. **选项B** “在自定义函数体中,`this`指代当前所属组件,组件的状态变量可以在自定义构建函数内访问。” **正确**。 - 私有构建函数(`@Builder`)的作用域为当前组件,`this`指向所属组件实例,可直接访问其状态变量(如`@State`、`@Prop`等)。 - 例如: ```typescript @State count: number = 0; @Builder MyBuilder() { Text(`Count: ${this.count}`) // 直接通过this访问状态变量 } ``` 3. **选项C** “私有自定义构建函数只能在自定义组件外部定义。” **错误**。 - 私有构建函数需在组件**内部**定义,通过`@Builder`装饰器声明,且仅限当前组件内使用。若在外部定义,则无法访问组件内部状态。 4. **选项D** “私有自定义构建函数不能在其他自定义构建函数中调用。” **错误**。 - 私有构建函数可以在同一组件内的其他构建函数中调用。例如: ```typescript @Builder BuilderA() { Text("Hello") } @Builder BuilderB() { this.BuilderA() // 调用另一个构建函数 } ``` --- ### **结论** **正确答案:B** 私有自定义构建函数中,`this`指向当前组件实例,可直接访问其状态变量,且语法规则允许此操作。其他选项均存在事实性错误。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值