ETS学习步骤:
参考 TS 写法学习:https://zhuanlan.zhihu.com/p/365352759 Data: 2023/5/15
官方文档:https://www.tslang.cn/docs/home.html 持续更新
TypeScript 4.0 使用手册:( 书栈网 ) https://www.bookstack.cn/read/TypeScript-4.0-zh/e371203807e019c3.md
书栈网 :https://www.bookstack.cn/books/TypeScript-4.0-zh
TS转JS代码编写 vscode编写:https://blog.csdn.net/qq_33650655/article/details/123415434
解决tsc无法加载文件报错:https://blog.csdn.net/ddx2019/article/details/106252949/
DevEco Studio 使用技巧:
1. 设置中文:
步骤:
1. 打开DevEco Studio 软件,进入项目初始界面。点击左下角的“configure”,在弹出菜单中选择“plugins”。
2. 在plugins界面,搜索框中输入“chinese”,在搜索结果中,选择第二个中文语言包,点击后面的install,安装完成后,点击ok。
3. 重新启动DevEco Studio 软件,可以看到其显示界面已经变成中文,说明改动成功。
2. 格式化代码快捷键:Ctrl + Alt + L
3. 设置黑色背景:打开DevEco Studio,文件→→设置→→外观与行为→→外观 / 主题 HUAWEI Dark Theme
第一天:
1. 参考官网 →→ 快速入门 / 开发准备 →→ 使用eTS语言开发 →→ 完成DevEco Studio的安装和开发环境配置
2. 编写第一个页面运行出 Hello World,实现页面跳转
https://developer.harmonyos.com/cn/docs/documentation/doc-guides/start-overview-0000000000029602
3. 开发 →→ UI →→ 方舟开发框架 →→基于TS →→ 声明式语法 →→ 全部学完
https://developer.harmonyos.com/cn/docs/documentation/doc-guides/ts-syntax-intro-0000001149818707
第二天:
1. 开发 →→ UI →→ 方舟开发框架 →→基于TS →→ 体验声明式UI( 量力而行 先会写)
https://developer.harmonyos.com/cn/docs/documentation/doc-guides/ui-ts-creating-project-0000001146785864
2. 以上配合Api 参考:JS API参考 →→ 手机、平板… →→ 基于TS →→组件 →→ 通用 →→通用事件 和 通用属性
https://developer.harmonyos.com/cn/docs/documentation/doc-references/ts-universal-events-click-0000001111581270
第三天:
1. 开发 →→ UI →→ 方舟开发框架 →→ 基于TS →→页面布局与连接( 量力而行 先会写)
https://developer.harmonyos.com/cn/docs/documentation/doc-guides/ui-ts-building-data-model-0000001146785866
2. 以上配合Api 参考:JS API参考 →→ 手机、平板… →→ 基于TS →→组件 →→ 通用 →→ 基础组件
https://developer.harmonyos.com/cn/docs/documentation/doc-references/ts-basic-components-blank-0000001169482471
第四天:
1. Api 参考:JS API参考 →→ 手机、平板… →→ 基于TS →→组件 →→ 通用 →→ 容器组件和媒体组件
https://developer.harmonyos.com/cn/docs/documentation/doc-references/ts-container-alphabetindexer-0000001190892709
第五天:
1. 把第二三天的两个示例了解并熟悉完成再进行下边的
2. Api 参考:JS API参考 →→ 手机、平板… →→ 基于TS →→组件 →→ 通用 →→ 绘制组件
以上所有组件熟悉完成在进行下方的
2. 开发 →→ UI →→ 方舟开发框架 →→ 基于TS →→绘画和动画
https://developer.harmonyos.com/cn/docs/documentation/doc-guides/ui-ts-drawing-feature-0000001192705721
第六天:
完成布置的UI 页面
第七天:第八天
1. 开始学习小成项目:购物应用 或者 极简声明式UI 规范
https://developer.harmonyos.com/cn/documentation/codelabs/
第九天:
1. 底部导航的编写( 辅助,学好的可不学 )https://blog.51cto.com/u_14772288/5183066
2. 进阶:项目:一次开发多段部署: https://developer.harmonyos.com/cn/documentation/codelabs/
第十天:
熟练完成以上三个项目之后
项目:转场动画的使用: https://developer.harmonyos.com/cn/documentation/codelabs/
第十一天:
项目:基础组件Slider的使用: https://developer.harmonyos.com/cn/documentation/codelabs/
第十二天后:
学习发的几个课件( 完整项目 )
学习文件:(系统设置应用)https://gitee.com/openharmony/applications_settings
(系统桌面)https://gitee.com/openharmony/applications_launcher
(系统界面应用)https://gitee.com/openharmony/applications_systemui
补充:
可以听课多了解:
https://developer.harmonyos.com/cn/documentation/teaching-vedio/
https://developer.harmonyos.com/cn/docs/documentation/doc-guides/video-tutorials-0000001121257792
去开发者社区逛逛:
https://developer.huawei.com/consumer/cn/forum/block/application
下方知识点理解跟补充:
组件化:
https://developer.harmonyos.com/cn/docs/documentation/doc-guides/ts-component-based-component-0000001103058932
1. @Entry:修饰的Component表示该Component是页面的总入口,也可以理解为页面的根节点。
一个页面有且仅能有一个@Entry,只有被@Entry修饰的组件或者其子组件,才会在页面上显示。
加载页面时,将首先创建并呈现@Entry装饰的自定义组件(出入口,所显示的内容)
2. @Component:修饰的struct表示这个结构体有了组件化的能力,通过@Component装饰的组件称为自定义组件。
在build方法里描述UI结构(就是自定义组件引用)
特点:可组合:允许开发人员组合使用内置组件、其他组件、公共属性和方法;
可重用:自定义组件可以被其他组件重用,并作为不同的实例在不同的父组件或容器中使用;
生命周期:生命周期的回调方法可以在组件中配置,用于业务逻辑处理;
数据驱动更新:由状态变量的数据驱动,实现UI自动更新。
注: 自定义组件必须定义build方法。
自定义组件禁止自定义构造函数。
3. @Preview:用@Preview装饰的自定义组件可以在DevEco Studio的预览器上进行预览,
加载页面时,将创建并呈现@Preview装饰的自定义组件。(相当于单独预览这个页面)
注:在单个源文件中,最多可以使用@Preview装饰一个自定义组件。
4. @Builder:@Builder装饰的方法用于定义组件的声明式UI描述,在一个自定义组件内快速生成多个布局内容。
@Builder装饰方法的功能和语法规范与build函数相同。(相当于创建一个函数)
例: @Builder SquareText(label: string) {
Text(label)
.width(1 * this.size)
.height(1 * this.size)
}
调用:build() {
Column() {
Row() {
this.SquareText("A")
this.SquareText("B")
}
}
}
5. @Extend:@Extend装饰器将新的属性函数添加到内置组件上,如Text、Column、Button等。
通过@Extend装饰器可以快速定义并复用组件的自定义样式。
注:@Extend装饰器不能用在自定义组件struct定义框内。
https://developer.harmonyos.com/cn/docs/documentation/doc-guides/ts-component-based-extend-0000001134698822
6. @CustomDialog:@CustomDialog装饰器用于装饰自定义弹窗。
https://developer.harmonyos.com/cn/docs/documentation/doc-guides/ts-component-based-customdialog-0000001192355895
状态变量装饰器:
https://developer.harmonyos.com/cn/docs/documentation/doc-guides/ts-ui-state-mgmt-concepts-0000001169868220
@State:组件拥有的状态属性,当@State装饰的变量更改时,组件会重新渲染更新UI。
@Link:组件依赖于其父组件拥有的某些状态属性,当任何一个组件中的数据更新时,另一个组件的状态都会更新,父子组件重新渲染。
@Prop:原理类似@Link,但是子组件所做的更改不会同步到父组件上,属于单向传递。
https://developer.harmonyos.com/cn/docs/documentation/doc-guides/ts-component-states-link-0000001103538550
上方链接:@Link、@State和@Prop结合使用示例
应用程序的数据存储:(本地存储:相当于localStorage):
https://developer.harmonyos.com/cn/docs/documentation/doc-guides/ts-application-states-appstorage-0000001119929480
补充内容:( 加深记忆和理解 )
1. @Link跟@ObjectLink区别:
@Link:双向同步父子组件的简单变量
@ObjectLink:双向同步父子组件的某个数据对象的部分信息进行同步时
https://developer.harmonyos.com/cn/docs/documentation/doc-guides/ts-other-states-observed-objectlink-0000001131671052
2. @Consume和@Provide区别:
Provide作为数据的提供方,可以更新其子孙节点的数据,并触发页面渲染。
Consume在感知到Provide数据的更新后,会触发当前view的重新渲染。
https://developer.harmonyos.com/cn/docs/documentation/doc-guides/ts-other-states-consume-provide-0000001177510803
3. @Watch:@Watch用于监听状态变量的变化
https://developer.harmonyos.com/cn/docs/documentation/doc-guides/ts-other-states-watch-0000001177658253
4. 循环:https://developer.harmonyos.com/cn/docs/documentation/doc-guides/ts-rending-control-syntax-foreach-0000001149978669
5. 懒加载:https://developer.harmonyos.com/cn/docs/documentation/doc-guides/ts-rending-control-syntax-lazyforeach-0000001136122422
6. 进阶:深入理解组件化:
https://developer.harmonyos.com/cn/docs/documentation/doc-guides/ts-function-build-0000001149818717
7. 语法糖:https://developer.harmonyos.com/cn/docs/documentation/doc-guides/ts-syntactic-sugar-0000001149698611
8. layoutWeight:设置各部分占比,flexGrow: Flex容器的剩余空间分配给给此属性所在的组件的比例。
9. private:初始化常规变量
当成员被标记成private时,它就不能在声明它的类的外部访问。
例:
class Animal {
private name: string;
constructor(theName: string) { this.name = theName; }
}
new Animal("Cat").name; // 错误: 'name' 是私有的.
10. enum: 枚举类型:
例: enum Color {Red, Green, Blue}
let c: Color = Color.Green; //1
默认情况下,从0开始为元素编号。 你也可以手动的指定成员的数值。
enum Color {Red = 10, Green, Blue}
let c: Color = Color.Green; //11
console.log(Color[10]); //Red
异构枚举:成员值是数字和字符串的混合:
enum Enum {
A,
B,
C = "C",
D = "D",
E = 8,
F
}
console.log(Enum['F']) //9
常量枚举:
const enum Direction {
NORTH,
SOUTH,
EAST,
WEST,
}
let dir: Direction = Direction.NORTH; // 0
11. any: 在编程阶段还不清楚类型的变量指定一个类型
( 就是你不知道这是什么变量或者说下边是动态的要更改,就用any声明,不会报错 )
例:let notSure: any = 4;
notSure = "maybe a string instead";
notSure = false;
12. 声明数组:两种方式: 例:let list: number[] = [1, 2, 3];
let list: string[] = [‘1’, ‘2’, ‘3’];
第二种:例:let list: Array<number> = [1, 2, 3];
注:Array<元素类型> 注意尖括号
13. 元组 Tuple:元组类型允许表示一个已知元素数量和类型的数组,各元素的类型不必相同
例:let x: [string, number];
x = ['hello', 10]; // OK
x = [10, 'hello']; // Error
console.log(x[0].substr(1)); // OK
console.log(x[1].substr(1)); // Error, 'number' does not have 'substr'
14. unknown:与any相似
例:let value: unknown;
value = true; // OK
value = 42; // OK
value = "Hello World"; // OK
value = []; // OK
value = {}; // OK
例:let value: unknown;
let value1: unknown = value; // OK
let value2: any = value; // OK
let value3: boolean = value; // Error
let value4: number = value; // Error
15. any 和 unknown区别:
any表示任意类型 ,any类型的变量可以执行任意操作,编译时不会报错
unknown 可以执行有限的操作(==、=== 、||、&&、?、!、typeof、instanceof 等等)
例://any和unknown
let foo: any;
let bar: unknown;
let num: number;
num = foo;
num = bar;
foo.NoFun();
bar.NoFun();
16. void
void 类型像是与 any 类型相反,它表示没有任何类型。
当一个函数没有返回值时,你通常会见到其返回值类型是 void
例:
// 声明函数返回值为void
function warnUser(): void {
console.log("This is my warning message");
}
17. object 和 {} 和 Object
object 表示的是常规的 Javascript 对象类型,非基础数据类型。
例:
declare function create(o: object): void;
create({ prop: 0 }); // OK
create(null); // Error
create(undefined); // Error
create(42); // Error
create("string"); // Error
create(false); // Error
create({
toString() {
return 3;
},
}); // OK
create({
toString() {
return 3;
},
}); // OK
{} 表示的非 null,非 undefined 的任意类型。
例:
declare function create(o: {}): void;
create({ prop: 0 }); // OK
create(null); // Error
create(undefined); // Error
create(42); // OK
create("string"); // OK
create(false); // OK
create({
toString() {
return 3;
},
}); // OK
Object 和 {} 几乎一致,区别是 Object 类型会对 Object 原型内置的方法(toString/hasOwnPreperty)进行校验。
例:
declare function create(o: Object): void;
create({ prop: 0 }); // OK
create(null); // Error
create(undefined); // Error
create(42); // OK
create("string"); // OK
create(false); // OK
create({
toString() {
return 3;
},
}); // Error
注:如果需要一个对象类型,但对对象的属性没有要求,使用 object。{} 和 Object 表示的范围太泛尽量不要使用。
18. repeat方法返回一个新字符串,表示将原字符串重复n次
例:
let s = '哈'
console.log(s.repeat(3)) // 哈哈哈
19. aboutToAppear :
自定义组件提供了两个生命周期的回调接口aboutToAppear和aboutToDisappear。aboutToAppear的执行时机在创建自定义组件后,执行自定义组件build方法之前。aboutToDisappear在自定义组件的去初始化的时机执行。
可以去计算宽高:例:用于设置Grid列表的宽高,防止页面宽高固定,不动态变化
aboutToAppear() {
// 数组的长度 / 2 ,因为是一行两列, 四舍五入
var rows = Math.round(this.foodItems.length / 2);
// 宽度分几行:数组的长度就是它的行数
this.gridRowTemplate = '1fr '.repeat(rows);
// 高度:每个FoodGridItem高度为184,行间距为8,是192, 192-8 就是它的最后一项不需要行间距
// 数组的长度 * 每一项的高度
this.heightValue = rows * 192 - 8;
}
Grid () { }
.rowsTemplate(this.gridRowTemplate)
// 原码 .rowsTemplate('1fr 1fr 1fr 1fr 1fr 1fr')
.height(this.heightValue)
// 原码 .height(1144)
20. 页面跳转
1. 路由容器组件Navigator,包装了页面路由的能力,指定页面target后,使其包裹的子组件都具有路由能力。
例:
Navigator({ target: 'pages/FoodDetail' }) {}.params({ foodData: this.foodItem })
2. 路由RouterAPI接口,通过在页面上引入router,可以调用router的各种接口,从而实现页面路由的各种操作。
例:
import router from '@system.router';
Column() { }
.onClick(() => {
router.push({
uri: 'pages/FoodDetail',
params: { foodData: this.foodItem }
})
})
接收路由传参:router.getParams().foodData
例:
private foodItem: foodData = router.getParams().foodData
HarmonyOS笔记
一.隐藏于显示
// 显示
Text('显示').visibility(Visibility.visibility)
// 隐藏不参与占位
Text('隐藏').visibility(Visibility.None)
// 隐藏参与占位
Text('隐藏').visibility(Visibility.Hidden)
二.文字超出显示...
Text('超出显示...').textOverflow({ overflow: TextOverflow.Ellipsis })
三. 边线条为1px,左右各15px
Divider().padding({ left: 15, right: 15}).color(0xF2F2F2).strokeWidth(1)
Stack组件为堆叠组件,可以包含一个或多个子组件,其特点是后一个子组件覆盖前一个子组件v
四. 组件化
1.@Component自定义组件,特点是可组合、可重用、生命周期、数据驱动更新,
自定义组件必须定义build方法。自定义组件禁止自定义构造函数。
@Entry装饰的自定义组件用作页面的默认入口组件,在单个源文件中,最多可以使用@Entry装饰一个自定义组件。
@CustomDialog 装饰器用于装饰自定义弹窗。
五.UI状态管理
参考链接:
https://blog.csdn.net/m0_61077450/article/details/123630139?spm=1001.2101.3001.6650.6&utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7Edefault-6.pc_relevant_default&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7Edefault-6.pc_relevant_default&utm_relevant_index=11
1.管理组件拥有的状态
@State
@State装饰的变量是组件内部的状态数据,当这些状态数据被修改时,将会调用所在组件的build方法进行UI刷新。
@State状态数据具有以下特征:
支持多种类型:允许class、number、boolean、string强类型的按值和按引用类型。允许这些强类型构成的数组,即Array<class>、Array<string>、Array<boolean>、Array<number>。不允许object和any。
支持多实例:组件不同实例的内部状态数据独立。
内部私有:标记为@State的属性是私有变量,只能在组件内访问。
需要本地初始化:必须为所有@State变量分配初始值,将变量保持未初始化可能导致框架行为未定义。
创建自定义组件时支持通过状态变量名设置初始值:在创建组件实例时,可以通过变量名显式指定@State状态属性的初始值。
@Prop
@Prop与@State有相同的语义,但初始化方式不同。@Prop装饰的变量必须使用其父组件提供的@State变量进行初始化,允许组件内部修改@Prop变量,但更改不会通知给父组件,即@Prop属于单向数据绑定。
@Prop状态数据具有以下特征:
支持简单类型:仅支持number、string、boolean简单类型;
私有:仅在组件内访问;
支持多个实例:一个组件中可以定义多个标有@Prop的属性;
创建自定义组件时将值传递给@Prop变量进行初始化:在创建组件的新实例时,必须初始化所有@Prop变量,不支持在组件内部进行初始化。
@Link
@Link装饰的变量可以和父组件的@State变量建立双向数据绑定:
支持多种类型:@Link变量的值与@State变量的类型相同,即class、number、string、boolean或这些类型的数组;
私有:仅在组件内访问;
单个数据源:初始化@Link变量的父组件的变量必须是@State变量;
双向通信:子组件对@Link变量的更改将同步修改父组件的@State变量;
创建自定义组件时需要将变量的引用传递给@Link变量:在创建组件的新实例时,必须使用命名参数初始化所有@Link变量。@Link变量可以使用@State变量或@Link变量的引用进行初始化,@State变量可以通过'$'操作符创建引用。
说明
@Link变量不能在组件内部进行初始化。
使用UI组件和装饰器
基础组件:Image、Text、 Video等 容器组件:Stack、Column、 List等
组件化装饰: @Component、@Entry、 @Builder 、@Extend等 实现组合目标面
配套实现页面组件开发及组件 自定义 状态管理装饰: @State 、 @Link 、@Observed、 @ObjectLink、 @StorageLink、 @Watch
实现数据驱动视图自动更新
使用UI渲染控制语法
条件渲染:if/elseif/else
进行UI描述时,根据不同状 态来动态控制组件的渲染
循环渲染: ForEach/LazyForEach
进行UI描述时,根据数据的 多少动态控制渲染的次数, 优化代码实现
引用UI资源
字符串引用: $ r (‘app.string.name’ )
resources的element目录 下定义字符串,支持全球化 小语种
媒体资源引用: $ r (‘app.media.name’ )
resources的media目录下存 放资源,支持png、jpg、 svg等多种格式
添加UI交互事件
基础手势事件:onClick / onTouch等
定义基础用户交互,结合 TouchEvent信息可以实现自定 义手势
高级手势事件:长按手势 / 滑 动手势 / 组合手势等
通过gesture属性函数配置 内置高级手势支持, GestureGroup可支持多种 高级手势组合
第三步:完善功能逻辑
使用生命周期接口
页面生命周期接口:onPageShow、 onPageHide
UI组件生命周期接口: aboutToAppear、aboutToDisappear
其它生命周期接口:onBackPressed、 onCreate、onDestroy等
结合页面、UI组件、系统状态的变化生命 周期接口添加功能逻辑
使用子系统能力接口
多个子系统提供大量系统能力接口 使用仅需两步:
一、导入依赖包。
二、直接调用系统能力接口。
调用系统能力实现具体功能逻辑
第四步:优化交互体验
实现动效
属性动画
animation :自动监听组 件所有通用属性变化,自动增加动画 补间
显式动画animateTo :指定特定 属性变化,为特定的属性动画自动增 加动画补间
修改组件属性,自动生成动画补 间,优化属性变化交互体验
转场动画
组件间转场: transition监听组件 的渲染状态变化,增加组件渲染、移除时的动画效果
页面间转场: pageTransition指定页面间跳转的切换动画效果
组件、页面切换时,自动生成动画 补间,优化切换交互体验
动画组件
ImageAnimator:支持逐帧图片播 放动画
使用多个图片组成动画,并动态控制 动画播放
Animator:组件形式提供动画控制器 动态控制播放状态,定制补间动画, 实现深度自定义动画效果。