建设企业网站公司价格,wordpress实现pdf浏览器,网络服务提供者是不是网络运营者,WordPress完美建站Builder装饰器-自定义构建函数
前面介绍了如何创建一个自定义组件。该自定义组件内部UI结构固定#xff0c;仅与使方法进行数据传递。ArkUI还提供了一种更轻量的UI 元素复用机制Builder#xff0c;Builder
所装饰的函数遵循build( )函数语法规则#xff0c;开发者可以将重…Builder装饰器-自定义构建函数
前面介绍了如何创建一个自定义组件。该自定义组件内部UI结构固定仅与使方法进行数据传递。ArkUI还提供了一种更轻量的UI 元素复用机制BuilderBuilder
所装饰的函数遵循build( )函数语法规则开发者可以将重复使用的UI 元素抽象成一个方法在 build 方法里调用。 为了简化语言我们将Builder 装饰的函数也称为“自定义构建函数”。从API version 9开始该装饰器支持在ArkTS卡片中使用。 装饰器使用说明
语法的定义
Builder MyBuilderFunction( ){...}
使用方法
this.MyBuilderFunction(){...} 允许在自定义组件内定义一个或多个Builder 方法该方法被认为是该组件的私有、特殊类型的成员函数。 自定义构建函数可以在所属组件的build 方法和其他自定义构建函数中调用但不允许在组件外调用。 在自定义函数体中this指代当前所属组件组件的状态变量可以在自定义构建函数内访问。建议通过this访问自定义组件的状态变量而不是参数传递 全局自定义构建函数
语法的定义
BUilder function MyGlobalBuilderFunction{...} 使用方法
MyGlobalBuilderFunction 全局的自定义构建函数可以被整个应用获取不允许使用this和bind方法。 如果不涉及组件状态变化建议使用全局的自定义构建方法 参数传递规则
自定义构建函数的参数传递有按值传递和按引用传递两种均需遵守以下规则:
参数的类型必须与参数声明的类型一致不允许undefined、nu1l和返回undefined、null的表达式 引用传参最常用
//自定义一个构建函数
//引用传参使用$$符号
Builder
function MyBulilder($$:{username:string}){
//用的时候也要使用$$Column(){Text(hello ${$$.username}).fontSize(40).margin(20)}
}
Entry
Component
struct Parent{
State person_name: string张三
build(){Column(){Divider()MyBulilder({username: this.person_name})Button(改变值).onClick((){this.person_name 李四})}}
} 值传参了解 并不实用
//自定义一个构建函数
//按值传参
Builder
function MyBulilder(username:string){
Column(){Text(hello ${username}).fontSize(40).margin(20)}
}
Entry
Component
struct Parent{
State person_name: string张三
build(){Column(){Divider()MyBulilder(this.person_name)Button(改变值).onClick((){this.person_name 李四})}}
}
状态管理 状态管理概述
在前文的描述中我们构建的页面多为静态界面。如果希望构建一个动态的、有交互的界面就需要引入“状态”的概念
在本章节开始的案例中用户与应用程序的交互触发了文本状态变更状态变更引起了UI 渲染UI 从“Hello world”变更为“Hello rkUI”这个过程就用到了状态。
在声明式UI编程框架中UI是程序状态的运行结果用户构建了一个U模型其中应用的运行时的状态是参数。当参数改变时UI作为返回结果也将进行对应的改变。这些运行时的状态变化所带来的UI的重新渲染在ArkUI中统称为状态管理机制。
自定义组件拥有变量变量必须被装饰器装饰才可以成为状态变量状态变量的改变会引起UI的渲染刷新。如果不使用状态变量UI只能在初始化时渲染后续将不会再刷新。下图展示了state和iew(UI)之间的关系 View(UI):UI 渲染指将build 方法内的 UI 描述和Builder 装饰的方法内的UI 描述映射到界面。 state:状态指驱动U更新的数据。用户通过触发组件的事件方法改变状态数据。状态数据的改变引起UI的重新渲染。 基本概念 状态变量:被状态装饰器装饰的变量状态变量值的改变会引起UI的染更新。示例:State num: number1,其中State是状态装饰器num是状态变量。 常规变量:没有被状态装饰器装饰的变量通常应用于辅助计算。它的改变永远不会引起UI的刷新。以下示例中increaseBy 变量为常规变量。 数据源/同步源:状态变量的原始来源可以同步给不同的状态数据。通常意义为父组件传给子组件的数据。以下示例中数据源为count:1。 命名参数机制:父组件通过指定参数传递给子组件的状态变量为父子传递同步参数的主要手段。示例:CompA:({aPrp:this.aProp})。 从父组件初始化:父组件使用命名参数机制将指定参数传递给子组件。子组件初始化的默认值在有父组件传值的情况下会被覆盖。 初始化子节点:父组件中状态变量可以传递给子组件初始化子组件对应的状态变量。 本地初始化:在变量声明的时候赋值作为变量的默认值。示例:statecount:number 0 管理组件拥有的状态 State装饰器-组件内状态 state 装饰的变量或称为状态变量一旦变量拥有了状态属性就和自定义组件的渲染绑定起来。当状态改变时UI会发生对应的渲染改变。
在状态变量相关装饰器中state是最基础的使变量拥有状态属性的装饰器它也是大部分状态变量的数据源。从Pversion9开始该装饰器支持在ArkTs 卡片中使用。 概述
State装饰的变量与声明式范式中的其他被装价变量一样是私有的只能从组件内部访问在声明时必须指定其类型和本地初始化。初始化也可选择使用命名参数机制从父组件完成初始化。 装饰器使用说明
使用场景
装饰简单类型的变量 以下示例为state装饰的简单类型count被state装饰成为状态变量count的改变引起Button组件的刷新: 当状态变量count改变时查询到只有Button组件关联了它; 执行Button组件的更新方法实现按需刷新。 示例 点击修改姓名将会在张三李四之间进行切换
点击修改年龄将会按照你设定的规则进行年龄的加减
当子组件上传参数的时候将使用子组件的参数
当没有的时候默认是父组件的数据 Prop装饰器-父子单项同步
Prop 装饰的变量可以和父组性建立单向的同步关系。Prop装饰的变量是可变但是变化不会同步回其父组件。从API version 9开始该装饰器支持在rkTS 卡中使用。
概述 Prop 装饰的变量和父组件建立单向的同步关系: Prop变量允许在本地修改但修改后的变化不会同步回父组件 当父组件中的数据源更改时与之相关的Prop 装饰的变量都会自动更新。如果子组件已经在本地修改了Prop 装饰的相关变量值而在父组件中对应的state装饰的变量被修改后子组件本地修改的Prop装饰的相关变量值将被覆盖 限制条件 Prop 修饰复杂类型时是深拷贝在拷贝的过程中除了基本类型、Map、Set、Date、Array 外都会丢失类型。 Prop装饰器不能在Entry装饰的自定义组件中使用 装饰器使用规则说明 使用场景
父组件State 到子组件Prop简单数据类型同步
以下示例是state 到子组件Prop 简单数据同步父组件ParentComponent的状态变量 countDownstartValue 初始化子组件 CountDowncomponent 中eprop 装饰的 count点击“Try again”count 的修改仅保留在 CountDownComponent不会同步给父组件ParentComponent。
ParentComponent的状态变量countDownstartValue 的变化将重冒CountDownComponent的count。 代码
Component
struct MyChid{Propage: number 33private increase: number1 //私有build(){Column(){if (this.age18){Text(已经age成年了:${this.age}).height(80)}else{Text(age未成年了:${this.age}).height(80)}Button(-修改子组件age).onClick((){this.age-this.increase}).height(80).width(250).margin(5)}}
}
Entry
Component
struct Myparent {Stateinit_age: number 16
build(){Column(){Text(父组件初始值${this.init_age}).height(80)
Button(修改父组件age).onClick((){this.init_age1}).height(80).margin(5).width(250)
Divider()MyChid({age:this.init_age,increase:2})}}
} Link装饰器-父子双向同步 子组件中被Link 装饰的变量与其父组件中对应的数据源建立双向数据绑定。从APIversion 9开始该装饰器支持在ArkTS卡片中使用。
需要注意:Link 装饰的变量与其父组件中的数据源共享相同的值。Link 装饰器不能在Entry 装饰的自定义组件中使用。
代码示例展示
//自定义按钮的信息类型
class ButtonState{value:string;width:number0;
constructor(value:string, width:number){this.value value;this.width width;}
}
Component
struct MyChildGreenButton{//拥有 绿色按钮的组件Link装饰器 实现双向同步LinkbuttonState:ButtonState //自定义对象类型
build(){Button(${this.buttonState.value}).width(this.buttonState.width).height(150).backgroundColor(Color.Green).onClick((){//点击按钮 实现宽度的变化if(this.buttonState.width700){this.buttonState.width100}else {//按钮宽度回到初始值this.buttonState new ButtonState(绿色按钮,100)}})}
}
Component
struct MyChildRedButton{//拥有 红色按钮的组件Link装饰器 实现双向同步Linkvalue: stringLinkbuttomWidth: number;
build(){Button(${this.value}).width(this.buttomWidth).height(150).backgroundColor(Color.Red).onClick((){//点击按钮 实现宽度的变化if(this.buttomWidth700){this.buttomWidth100}else {//按钮宽度回到初始值this.buttomWidth 100}})}
}
Entry
Component
struct MYParent{State parentGreenButton:ButtonStatenew ButtonState(一号,100) //状态变量State parentRedValue: string 二号子组件 //状态变量State parentRedWidth: number 200 //状态变量 //绿色按钮的宽度
build(){Column(){//父组件中调整按钮宽度Button(父组件中修改绿色按钮的宽度${this.parentGreenButton.width}).onClick((){this.parentGreenButton.width this.parentGreenButton.width 700 ? this.parentGreenButton.width100:100})
Button(父组件中修改红色按钮的宽度${this.parentRedWidth}).onClick((){this.parentRedWidth this.parentRedWidth 700 ? this.parentRedWidth100:100})
Divider()
MyChildGreenButton({buttonState:$parentGreenButton}) //传递Link装饰器的变量时候加 $ 符号MyChildRedButton({value:$parentRedValue,buttomWidth:$parentRedWidth})}}
}
if/else 条件渲染
ArkTS 提供了渲染控制的能力。条件渲染可根据应用的不同状态使用if、else 和else if 渲染对应状态下的UI内容。从API version 9开始该接口支持在 ArkTS卡片中使用。 使用规则 支持if、else和else if 语句。 if、else if 后跟随的条件语句可以使用状态变量 允许在容器组件内使用通过条件渲染语句构建不同的子组件。 条件渲染语句在涉及到组件的父子关系时是“透明”的当父组件和子组件之间存在一个或多个if语句时必须遵守父组件关于子组件使用的规则。 “每个分支内部的构建函数必须遵循构建函数的规则并创建一个或多个组件。无法创建组件的空构建函数会产生语法错误。 某些容器组件限制子组件的类型或数量将条件渲染语句用于这些组件内时这些限制将同样应用于条件渲染语句内创建的组件。例如Grid容器组件的子组件仅支持GridItem 组件在Grid 内使用条件渲染语句时条件渲染语句内仅允许使用GridItem组件
更新机制 当if、else if 后跟随的状态判断中使用的状态变量值变化时条件渲染语句会进行更新更新步骤如下: 评估if和else if的状态判断条件如果分支没有变化请无需执行以下步骤。如果分支有变化则执行2、3步骤: 删除此前构建的所有子组件。 执行新分支的构造函数将获取到的组件添加到if 父容器中。如果缺少适用的 else分支则不构建任何内容。 条件可以包括 Typescript 表达式。对于构造函数中的表达式此类表达式不得更改应用程序状态。 使用if进行条件渲染
if 语句的每个分支都包含一个构建函数。此类构建函数必须创建一个或多个子组件。在初始渲染时if语句会执行构建函数并将生成的子组件添加到其父组件中。
“每当if或else if条件语句中使用的状态变量发生变化时条件语句都会更新并重新评估新的条件值。如果条件值评估发生了变化这意味着需要构建另一个条件分支。此时ArkUI 框架将: 删除所有以前渲染的(早期分支的)组件。 执行新分支的构造函数将生成的子组件添加到其父组件中 代码演示
分为两种 第一种 点击“是否真假的按钮的时候” 计数器的值会归零
//定义子组件
Component
struct MyChild{
//计数器State counter:number0label: string;
build(){Row(){Text(${this.label}).width(100).height(100).fontSize(20)
Button(计数器的值${this.counter}).width(200).height(60).onClick((){this.counter 1;})}}
}
Entry
Component
struct MyParent{State flag:booleanfalse;build(){Column(){//根据判断决定子组件if(this.flag){MyChild({label:zhenzhen})}else {MyChild({label:jiajia})}Divider()Button(是否真假:${this.flag}).width(300).height(60).fontSize(30).margin(40).onClick((){this.flag!this.flag})}}
} 第二种 点击是否真假的时候计数器的值不会进行更新归零
//定义子组件
Component
struct MyChild{
//计数器Link counter:number;label: string;
build(){Row(){Text(${this.label}).width(100).height(100).fontSize(20)
Button(计数器的值${this.counter}).width(200).height(60).onClick((){this.counter 1;})}}
}
Entry
Component
struct MyParent{State flag:booleanfalse;State parentCount: number0build(){Column(){//根据判断决定子组件if(this.flag){MyChild({counter:$parentCount,label:zhenzhen})}else {MyChild({counter:$parentCount,label:jiajia})}Divider()Button(是否真假:${this.flag}).width(300).height(60).fontSize(30).margin(40).onClick((){this.flag!this.flag})}}
}