当前位置: 首页 > 编程日记 > 正文

【HarmonyOS】装饰器下的状态管理与页面路由跳转实现

从今天开始,博主将开设一门新的专栏用来讲解市面上比较热门的技术 “鸿蒙开发”,对于刚接触这项技术的小伙伴在学习鸿蒙开发之前,有必要先了解一下鸿蒙,从你的角度来讲,你认为什么是鸿蒙呢?它出现的意义又是什么?鸿蒙仅仅是一个手机操作系统吗?它的出现能够和Android和IOS三分天下吗?它未来的潜力能否制霸整个手机市场呢?

抱着这样的疑问和对鸿蒙开发的好奇,让我们开始今天对ArkUI状态管理的掌握吧!

目录

ArkUI状态管理

@State装饰器

@Provide和@Consume

页面路由


ArkUI状态管理

在声明式UI中是以状态来驱动视图进行更新的,其中的核心概念就是状态和视图所谓状态就是驱动视图更新这个数据,或者说是我们自定义组件当中定义好的那些被装饰器标记好的变量;所谓视图就是指GUI描述渲染得到的用户界面;视图渲染好了之后用户就可以对视图中的页面元素产生交互,通过点击、触摸、拖拽等互动事件来改变状态变量的值,在arkui的内部就有一种机制去监控状态变量的值,一旦发现它发生了变更就会去触发视图的重新渲染。所以像这种状态和视图之间的相互作用的机制,我们就称之为状态管理机制。

状态管理需要用到多个不同的装饰器,接下来我们开始学习状态管理的基本概念以及以下几个装饰器的基本用法和注意事项。

@State装饰器

使用@State装饰器有以下注意事项:

1)@State装饰器标记的变量必须初始化,不能为空值

2)@State支持Object、class、string、number、boolean、enum类型以及这些类型的数组

3)嵌套类型(Object里面的某个属性又是一个Object)以及数组中的对象属性无法触发视图更新,以下是演示代码:

class Person {
  name: string
  age: number

  constructor(name: string, age: number) {
    this.name = name
    this.age = age
  }
}
@Entry
@Component
struct StatePage {
  idx: number = 1
  @State p: Person[] = [
    new Person('张三', 20)
  ]

  build(){
    Column(){
      Button('添加')
        .onClick(()=>{
          this.p.push(new Person('张三'+this.idx++, 20 ))
        })
      ForEach(
        this.p,
        (p, index) => {
          Row(){
            Text(`${p.name}: ${p.age}`)
              .fontSize(30)
              .onClick(() => {
                //数组内的元素变更不会触发数组的重新渲染
                // p.age++
                //数组重新添加、删除或者赋值的时候才会触发数组的重新渲染
                this.p[index] = new Person(p.name, p.age+1)
              })
            Button('删除')
              .onClick(()=>{
                this.p.splice(index, 1)
              })
          }
          .width('100%')
          .justifyContent(FlexAlign.SpaceAround)
        }
      )
    }
    .width('100%')
    .height('100%')
  }
}

Prop和Link这两个装饰器是在父子组件之间数据同步的时候去使用的,以下是两者的使用情况:

装饰器@Prop@Link
同步类型单向同步双向同步
允许装饰的变量类型

1)@Prop只支持string、number、boolean、enum类型

2)父组件是对象类型,子组件是对象属性

3)不可以是数组、any

1)父子类型一致:string、number、boolean、enum、object、class,以及他们的数组

2)数组中的元素增、删、替换会引起刷新

3)嵌套类型以及数组中的对象属性无法触发视图更新

接下来借助Prop和Link完成一个小案例:

我们在父组件中通过prop向子组件传值,子组件通过@Prop装饰器接受到值之后进行页面渲染,这里我们采用了ArkUI提供的堆叠容器和进度条组件实现页面的配置:

// 统一卡片样式
@Styles function card(){
  .width('95%')
  .padding(20)
  .backgroundColor(Color.White)
  .borderRadius(15)
  .shadow({radius: 6, color: '#1F000000', offsetX: 2, offsetY: 4})
}

@Component
export struct TaskStatistics {
  @Prop totalTask: number // 总任务数量
  @Prop finishTask: number // 已完成任务数量
  build() {
    // 任务进度卡片
    Row(){
      Text('任务进度')
        .fontSize(30)
        .fontWeight(FontWeight.Bold)
      // 堆叠容器,组件之间可以相互叠加显示
      Stack(){
        // 环形进度条
        Progress({
          value: this.finishTask,
          total: this.totalTask,
          type: ProgressType.Ring // 选择环形进度条
        })
          .width(100)
        Row(){
          Text(this.finishTask.toString())
            .fontColor('#36D')
            .fontSize(24)
          Text(' / ' + this.totalTask.toString())
            .fontSize(24)
        }
      }
    }
    .margin({top: 20, bottom: 10})
    .justifyContent(FlexAlign.SpaceEvenly)
    .card()

  }
}

子组件如果修改父组件的值的话,需要通过装饰器@Link来实现,父组件需要通过$来拿值:

// 任务类
class Task {
  static id: number = 1 // 静态变量,内部共享
  name: string = `任务${Task.id++}` // 任务名称
  finished: boolean = false // 任务状态,是否已完成
}

// 统一卡片样式
@Styles function card(){
  .width('95%')
  .padding(20)
  .backgroundColor(Color.White)
  .borderRadius(15)
  .shadow({radius: 6, color: '#1F000000', offsetX: 2, offsetY: 4})
}

@Component
export struct TaskList {
  @Link totalTask: number // 总任务数量
  @Link finishTask: number // 已完成任务数量
  @State tasks: Task[] = [] // 任务数组
  // 任务更新触发函数
  handleTaskChange(){
    this.totalTask = this.tasks.length // 更新任务总数量
    this.finishTask = this.tasks.filter(item => item.finished).length // 更新任务数量
  }
  build() {
    Column(){
      // 任务新增按钮
      Button('新增任务')
        .width(200)
        .onClick(()=>{
          this.tasks.push(new Task()) // 新增任务数组
          this.handleTaskChange()
        })

      // 任务列表
      List({space: 10}){
        ForEach(
          this.tasks,
          (item: Task, index)=>{
            ListItem(){
              Row(){
                Text(item.name)
                  .fontSize(20)
                Checkbox()
                  .select(item.finished)
                  .onChange(val => {
                    item.finished = val // 更新当前的任务状态
                    this.handleTaskChange()
                  })
              }
              .card()
              .justifyContent(FlexAlign.SpaceBetween)
            }
            .swipeAction({end: this.DeleteButton(index)})
          }
        )
      }
      .width('100%')
      .layoutWeight(1)
      .alignListItem(ListItemAlign.Center)
    }
  }
  @Builder DeleteButton(index: number){
    Button(){
      Image($r('app.media.delete'))
        .fillColor(Color.Red)
        .width(20)
    }
    .width(40)
    .height(40)
    .type(ButtonType.Circle)
    .backgroundColor(Color.Red)
    .margin(5)
    .onClick(()=>{
      this.tasks.splice(index, 1)
      this.handleTaskChange()
    })
  }
}

接下来就需要在父组件引用这两个子组件了,然后传参来获取和传递相关数值:

// 任务类
class Task {
  static id: number = 1 // 静态变量,内部共享
  name: string = `任务${Task.id++}` // 任务名称
  finished: boolean = false // 任务状态,是否已完成
}

import { TaskStatistics } from '../components/TaskStatistics'
import { TaskList } from '../components/TaskList'
@Entry
@Component
struct PropPage {
  @State totalTask: number = 0 // 总任务数量
  @State finishTask: number = 0 // 已完成任务数量
  @State tasks: Task[] = [] // 任务数组
  build(){
    Column({space: 10}){
      // 任务进度卡片
      TaskStatistics({ totalTask: this.totalTask, finishTask: this.finishTask })
      // 任务列表
      TaskList({ totalTask: $totalTask, finishTask: $finishTask })
    }
    .width('100%')
    .height('100%')
    .backgroundColor('#F1F2F3')
  }
}

最终呈现的结果如下:

@Provide和@Consume

这两个装饰器可以跨组件提供类似@State和@Link的双向同步,操作方式很简单,父组件之间使用Provide装饰器,子组件全部使用Consume装饰器,父组件都不需要传递参数了,直接调用子组件函数即可:

最终呈现的结果如下:

虽然相对来说比Prop和Link简便许多,但是使用Provide和Consume还是有代价的,本来需要传递参数的,但是使用Provide不需要传递参数,其内部自动帮助我们去维护,肯定是有一些资源上的浪费,所以说我们能用Prop还是尽量用Prop,实在用不了的可以去考虑Provide。

这两个装饰器用于在涉及嵌套对象或数组元素为对象的场景中进行双向数据同步:

我们给任务列表中的文本添加一个样式属性,当我们点击勾选的话,文本就会变灰并且加上一个中划线样式:

但是当我们勾选之后,视图并没有发生变化,原因是我们的Task是一个对象类型,数组的元素是对象,对象的属性发生修改是不会触发视图的重新渲染的,所以这里我们需要使用本次讲解的装饰器来进行解决:

我们给class对象设置@Observed装饰器:

然后在要修改对象属性值的位置进行设置@ObjectLink装饰器,因为这里一个任务列表通过ForEach遍历出来的,所以我们需要将这个位置单独抽离出来形成一个函数,然后将要使用的item设置@ObjectLink装饰器,因为还需要调用函数,但是任务列表的函数不能动,所以我们也将调用的函数作为参数传递过去:

@Component
struct TaskItem {
  @ObjectLink item: Task
  onTaskChange: () => void
  build(){
    Row(){
      if (this.item.finished){
        Text(this.item.name)
          .finishedTask()
      }else{
        Text(this.item.name)
      }
      Checkbox()
        .select(this.item.finished)
        .onChange(val => {
          this.item.finished = val // 更新当前的任务状态
          this.onTaskChange()
        })
    }
    .card()
    .justifyContent(FlexAlign.SpaceBetween)
  }
}

传递过程中为了确保this指向没有发生改变,我们在传递函数的时候,还需要通过bind函数指定this指向:

最终呈现的结果如下:

页面路由

页面路由是指在应用程序中实现不同页面之间的跳转和数据传递,如果学习过前端vue或react框架的人,可以非常简单的理解页面路由跳转的概念,以下是在鸿蒙开发中进行页面路由跳转所调用的API函数以及相应函数的作用,与前端的vue框架十分类似:

Router有两种页面跳转模式,分别是:

router.pushUrl():目标页不会替换当前页,而是压入页面栈,因此可以用router.back()返回当前页

router.replaceUrl():目标页替换当前页,当前页会被销毁并释放资源,无法返回当前页

Router有两种页面实例模式,分别是:

Standard:标准实例模式,每次跳转都会新建一个目标页并压入栈顶,默认就是这种模式

Single:单实例模式,如果目标页已经在栈中,则离栈顶最近的同url页面会被移动到栈顶并重新加载

了解完页面路由基本概念之后,接下来在案例中开始介绍如何使用页面路由:

首先我们在index首页定义路由信息:

// 定义路由信息
class RouterInfo {
  url: string // 页面路径
  title: string // 页面标题
  constructor(url: string, title: string) {
    this.url = url
    this.title = title
  }
}

接下在struct结构体里面定义路由相关信息以及页面的静态样式:

  @State message: string = '页面列表'
  private routers: RouterInfo[] = [
    new RouterInfo('pages/router/test1', '页面1'),
    new RouterInfo('pages/router/test2', '页面2'),
    new RouterInfo('pages/router/test3', '页面3'),
    new RouterInfo('pages/router/test4', '页面4')
  ]

  build() {
    Row() {
      Column() {
        Text(this.message)
          .fontSize(50)
          .fontWeight(FontWeight.Bold)
          .fontColor('#008c8c')
          .height(80)

        List({space: 15}){
          ForEach(
            this.routers,
            (router, index) => {
              ListItem(){
                this.RouterItem(router, index + 1)
              }
            }
          )
        }
        .layoutWeight(1)
        .alignListItem(ListItemAlign.Center)
        .width('100%')
      }
      .width('100%')
      .height('100%')
    }
  }

定义RouterItem函数,设置点击函数进行路由跳转:

@Builder RouterItem(r: RouterInfo, i: number){
    Row(){
      Text(i+'.')
        .fontSize(20)
        .fontColor(Color.White)
      Blank()
      Text(r.title)
        .fontSize(20)
        .fontColor(Color.White)
    }
    .width('90%')
    .padding(12)
    .backgroundColor('#38f')
    .shadow({radius: 6, color: '#4f0000', offsetX: 2, offsetY: 4})
    .onClick(()=>{
      // router跳转,传递3个参数
      router.pushUrl(
        // 跳转路径及参数
        {
          url: r.url,
          params: {id: i}
        },
        // 页面实例
        router.RouterMode.Single,
        // 跳转失败的一个回调
        err => {
          if (err) {
            console.log(`跳转失败,errCode:${err.code} errMsg: ${err.message}`)
          }
        }
      )
    })
  }

定义3个路由跳转页,设置第四个路由没有跳转页面,作对照:

注意,如果是仅仅是新建一个ArkTS页面的话需要在以下的文件中进行路由配置:

如果觉得每次创建一个页面都要进行一次路由路径的创建比较烦的话,可以采用以下创建方式,会自动帮我们配置好路由路径,而不需在去手动设置:

在子组件中,如果我们想拿到传递过来的参数可以调用getParams函数,返回调用back函数:

想要加个返回的警告可以采用如下的方式:

最终呈现的结果为:

相关文章:

openharmony开发版应用安装签名

配置签名信息应用/服务在真机设备上运行,需要提前为应用/服务进行签名,DevEco Studio为开发者提供了自动化签名方案,可以一键完成应用/服务签名。具体操作如下:单击File > Project Structure > Project > Signing Configs界面勾选Automatically generate signature,等待自动签名完成即可,单击OK。如下图所示:说明。

鸿蒙Harmony-页面路由(router)详解

慢慢理解世界,慢慢更新自己,希望你的每一个昨天,今天,和明天都会很快乐,你知道的,先好起来的从来都不是生活,而是你自己

鸿蒙harmony--数据库sqlite详解

今天是1月20号星期六,早安,岁末大寒至,静后春归来。愿他乡故人,漂泊有归宿,前程有奔赴,愿人间不寒,温暖常伴,诸事顺利,喜乐长安。

HarmonyOS 应用开发入门

HarmonyOS 应用有两种模型,分别是 FA(Feature Ability)模型和Stage模型。FA模型ArkTS应用(过时)JS应用(最新版IDE已不再支持)Stage模型ArkTS应用(推荐)应用模型的演进API 4-8 仅支持FA模型,API 9 后新增 Stage模型,是目前主推且会长期演进的模型,FA 暂时保留但不推荐。Stage模型的优点为复杂应用而设计支持多设备和多窗口形态平衡应用能力和系统管控成本对比传统FA模型和Stage模型。

解决鸿蒙APP的内存泄漏

解决鸿蒙应用的内存泄漏问题需要开发者对鸿蒙框架和组件的生命周期有深入的了解,以确保资源能够在适当的时候得到释放。LeakCanary同样可以用于鸿蒙应用,它是一款流行的内存泄漏检测库,可以在应用运行时检测内存泄漏并提供详细的报告。使用这些工具来监测应用的内存使用情况,找到潜在的内存泄漏问题。在某些场景下,使用弱引用(WeakReference)可以帮助避免对对象的强引用,从而减少内存泄漏的可能性。通过模拟各种使用场景,找到潜在的内存泄漏问题。释放不再需要的资源,避免在组件销毁后仍然持有对它的引用。

15.鸿蒙HarmonyOS App(JAVA)进度条与圆形进度条

/设置无限模式,运行查看动态效果。15.鸿蒙HarmonyOS App(JAVA)进度条与圆形进度条。//创建并设置无限模式元素。

鸿蒙APP闪退的问题

以下是一些建议的步骤,可以帮助你定位和解决鸿蒙应用闪退的原因,希望对大家有所帮助。使用鸿蒙开发者工具中的调试功能,尝试在应用发生闪退的情况下进行调试。这可以帮助你实时观察应用的状态,查看变量的值,并找到可能的问题。如果你的应用使用版本控制工具(如Git),回退到之前的稳定版本,看看问题是否仍然存在。有时,一个小的更改可能导致应用闪退,因此查看最近的代码修改是很重要的。如果应用使用第三方库或依赖,确保它们的版本与应用的其他部分兼容。使用鸿蒙开发者工具提供的崩溃分析服务,分析应用的崩溃报告。

鸿蒙Harmony-层叠布局(Stack)详解

我们总是为了太多遥不可及的东西去拼命,却忘了人生真正的幸福不过是灯火阑珊处的温暖,柴米油盐的充实,人生无论你赚的钱,是多还是少,经历的事情是好还是坏,都不如过好当下的每一天!

