AI 摘要 文章聚焦 HarmonyOS 4.0 应用开发核心技能：先讲解 ATM 权限模型，区分 system_grant 与 user_grant，演示在 module.json5 中声明网络权限；随后用 @ohos.net.http 实现一键发请求并刷新 UI；接着详解 router.pushUrl、replaceUrl、back 及参数传递，完成页面间导航；最后梳理 UIAbility 与组件生命周期回调，助开发者掌握从权限、网络、路由到生命周期的完整入门路径。 此摘要根据文章内容自动生成，仅用于文章内容的解释与总结应用权限ATM参考文档：https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V2/accesstoken-overview-0000001544703857-V2#ZH-CN_TOPIC_0000001574088913__%E6%9D%83%E9%99%90%E7%B1%BB%E5%9E%8B%E8%AF%B4%E6%98%8EATM（AccessTokenManage）是 HarmonyOS 上基于 AccessToken 构建的统一的应用权限管理能力。应用权限保护的对象可以分为：数据：包含了个人数据（如照片、通讯录、日历、位置等）、设备数据（如设备标识、相机、麦克风等）、应用数据。功能：包括了设备功能（如打电话、发短信、联网等）、应用功能（如弹出悬浮框、创建快捷方式等）等。根据授权方式的不同，权限类型可分为：system_grant：即系统授权，应用被允许访问的数据不会涉及到用户或设备的敏感信息。user_grant：即用户授权，应用被允许访问的数据将会涉及到用户或设备的敏感信息。配置权限参考文档：https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V2/accesstoken-guidelines-0000001493744016-V2比如：应用需要访问网络图片或发送 HTTP 请求，需要在工程配置文件（src/main/module.json5）中授予网络访问权限。示例：配置权限工程配置文件（src/main/module.json5）：{ "module": { // ... "requestPermissions": [ { "name": "ohos.permission.INTERNET" } ] } }HTTP 请求@ohos.net.http参考文档：https://developer.huawei.com/consumer/cn/doc/harmonyos-references-V2/js-apis-http-0000001478061929-V2@ohos.net.http 模块提供HTTP数据请求能力。应用可以通过 HTTP 发起一个数据请求，支持常见的 GET、POST、PUT、DELETE 等方法。示例：发送 HTTP 请求Index组件（src/main/ets/pages/Index.ets）：import http from '@ohos.net.http' @Entry @Component struct Index { @State data: string = '' build() { Column({space: 16}) { Button('send request') .onClick(() => { // 创建 HTTP 请求对象 http.createHttp().request('http://duoapi.fjisp.com/saying.random') .then((response) => { console.log('response：' + response) // 获取服务器返回的数据 this.data = response.result.toString() }) .catch((err) => { // 请求失败查看错误信息 console.log('request error：' + err.message) }) }) Text('随机一言：' + this.data) } .padding(20) .width('100%') } }示例效果：路由路由 API参考文档：https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V2/arkts-routing-0000001503325125-V2常见的路由 API：router.pushUrl：跳转到应用内的指定页面。router.replaceUrl：用应用内的某个页面替换当前页面，并销毁被替换的页面，并且无法返回到当前页。router.back：返回上一页面或指定的页面。router.clear：页面栈的最大容量为 32 个页面，如果超过这个限制，可以调用该方法清空历史页面栈，释放内存空间。示例：路由 APIIndex组件（src/main/ets/pages/Index.ets）：import router from '@ohos.router' @Entry @Component struct Index { build() { Column({space: 16}) { Text('Index') Button('Router pushUrl Other') .onClick(() => { // 路由跳转到pages/Other，有浏览记录 router.pushUrl({url:'pages/Other'}) }) Button('Router replaceUrl Other') .onClick(() => { // 路由跳转（替换）到pages/Other，无浏览记录 router.replaceUrl({url: 'pages/Other'}) }) } .padding(20) .width('100%') } }Other组件（src/main/ets/pages/Other.ets）：import router from '@ohos.router' @Entry @Component struct Other { build() { Column({space: 16}) { Text('Other') Button('返回上一页') .onClick(() => { // 路由返回到上一页 router.back() }) } .padding(20) .width('100%') } }示例效果：路由参数传递如果需要在跳转时传递一些数据给目标页，则可以在调用 Router 模块的方法时，添加一个 params 属性，并指定一个对象作为参数。在目标页中，可以通过调用 Router 模块的 getParams 方法来获取传递过来的参数。示例：路由参数传递Index组件（src/main/ets/pages/Index.ets）：import router from '@ohos.router' @Entry @Component struct Index { build() { Column({space: 16}) { Button('Router pushUrl Other') .onClick(() => { // 路由跳转到pages/Other，有浏览记录 router.pushUrl({ url:'pages/Other', // 传递参数 params: { id: 1, message: 'Hello HarmonyOS' } }) }) } .padding(20) .width('100%') } }Other组件（src/main/ets/pages/Other.ets）：import router from '@ohos.router' // 获取参数对象 const params = router.getParams() @Entry @Component struct Other { build() { Column({space: 16}) { // 获取参数 Text('接收到的id参数为：' + params['id']) Text('接收到的message参数为：' + params['message']) } .padding(20) .width('100%') } }示例效果：生命周期UIAbility 生命周期参考文档：https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V2/uiability-lifecycle-0000001427902208-V2当用户打开、切换和返回到对应应用时，应用中的 UIAbility 实例会在其生命周期的不同状态之间转换。onCreate：在 Ability 创建时回调，执行初始化业务逻辑操作。onWindowStageCreate：当 WindowStage 创建后调用。onForeground：当应用从后台转到前台时触发。onBackground：当应用从前台转到后台时触发。onDestroy：在 Ability 销毁时回调。UIAbility 生命周期示例图：示例：UIAbility 生命周期EntryAbility（src/main/ets/pages/entryability.ts）：import UIAbility from '@ohos.app.ability.UIAbility'; import hilog from '@ohos.hilog'; import window from '@ohos.window'; export default class EntryAbility extends UIAbility { // UIAbility实例创建完成后调用 onCreate(want, launchParam) { hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onCreate'); } // UIAbility实例销毁时调用 onDestroy() { hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onDestroy'); } // WindowStage创建完成后调用 onWindowStageCreate(windowStage: window.WindowStage) { // Main window is created, set main page for this ability hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageCreate'); windowStage.loadContent('pages/Index', (err, data) => { if (err.code) { hilog.error(0x0000, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err) ?? ''); return; } hilog.info(0x0000, 'testTag', 'Succeeded in loading the content. Data: %{public}s', JSON.stringify(data) ?? ''); }); } // WindowStage销毁后调用 onWindowStageDestroy() { // Main window is destroyed, release UI related resources hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageDestroy'); } // 应用从后台转到前台时触发 onForeground() { // Ability has brought to foreground hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onForeground'); } // 应用从前台转到后台时触发 onBackground() { // Ability has back to background hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onBackground'); } }组件生命周期参考文档：https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V2/arkts-page-custom-components-lifecycle-0000001524296665-V2页面生命周期，即被 @Entry 装饰的组件生命周期：onPageShow：页面每次显示时触发一次，包括路由过程、应用进入前台等场景。onPageHide：页面每次隐藏时触发一次，包括路由过程、应用进入后台等场景。onBackPress：当用户点击返回按钮时触发。组件生命周期，即用 @Component 装饰的自定义组件的生命周期。aboutToAppear：组件即将出现时回调该接口，具体时机为在创建自定义组件的新实例后，在执行其 build() 函数之前执行。aboutToDisappear：在自定义组件销毁之前执行。示例：页面和组件生命周期Index组件（src/main/ets/pages/Index.ets）：import promptAction from '@ohos.promptAction' @Entry @Component struct Index { aboutToAppear() { promptAction.showToast({message: 'Index aboutToAppear'}) } onPageShow() { promptAction.showToast({message: 'Index onPageShow'}) } onPageHide() { promptAction.showToast({message: 'Index onPageHide'}) } build() { Column({space: 16}) { Text('首页') } .padding(20) .width('100%') } }
AI 摘要 文章系统梳理 HarmonyOS 4.0 ArkTS 状态管理：@Prop 单向、@Link 双向父子同步；@Provide/@Consume 跨代共享；@Watch 监听；@Observed/@ObjectLink 解决嵌套对象同步；LocalStorage 页面级、AppStorage 应用级、PersistentStorage 持久化存储，并附完整代码示例与动图效果，帮助开发者快速掌握各种场景的状态管理技巧。 此摘要根据文章内容自动生成，仅用于文章内容的解释与总结组件状态共享父子单向状态共享参考文档：https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V2/arkts-prop-0000001473537702-V2@Prop 装饰的变量可以和父组件建立单向的同步关系。@Prop 只能接收 string、number、boolean、enum 数据类型。@Prop 是单向状态共享，父组件的数据发生变化会同步到子组件，子组件的数据发生变化不会同步到父组件。父组件更的数据新后，会覆盖子组件的 Prop 数据。@Prop 不能在 @Entry 装饰的自定义组件中使用。示例：父子单向状态共享Index 组件（src/main/ets/pages/Index.ets）：// 父组件 @Entry @Component struct Index { // 父组件声明数据 @State count: number = 0 build() { Column({space: 16}){ Text('父组件的count：' + this.count) // 父组件按钮被点击，父子count均发生变化 Button('parent count++') .onClick(() => { this.count++ }) Divider() // 在父组件中调用子组件 // 父组件的count传递给子组件 Child({count: this.count}) } .width('100%') .height('100%') .padding(20) } } // 子组件 @Component struct Child { // 子组件要接收一个count参数 @Prop count: number build() { Column({space: 16}){ Text('子组件接收到的count：' + this.count) // 子组件按钮被点击，子count发生变化 // 父count不变，为单向数据传递 Button('child count++') .onClick(() => { this.count++ }) } } }示例效果：父子双向状态共享参考文档：https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V2/arkts-link-0000001524297305-V2子组件中被 @Link 装饰的变量与其父组件中对应的数据源建立双向数据绑定。@Link 支持简单数据类型（string、number 等）和复杂数据类型（Object、class 等）。@Link 是双向状态共享，父组件的数据发生变化会同步到子组件，子组件的数据发生变化也会同步到父组件。@Link 不能在 @Entry 装饰的自定义组件中使用。父组件传值的时候需要使用 $ 而不是 this，子组件 中使用 @Link 修饰数据。示例：父子双向状态共享Index 组件（src/main/ets/pages/Index.ets）：@Entry @Component struct Index { @State count: number = 0 build() { Column({space: 16}){ Text('父组件的count：' + this.count) Button('parent count++') .onClick(() => { this.count++ }) Divider() // 在父组件中调用子组件 // 父组件的count传递给子组件 // 双向传递不能使用this传递，要使用$传递 Child({count: $count}) } .width('100%') .height('100%') .padding(20) } } @Component struct Child { // 子组件要接收一个 count 参数 @Link count: number build() { Column({space: 16}){ Text('子组件接收到的count：' + this.count) // 子组件按钮被点击，父子 count 均发生变化 Button('child count++') .onClick(() => { this.count++ }) } } }示例效果：后代组件状态共享参考文档：https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V2/arkts-provide-and-consume-0000001473857338-V2@Provide 和 @ Consume 应用于与后代组件的双向数据同步，应用于状态数据在多个层级之间传递的场景。@Provide 装饰的状态变量自动对其所有后代组件可用。后代通过使用 @Consume 去获取 @Provide 提供的变量，建立在 @Provide 和 @Consume 之间的双向数据同步。@Provide 和 @Consume 可以通过相同的变量名或者相同的变量别名绑定，变量类型必须相同。示例：后代组件状态共享Index 组件（src/main/ets/pages/Index.ets）：// 父组件 @Entry @Component struct Index { // 父组件定义数据 // 自动对其所有后代组件可用 @Provide count: number = 0 build() { Column({space: 16}){ Text('父组件的count：' + this.count) // 父组件按钮被点击，父、子、后代count均发生变化 Button('parent count++') .onClick(() => { this.count++ }) Divider() // 父组件调用子组件 Child() } .width('100%') .height('100%') .padding(20) } } // 子组件 @Component struct Child { build() { Column({space: 16}){ Text('子组件') Divider() // 子组件调用后代组件 GrandSon() } } } // 后代组件 @Component struct GrandSon { // 后代组件直接接收父组件传递的count @Consume count: number build() { Column({space: 16}){ Text('后代组件接收到的count：' + this.count) // 后代组件按钮被点击，父、子、后代 count 均发生变化 Button('child count++') .onClick(() => { this.count++ }) } } }示例效果：状态监听器参考文档：https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V2/arkts-watch-0000001473697342-V2@Watch 应用于对状态变量的监听。在第一次初始化的时候，@Watch 装饰的方法不会被调用。@Watch 方法在自定义组件的属性变更之后同步执行。@Watch 装饰器必须写在 @State / @Prop / @Link 注解的后面。示例：状态监听器Index 组件（src/main/ets/pages/Index.ets）：import promptAction from '@ohos.promptAction' @Entry @Component struct Index { @State @Watch('onCountUpdate') // 监听count变化 count: number = 0 // 定义一个监听函数 onCountUpdate() { promptAction.showToast({ message: 'count 变化' }) } build() { Column({space: 16}){ Text('count：' + this.count) Button('count++') .onClick(() => { this.count++ }) } .width('100%') .height('100%') .padding(20) } }示例效果：解决嵌套引用数据问题参考文档：https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V2/arkts-observed-and-objectlink-0000001473697338-V2当 @State 装饰的是一个嵌套的对象类型、对象数组时，@State 无法监听到嵌套的数据的变化。@ObjectLink 和 @Observed 类装饰器用于在涉及嵌套对象或数组的场景中进行双向数据同步。被 @Observed 装饰的类，可以被观察到属性的变化。子组件中 @ObjectLink 装饰器装饰的状态变量用于接收 @Observed 装饰的类的实例，和父组件中对应的状态变量建立双向数据绑定。@ObjectLink 装饰器不能在 @Entry 装饰的自定义组件中使用。示例：解决嵌套引用数据问题Index 组件（src/main/ets/pages/Index.ets）：// 使用@Observed装饰User类 @Observed class User { name: string age: number // 类必须提供构造方法 constructor(name: string, age: number) { this.name = name this.age = age } } // 父组件 @Entry @Component struct Index { // 实例化User对象数组 @State userList: User[] = [ // 对象数组中的对象要使用new创建 // 通过初始化构造函数的方式往数组中添加 new User('张三', 18), new User('李四', 19) ] build() { Column({space: 16}){ Text('父组件区域') Divider() // 父组件调用子组件1展示信息 Text('子组件1区域') ForEach(this.userList, (item: User, index: number) => { Child({user: item}) }) Divider() // 父组件调用子组件2展示信息 // 可以观察到this.userList的变化 Text('子组件2区域') ForEach(this.userList, (item: User, index: number) => { ItemList({user: item}) }) // ForEach遍历的是同一个this.userList } .width('100%') .height('100%') .padding(20) } } // 子组件1 @Component struct Child { // 接收@Observed装饰的类的实例 // 进行双向数据绑定 @ObjectLink user: User build() { Row({space: 16}) { Text(this.user.name + '的年龄是：' + this.user.age) // 子组件1中的数据被修改，父组件的userList中的数据也被修改 // 故子组件2中的数据也被修改 Button('age++') .onClick(() => { this.user.age++ }) } } } // 子组件2 @Component struct ItemList { @ObjectLink user: User build() { Row({space: 16}) { Text(this.user.name + '的年龄是：' + this.user.age) } } }示例效果：应用状态localStorage参考文档：https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V2/arkts-localstorage-0000001524537149-V2LocalStorage 是 ArkTS 为构建页面级别状态变量提供存储的内存内“数据库”。localStorage 是页面级的状态共享。通过 @Entry 装饰器接收的参数可以在页面内共享同一个 LocalStorage 实例。LocalStorage 也可以在 UIAbility 内，页面间共享状态。页面内共享 LocalStorage：使用构造函数创建 LocalStorage 实例。使用 @Entry 装饰器将 LocalStorage 实例添加到顶层组件中。@LocalStorageProp 绑定 LocalStorage 对给定的属性，建立单向数据同步。@LocalStorageLink 绑定 LocalStorage 对给定的属性，建立双向数据同步。@LocalStorageProp 或 @LocalStorageLink 装饰的数据需要设置默认值。示例：页面内共享 LocalStorageIndex 组件（src/main/ets/pages/Index.ets）：// 创建一个LocalStorage实例 const localStorage = new LocalStorage({ count: 10 }) // 将实例对象传给Entry @Entry(localStorage) @Component struct Index { // 建立双向数据同步 @LocalStorageLink('count') count: number = 0 build() { Column({space: 16}) { Text('我是父组件') Text('count is ' + this.count) // 按钮点击，父子组件数据均会发生变化 Button('count++') .onClick(() => { this.count++ }) Divider() // 父组件调用子组件 Child() } .padding(20) } } @Component struct Child { // 建立双向数据同步 @LocalStorageLink('count') count: number = 0 build() { Column({space: 16}) { Text('我是子组件') Text('count is ' + this.count) } } }示例效果：页面间共享 LocalStorage：修改 src/main/ets/entryability/EntryAbility.ts，在 UIAbility 创建 LocalStorage，并通过 loadContent 提供给加载的窗口。在页面使用 LocalStorage.GetShared() 得到实例，通过 @Entry 传入页面。页面间共享只在模拟器或者实机上有效，不能在 Preview 预览器中使用。示例：页面间共享 LocalStorageEntryAbility（src/main/ets/pages/entryability.ts）：export default class EntryAbility extends UIAbility { // 实例化LocalStorage localStorage = new LocalStorage({ count: 10 }) // ... onWindowStageCreate(windowStage: window.WindowStage) { // ... // 通过windowStage.loadContent提供localStorage给窗口 windowStage.loadContent('pages/Index', this.localStorage, (err, data) => { // ... }); } // ... }Index 组件（src/main/ets/pages/Index.ets）：// 获取共享的LocalStorage实例 const localStorage = LocalStorage.GetShared() // 传给Entry @Entry(localStorage) @Component struct Index { // 建立双向数据同步 @LocalStorageLink('count') count: number = 0 build() { Column({space: 16}) { Text('Home Page') Text('LocalStorage count is ' + this.count) Button('count++') .onClick(() =>{ this.count++ }) Navigator({target: 'pages/Other'}) { Button('点我跳转到 Other Page') } } .padding(20) .width('100%') } }OtherPage 组件（src/main/ets/pages/OtherPage.ets）：const storage = LocalStorage.GetShared() @Entry(storage) @Component struct OtherPage { @LocalStorageLink('count') count: number = 0 build() { Column({space: 16}) { Text('Other Page') // 数据是双向的 Text('LocalStorage count is ' + this.count) Button('count++') .onClick(() =>{ this.count++ }) Navigator({target: 'pages/Index'}) { Button('点我跳转到Home Page') } } .padding(20) .width('100%') } }示例效果：appStorage参考文档：https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V2/arkts-appstorage-0000001524417209-V2AppStorage 是应用全局的 UI 状态存储，是和应用的进程绑定的，由 UI 框架在应用程序启动时创建，为应用程序 UI 状态属性提供中央存储。AppStorage 是应用级的全局状态共享。AppStorage 是单例，通过其 SetOrCreate 方法初始化数据。@StorageProp 绑定 AppStorage 对给定的属性，建立单向数据同步。@StorageLink 绑定 AppStorage 对给定的属性，建立双向数据同步。@StorageProp 或 @StorageLink 装饰的数据需要设置默认值。示例：全局共享 appStorageIndex 组件（src/main/ets/pages/Index.ets）：import promptAction from '@ohos.promptAction' // 初始化数据 AppStorage.SetOrCreate('count', 10) @Entry @Component struct Index { // 建立双向数据同步 @StorageLink('count') count: number = 0 build() { Column({space: 16}) { Text('AppStorage count is ' + this.count) Button('count++') .onClick(() =>{ // count被修改 this.count++ }) Button('Get++') .onClick(() =>{ // 获取数据 const count = AppStorage.Get('count') promptAction.showToast({ message: 'count is ' + count }) }) Button('Set++') .onClick(() =>{ // 修改数据 const count = AppStorage.Set('count', 99) promptAction.showToast({ message: 'count set ' + count }) }) Divider() Child() } .padding(20) } } @Component struct Child { // 建立双向数据同步 @StorageLink('count') count: number = 0 build() { Column({space: 16}) { Text('Child') Text('count is ' + this.count) } } }示例效果：PersistentStorage参考文档：https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V2/arkts-persiststorage-0000001474017166-V2PersistentStorage 可以将选定的 AppStorage 属性保留在设备磁盘上（即持久化）。PersistentStorage 支持 number、string、boolean、enum 等简单类型。UI 和业务逻辑不直接访问 PersistentStorage 中的属性，所有属性访问都是对 AppStorage 的访问，AppStorage 中的更改会自动同步到 PersistentStorage。PersistentStorage 和 AppStorage 关联在一起。持久化变量最好是小于 2kb 的数据，如果需要存储大量的数据，建议使用数据库 API。示例：持久化存储状态Index 组件（src/main/ets/pages/Index.ets）：// 初始化数据 // AppStorage.SetOrCreate('count', 10) // 运行时，先到硬盘上查找count，若数据不存在，初始化值为10 PersistentStorage.PersistProp('count', 10) @Entry @Component struct Index { // 通过AppStorage的方式建立双向数据同步 @StorageLink('count') count: number = 0 build() { Column({space: 16}) { Text('PersistentStorage count is ' + this.count) Button('count++') .onClick(() =>{ this.count++ }) Divider() } .padding(20) } }
AI 摘要 文章聚焦 HarmonyOS 4.0 ArkTS 进阶：@State 对普通对象可监听，嵌套对象与数组需整体替换触发刷新；条件渲染 if/else 会销毁组件，ForEach 完成列表循环；@Builder 支持全局/局部复用 UI，参数按值传递不响应状态，按引用($$)传递可随状态刷新。 此摘要根据文章内容自动生成，仅用于文章内容的解释与总结组件状态进阶对象类型状态参考文档：https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V2/arkts-state-0000001474017162-V2#section1822514413343当 @State 装饰的是一个普通的对象类型时，@State 能监听到数据的变化。示例：对象类型的状态监听Index 组件（src/main/ets/pages/Index.ets）：// 定义对象模型 class User { name: string age: number } @Entry @Component struct Index { // 实例化User对象 @State user: User = { name: '张三', age: 18 } build() { Row() { Column({space: 10}) { Text('姓名：' + this.user.name) Text('年龄：' + this.user.age) Button('age++') .onClick(() => { this.user.age++ }) } .width('100%') } .padding(20) } }示例效果：嵌套对象类型状态当 @State 装饰的是一个嵌套的对象类型时，@State 无法监听到嵌套的数据的变化。示例：嵌套对象类型的状态监听Index 组件（src/main/ets/pages/Index.ets）：// 定义对象模型 class Role { roleName: string } class User { name: string age: number // User嵌套Role role: Role } @Entry @Component struct Index { // 实例化User对象 @State user: User = { name: '张三', age: 18, role: { roleName: '技术部' } } build() { Row() { Column({space: 10}) { Text('姓名：' + this.user.name) Text('年龄：' + this.user.age) Text('部门名称：' + this.user.role.roleName) Button('age++') .onClick(() => { this.user.age++ }) Button('role change') .onClick(() => { // 在JavaScript中引用数据类型，变量保存的值是引用地址 // 直接修改this.user.role.roleName导致user.role的内存地址未变化 // @State无法监测到数据的变化 // this.user.role.roleName = '综合部' // 将旧的role对象复制到一个新对象 // ...符号表示拷贝 const role = {...this.user.role} // 修改roleName role.roleName = '综合部' // 将新的role对象赋值给user对象 this.user.role = role }) } .width('100%') } .padding(20) } }示例效果：对象数组类型状态当 @State 装饰的是一个对象数组类型时，@State 无法监听到数组内部的数据的变化。示例：对象数组类型的状态监听Index 组件（src/main/ets/pages/Index.ets）：class User { name: string age: number } @Entry @Component struct Index { // 实例化User对象数组 @State userList: User[] = [ { name: '张三', age: 18 }, { name: '李四', age: 19 }, { name: '王五', age: 20 } ] build() { Row() { Column({space: 10}) { Text('姓名：' + this.userList[0].name) Text('年龄：' + this.userList[0].age) Button('age++') .onClick(() => { const user = {...this.userList[0]} user.age++ this.userList[0] = user }) } .width('100%') } .padding(20) } }示例效果：界面渲染条件渲染参考文档：https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V2/arkts-rendering-control-ifelse-0000001524177637-V2条件渲染可根据应用的不同状态，使用 if、else 和 else if 渲染对应状态下的 UI 内容。条件渲染是根据状态数据进行判断展示不同 UI。条件渲染时会销毁和创建组件（包括自定义组件和内置组件），组件状态将不会保留。示例：条件渲染Index 组件（src/main/ets/pages/Index.ets）：@Entry @Component struct Index { // 是否显示加载动效组件 @State loading: boolean = true build() { Row() { Column({space: 10}) { // 按钮点击切换加载动效 Button('change') .onClick(() => { this.loading = !this.loading }) // 条件判断 if(this.loading) { LoadingProgress() } else { Text('Hello HarmonyOS') // 条件渲染会销毁和创建组件，因此切换时输入框的数据不会被保留 TextInput() } } .width('100%') } .height('100%') } }示例效果：循环渲染参考文档：https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V2/arkts-rendering-control-foreach-0000001524537153-V2ForEach 基于数组类型数据来进行循环渲染，需要与容器组件配合使用。ForEach 的基本用法：ForEach( arr: Array, itemGenerator: (item: any, index?: number) => void, keyGenerator?: (item: any, index?: number) => string )ForEach 的基本参数：名称类型描述arrarray要遍历的列表itemGenerator(item: any, index?: number) => void组件生成函数item：遍历后每个数据项的别名index：数据下标索引keyGenerator(item: any, index?: number) => string键值生成函数，为数据源 arr 的每个数组项生成唯一且持久的键值示例：循环渲染Index 组件（src/main/ets/pages/Index.ets）：class User { name: string age: number } @Entry @Component struct Index { // 实例化User对象数组 @State userList: User[] = [ { name: '张三', age: 18 }, { name: '李四', age: 19 }, { name: '王五', age: 20 }, { name: '唐三藏', age: 21 }, { name: '孙悟空', age: 22 }, { name: '猪八戒', age: 23 }, { name: '沙悟净', age: 24 } ] build() { Row() { Column({space: 10}) { ForEach(this.userList, (item: User, index: number) => { Text('id is ' + index + ', name is ' + item.name + ', age is ' + item.age) }) } .width('100%') } .padding(20) } }示例效果：自定义构建函数@Builder参考文档：https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V2/arkts-builder-0000001524176981-V2ArkUI 还提供了一种更轻量的 UI 元素复用机制 @Builder，@Builder 所装饰的函数遵循 build() 函数语法规则，开发者可以将重复使用的 UI 元素抽象成一个方法，在 build 方法里调用。自定义构建函数支持全局定义和组件内定义。示例：自定义构建函数Index 组件（src/main/ets/pages/Index.ets）：// 全局定义自定义构建函数 @Builder function publicBuilderFunction() { Text('查看更多 >>') .fontColor(Color.Gray) } @Entry @Component struct Index { // 组件内定义自定义构建函数 @Builder myBuilderFunction() { Text('查看更多 >>') .fontColor(Color.Gray) } build() { Column(){ Row() { Text('评价 (2000)') .layoutWeight(1) .fontWeight(FontWeight.Bold) // 调用组件内自定义构建函数 this.myBuilderFunction() } .padding(10) Row() { Text('推荐') .layoutWeight(1) // 调用全局自定义构建函数 publicBuilderFunction() } .padding(10) } .width('100%') .height('100%') .padding(20) .backgroundColor('#ffeaeaea') } }示例效果：传递参数自定义构建函数的参数传递有按值传递和按引用传递两种。按值传递：调用 @Builder 装饰的函数默认按值传递。当传递的参数为状态变量时，状态变量的改变不会引起 @Builder 方法内的 UI 刷新。示例：按值传递参数Index 组件（src/main/ets/pages/Index.ets）：@Entry @Component struct Index { // 组件内定义自定义构建函数 @Builder myBuilderFunction(title: string) { Text(title) .fontColor(Color.Gray) } build() { Column(){ Row() { Text('评价 (2000)') .layoutWeight(1) .fontWeight(FontWeight.Bold) // 调用组件内自定义构建函数 // 传递title参数 this.myBuilderFunction('查看更多 >>') } .padding(10) } .width('100%') .height('100%') .padding(20) .backgroundColor('#ffeaeaea') } }示例效果：按引用传递：传递的参数可为状态变量，且状态变量的改变会引起 @Builder 方法内的 UI 刷新。示例：按引用传递参数Index 组件（src/main/ets/pages/Index.ets）：@Entry @Component struct Index { @State rate: number = 0 // 组件内定义自定义构建函数 // $$：按引用传递参数的范式 @Builder myBuilderFunction($$: {title: string}) { Text($$.title) .fontColor(Color.Gray) } build() { Column(){ Row() { Text('评价 (2000)') .layoutWeight(1) .fontWeight(FontWeight.Bold) // 调用组件内自定义构建函数 // 引用传递title参数 // this.rate变化时，UI变化 this.myBuilderFunction({title: 'rate is ' + this.rate}) } .padding(10) Row() { Button('rate++') .onClick(() => { this.rate++ }) } .padding(10) } .width('100%') .height('100%') .padding(20) .backgroundColor('#ffeaeaea') } }示例效果：
AI 摘要 文章系统梳理 HarmonyOS 4.0 ArkTS 样式处理：链式与枚举语法、vp/px/fp/lpx 像素单位、layoutWeight 与 aspectRatio 适配；@Styles 全局/组件内复用通用样式，@Extend 带参扩展原生组件；stateStyles 依据 focused、pressed、disabled 等状态动态切换样式，并可与 @Styles 组合实现复用，覆盖开发中 90% 样式场景。 此摘要根据文章内容自动生成，仅用于文章内容的解释与总结样式语法链式参考文档：https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V2/arkts-declarative-ui-description-0000001524416537-V2#section43320720411属性方法以链式调用的方式配置系统组件的样式和其他属性，建议每个属性方法单独写一行。示例：链式调用样式属性Index 组件（src/main/ets/pages/Index.ets）：Text('Hello HarmonyOS') .backgroundColor('red') // 背景颜色 .fontSize(50) // 字体大小 .width('100%') // 宽度 .height(100) // 高度枚举参考文档：https://developer.huawei.com/consumer/cn/doc/harmonyos-references-V2/ts-appendix-enums-0000001478061741-V2对于系统组件，ArkUI 还为其属性预定义了一些枚举类型。示例：设置枚举样式属性Index 组件（src/main/ets/pages/Index.ets）：Text('Hello HarmonyOS') .backgroundColor(Color.Blue) // 背景颜色 .textAlign(TextAlign.Center) // 对齐方式 .fontColor(Color.White) // 文本颜色样式适配像素单位参考文档：https://developer.huawei.com/consumer/cn/doc/harmonyos-references-V2/ts-pixel-units-0000001478341189-V2HarmonyOS 为开发者提供 4 种像素单位，ArkTS 采用 vp 为基准数据单位。名称描述px物理像素单位vp虚拟像素单位，根据屏幕像素密度转换为屏幕物理像素fp字体像素lpx逻辑像素单位，为实际屏幕宽度与逻辑宽度的比值layoutWeight参考文档：https://developer.huawei.com/consumer/cn/doc/harmonyos-references-V2/ts-universal-attributes-size-0000001428061700-V2layoutWeigh 在父容器尺寸确定时，设置了 layoutWeight 属性的子元素与兄弟元素占主轴尺寸按照权重进行分配，忽略元素本身尺寸设置，表示自适应占满剩余空间。示例：layoutWeighIndex 组件（src/main/ets/pages/Index.ets）：Row() { Text('请输入手机号：') // TextInput占满行组件剩余的宽度 TextInput() .layoutWeight(1) }.padding(20)示例效果：aspectRatio参考文档：https://developer.huawei.com/consumer/cn/doc/harmonyos-references-V2/ts-universal-attributes-layout-constraints-0000001427744784-V2aspectRadio 用于指定当前组件的宽高比。示例：aspectRatioIndex 组件（src/main/ets/pages/Index.ets）：Image($r('app.media.avatar')) .width(96) .aspectRatio(1)示例效果：复用样式@Styles 复用样式参考文档：https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V2/arkts-style-0000001473856690-V2在开发过程中会出现大量代码在进行重复样式设置，@Styles 可以帮我们进行样式复用。当前 @Styles 仅支持通用属性复用和通用事件复用。支持全局定义和组件内定义，同时存在组件内覆盖全局生效。全局定义复用样式：写在 struct 声明的组件外。用 function 关键字声明。目前仅支持当前的页面组件有效。示例：全局定义复用样式Index 组件（src/main/ets/pages/Index.ets）：// 全局定义复用样式 @Styles function myStyle() { // 支持统一样式 .backgroundColor('green') .margin({bottom: 10}) // 支持通用事件 .onClick(() =>{ console.log('click') }) } @Entry @Component struct Index { build() { Row() { Column({space : 10}) { Button('Count--') // 调用自定义样式 .myStyle() Button('Count++') // 调用自定义样式 .myStyle() } .alignItems(HorizontalAlign.Start) .width('100%') } .height("100%") .padding(20) .alignItems(VerticalAlign.Top) } }示例效果：组件内定义复用样式：写在 struct 组件内。对当前的组件有效，覆盖全局同名的复用样式。不需要 function 关键字。示例：组件内定义复用样式Index 组件（src/main/ets/pages/Index.ets）：@Entry @Component struct Index { // 组件内定义复用样式 @Styles myStyle() { .backgroundColor('red') .margin({bottom: 10}) .onClick(() =>{ console.log('click') }) } build() { Row() { Column({space : 10}) { Button('Count--') // 调用自定义样式 .myStyle() Button('Count++') // 调用自定义样式 .myStyle() } .alignItems(HorizontalAlign.Start) .width('100%') } .height("100%") .padding(20) .alignItems(VerticalAlign.Top) } }示例效果：@Extend 复用样式参考文档：https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V2/arkts-extend-0000001473696678-V2@Extend 用于扩展指定的原生组件样式，通过传参提供更灵活的样式复用。使用 @Extend 装饰器修饰的函数只能是全局函数。@Extend 必须指定扩展的组件，且复用样式只针对该组件有效。复用样式函数可以进行传参，如果参数是状态变量，状态更新后会刷新 UI。参数可以是一个函数，实现复用事件且可处理不同逻辑。示例：扩展原生组件样式Index 组件（src/main/ets/pages/Index.ets）：@Extend(Text) // 指定扩展Text组件 function myStyle(color:string, cb:()=>void) { .backgroundColor(color) .padding(10) .border({radius : 6}) .onClick(cb) } @Entry @Component struct Index { build() { Row() { Column({space : 10}) { Text('Text按钮1') .myStyle('green', () => { console.log('Text1 Click') }) Text('Text按钮2') .myStyle('red', () => { console.log('Text2 Click') }) } .alignItems(HorizontalAlign.Center) .width('100%') } .height("100%") .padding(20) .alignItems(VerticalAlign.Center) } }示例效果：复用样式总结作用不同：@Styles 用来定义可复用的样式和事件，只支持通用样式和通用事件。@Extend 用来扩展指定的原生组件的样式和事件。定义方式不同：@Styles 支持全局定义和组件内定义。@Extend 只支持全局定义。传参方式不同：@Styles 不支持传参。@Extend 支持传参，参数可以是一个函数。多态样式stateStyles参考文档：https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V2/arkts-statestyles-0000001482592098-V2stateStyles 可以依据组件的内部状态的不同，快速设置不同样式。ArkUI 提供四种状态：focused 获焦态、normal 正常态、pressed 按压态、disabled 禁用态。在 HarmonyOS 中，页面初始化时默认第一个能获取焦点的元素会自动获取焦点。Button 组件可以通过 enabled 属性设置为 false，使其变成禁用态。参考文档：https://developer.huawei.com/consumer/cn/doc/harmonyos-references-V3/ts-universal-attributes-enable-0000001333321237-V3disabled 禁用态的样式，只有组件从正常态转变成禁用态时（如按钮点击后切换状态），样式才会生效。一个非 TextInput 组件无法通过点击进入 focus 状态，可以通过 focusable 属性设置为 true，并且放在第一个位置，即可进入 focus 状态。参考文档：https://developer.huawei.com/consumer/cn/doc/harmonyos-references-V3/ts-universal-attributes-focus-0000001281001274-V3示例：设置不同组件不同状态下的样式Index 组件（src/main/ets/pages/Index.ets）：@Entry @Component struct Index { build() { Row() { Column({space : 10}) { // 可以获得获焦态的第一个元素会自动获焦，故该TextInput默认获得焦点 TextInput() .stateStyles({ // 组件获焦态的样式 focused: { .backgroundColor('blue') } }) Button('按钮') .stateStyles({ // 组件正常态时的样式 normal: { .backgroundColor('green') }, // 组件按压态的样式 pressed: { .backgroundColor('red') } }) TextInput() .stateStyles({ // 当从正常态转换到禁用态时，样式生效 disabled: { .backgroundColor('black') } }) } .alignItems(HorizontalAlign.Center) .width('100%') } .height("100%") .padding(20) .alignItems(VerticalAlign.Center) } }示例效果：stateStyles + @StylesstateStyles 可以结合 @Styles 实现样式复用。示例：多态样式实现样式复用Index 组件（src/main/ets/pages/Index.ets）：@Entry @Component struct Index { @Styles greenColor() { .backgroundColor('green') } build() { Row() { Column({space : 10}) { Button('按钮') .stateStyles({ pressed: this.greenColor }) } .alignItems(HorizontalAlign.Center) .width('100%') } .height("100%") .padding(20) .alignItems(VerticalAlign.Center) } }
AI 摘要 文章系统梳理 HarmonyOS 4.0 ArkTS 组件开发基础：先回顾 JS→TS→ArkTS 演进与声明式 UI 思想；再详解 @Component、@Entry、build 结构及页面注册流程；示范 Text、Column、Row、Button、TextInput、Image 等系统组件用法与样式；最后对比普通变量与 @State 状态变量，并给出 TextInput 双向绑定完整示例，帮助开发者快速上手组件化与状态管理。 此摘要根据文章内容自动生成，仅用于文章内容的解释与总结ArkTSArkTS 简介参考文档：https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V2/arkts-get-started-0000001504769321-V2ArkTS 是 HarmonyOS 的主力应用开发语言。ArkTS 围绕应用开发在 TypeScript 生态基础上做了进一步扩展，继承了 TypeScript 的所有特性，是 TypeScript 的超集。JS、TS、ArkTS 的历史：JavaScript 由 Mozilla 创建，最初用于解决网页逻辑交互问题，成为 Web 开发基础。TypeScript 由 Microsoft 创建，旨在增强 JavaScript，引入类型系统、类型检查等，提高大型应用程序的可维护性。React.js 和 Vue.js 等前端框架引入了声明式 UI 和响应式编程的概念，使 Web 应用程序更容易开发和维护。ArkTS 建立在 JS 和 TS 的基础之上，扩展了声明式 UI 开发范式和状态管理，提供更简洁和自然的开发方式。声明式 UI参考文档：https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V2/arkts-declarative-ui-description-0000001524416537-V2声明式 UI 是一种编程范式，开发者只需要告诉程序希望界面呈现什么样的结果，而不需要告诉它具体如何去一步步实现这个界面。声明式 UI 的思想：描述 UI 的呈现结果，而不关心过程。状态驱动视图更新。组件结构基础组件结构参考文档：https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V2/start-with-ets-stage-0000001477980905-V2#ZH-CN_TOPIC_0000001523985912__arkts%E5%B7%A5%E7%A8%8B%E7%9B%AE%E5%BD%95%E7%BB%93%E6%9E%84stage%E6%A8%A1%E5%9E%8Bets 文件代码的基本结构：基础组件的构成：ArkTS 通过装饰器 @Component 和 @Entry 装饰 struct 关键字声明的数据结构，构成页面组件。自定义组件中提供了一个 build 函数，开发者需在该函数内以链式调用的方式进行基本的 UI 描述，UI 描述的方法请参考 UI 描述规范。在组件中，UI 描述的 build 方法必须实现，并且里面有且只能有一个根元素。页面组件参考文档：https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V2/start-with-ets-stage-0000001477980905-V2#ZH-CN_TOPIC_0000001523985912__%E6%9E%84%E5%BB%BA%E7%AC%AC%E4%BA%8C%E4%B8%AA%E9%A1%B5%E9%9D%A2在 DevEco Studio 中，右键 pages 文件夹 → 新建 → Page，可以快速新建一个页面组件。所有的页面都要在 src/main/resources/base/profile/main_pages.json 中存在配置。{ "src": [ "pages/Index" ] }在页面中自定义组件参考文档：https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V2/arkts-create-custom-components-0000001473537046-V2在页面组件中，可以将通用的部分抽取成一个公共的组件。示例：在页面中定义 Footer 组件Index 组件（src/main/ets/pages/Index.ets）：// 定义Footer组件 @Component struct Footer { build() { Text('Footer') } } @Entry @Component struct Index { build() { Column() { // 在页面中调用组件 Footer() } } }示例效果：将组件抽取到一个 ets 文件为了更好地维护组件，自定义组件通常会新建为一个 ets 文件，并放在 ets/components 文件夹下。示例：将 Footer 组件抽取到一个 ets 文件Footer 组件（src/main/ets/components/Footer.ets）：@Preview // 用于在预览模式下预览该组件 @Component // export default导出组件 export default struct Footer { build() { Column() { Text('Footer') } } }Index 组件（src/main/ets/Index.ets）：// import导入组件 import Footer from './components/Footer.ets' @Entry @Component struct Index { build() { Column() { // 在页面中调用组件 Footer() } } }系统组件Text 文本组件参考文档：https://developer.huawei.com/consumer/cn/doc/harmonyos-references-V2/ts-basic-components-text-0000001477981201-V2Text 文本组件用于显示一段文本。Text 文本组件的基本用法：Text(content?: string | Resource)Text 文本组件的基本参数：名称类型描述contentstring/Resource文本内容Text 文本组件的基本样式属性：名称类型描述textAlignTextAlign文本水平对齐方式，默认值为 TextAlign.StartlineHeightstring/number/Resource文本行高示例：Text 文本组件Index 组件（src/main/ets/pages/Index.ets）：Text('Hello HarmonyOS') .fontSize(50) // 字体大小 .fontWeight(FontWeight.Bold) // 字体粗细 .lineHeight(60) // 行高示例效果：Column 列组件参考文档：https://developer.huawei.com/consumer/cn/doc/harmonyos-references-V2/ts-container-column-0000001478341157-V2Column 列组件用于创建沿垂直方向布局的容器。Column 列组件的基本用法：Column(value?: {space?: string | number})Column 列组件的基本参数：名称类型描述spacestring/number纵向布局元素垂直方向间距Column 列组件的基本样式属性：名称类型描述alignItemsHorizontalAlign子组件水平方向上的对齐格式，默认值为 HorizontalAlign.CenterjustifyContentFlexAlign子组件在垂直方向上的对齐格式，默认值为 FlexAlign.Start示例：Column 列组件Index 组件（src/main/ets/pages/Index.ets）：Column() { Text('Hello HarmonyOS') .fontSize(22) } .width('100%') // 宽度 .alignItems(HorizontalAlign.Start) // 水平居左 .justifyContent(FlexAlign.Start) // 垂直居上示例效果：Row 行组件参考文档：https://developer.huawei.com/consumer/cn/doc/harmonyos-references-V2/ts-container-row-0000001478061717-V2Row 行组件用于创建沿水平方向布局的容器。Row 行组件的基本用法：Row(value?:{space?: number | string })Row 行组件的基本参数：名称类型描述spacestring/number横向布局元素垂直方向间距Row 行组件的基本样式属性：名称类型描述alignItemsVerticalAlign子组件在垂直方向上的对齐格式，默认值为 VerticalAlign.CenterjustifyContentFlexAlign子组件在水平方向上的对齐格式，默认值为 FlexAlign.Start示例：Row 行组件Index 组件（src/main/ets/pages/Index.ets）：Row() { Text('Hello HarmonyOS') .fontSize(22) } .alignItems(VerticalAlign.Top) // 垂直居上 .justifyContent(FlexAlign.Center) // 水平居中 .width('100%')示例效果：Button 按钮组件参考文档：https://developer.huawei.com/consumer/cn/doc/harmonyos-references-V2/ts-basic-components-button-0000001427584848-V2Button 按钮组件用于快速创建不同样式的按钮。Button 按钮组件的基本用法：Button(options?: {type?: ButtonType, stateEffect?: boolean}) Button(label?: ResourceStr, options?: { type?: ButtonType, stateEffect?: boolean })Button 按钮组件的基本参数：名称类型描述labelResourceStr按钮的文本内容options{ type?: ButtonType, stateEffect?: boolean }按钮的配置信息typeButtonType按钮显示样式，默认值为 ButtonType.CapsulestateEffectboolean按钮按下时是否开启按压态显示效果，默认值为 trueButton 按钮组件的基本样式属性：名称类型描述typeButtonType同上stateEffectboolean同上Button 按钮组件的基本事件：名称描述onClick(event: (event?: ClickEvent) => void)点击事件event：按钮点击时触发的方法stateEffect同上示例：Button 按钮组件Index 组件（src/main/ets/pages/Index.ets）：// 普通按钮 Button('Button') // 圆形按钮 Button('Button', { type: ButtonType.Circle }) Button('Button') .type(ButtonType.Circle) // 按钮点击事件 Button('Button') .onClick(() => { console.log('Button click') })示例效果：TextInput 单行文本框组件参考文档：https://developer.huawei.com/consumer/cn/doc/harmonyos-references-V2/ts-basic-components-textinput-0000001427584864-V2TextInput 单行文本框组件用于快速创建单行文本输入框。TextInput 单行文本框组件的基本用法：TextInput(value?:{placeholder?: ResourceStr, text?: ResourceStr, controller?: TextInputController})TextInput 单行文本框组件的基本参数：名称类型描述placeholderResourceStr输入框的提示文本textResourceStr输入框的文本内容TextInput 单行文本框组件的基本样式属性：名称类型描述typeInputType输入框类型，默认值为 InputType.NormalmaxLengthnumber文本的最大输入字符数TextInput 单行文本框组件的基本事件：名称描述onChange(callback: (value: string) => void)输入内容发生变化时，触发该回调callback：内容发生变化时触发的方法value：输入的文本内容示例：TextInput 单行文本框组件Index 组件（src/main/ets/pages/Index.ets）：// 普通的单行文本框 TextInput({placeholder: '请输入手机号'}) // 密码类型的单行文本框 TextInput() .type(InputType.Password) // 单行文本框内容变化回调事件 TextInput() .onChange((value) => { console.log('new value is ' + value) })示例效果：Image 图片组件参考文档：https://developer.huawei.com/consumer/cn/doc/harmonyos-references-V2/ts-basic-components-image-0000001428061728-V2Image 图片组件常用于在应用中显示图片。Image 图片组件的基本用法：Image(src: string | PixelMap | Resource)Image 图片组件的基本参数：名称类型描述srcstring/PixelMap/Resource图片的数据源Image 图片组件的基本样式属性：名称类型描述objectFitImageFit图片的填充效果，默认值为 ImageFit.CoverfillColorResourceColor设置填充颜色，仅对 svg 图源生效示例：Image 图片组件Index 组件（src/main/ets/pages/Index.ets）：Image($r('app.media.avatar')) .width(50) Image($r('app.media.ic_public_heart')) .fillColor('#c3c44c5') .width(50)示例效果：组件状态基础组件变量组件变量不具备驱动 UI 更新能力。示例：组件变量Index 组件（src/main/ets/pages/Index.ets）：@Entry @Component struct Index { // 组件变量，数据改变，界面不会自动变化 count = 0 build() { Column(){ Text(this.count.toString()) Button('++') .onClick(() => { this.count++ }) } } }示例效果：状态变量参考文档：https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V2/arkts-state-0000001474017162-V2状态变量指驱动 UI 更新的数据，加上 @State 装饰器即可。示例：状态变量Index 组件（src/main/ets/pages/Index.ets）：@Entry @Component struct Index { // 组件变量，数据改变，界面自动变化 @State count: number = 0 build() { Column(){ Text(this.count.toString()) Button('++') .onClick(() => { this.count++ }) } } } 示例效果：双向数据绑定在 TextInput 组件中实现双向数据绑定：设置 TextInput 组件的 text 属性为 TextInput 绑定数据。通过 onChange 事件将状态变量与文本实时绑定，避免组件刷新时 TextArea 中的文本内容异常。示例：在 TextInput 组件中实现双向数据绑定Index 组件（src/main/ets/pages/Index.ets）：@Entry @Component struct Index { @State phone:string = '' build() { Row() { Column({space: 10}) { Row() { // TextInput双向数据绑定： // 1、通过onChange事件将状态变量与文本实时绑定 // 2、通过text属性设置输入框的文本内容 TextInput({text: this.phone, placeholder: '请输入手机号'}) .onChange((value) => {this.phone = value}) } Row() { Button('重置') .backgroundColor('#CCCCCC') .margin(10) .onClick(() => { this.phone = '' }) Button('登录') .margin(10) .onClick(() => { console.log('success') }) } Row() { Text('输入的手机号：' + this.phone) } } .width('100%') } .height("100%") .padding(20) .alignItems(VerticalAlign.Top) } }示例效果：
AI 摘要 文章面向 HarmonyOS 4.0 新手，系统梳理开发环境搭建全流程：先回顾 HarmonyOS 1.0→Next 演进，再详解 DevEco Studio 下载、安装与汉化；随后以 Hello 项目为例，示范模板选择、项目信息配置及 Stage 模型工程结构；最后对比 Previewer、Local/Remote Emulator、Remote/Loca 此摘要根据文章内容自动生成，仅用于文章内容的解释与总结HarmonyOS 开发环境前言本课所使用的版本为 HarmonyOS 开发者 3.1/4.0，对应 API 能力级别为 API 9 Release。本课适合快速入门上手，且 HarmonyOS 开发更新迭代速度较快。建议学习的过程中结合文档中心进行学习。3.1/4.0 版本文档：https://developer.huawei.com/consumer/cn/hmos/overview/?catalogVersion=V2HarmonyOS 简介HarmonyOS：新一代的智能终端操作系统，为不同设备的智能化、互联与协同提供了统一的语言，带来简洁，流畅，连续，安全可靠的全场景交互体验。HarmonyOS 发展历程：时间事件2019 年HarmonyOS 1.0，华为在东莞举行华为开发者大会，正式发布操作系统鸿蒙 OS，主要用于物联网2020 年HarmonyOS 2.0，基于开源项目 OpenHarmony 开发的面向多种全场景智能设备的商用版本2021 年HarmonyOS 3.0，先后优化游戏流畅度、地图三维体验、系统安全，另外系统的稳定性也得到了增强2023 年HarmonyOS 3.1，系统纯净能力进一步提升，对后台弹窗、 隐藏应用、后台跳转等情况2024 年HarmonyOS Next 即将发布，将不在兼容安卓应用HarmonyOS 开发套件DevEco Studio下载 DevEco Studio：https://developer.huawei.com/consumer/cn/deveco-studio/archive/安装 DevEco Studio：https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V2/environment_config-0000001052902427-V2汉化 DevEco Studio：DevEco Studio 自带汉化插件，在插件中心即可启用。Hello HarmonyOS新建项目新建项目，选择项目模板。项目信息配置参考文档：https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V2/create_new_project-0000001053342414-V2填写项目信息。项目的基本信息：名称描述Project name项目名称，由大小写字母、数字和下划线组成Bundle name项目的包名Save location本地存储路径，由大小写字母、数字和下划线等组成，不能包含中文Complie SDK鸿蒙 SDK 版本Model应用模型，可选 Stage（推荐）/ FA参考文档：https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V2/application-model-description-0000001493584092-V2Enable Suoer Visual是否开启低代码开发模式Language开发语言，可选 ArkTSCompatible SDK兼容 SDK 版本Device type适配的设备类型，可选手机/平板项目工程结构参考文档：https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V2/application-package-structure-stage-0000001478061425-V2了解创建后的工程项目结构。项目的基本结构：名称描述entryModule 应用包文件夹entry/src/main/etsUIAbilityentry/src/main/ets/pages页面代码文件夹entry/src/main/resources资源文件夹参考文档：https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V2/resource-categories-and-access-0000001711674888-V2entry/src/main/resources/media静态资源（如图片）文件夹预览与调试DevEco Studio 支持 5 种调试模式。1、Previewer 预览模式。参考文档：https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V2/previewer-0000001054328973-V2场景：静态页面、没有组件间数据通信、不涉及到网络请求。条件：有 @Entry 或 @Preview 装饰器的页面或组件。2、Local Emulator 本地模拟器。参考文档：https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V2/run_simulator-0000001053303709-V2场景：动态页面，几乎支持全场景。条件：由于没有网络数据的交换，因此可以保持很好的流畅性和稳定性；但是需要耗费一定的计算机磁盘资源。3、Remote Emulator 远程模拟器。参考文档：https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V2/run_simulator-0000001053303709-V2场景：适合分布式应用开发调试，可利用云端资源模拟多种设备。条件：需要申请资源，每次使用时长为 2 小时，到期前可申请延长使用时间。4、Remote Device 远程真机。参考文档：https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V2/ide-remote-real-device-0000001167977777-V2场景：没有真机设备资源，可以申请远程真机，方便开发者进行调试。条件：远程真机每次释放后重新申请，服务端分配的设备都不一样，因此每次重新申请远程真机后，都需要对应用/服务重新进行签名。5、Local Device 本地真机。参考文档：https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V2/device_run-0000001053502422-V2场景：适用于 HarmonyOS 应用在真实设备上的精准测试，包括性能、兼容性、传感器交互等。条件：需通过 USB 连接方式或者 IP Connection 连接开发电脑，设备支持 HarmonyOS 且开启开发者模式。