本节摘要:不靠模板,从空白文件手写一个含标题、两个输入框、按钮与点击响应的登录页,过程中拆解 ArkTS 页面的三层语法:装饰器组件层、build 描述层、链式属性层,并初次使用 @State 让按钮点击能改变界面。
现在把工程 pages 目录下的 Index 清空,只留一个空文件,我们一行行手写。声明式 UI 的页面长这样:
@Entry @Component struct Index { build() { Column() { Text('登录') } } }
第一层语法是装饰器。@Component 标记这是一个自定义组件,struct 是它的载体——ArkTS 没有类组件,组件一律是结构体;@Entry 标记它是页面入口,UIAbility 的 loadContent 加载的就是它。没有 @Entry 的组件只能被别的组件引用,不能独立成页(上一节新建 Second 页面时 IDE 自动带上了这两个装饰器,原因在此)。
第二层是 build 方法:每个组件必须且只能有一个 build,返回一段界面描述。注意措辞——是"描述",不是"绘制"。你声明"这里有一个纵向容器,容器里有段文字",至于怎么画,是 ArkUI 框架的事。这就是声明式的核心:界面是数据的函数,你负责说清"是什么",框架负责"怎么变"。
第三层是链式调用:Column()、Text() 这些组件后可以串一串点方法设置属性。下面写完整登录页时会大量出现。
目标:标题、账号与密码输入框、登录按钮;点击按钮时先做本地校验,界面上给出提示文字。完整代码:
@Entry @Component struct Index { @State account: string = '' @State password: string = '' @State tip: string = '' build() { Column({ space: 16 }) { Text('账号登录') .fontSize(28) .fontWeight(FontWeight.Bold) .margin({ top: 60 }) TextInput({ placeholder: '请输入账号' }) .height(48) .onChange((value: string) => { this.account = value }) TextInput({ placeholder: '请输入密码' }) .type(InputType.Password) .height(48) .onChange((value: string) => { this.password = value }) Button('登录') .width('100%') .height(44) .backgroundColor('#007DFF') .onClick(() => { if (this.account.length === 0) { this.tip = '账号不能为空' } else if (this.password.length < 6) { this.tip = '密码至少 6 位' } else { this.tip = '校验通过,准备发起请求' } }) if (this.tip !== '') { Text(this.tip) .fontSize(14) .fontColor('#E8402F') } } .padding(24) .width('100%') .height('100%') .alignItems(HorizontalAlign.Center) } }
逐层拆这段代码:

登录页里出现了 TypeScript 的影子(类型标注、箭头函数),这里把用到的部分现场补齐。ArkTS 是 TypeScript 的超集再收紧:变量声明要带类型或可推导,函数参数必须标类型。同时它加了几条硬约束——不能使用 any 与 unknown、不能用解构赋值修改对象属性、组件成员变量不能用某些动态特性。这些约束服务于编译优化:类型确定,方舟运行时才能生成高效代码。
对本页而言只需记住三条:onChange 回调的参数写 (value: string);@State 变量声明时必须给类型与初值;给 this.tip 赋值的箭头函数里的 this 指向组件自身,不要改回普通 function(会丢 this)。
⚠️ 常见坑:把 @State 变量的类型写成联合类型或 any。编译器会直接拒绝。状态变量的类型越具体,框架的依赖分析越精确,这既是约束也是性能提示。
运行工程,按三条路径测试:不填账号点登录——出现红色"账号不能为空";填账号、填短密码——提示切换为"密码至少 6 位";填合规内容——提示"校验通过"。三条路径覆盖了状态驱动的两种典型变化:文字内容变化与元素出现消失。
变式练习两个:其一,把提示文字从底部挪到输入框下方,练习调整组件顺序;其二,加一个"记住账号"的勾选框(Toggle 组件),切换时往 hilog 打一行日志,为第 4 章的状态记录热身。这两个改动都只动 build 内的结构,不需要任何新机制。
本节要点回顾:
登录页已经能看、能点、能提示,但它还是一列竖排的控件,谈不上布局。下一章进入组件与布局容器的正题,把这页重排成一个像样的界面,并让同一份代码适配不同大小的屏幕。