HarmonyOS开发FA应用模型下多个页面的声明方式

HarmonyOS配套的IDE是DevEco Studio,目前的版本是3.1。官网可以直接下载​。

鸿蒙开发-ArkTS基础,它与TS区别在那?

ArkTS是HarmonyOS优选的主力应用开发语言。ArkTS围绕应用开发在TypeScript(简称TS)生态基础上做了进一步扩展,继承了TS的所有特性,是TS的超集。说明: 也就是前端开发过程中所有的js/ts语法大部分支持的,比如es6中的箭头函数-模板字符串-promise-async/await-数组对象方法- 注意: 根据对下一代的Next版本的内部沟通,下一版本的ArkTs对类型最了更一步的限制。

OpenHarmony之消息机制实现

以上只是消息机制核外用户态的实现,最后会执行到系统调用以上的内容只是简单介绍了OpenHarmony之消息机制实现,没有具体到代码分析,移植等细节。要想成为一名鸿蒙高级开发,以上知识点是必须要掌握的,除此之外,还需要掌握一些鸿蒙应用开发相关的一些技术,需要我们共同去探索。

HarmonyOS应用开发学习笔记 包名、icon图标,应用名修改 UIAbility组件介绍、UIAbility启动模式、UIAbility组件基本用法

UIAbility组件是一种包含UI界面的应用组件,主要用于和用户交互。UIAbility组件是系统调度的基本单元,为应用提供绘制界面的窗口;一个UIAbility组件中可以通过多个页面来实现一个功能模块。每一个UIAbility组件实例,都对应于一个最近任务列表中的任务。UIAbility声明:UIAbility编辑完成后,还需要在module.json5上声明,才能使用"name": "EntryAbility", // UIAbility组件的名称。

HarmonyOS UI框架简介

HarmonyOSUI框架是一个用于构建跨设备应用的开发框架,它属于HarmonyOS系统架构的上层框架。该框架通过提供一系列的开发模型、声明式UI范式、系统API等,帮助开发者更高效地构建用户界面。在HarmonyOSUI框架中,开发语言目前主要支持arkts/TS语言。该框架通过自研的声明式UI范式,使开发者能够描述用户界面的状态和变化,而无需关注具体的实现细节。这种范式降低了学习成本,提高了开发效率。

HarmonyOS 应用开发学习笔记 ets组件生命周期

官网文档里有一句话:一个页面有且仅能有一个@Entry。只有被@Entry装饰的组件才可以调用页面的生命周期经木子测,自定义组件用@Entry修饰了不能触发(onPageShow、onPageHide、onBackPress )回调index.ets 组件(入口组件)能触发 onPageShow、onPageHide、onBackPress、aboutToAppear、aboutToDisappear自定义组件ComponentA。

是否需要跟上鸿蒙(OpenHarmony)开发岗位热潮?

自打华为2019年发布鸿蒙操作系统以来,网上各种声音百家争鸣。尤其是2023年发布会公布的鸿蒙4.0宣称不再支持Android,更激烈的讨论随之而来。本文没有宏大的叙事,只有基于现实的考量。

OpenHarmony之HDF驱动框架

HDF最核心几大块:配置管理,驱动管理,对外服务,消息机制对外接口侧重于服务,消息,而不是设备节点,这个是很大的一个转变以上内容主要概括了《OpenHarmony之HDF驱动框架》基础知识,为了让大家更快的了解《OpenHarmony4.0&Next》,我特意邀请几位行业大佬,联合整理了一份思维导图提供大家参考学习,大家可以根据自己的情况借鉴:《做鸿蒙应用开发到底学习些啥?除了上面整理的思维导图以外,这里还特别整理的一份《鸿蒙 (Harmony OS)开发学习手册》给大家进行参考学习:一、入门必看。

HarmonyOS page生命周期函数讲解

因为已经跳转 index 组件隐藏 onPageHide 触发 然后 AppView 页面显示 onPageShow触发。然后 我们打开预览器 运行index组件 然后 index 组件 被显示 onPageShow生命周期随之触发。然后 设置了一个button按钮 点击跳转向 pages/AppView页面。这个函数是页面返回时 触发 这里所说的返回不是说 router.back。调回 index界面 AppView被隐藏 触发onPageHide。

