注意:博主有个鸿蒙专栏,内里从上到下有关于鸿蒙next的讲授文档,大家感兴趣可以学习下
假如大家觉得博主文章写的好的话,可以点下关注,博主会一直更新鸿蒙next相关知识
专栏地址: https://blog.csdn.net/qq_56760790/category_12794123.html
目次
1. ArkTS基本先容
2. ArkTS语法
2.1 变量声明
2.2 常量声明
2.3 主动范例推断
2.4 联合范例
2.5 枚举范例
2.6 数组
2.7 函数
2.7.1 可选参数
2.7.2 Rest参数
2.7.3 返回范例
2.7.4 箭头函数(又名Lambda函数)
2.8 类
2.9 接口
2.10 对象
2.10.1 接口范例
2.10.2 类范例
2.11 泛型范例和函数
2.11.1 泛型类和接口
2.11.2 泛型束缚
2.11.3 泛型函数
2.12 语句
2.12.1 if语句
2.12.2 Switch语句
2.12.3 条件表达式
2.12.4 For语句
2.12.5 For-of语句
2.12.6 While语句
2.12.7 Do-while语句
2.12.8 Break语句
2.12.9 Continue语句
2.13 模块
2.13.1 导出
2.13.2 导入
3. ArkTS组件布局
3.1 基于struct实现自定义组件
3.2 Component修饰符
3.3 Build函数
3.4 entry修饰符
3.5 组件复用
4. 视频学习链接
1. ArkTS基本先容
ArkTS是HarmonyOS优选的主力应用开发语言。
ArkTS围绕应用开发在TypeScript(简称TS)生态底子上做了进一步扩展,保持了TS的基本风格,同时通过规范定义强化开发期静态检查和分析,提升程序执行稳固性和性能。
从API version 10开始,ArkTS进一步通过规范强化静态检查和分析,对比标准TS的差异可以参考从TypeScript到ArkTS的适配规则:
- 强制使用静态范例:静态范例是ArkTS最紧张的特性之一。假如使用静态范例,那么程序中变量的范例就是确定的。同时,由于所有范例在程序实际运行前都是已知的,编译器可以验证代码的精确性,从而减少运行时的范例检查,有助于性能提升。
- 禁止在运行时改变对象布局:为实现最大性能,ArkTS要求在程序执行期间不能更改对象布局。
- 限制运算符语义:为获得更好的性能并鼓励开发者编写更清楚的代码,ArkTS限制了一些运算符的语义。比如,一元加法运算符只能作用于数字,不能用于其他范例的变量。
- 不支持Structural typing:对Structural typing的支持须要在语言、编译器和运行时进行大量的思量和细致的实现,当前ArkTS不支持该特性。根据实际场景的需求和反馈,我们后续会重新思量。
ArkTS它是纯新的一门语言,它不是前端也不是TypeScript,它是TS的超集
- 定义声明式UI、自定义组件、动态扩展UI元素;
- 提供ArkUI体系组件,提供组件事件、方法、属性;
- 共同构成 UI 开发主体
ArkTS以声明方式组合和扩展组件来描述应用程序的UI,同时还提供了基本的属性、事件和子组件配置方法,资助开发者实现应用交互逻辑。
- 命令式UI- document.createElement("div")- <div>
- 声明式UI
ArkTS提供了标准内置对象,例如Array、Map、TypedArray、Math等,供开发者直接使用。另外,ArkTS也提供了语言底子类库,为应用开发者提供常用的底子本领,重要包含本领如下图所示。
2. ArkTS语法
ArkTS通过声明引入变量、常量、函数和范例。
2.1 变量声明
以关键字let开头的声明引入变量,该变量在程序执行期间可以具有不同的值。
- let hi: string = 'hello';
- hi = 'hello, world';
复制代码
2.2 常量声明
以关键字const开头的声明引入只读常量,该常量只能被赋值一次。
- const hello: string = 'hello';
复制代码
对常量重新赋值会造成编译时错误。
变量、常量的命名规则:
- 只能包含数字、字母、下划线、$,不能以数字开头
- 不能使用内置关键字或保留字(比如let const)
- 严酷区分大小写
2.3 主动范例推断
由于ArkTS是一种静态范例语言,所有数据的范例都必须在编译时确定。
但是,假如一个变量或常量的声明包含了初始值,那么开发者就不须要显式指定其范例。ArkTS规范中列举了所有答应主动推断范例的场景。
以下示例中,两条声明语句都是有效的,两个变量都是string范例:
- let hi1: string = 'hello';
- let hi2 = 'hello, world';
复制代码
2.4 联合范例
联合范例是一种灵活的数据范例,它修饰的变量可以存储不同范例的数据;
语法:
let 变量:范例1|范例2|范例3 =值
- let name:string|number;
- name=1
- name='东林'
复制代码
2.5 枚举范例
枚举范例是一种特殊的数据范例,约定变量只能在一组数据范围内选择值
语法:
enum 枚举名{
常量1=值,
常量2=值
}
- enum Color{
- Red='#ff0f29',
- Green='#30b30e'
- }
- // 使用枚举
- let color:Color=Color.Red
复制代码
2.6 数组
ArkTS基本数据范例(string、number、boolean等,语法跟ts差不多,大家可以在东林录制的视频前置课内里学习)
数组,是一个容器,可以存储多个数据;
语法:
let 数组名:范例[]=[数据1,数据2,....]
- let names:string[]=['小头','东林']
复制代码
注意:数组指定的范例和存储的数据范例必须要一致,否则会报错
数组中存储的每个数据,都有本身的编号,编号从0开始(索引)
联合范例:
- let names:(string|number)[]=[1,2,'小头']
复制代码
2.7 函数
函数:是可以被重复使用的代码块
定义函数:
function 函数名()
{
}
调用函数:
函数名()
函数的完备用法
- function add(x: string, y: string): string {
- let z: string = `${x} ${y}`;
- return z;
- }
复制代码
2.7.1 可选参数
可选参数的格式可为name?: Type
- function hello(name?: string) {
- if (name == undefined) {
- console.log('Hello!');
- } else {
- console.log(`Hello, ${name}!`);
- }
- }
复制代码 可选参数的另一种情势为设置的参数默认值。假如在函数调用中这个参数被省略了,则会使用此参数的默认值作为实参。
- function multiply(n: number, coeff: number = 2): number {
- return n * coeff;
- }
- multiply(2); // 返回2*2
- multiply(2, 3); // 返回2*3
复制代码
2.7.2 Rest参数
函数的最后一个参数可以是rest参数。使用rest参数时,答应函数或方法担当恣意数目的实参。
- function sum(...numbers: number[]): number {
- let res = 0;
- for (let n of numbers)
- res += n;
- return res;
- }
- sum() // 返回0
- sum(1, 2, 3) // 返回6
复制代码
2.7.3 返回范例
假如可以从函数体内推断出函数返回范例,则可在函数声明中省略标注返回范例。
- // 显式指定返回类型
- function foo(): string { return 'foo'; }
- // 推断返回类型为string
- function goo() { return 'goo'; }
复制代码 不须要返回值的函数的返回范例可以显式指定为void或省略标注。这类函数不须要返回语句。
2.7.4 箭头函数(又名Lambda函数)
箭头函数是比普通函数更简洁的一种函数写法
函数可以定义为箭头函数,例如:
- let sum = (x: number, y: number): number => {
- return x + y;
- }
复制代码
2.8 类
类声明引入一个新范例,并定义其字段、方法和构造函数。
在以下示例中,定义了Person类,该类具有字段name和surname、构造函数和方法fullName:
- class Person {
- name: string = ''
- surname: string = ''
- constructor (n: string, sn: string) {
- this.name = n;
- this.surname = sn;
- }
- fullName(): string {
- return this.name + ' ' + this.surname;
- }
- }
复制代码 定义类后,可以使用关键字new创建实例:
- let p = new Person('John', 'Smith');
- console.log(p.fullName());
复制代码 2.9 接口
接口声明引入新范例。接口是定义代码协定的常见方式。
任何一个类的实例只要实现了特定接口,就可以通过该接口实现多态。
接口通常包含属性和方法的声明
- interface Style {
- color: string // 属性
- }
- interface AreaSize {
- calculateAreaSize(): number // 方法的声明
- someMethod(): void; // 方法的声明
- }
复制代码
实现接口的类示例:
- // 接口:
- interface AreaSize {
- calculateAreaSize(): number // 方法的声明
- someMethod(): void; // 方法的声明
- }
- // 实现:
- class RectangleSize implements AreaSize {
- private width: number = 0
- private height: number = 0
- someMethod(): void {
- console.log('someMethod called');
- }
- calculateAreaSize(): number {
- this.someMethod(); // 调用另一个方法并返回结果
- return this.width * this.height;
- }
- }
复制代码
2.10 对象
语法:let 对象名称:对应布局范例=值
2.10.1 接口范例
- interface People{
- name:string
- age:number
- }
- let pick:People={
- name:'pick',
- age:1
- }
复制代码
2.10.2 类范例
- class People{
- name:string=''
- age:number=0
- }
- let pick:People={
- name:'pick',
- age:1
- }
复制代码
2.11 泛型范例和函数
泛型范例和函数答应创建的代码在各种范例上运行,而不仅支持单一范例。
2.11.1 泛型类和接口
类和接口可以定义为泛型,将参数添加到范例定义中,如以下示例中的范例参数Element:
- class CustomStack<Element> {
- public push(e: Element):void {
- // ...
- }
- }
复制代码 要使用范例CustomStack,必须为每个范例参数指定范例实参:
- let s = new CustomStack<string>();
- s.push('hello');
复制代码
2.11.2 泛型束缚
泛型范例的范例参数可以被限制只能取某些特定的值。例如,MyHashMap<Key, Value>这个类中的Key范例参数必须具有hash方法。
- interface Hashable {
- hash(): number
- }
- class MyHashMap<Key extends Hashable, Value> {
- public set(k: Key, v: Value) {
- let h = k.hash();
- // ...其他代码...
- }
- }
复制代码 在上面的例子中,Key范例扩展了Hashable,Hashable接口的所有方法都可以为key调用。
2.11.3 泛型函数
使用泛型函数可编写更通用的代码。比如返回数组最后一个元素的函数:
- function last(x: number[]): number {
- return x[x.length - 1];
- }
- last([1, 2, 3]); // 3
复制代码 假如须要为任何数组定义相同的函数,使用范例参数将该函数定义为泛型:
- function last<T>(x: T[]): T {
- return x[x.length - 1];
- }
复制代码
2.12 语句
2.12.1 if语句
if语句用于须要根据逻辑条件执行不同语句的场景。当逻辑条件为真时,执行对应的一组语句,否则执行另一组语句(假如有的话)。
else部分也大概包含if语句。
if语句如下所示:
- if (condition1) {
- // 语句1
- } else if (condition2) {
- // 语句2
- } else {
- // else语句
- }
复制代码 条件表达式可以是任何范例。但是对于boolean以外的范例,会进行隐式范例转换:
- let s1 = 'Hello';
- if (s1) {
- console.log(s1); // 打印“Hello”
- }
- let s2 = 'World';
- if (s2.length != 0) {
- console.log(s2); // 打印“World”
- }
复制代码
2.12.2 Switch语句
使用switch语句来执行与switch表达式值匹配的代码块。
switch语句如下所示:
- switch (expression) {
- case label1: // 如果label1匹配,则执行
- // ...
- // 语句1
- // ...
- break; // 可省略
- case label2:
- case label3: // 如果label2或label3匹配,则执行
- // ...
- // 语句23
- // ...
- break; // 可省略
- default:
- // 默认语句
- }
复制代码
2.12.3 条件表达式
条件表达式由第一个表达式的布尔值来决定返回其它两个表达式中的哪一个。
- condition ? expression1 : expression2
复制代码 假如condition的为真值(转换后为true的值),则使用expression1作为该表达式的效果;否则,使用expression2。
2.12.4 For语句
for语句会被重复执行,直到循环退出语句值为false。
- for ([init]; [condition]; [update]) {
- statements
- }
复制代码
2.12.5 For-of语句
使用for-of语句可遍历数组或字符串。示例如下:
- for (forVar of expression) {
- statements
- }
复制代码
- for (let ch of 'a string object') {
- /* process ch */
- }
复制代码
2.12.6 While语句
只要condition为真值(转换后为true的值),while语句就会执行statements语句。示例如下:
- while (condition) {
- statements
- }
复制代码- let n = 0;
- let x = 0;
- while (n < 3) {
- n++;
- x += n;
- }
复制代码
2.12.7 Do-while语句
假如condition的值为真值(转换后为true的值),那么statements语句会重复执行。示例如下:
- do {
- statements
- } while (condition)
复制代码- let i = 0;
- do {
- i += 1;
- } while (i < 10)
复制代码
2.12.8 Break语句
使用break语句可以终止循环语句或switch。
- let x = 0;
- while (true) {
- x++;
- if (x > 5) {
- break;
- }
- }
复制代码
2.12.9 Continue语句
continue语句会制止当前循环迭代的执行,并将控制传递给下一个迭代。
- let sum = 0;
- for (let x = 0; x < 100; x++) {
- if (x % 2 == 0) {
- continue
- }
- sum += x;
- }
复制代码
2.13 模块
程序可划分为多组编译单位或模块。
每个模块都有其本身的作用域,即,在模块中创建的任何声明(变量、函数、类等)在该模块之外都不可见,除非它们被显式导出。
与此相对,从另一个模块导出的变量、函数、类、接口等必须首先导入到模块中。
2.13.1 导出
可以使用关键字export导出顶层的声明。
未导出的声明名称被视为私著名称,只能在声明该名称的模块中使用。
注意:通过export方式导出,在导入时要加{}。
- export class Point {
- x: number = 0
- y: number = 0
- constructor(x: number, y: number) {
- this.x = x;
- this.y = y;
- }
- }
- export let Origin = new Point(0, 0);
- export function Distance(p1: Point, p2: Point): number {
- return Math.sqrt((p2.x - p1.x) * (p2.x - p1.x) + (p2.y - p1.y) * (p2.y - p1.y));
- }
复制代码 2.13.2 导入
导入声明用于导入从其他模块导出的实体,并在当前模块中提供其绑定。导入声明由两部分组成:
- 导入路径,用于指定导入的模块;
- 导入绑定,用于定义导入的模块中的可用实体集和使用情势(限定或不限定使用)。
导入绑定可以有几种情势。
假设模块具有路径“./utils”和导出实体“X”和“Y”。
导入绑定* as A表示绑定名称“A”,通过A.name可访问从导入路径指定的模块导出的所有实体:
- import * as Utils from './utils'
- Utils.X // 表示来自Utils的X
- Utils.Y // 表示来自Utils的Y
复制代码 导入绑定{ ident1, ..., identN }表示将导出的实体与指定名称绑定,该名称可以用作简单名称:
- import { X, Y } from './utils'
- X // 表示来自utils的X
- Y // 表示来自utils的Y
复制代码 假如标识符列表定义了ident as alias,则实体ident将绑定在名称alias下:
- import { X as Z, Y } from './utils'
- Z // 表示来自Utils的X
- Y // 表示来自Utils的Y
- X // 编译时错误:'X'不可见
复制代码
3. ArkTS组件布局
ArkTS的基本组成
说明
自定义变量不能与底子通用属性/事件名重复。
ArkTS通过装饰器 @Component 和 @Entry 装饰 struct 关键字声明的数据布局,构成一个自定义组件。
自定义组件中提供了一个 build 函数,开发者需在该函数内以链式调用的方式进行基本的 UI 描述,UI 描述的方法请参考 UI 描述规范。
3.1 基于struct实现自定义组件
要想实现一段UI的描述,必须使用struct关键字来声明- 注意不能有继承关系-组件名不能和体系组件名重名
语法: struct 组件名 {}
- @Component
- struct Index {
- }
复制代码 struct关键字声明的UI描述-必须被@Component修饰
3.2 Component修饰符
Component装饰器只能修饰struct关键字声明的布局,被修饰后的struct具备组件的描述(渲染)本领
3.3 Build函数
用于定义组件的UI描述,一个struct布局必须实现build函数
- @Component
- struct MyComponent {
- build() {
- }
- }
复制代码
3.4 entry修饰符
entry将自定义组件定义为UI页面的入口,也就是我们原来前端常说的一个页面,最多可以使用entry装饰一个自定义组件(在一个ets文件中)-如下面的代码就是不被答应的
- @Entry
- @Component
- struct Index {
- build() {
- }
- }
- @Entry
- @Component
- struct Index2 {
- build() {
- }
- }
复制代码
entry修饰的组件,最终会被注册,具体文件位置-main/resources/base/profile/main_pages.json
- 主动注册-新建组件时,采用新建Page的方式
- 手动注册-新建一个ets文件,本身在main_pages.json中手动添加路径
3.5 组件复用
在很多环境下,由于业务的复杂度,我们经常会将一个大的业务拆成若干个组件,进行组装,这里我们非常灵活的复用组件,比如
- 我们可以把上图抽象成三个组件- Header- Main- Footer
- import Header from '../pages/Header';
- import Main from '../pages/Main';
- import Foot from '../pages/Foot';
- @Entry
- @Component
- struct Demo {
- build() {
- Column() {
- Header().backgroundColor(Color.Pink)
- Main().backgroundColor(Color.Green)
- Foot().backgroundColor(Color.Red)
- }.height('100%')
- .width('100%')
- }
- }
复制代码
- @Component
- export default struct Header {
- build() {
- Row() {
- Text('头部')
- }
- .width('100%')
- .height(60).justifyContent(FlexAlign.Center)
- }
- }
复制代码
- @Component
- export default struct Main{
- build() {
- Row(){
- Text('主体')
- }
- .width('100%').height('80%')
- .justifyContent(FlexAlign.Center)
- }
- }
复制代码
- @Component
- export default struct Foot{
- build() {
- Row(){
- Text('底部')
- }
- .width('100%').height('10%')
- .justifyContent(FlexAlign.Center)
- }
- }
复制代码
总结:
- 一个UI描述必须使用struct来声明,不能继承
- struct必须被Component或者CustomDialog修饰
- struct必须实现build方法,build方法可以没有元素,但是有的话有且只有一个可容纳子组件的容器组件(entry修饰的组件)
- entry修饰符表示该组件是页面级组件,一个文件中只答应修饰一个struct组件
- 采用分拆组件的情势可以有效解解耦我们的业务
4. 视频学习链接
全网首发鸿蒙NEXT星河版零底子入门到实战,2024年最新版,企业级开发!视频连续更新中!_哔哩哔哩_bilibili
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |