【最新鸿蒙应用开发】——警惕这些坑!不同API版本带来的差异

关于HarmonyOS的API从8到API12,存在不少版本的差异,比如一些ArkTS语法上的差异;一些组件在API9之前不支持的功能,本人在项目开发过程中也是踩了不少坑,现在给大家分享一下心得。

1.语法差异

首先是ArkTS语法上的差异。可以参考官方文档:从TypeScript到ArkTS语言适配规则| 华为开发者联盟 (huawei.com)

  • 函数表达式不支持,必须用箭头函数;
  • 展开运算符只支持数组;
  • 不支持赋值解构;
  • var 不支持,必须用 let 或者 const;
  • 类型限制更为严格,声明变量后面必须定义类型;
ts 复制代码
@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.name
          const 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: string
            color: string
            price: number
​
            constructor(vegetable:Vegetable,price:number) {
              this.name =vegetable.name
              this.color = vegetable.color
              this.price = price
            }
          }
​
          const vegetable: Vegetable = {
            name: '西兰花',
            color: '黄绿色'
          }
​
          // 不支持用来展开对象
          // const food:Food ={
          //   ...vegetable,
          //   price:10
          // }
​
          // 改写为挨个赋值即可
          const food:Food = new Food(vegetable,10)
​
​
        })
​
      // more
      Button('..........更多')
        .width('100%')
        .onClick(() => {
        })
    }
    .padding(10)
​
  }
}

2. 组件用法上的差异

2.1. $$语法:内置组件双向同步

  • 当前$$支持基础类型变量,以及@State、@Link和@Prop装饰的变量。
  • 当前$$支持的组件:
  • / $$绑定的变量变化时,会触发UI的同步刷新。

使用示例

以TextInput方法的text参数为例:

ts 复制代码
// 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实例,使用Promise异步回调。

示例:

typescript 复制代码
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实例,此为同步接口。

示例:

typescript 复制代码
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将会被废弃,以后再补充。

相关推荐
sanzk3 小时前
华为鸿蒙应用开发
华为·harmonyos
SoraLuna7 小时前
「Mac畅玩鸿蒙与硬件28」UI互动应用篇5 - 滑动选择器实现
macos·ui·harmonyos
ClkLog-开源埋点用户分析8 小时前
ClkLog企业版(CDP)预售开启,更有鸿蒙SDK前来助力
华为·开源·开源软件·harmonyos
mg6688 小时前
鸿蒙系统的优势 开发 环境搭建 开发小示例
华为·harmonyos
lqj_本人9 小时前
鸿蒙next选择 Flutter 开发跨平台应用的原因
flutter·华为·harmonyos
lqj_本人9 小时前
使用 Flutter 绘制一个棋盘
harmonyos
lqj_本人12 小时前
Flutter&鸿蒙next 状态管理框架对比分析
flutter·华为·harmonyos
青瓷看世界13 小时前
华为HarmonyOS打造开放、合规的广告生态 - 插屏广告
华为·harmonyos·广告投放
青瓷看世界13 小时前
华为HarmonyOS借助AR引擎帮助应用实现虚拟与现实交互的能力2-管理AR会话
华为·ar·harmonyos·虚拟现实
2301_7955586414 小时前
鸿蒙的进化史
华为·harmonyos