鸿蒙(HarmonyOS)项目方舟框架(ArkUI)之Dialog对话框组件

鸿蒙(HarmonyOS)项目方舟框架(ArkUI)之Dialog对话框组件

HarmonyOS应用性能与功耗云测试

应用程序:选择待测试的HarmonyOS应用包,包括HAP和APP两种格式,如果未上传应用,请先从本地上传一个HarmonyOS应用包。应用程序:选择待测试的HarmonyOS应用包,包括HAP和APP两种格式,如果未上传应用,请先从本地上传一个HarmonyOS应用包。在测试报告的概览页,可以查看测试任务的整体情况,如测试通过率、问题分布、在各个测试终端上的问题分布情况。在测试报告的概览页,可以查看测试任务的整体情况,如测试通过率、问题分布、在各个测试终端上的问题分布情况。

HarmonyOS的功能及场景应用

鸿蒙HarmonyOS主要应用的设备包括智慧屏、平板、手表、智能音箱、IoT设备等。具体来说,鸿蒙系统是一款面向全场景(移动办公、运动健康、社交通信、媒体娱乐等)的分布式操作系统,能够支持手机、平板、智能穿戴、智慧屏、车机等多种终端设备,通过同一套系统能力、适配多种终端形态。以下是关于鸿蒙系统技术知识的介绍:分布式架构首次用于终端OS,实现跨终端无缝协同体验。

HarmonyOS官网案例解析——新闻数据加载(ArkTS)

/ 发送数据请求header: {},});// 处理数据,并返回// 处理数据,并返回} else {serverData.msg = `${'网络错误'}&${value.responseCode}`;serverData.msg = '网络错误';})....// 获取服务端新闻数据列表url += '?});...Promise构造函数接受一个函数作为参数,该函数的两个参数分别是resolve。

【HarmonyOS开发】拖拽动画的实现

在开发拖拽动画时,发现png的图片在拖拽结束后,会出现图片闪动的不流畅问题,改为svg图片解决。因此通过大量的对比验证,确认为鸿蒙底层窜然问题。

【Harmony】鸿蒙操作系统架构

鸿蒙操作系统以其微内核架构、分布式能力和全场景覆盖的设计理念,成为当前技术领域一颗璀璨的明星。其架构设计满足了当前多样化的设备需求,注重了设备之间的协同工作和开发者的友好体验。随着鸿蒙操作系统的不断演进和生态系统的丰富,我们对于这个在全球范围内掀起一场科技变革的产物充满期待。在未来的智能互联时代,鸿蒙操作系统必将发挥更为重要的作用,引领技术的潮流。_鸿蒙系统的架构

HarmonyOS之 开发环境搭建

HarmonyOS开发环境搭建_鸿蒙开发环境搭建

鸿蒙开发软件用什么编程语言?

鸿蒙经过几年的迭代,抛弃了Java,基于TS出了一个官方推荐的ArkTS语言,甩开了JVM,提升效率,同时支持自己研发的一些现代化特性,没有版权的问题,现在唯一的问题就是各大公司愿不愿意为它去适配生态了,还好的是,目前各大互联网公司已经开始适配了。

HarmonyOS 数据管理与应用数据持久化(二)

文章浏览阅读31次。关系型数据库基于 SQLite 组件,适用于存储包含复杂关系数据的场景,比如一个班级的学生信息,需要包括姓名、学号、各科成绩等,又或者公司的雇员信息,需要包括姓名、工号、职位等,由于数据之间有较强的对应关系,复杂程度比键值型数据更高,此时需要使用关系型数据库来持久化保存数据。

HarmonyOS数据管理与应用数据持久化(一)

文章浏览阅读599次。一.

鸿蒙ArkUI-X跨端应用开发,一套代码构建多平台应用

文章浏览阅读164次。ArkUI是一套构建分布式应用的声明式UI开发框架。它具备简洁自然的UI信息语法、丰富的UI组件、多维的状态管理,以及实时界面预览等相关能力,帮助您提升应用开发效率,并能在多种设备上实现生动而流畅的用户体验。详情可参考ArkUI框架介绍ArkUI-X进一步将ArkUI扩展到了多个OS平台:目前支持OpenHarmony、HarmonyOS、Android、 iOS,后续会逐步增加更多平台支持。开发者基于一套主代码,就可以构建支持多平台的精美、高性能应用。