当前位置: 首页 > news >正文

互联网兼职做网站维护做ui设计用什么素材网站

互联网兼职做网站维护,做ui设计用什么素材网站,南通的电商网站建设,wordpress添加主题设置选项好的,请看这篇关于 HarmonyOS 应用开发中核心开发范式——ArkTS 声明式 UI 与状态管理的技术文章。 深入浅出 HarmonyOS 应用开发:ArkTS 声明式 UI 与状态管理最佳实践 引言 随着 HarmonyOS 4、5 的持续迭代以及面向未来的 HarmonyOS NEXT 的发布&…

好的,请看这篇关于 HarmonyOS 应用开发中核心开发范式——ArkTS 声明式 UI 与状态管理的技术文章。

深入浅出 HarmonyOS 应用开发:ArkTS 声明式 UI 与状态管理最佳实践

引言

随着 HarmonyOS 4、5 的持续迭代以及面向未来的 HarmonyOS NEXT 的发布,华为的鸿蒙生态正式进入了独立发展的快车道。对于开发者而言,基于 API 12 及以上的应用开发已成为主流。其核心开发语言 ArkTS,作为 TypeScript 的超集,结合了声明式 UI 和状态管理的现代化前端开发理念,极大地提升了开发效率和应用的性能表现。

本文将深入探讨基于 ArkTS 的声明式 UI 开发范式,并聚焦于其核心:状态管理。我们将通过一个具体的任务管理(Todo)应用示例,剖析 @State, @Prop, @Link, @Provide/@Consume 等装饰器的使用场景、区别以及最佳实践,助力开发者构建高性能、可维护的鸿蒙应用。


一、ArkTS 与声明式 UI 基础

ArkTS 的 UI 开发范式是声明式的。与传统的命令式(如 Android 的 XML + Java)相比,开发者无需关心 UI 组件的具体创建和更新步骤,只需描述当前状态下的 UI 应该是什么样子。当应用的状态(State)发生变化时,框架会自动、高效地更新 UI。

一个简单的声明式 UI 组件

// TaskListItem.ets
@Component
export struct TaskListItem {// 使用 @State 装饰器表示组件的内部状态@State isComplete: boolean = false;private taskName: string;build() {// UI 描述依赖于状态 isCompleteRow() {Image(this.isComplete ? $r('app.media.ic_checked') : $r('app.media.ic_unchecked')).onClick(() => {// 改变状态,UI 会自动更新this.isComplete = !this.isComplete;})Text(this.taskName).decoration({ type: this.isComplete ? TextDecorationType.LineThrough : TextDecorationType.None })}.padding(12)}
}

代码解析

  • @State 装饰的 isComplete 变量是该组件的内部状态。
  • 当用户点击 Image 时,onClick 事件处理函数改变了 isComplete 的值。
  • 状态变化触发组件的重新渲染(build 方法再次被调用),UI 根据新的状态自动更新了图片和文本样式。

这种“数据驱动视图”的模式是声明式 UI 的基石。


二、状态管理装饰器深度解析

在复杂的应用中,状态往往需要在不同层级的组件间传递和共享。ArkTS 提供了一系列装饰器来实现灵活的状态管理。

1. @State:组件内部状态

作用:用于组件内部管理的状态,状态变化会引起该组件及其子组件的重新渲染。 最佳实践:适用于完全封装在组件内部,不需要传递给父组件或其他兄弟组件的状态。

@Component
struct ParentComponent {@State parentCount: number = 0;build() {Column() {Text(`Parent Count: ${this.parentCount}`)Button('Increment in Parent').onClick(() => {this.parentCount += 1; // 改变父组件的状态})// 将父组件的状态传递给子组件ChildComponent({ countFromParent: this.parentCount })}}
}@Component
struct ChildComponent {// 使用 @Prop 接收来自父组件的数据@Prop countFromParent: number;build() {Text(`Child Received: ${this.countFromParent}`) // 子组件会随父组件状态更新而更新}
}

2. @Prop:单向同步

作用:从父组件单向同步数据到子组件。子组件可以修改 @Prop 变量,但不会回传给父组件,只会更新子组件自身的 UI。 最佳实践:适用于父组件传递原始数据或简单对象给子组件,且子组件的修改不需要影响父组件源数据的场景。类似于“副本”。

@Component
struct ChildComponent {@Prop countFromParent: number;@State private localCount: number = 0;build() {Column() {Text(`From Parent: ${this.countFromParent}`)Text(`Local: ${this.localCount}`)Button('Modify @Prop (only affects child)').onClick(() => {this.countFromParent += 1; // 不会影响父组件的 parentCount})Button('Modify Local State').onClick(() => {this.localCount += 1;})}}
}

3. @Link:双向同步

作用:建立父子组件之间的双向数据同步。任何一方对数据的修改都会导致另一方的数据源和 UI 更新。 最佳实践:适用于需要子组件和父组件共同维护同一份数据的场景,如表单输入、开关切换等。

@Component
struct ParentComponent {@State parentCount: number = 0;build() {Column() {Text(`Parent Count: ${this.parentCount}`)// 使用 $ 操作符创建双向绑定ChildWithLinkComponent({ countLink: $parentCount })}}
}@Component
struct ChildWithLinkComponent {@Link countLink: number; // 与父组件的 parentCount 双向绑定build() {Button('Increment in Child via @Link').onClick(() => {this.countLink += 1; // 此修改会同步回父组件的 parentCount})}
}

4. @Provide 和 @Consume:跨组件层级双向同步

作用:在组件树中跨层级(无需逐层传递)提供和消费数据,实现祖先组件与后代组件之间的双向同步。这是解决“prop 逐层传递”难题的利器。 最佳实践:适用于全局主题、用户信息、应用配置等在多个不相关组件间共享的数据。

// 在顶层组件(如 EntryAbility 的页面组件)提供数据
@Component
struct RootComponent {// 通过 @Provide 装饰器提供 'themeSize' 数据@Provide('themeSize') themeFontSize: number = 16;build() {Column() {Text('Root Component').fontSize(this.themeFontSize)Button('Enlarge Root Font').onClick(() => {this.themeFontSize += 2; // 修改会通知所有消费者})// 中间可能嵌套很多层组件...DeeplyNestedChildComponent()}}
}// 在深层嵌套的子组件中直接消费数据
@Component
struct DeeplyNestedChildComponent {// 通过 @Consume 装饰器消费 'themeSize' 数据@Consume('themeSize') consumedFontSize: number;build() {Column() {Text('Deep Child Component').fontSize(this.consumedFontSize) // 直接使用消费的数据Button('Enlarge from Deep Child').onClick(() => {this.consumedFontSize += 2; // 修改会同步回提供者 RootComponent})}}
}

三、综合实践:构建一个任务管理应用

让我们综合运用上述概念,构建一个简单的任务列表。

1. 定义数据模型

// model/Task.ets
export class Task {id: string;title: string;isCompleted: boolean = false;constructor(title: string) {this.id = Math.random().toString(36).substring(2, 9);this.title = title;}
}

2. 父组件(页面级,管理任务列表)

// Index.ets
@Entry
@Component
struct TaskPage {// 页面级状态:任务列表@State tasks: Task[] = [];@State newTaskTitle: string = '';build() {Column() {// 输入新任务TextInput({ placeholder: 'Enter new task', text: this.newTaskTitle }).onChange((value) => {this.newTaskTitle = value;})Button('Add Task').onClick(() => {if (this.newTaskTitle.trim()) {this.tasks = [...this.tasks, new Task(this.newTaskTitle.trim())]; // 使用数组扩展运算符创建新数组,触发UI更新this.newTaskTitle = '';}})// 任务列表List({ space: 10 }) {ForEach(this.tasks, (task: Task) => {ListItem() {// 将每个 task 对象和其 id 的双向绑定传递给子项TaskListItem({ task: task, onTaskChange: $tasks })}}, (task: Task) => task.id)}.layoutWeight(1)}.padding(20)}
}

3. 子组件(单个任务项)

// TaskListItem.ets
@Component
export struct TaskListItem {// 双向绑定父组件传递的 task 对象@Link task: Task;// 接收父组件传递的整个 tasks 数组的引用,用于删除操作@Link onTaskChange: Task[];build() {Row() {// 完成状态切换Image(this.task.isCompleted ? $r('app.media.ic_checked') : $r('app.media.ic_unchecked')).onClick(() => {this.task.isCompleted = !this.task.isCompleted; // 通过 @Link 双向同步,修改会反映到父组件的 tasks 数组中})Text(this.task.title).decoration({ type: this.task.isCompleted ? TextDecorationType.LineThrough : TextDecorationType.None }).layoutWeight(1)// 删除任务Button('Delete').onClick(() => {// 从父组件传递的数组中过滤掉当前任务// 注意:这里直接修改了 onTaskChange(即父组件的 tasks),因为它是 @Linkthis.onTaskChange = this.onTaskChange.filter(t => t.id !== this.task.id);})}.padding(12).borderRadius(8).backgroundColor(Color.White).shadow({ radius: 2, color: Color.Gray, offsetX: 1, offsetY: 1 })}
}

最佳实践总结

  1. 不可变数据:在更新数组或对象时(如 TaskPage 中的 Add Task),优先使用扩展运算符 ...Array.prototype.map()/filter() 创建新的引用,而不是直接 push 或修改下标。这能确保状态变化的可检测性。
  2. 状态提升:将状态管理提升到尽可能高的、需要该状态的所有组件的共同祖先中。tasks 数组在 TaskPage 中管理,而不是在单个 TaskListItem 中。
  3. 合理的装饰器选择
    • @State 用于组件私有状态。
    • @Prop 用于单向传递的只读数据(如果需要)。
    • @Link 用于需要子组件修改父组件状态的场景(如切换完成状态、删除)。
    • @Provide/@Consume 用于真正全局的、跨多层的数据(本例未极致体现,但可想象为 ThemeUserProfile)。
  4. Key 的重要性:在 ForEach 中始终提供稳定的、唯一的 id 作为键,这是 ArkUI 高效进行差异对比(diff)和更新 UI 的关键。

结语

掌握 ArkTS 的声明式 UI 和状态管理机制,是构建现代化、高性能 HarmonyOS 应用的核心。通过合理运用 @State, @Prop, @Link, @Provide/@Consume 等装饰器,开发者可以构建出数据流清晰、易于维护和测试的复杂应用。

随着 HarmonyOS 的不断发展,其开发体验和能力也在快速演进。建议开发者持续关注 HarmonyOS Developer 官网和 ArkTS API 文档,及时了解最新的最佳实践和功能特性,从而在鸿蒙生态中打造出更卓越的应用。

http://www.dtcms.com/a/427397.html

相关文章:

  • ETL参数化技巧:如何避免写一堆重复任务?
  • git下载分支
  • Linux应用开发·Makefile菜鸟教程
  • ai智能化算法
  • 【专业词典】冰山模型
  • 第三方应用测试:【移动应用后端API自动化测试:Postman与Newman的集成】
  • 企业网站备案 淘宝客前端工程师主要做什么
  • 桌面预测类开发,桌面%雷达,信号预测%系统开发,基于python,tk,scikit-learn机器学习算法实现,桌面预支持向量机分类算法,CSV无数据库
  • 网站备案黑名单重庆新闻头条24小时
  • 使用vscode的ssh功能连接远程服务器卡在Setting up SSH Host IP: Downloading VS Code Server的解决方案
  • vscode连接算力平台
  • VSCode中Java开发环境配置的三个层级(Windows版)1-3
  • 西安建设网站的公司网页装修设计
  • 太空算力革命:卫星如何成为地面交通的“天脑“
  • 大数据 Python小说数据分析平台 小说网数据爬取分析系统 Django框架 requests爬虫 Echarts图表 17k小说网 (源码)✅
  • 第 1 天:零基础入门 C 语言 —— 认识 C 语言的起源、特点与应用场景
  • 网站建设制作公司地址网站建设费用明细
  • image process unit 模块实现防抖的原理
  • 【LeetCode 每日一题】2221. 数组的三角和
  • 爬虫之淘宝接口获取:Python 返回淘宝商品详情数据 API 接口
  • 合肥专业网站优化seo在线培训机构排名
  • 便利的聊城网站建设整站网站优化
  • C# 对Bitmap 的一些处理方法,裁剪,压缩,旋转等
  • Labview多个子VI加密码和去密码
  • LabVIEW声音压力与响度实时监测
  • 网站毕业设计选题本溪网站建设兼职
  • Python利用ffmpeg实现rtmp视频拉流和推流
  • 佛山电商网站建设软件开发流程流程图
  • 嵌入式软件开发工程师待遇seo管理员
  • cuda编程笔记(25)-- 如何像函数对象一样使用核函数