Skip to content

@Builder 使用

注意

  1. @Builder 个人理解就是 vue 插槽

  2. 它要是内部使用,完全可以被方法代替

  3. 它要是外部使用,组件也可以代替

  4. 但是它要是配合@BuilderParam 和 wrapBuilder 使用,那它就是无敌了,

  5. 给组件里面传递 html 也只有它能办到了

@Builder 分类

注意

  1. 分成全局和局部

  2. 在鸿蒙体系中全局和局部的区分普遍都是全局比局部多了个 function

全局和局部的共同点

注意

  1. 自定义构建函数的参数传递有按值引用传递

  2. 参数的类型必须与参数的声明的类型保持一致,不允许 undefined,null 和返回 undefined,null 的表达式

  3. 在@Builder 修饰的函数内部,不允许改变参数的值

  4. 在@Builder 内 UI 语法遵循 UI 语法原则(不允许写 js 方法和变量)

  5. 只有传入一个参数,且参数需要直接传入对象字面量才会按照引用传递该参数,其余都是按值传递,UI 不会改变

(一)局部

总结

  1. 只有在传递 1 个参数

  2. 引用类型

  3. 并且是对象字面量,才会变更内部数据

  4. 其余情况内部都不变

语法

bash
@Builder
xxxx(){

}

// 使用

this.xxxx()

使用如下

  • 点击后 详情如下

代码如下

ts

interface hasObjType {
    name: string,
    age: number
}


@Entry
@Component
struct Index {
    @State messageNoParams: string = "不用传递参数"
    @State message: string = "需要传递参数"
    @State age: number = 68
    @State hasObj: hasObjType = { name: this.message, age: this.age }

    // 局部Builder,无Params 值传递

    @Builder
    showNoParamsBuilder() {
        Text(this.messageNoParams).fontSize(34).fontColor(Color.Red)
    }

    @Builder
    showNoParamsObjBuilder() {
        Text(this.hasObj.name).fontSize(34).fontColor(Color.Red)
        Text(this.hasObj.age.toString()).fontSize(34).fontColor(Color.Red)
    }

    // 局部Builder,有Params,值传递

    @Builder
    showHasParamsBuilder(params: string) {
        Text(params).fontSize(24).fontColor(Color.Blue)
    }

    // 局部Budiler,有Params 引用传递

    @Builder
    showHasParamsObjBuilder(obj: hasObjType) {
        Text(obj.name).fontSize(24).fontColor(Color.Blue)
        Text(obj.age.toString()).fontSize(24).fontColor(Color.Blue)
    }

    handleClick() {
        console.log("点击了")
        this.message = "彻底改变了"
        this.messageNoParams = "彻底改变了不用传递参数"
        this.age = 24;
        this.hasObj.name = "彻底改变了"
        this.hasObj.age = 168;
    }

    build() {
        Column({ space: 10 }) {
            Text("不传递参数,内部值传递,会改变").fontSize(22)
            Divider()
            this.showNoParamsBuilder()
            Divider()
            Text("不传递参数,内部引用传递,会改变").fontSize(22)
            this.showNoParamsObjBuilder()
            Divider()
            Text("传递参数,外部值转递,所以不会改变").fontSize(22)
            this.showHasParamsBuilder(this.message)
            Divider()
            Text("传递参数,外部引用传递,不会被改变,因为不是字面量").fontSize(22)
            this.showHasParamsObjBuilder(this.hasObj)
            Divider()
            Text("传递参数,外部引用传递,会被改变,因为是字面量").fontSize(22)
            this.showHasParamsObjBuilder({ name: this.message, age: this.age })
            Divider()
            Button("改变message").onClick(() => {
                this.handleClick()
            })
        }
    }
}

(二) 全局

语法

ts
// 现在组件或者页面外边
@Builder
function xxx(){}

// 调用的时候
xxx()

示例

  • 点击后 详情如下

总结

总结

  1. 只有在传递 1 个参数

  2. 引用类型

  3. 并且是对象字面量,才会变更内部数据

  4. 其余情况内部都不变

代码如下

ts
interface hasObjType2 {
    name: string,
    age: number
}

// 传递参数 内部值类型
@Builder
function showParams(message: string) {
    Text(message).fontSize(22).fontColor(Color.Red)
}

// 传递参数 内部引用类型

@Builder
function showNoObjParams(obj: hasObjType2) {
    Text(obj.name).fontSize(22).fontColor(Color.Green)
    Text(obj.age.toString()).fontSize(22).fontColor(Color.Green)
}


@Entry
@Component
struct Index2 {
    @State messageNoParams: string = "不用传递参数"
    @State message: string = "需要传递参数"
    @State age: number = 68
    @State hasObj: hasObjType2 = { name: this.message, age: this.age }

    handleClick() {
        console.log("点击了")
        this.message = "彻底改变了"
        this.messageNoParams = "彻底改变了不用传递参数"
        this.age = 24;
        this.hasObj.name = "彻底改变了"
        this.hasObj.age = 168;
    }

    build() {
        Column() {
            Text("传递参数,外部值转递,所以不会改变").fontSize(22)
            showParams(this.message)
            Divider()
            Text("传递参数,外部引用传递,不会被改变,因为不是字面量").fontSize(22)
            showNoObjParams(this.hasObj)
            Divider()
            Text("传递参数,外部引用传递,会被改变,因为是字面量").fontSize(22)
            showNoObjParams({ name: this.message, age: this.age })
            Divider()
            Button("改变message").onClick(() => {
                this.handleClick()
            })
        }
    }
}