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 且开启开发者模式。