一、一个ArkTs的目录结构
二、一个页面的结构
A、装饰器
@Entry 装饰器 : 标记组件为入口组件,一个页面由多个自定义组件组成,但是只能有一个组件被标记
@Component : 自定义组件, 仅能装饰struct关键字声明的数据结构
@State:组件中的状态变量,就是ui绑定的数据,状态变量变化,ui中绑定的也会变
B、UI描述
整个build里面的,以声明式的方式来描述UI的结构,跟平常写的标签式的区别挺大
1)系统组件用的时候后面跟(), 分为有参数和无参数
bash
Column() {
Text('item 1') // 参数可选
Text(`count: ${this.count}`) // 用变量赋值
Divider()
Image('https://xyz/test.jpg') // 参数必填
}
2)css和事件都是以链式的方式挂在系统组件后面,每个单独一行(css可以做成函数式的,可复用,还没细看)
bash
Text('test')
.fontSize(12) // 属性参数为常量
Text('hello')
.fontSize(this.size) // 属性参数为变量赋值或者表达式
.fontColor(Color.Red) // 属性参数为可调用的枚举类型
.fontWeight(FontWeight.Bold)
3)事件
java
// 形式1:
Button('Click me')
.onClick(() => { // 箭头函数
// do sth
})
java
// 形式2:
Button('add counter')
.onClick(function(){ // 匿名函数表达式
// do sth
}.bind(this)) // 必须用bind, 确保函数体中this指向当前组件
java
// 形式3:
myClickHandler(): void {
// do sth
}
...
Button('add counter')
.onClick(this.myClickHandler.bind(this)) // 组件的成员函数
java
// 形式4:
fn = () => {
// do sth
}
...
Button('add counter')
.onClick(this.fn) // 声明的箭头函数,不需要bind this
4)布局有专门的系统组件,比如Column组件,Row组件、Flex组件、Grid组件, 这些都是容器组件,可以嵌套子组件
4)UI描述里面可以有自定义组件
C、自定义组件
可复用,可组合,数据驱动UI更新
- 结构
java
@Component
struct 组件名称 { // 组件名称用大驼峰
@State 变量名称: 变量类型 = 变量值
build() {
// ui声明
}
}
- struct: 实例化,可以省略new
- struct被@Component装饰后具备组件化的能力
- 一个struct只能被一个@Component装饰,如果一个自定义组件设置为页面,必须用@Entry 装饰
- 成员函数/变量
- 自定义组件的成员函数为私有的,且不建议声明成静态函数
- 自定义组件的成员变量本地初始化有些是可选的,有些是必选的。 -- 涉及到传参
- build()函数
- @Entry装饰的自定义组件,其build()函数下的根节点唯一且必要,且必须为容器组件,其中ForEach禁止作为根节点。
- @Component装饰的自定义组件,其build()函数下的根节点唯一且必要,可以为非容器组件,其中ForEach禁止作为根节点。
- 自定义组件通用样式
java
@Entry
@Component
struct MyPage {
build() {
Row() {
MyComponent()
.width(200) // 这里的样式并不是直接加在MyComponent里面的根组件上的,而是根组件外部一个不可见的容器组件上的
.height(300)
.backgroundColor(Color.Red)
}
}
}
- 不允许做的
java
@Component
struct MyComponent{
doSomeCalculations() {
}
calcTextValue(): string {
return 'Hello World';
}
@Builder doSomeRender() {
Text(`Hello World`)
}
build() {
// 不允许声明本地变量
let a: number = 1;
// 不允许在UI描述里直接使用console.info,但允许在方法或者函数里使用
console.info('print debug log');
// 不允许创建本地的作用域
{
...
}
// 不允许调用没有用@Builder装饰的方法,允许系统组件的参数是TS方法的返回值
this.doSomeCalculations();
// 可以调用@Builder装饰的方法
this.doSomeRender()
// 允许系统组件的参数是TS方法的返回值
Text(this.calcTextValue())
// 不允许switch语法,如果需要使用条件判断,请使用if
switch (expression) {
case 1:
Text('...')
break;
case 2:
Image('...')
break;
default:
Text('...')
break;
}
// 不允许使用表达式
(this.aVar > 10) ? Text('...') : Image('...')
}
}
- 被外部引用的自定义组件,需要使用export导出
java
@Component
exprot struct 组件名称 {
private message: string= '123'
build() {
// ui声明
}
}
- 使用自定义组件的地方用import引入
java
import { 组件名 } from '相对路径'
@Entry
@Component
struct ParentComponent {
build() {
Column() {
Text('ArkUI message')
组件名({ message: 'Hello, World!' }) // 传参,对象形式
Divider()
组件名({ message: '你好!' });
}
}
}
-------------------------------------------------------补充分割线2024.06.20---------------------------------
1、一个页面中可以引用外部组件,也可以直接在页面中写组件并运用
java
@Entry
@Component
struct MyPage {
build() {
Column() {
TitleComponent()
BodyComponent()
}
}
}
@Component
struct TitleComponent {
build() {
Text('我是页面的标题')
}
}
@Component
struct BodyComponent {
build() {
Text('我是页面的内容')
}
}
2、在一个页面中可以预览整个页面,也可以预览里面的自定义组件,@Preview({...})里面可以配置参数(还没研究),预览是实时的
3、预览SDK在设置->SDK中
4、Text组件引入静态资源
应用资源在目录src->resources中:base和en_US和zh_CN【官方文档传送门】
- base: 默认存在的目录,二级子目录element用于存放字符串、颜色、布尔值等基础元素,media、profile存放媒体、动画、布局等资源文件。
- zh_CN/en_US: 配置不同的语言
注意:element里面不能自定义文件名,只能用这几个固定的
上图中 app.string.test_name, 需要在base/element/string.json中添加,同时zh_CN和en_US的element/string.json中也要添加,否则会报如下错误:
注意:不能用中划线 '-'
添加完后需要重新预览,否则报如下错误:
同理 app.color.front_red在base/element/color.json中添加
5、Image引用应用资源
6、zh_CN和en_US预览设置