关于HarmonyOS的API从8到API12,存在不少版本的差异,比如一些ArkTS语法上的差异;一些组件在API9之前不支持的功能,本人在项目开发过程中也是踩了不少坑,现在给大家分享一下心得。
1.语法差异
首先是ArkTS语法上的差异。可以参考官方文档:从TypeScript到ArkTS语言适配规则| 华为开发者联盟 (huawei.com)
-
函数表达式不支持,必须用箭头函数;
-
展开运算符只支持数组;
-
不支持赋值解构;
-
var 不支持,必须用 let 或者 const;
-
类型限制更为严格,声明变量后面必须定义类型;
@Entry
@Component
struct ArkTSPage {build() {Column({ space: 20 }) {// 以下的是 不支持(推荐)的特性Button('1. 不使用Var').width('100%').onClick(() => {// 1. var有变量提升,不再建议使用//// var str// AlertDialog.show({ message: str })// str = '西兰花炒蛋'
// 2. 使用 let替代(推荐写法!!!)let str = '西兰花炒蛋'AlertDialog.show({ message: str })// let str = '西兰花炒蛋'
})
Button('2. 声明变量+类型').width('100%').onClick(() => {// api9可以不使用类型推断// let message = 'itheima'
// next 刚出来必须写,现在可以省略
// 1. 基本类型 直接写let food: string = '西兰花炒蛋'let age: number = 20
// 2. 对象 可以结合 class 使用// class Food{// name:string// color:string//// constructor(name:string,color:string) {// this.name = name// this.color = color// }// }// const f:Food = new Food('西兰花','黄绿色')
// 3. 对象的字面量 结合 class的初始值class Food {name: string = ''color: string = ''}
const f: Food = {name: '西兰花',color: '黄绿色'}})
Button('3. for in').width('100%').onClick(() => {// 定义Class 并设置默认值class Food {name: string = ''color: string = ''}
let food: Food = {name: '西兰花',color: '黄绿色'}
// 不支持 for in// for (const key in food) {// food[key] // ArkTS中 不推荐// // food.key // 属性名 叫做key// }
// 可以通过 Object.keys 结合 forEach 进行遍历// 获取 所有的key 字符串数组// const keys: string[] = Object.keys(food)// // AlertDialog.show({ message : JSON.stringify(keys)})// keys.forEach((key: string) => {// AlertDialog.show({ message: key })// })Object.keys(food).forEach((key: string) => {AlertDialog.show({ message: key })})
})
Button('4. 解构赋值').width('100%').onClick(() => {class Food {name: string = ''color: string = ''}
let food: Food = {name: '西兰花',color: '黄绿色'}
// 不支持(不推荐)// const {name,color} = food
// 通过 点语法取值const name: string = food.nameconst color: string = food.color
})
Button('5. 函数表达式').width('100%').onClick(() => {// 不支持 函数表达式// const sayHI:()=>void= function (){// AlertDialog.show({message:'(づ ̄ 3 ̄)づ'})// }
// 改写为 箭头函数// const sayHI: () => void = () => {// AlertDialog.show({ message: '(づ ̄ 3 ̄)づ' })// }
const sayHI: () => void = () => AlertDialog.show({ message: '(づ ̄ 3 ̄)づ' })
})
// 以下是部分支持的特性Button('6. 展开运算符...').width('100%').onClick(() => {// 用来合并数组 支持const numArr1: number[] = [1, 2, 3, 4]const numArr2: number[] = [4, 5, 6]
// ArkTS中支持,可以使用const totalArr: number[] = [...numArr1, ...numArr2]// AlertDialog.show({ message: JSON.stringify(totalArr) })
// 合并对象 不支持class Vegetable {name: string = ''color: string = ''}
class Food {name: stringcolor: stringprice: number
constructor(vegetable:Vegetable,price:number) {this.name =vegetable.namethis.color = vegetable.colorthis.price = price}}
const vegetable: Vegetable = {name: '西兰花',color: '黄绿色'}
// 不支持用来展开对象// const food:Food ={// ...vegetable,// price:10// }
// 改写为挨个赋值即可const food:Food = new Food(vegetable,10)
})
// moreButton('..........更多').width('100%').onClick(() => {})}.padding(10)
}
}
2. 组件用法上的差异
2.1. $$语法:内置组件双向同步
$$运算符为系统内置组件提供TS变量的引用,使得TS变量和系统内置组件的内部状态保持同步。
内部状态具体指什么取决于组件。例如,TextInput组件的text参数。
说明:
$$还用于@Builder装饰器的按引用传递参数,开发者需要注意两种用法的区别。
使用规则
-
当前$$支持基础类型变量,以及@State、@Link和@Prop装饰的变量。
-
当前$$支持的组件:
组件 支持的参数/属性 起始API版本 Checkbox select 10 CheckboxGroup selectAll 10 DatePicker selected 10 TimePicker selected 10 MenuItem selected 10 Panel mode 10 Radio checked 10 Rating rating 10 Search value 10 SideBarContainer showSideBar 10 Slider value 10 Stepper index 10 Swiper index 10 Tabs index 10 TextArea text 10 TextInput text 10 TextPicker selected、value 10 Toggle isOn 10 AlphabetIndexer selected 10 Select selected、value 10 BindSheet isShow 10 BindContentCover isShow 10 Refresh refreshing 8 GridItem selected 10 ListItem selected 10 -
$$绑定的变量变化时,会触发UI的同步刷新。
使用示例
以TextInput方法的text参数为例:
// xxx.ets
@Entry
@Component
struct TextInputExample {@State text: string = ''controller: TextInputController = new TextInputController()
build() {Column({ space: 20 }) {Text(this.text)TextInput({ text: $$this.text, placeholder: 'input your word...', controller: this.controller }).placeholderColor(Color.Grey).placeholderFont({ size: 14, weight: 400 }).caretColor(Color.Blue).width(300)}.width('100%').height('100%').justifyContent(FlexAlign.Center)}
}
3. API使用上的差异
首选项持久化在API10以后提供了同步接口来返回preferences实例,代码写法上更简洁实用。
dataPreferences.getPreferences
getPreferences(context: Context, options: Options): Promise<Preferences>
获取Preferences实例,使用Promise异步回调。
示例:
import UIAbility from '@ohos.app.ability.UIAbility';
import { BusinessError } from '@ohos.base'
import window from '@ohos.window';
let preferences: dataPreferences.Preferences | null = null;
class EntryAbility extends UIAbility {onWindowStageCreate(windowStage: window.WindowStage) {let options: dataPreferences.Options = { name: 'myStore', dataGroupId: 'myId' };let promise = dataPreferences.getPreferences(this.context, options);promise.then((object: dataPreferences.Preferences) => {preferences = object;console.info("Succeeded in getting preferences.");}).catch((err: BusinessError) => {console.error("Failed to get preferences. code =" + err.code + ", message =" + err.message);})}
}
dataPreferences.getPreferencesSync10+
getPreferencesSync(context: Context, options: Options): Preferences
获取Preferences实例,此为同步接口。
示例:
import UIAbility from '@ohos.app.ability.UIAbility';
import window from '@ohos.window';
let preferences: dataPreferences.Preferences | null = null;
class EntryAbility extends UIAbility {onWindowStageCreate(windowStage: window.WindowStage) {let options: dataPreferences.Options = { name: 'myStore', dataGroupId: 'myId' };preferences = dataPreferences.getPreferencesSync(this.context, options);}
}
暂时想到这么多,有些在API9之前的API将会被废弃,以后再补充。