※※ 前端必看!0 基础手把手教你鸿蒙开发(ArkTS+ArkUI 从入门到精通)附完整代码注释 + 实战案例

1. 开发环境搭建

首先需要安装DevEco Studio开发工具:

  1. 访问华为开发者网站下载最新版DevEco Studio
  2. 安装过程中选择"自定义安装",确保勾选"模拟器"组件
  3. 安装完成后启动DevEco Studio,配置JDK和SDK路径
    在这里插入图片描述

2. 第一个鸿蒙应用:Hello World

下面是一个最基础的鸿蒙应用代码,使用ArkTS语言编写:

// pages/Index.ets
import router from '@ohos.router';

@Entry  // 标记为应用入口页面
@Component  // 声明为组件
struct Index {
  build() {  // 组件构建函数
    Column() {  // 创建垂直布局容器
      Text('Hello World')  // 创建文本组件
        .fontSize(50)  // 设置字体大小
        .fontWeight(FontWeight.Bold)  // 设置字体加粗
        .margin({ top: 100 })  // 设置顶部边距
      
      Button('点击跳转')  // 创建按钮组件
        .margin({ top: 50 })  // 设置顶部边距
        .onClick(() => {  // 绑定点击事件
          router.pushUrl({  // 路由跳转
            url: 'pages/Second'  // 目标页面路径
          })
        })
    }
    .width('100%')  // 设置容器宽度为100%
    .height('100%')  // 设置容器高度为100%
    .backgroundColor('#F5F5F5')  // 设置背景颜色
  }
}

这个代码创建了一个简单的页面,包含一个标题和一个按钮。按钮点击后会跳转到另一个页面。

3. 鸿蒙UI组件基础

鸿蒙提供了丰富的UI组件,下面是一个综合示例:

// pages/ComponentsDemo.ets
import router from '@ohos.router';

@Entry
@Component
struct ComponentsDemo {
  @State message: string = '组件演示';  // 声明响应式状态变量
  @State count: number = 0;  // 声明计数器变量
  
  build() {
    Column() {
      // 标题区域
      Text(this.message)
        .fontSize(30)
        .fontWeight(FontWeight.Bold)
        .margin({ top: 20 })
      
      // 文本输入框
      TextField({
        placeholder: '请输入文本',
        onInput: (value: string) => {  // 绑定输入事件
          this.message = value;  // 更新状态变量
        }
      })
      .width('80%')
      .margin({ top: 20 })
      
      // 图片组件
      Image($r('app.media.sample'))  // 加载应用资源中的图片
        .width(200)
        .height(200)
        .objectFit(ImageFit.Contain)  // 设置图片适应方式
        .margin({ top: 20 })
      
      // 开关组件
      Switch({
        isOn: this.count % 2 === 0,  // 根据计数器值设置开关状态
        onChange: (isOn: boolean) => {  // 绑定状态变化事件
          this.count = isOn ? this.count + 1 : this.count - 1;
        }
      })
      .margin({ top: 20 })
      
      // 列表组件
      List() {
        ForEach([1, 2, 3, 4, 5], (item: number) => {  // 循环创建列表项
          ListItem() {
            Text(`列表项 ${item}`)
              .fontSize(20)
              .width('100%')
              .height(50)
              .textAlign(TextAlign.Center)
          }
          .backgroundColor(item % 2 === 0 ? '#E0E0E0' : '#FFFFFF')
        })
      }
      .width('90%')
      .height(200)
      .margin({ top: 20 })
      
      // 按钮组
      Row() {
        Button('增加计数')
          .onClick(() => {  // 绑定点击事件
            this.count++;  // 增加计数器值
          })
        
        Button('重置')
          .onClick(() => {  // 绑定点击事件
            this.count = 0;  // 重置计数器
            this.message = '组件演示';  // 重置文本
          })
      }
      .width('80%')
      .justifyContent(FlexAlign.SpaceAround)  // 水平均匀分布
      .margin({ top: 20 })
      
      // 显示计数结果
      Text(`当前计数: ${this.count}`)
        .fontSize(25)
        .margin({ top: 20 })
    }
    .width('100%')
    .height('100%')
    .backgroundColor('#F5F5F5')
    .padding(20)  // 设置内边距
    .alignItems(HorizontalAlign.Center)  // 水平居中对齐
  }
}

以上展示了鸿蒙中常见的UI组件使用方法,包括文本输入框、图片、开关、列表和按钮等。

4. 状态管理与事件处理

鸿蒙应用中使用@State装饰器实现响应式状态管理:

// pages/TodoList.ets
import router from '@ohos.router';

// 定义待办事项数据结构
interface TodoItem {
  id: number;
  text: string;
  completed: boolean;
}

@Entry
@Component
struct TodoList {
  @State todos: TodoItem[] = [  // 声明待办事项列表状态
    { id: 1, text: '学习鸿蒙开发', completed: false },
    { id: 2, text: '完成示例项目', completed: false },
    { id: 3, text: '提交应用', completed: false }
  ];
  
  @State newTodoText: string = '';  // 声明新待办事项文本状态
  @State filter: 'all' | 'active' | 'completed' = 'all';  // 声明筛选状态
  
  // 添加新待办事项方法
  addTodo() {
    if (this.newTodoText.trim() === '') return;
    
    const newTodo: TodoItem = {
      id: Date.now(),  // 使用时间戳作为ID
      text: this.newTodoText,
      completed: false
    };
    
    this.todos = [...this.todos, newTodo];  // 更新待办事项列表
    this.newTodoText = '';  // 清空输入框
  }
  
  // 切换待办事项完成状态方法
  toggleTodo(id: number) {
    this.todos = this.todos.map(todo => 
      todo.id === id ? { ...todo, completed: !todo.completed } : todo
    );
  }
  
  // 删除待办事项方法
  deleteTodo(id: number) {
    this.todos = this.todos.filter(todo => todo.id !== id);
  }
  
  // 获取筛选后的待办事项
  getFilteredTodos() {
    if (this.filter === 'active') {
      return this.todos.filter(todo => !todo.completed);
    } else if (this.filter === 'completed') {
      return this.todos.filter(todo => todo.completed);
    }
    return this.todos;
  }
  
  build() {
    Column() {
      // 标题
      Text('待办事项列表')
        .fontSize(30)
        .fontWeight(FontWeight.Bold)
        .margin({ top: 20 })
      
      // 输入区域
      Row() {
        TextField({
          placeholder: '添加新待办事项',
          onInput: (value: string) => {
            this.newTodoText = value;
          }
        })
        .width('70%')
        
        Button('添加')
          .onClick(() => this.addTodo())  // 绑定添加方法
          .width('25%')
      }
      .width('90%')
      .margin({ top: 20 })
      
      // 筛选按钮组
      Row() {
        ['全部', '未完成', '已完成'].forEach((label, index) => {
          const filterValue = ['all', 'active', 'completed'][index];
          
          Button(label)
            .backgroundColor(this.filter === filterValue ? '#4CAF50' : '#FFFFFF')
            .fontColor(this.filter === filterValue ? '#FFFFFF' : '#000000')
            .onClick(() => {
              this.filter = filterValue as 'all' | 'active' | 'completed';
            })
        })
      }
      .width('90%')
      .justifyContent(FlexAlign.SpaceAround)
      .margin({ top: 20 })
      
      // 待办事项列表
      List() {
        ForEach(this.getFilteredTodos(), (todo: TodoItem) => {
          ListItem() {
            Row() {
              Checkbox({
                isChecked: todo.completed,
                onChange: () => this.toggleTodo(todo.id)  // 绑定切换状态方法
              })
              
              Text(todo.text)
                .fontSize(20)
                .fontColor(todo.completed ? '#9E9E9E' : '#000000')
                .strikethrough(todo.completed)  // 已完成的任务添加删除线
              
              Button('删除')
                .backgroundColor('#F44336')
                .fontColor('#FFFFFF')
                .onClick(() => this.deleteTodo(todo.id))  // 绑定删除方法
            }
            .width('100%')
            .justifyContent(FlexAlign.SpaceBetween)
          }
          .backgroundColor(todo.id % 2 === 0 ? '#E0E0E0' : '#FFFFFF')
        })
      }
      .width('90%')
      .height(300)
      .margin({ top: 20 })
      
      // 统计信息
      Text(`总共: ${this.todos.length},已完成: ${this.todos.filter(t => t.completed).length}`)
        .fontSize(20)
        .margin({ top: 20 })
    }
    .width('100%')
    .height('100%')
    .backgroundColor('#F5F5F5')
    .padding(20)
    .alignItems(HorizontalAlign.Center)
  }
}

以上示例实现了一个完整的待办事项应用,包含添加、删除、标记完成和筛选等功能,展示了鸿蒙应用中状态管理和事件处理的实践。

5. 页面路由与导航

鸿蒙应用中使用router模块实现页面间的导航:

// pages/Index.ets
import router from '@ohos.router';

@Entry
@Component
struct Index {
  build() {
    Column() {
      Text('多页面应用示例')
        .fontSize(30)
        .fontWeight(FontWeight.Bold)
        .margin({ top: 50 })
      
      Button('查看商品列表')
        .margin({ top: 50 })
        .onClick(() => {
          router.pushUrl({
            url: 'pages/Products',
            params: { category: 'phones' }  // 传递参数
          });
        })
      
      Button('用户信息')
        .margin({ top: 20 })
        .onClick(() => {
          router.pushUrl({
            url: 'pages/UserInfo',
            params: { userId: 123 }  // 传递参数
          });
        })
      
      Button('设置')
        .margin({ top: 20 })
        .onClick(() => {
          router.pushUrl({ url: 'pages/Settings' });
        })
    }
    .width('100%')
    .height('100%')
    .backgroundColor('#F5F5F5')
    .alignItems(HorizontalAlign.Center)
  }
}

// pages/Products.ets
import router from '@ohos.router';

@Entry
@Component
struct Products {
  @Link category: string = '';  // 接收传递的参数
  
  build() {
    Column() {
      // 返回按钮
      Button('返回')
        .margin({ top: 20, left: 20 })
        .onClick(() => {
          router.back();  // 返回上一页
        })
      
      Text(`商品列表 - ${this.category}`)
        .fontSize(30)
        .fontWeight(FontWeight.Bold)
        .margin({ top: 30 })
      
      // 模拟商品列表
      List() {
        ForEach([1, 2, 3, 4, 5], (index: number) => {
          ListItem() {
            Column() {
              Image($r('app.media.sample'))  // 使用示例图片
                .width('100%')
                .height(150)
                .objectFit(ImageFit.Cover)
              
              Text(`商品 ${index}`)
                .fontSize(20)
                .margin({ top: 10 })
              
              Text('¥999.00')
                .fontSize(18)
                .fontColor('#FF5722')
                .margin({ top: 5 })
            }
            .width('100%')
            .padding(10)
            .backgroundColor(index % 2 === 0 ? '#E0E0E0' : '#FFFFFF')
            .onClick(() => {
              router.pushUrl({
                url: 'pages/ProductDetail',
                params: { productId: index }
              });
            })
          }
        })
      }
      .width('90%')
      .height('70%')
      .margin({ top: 20 })
    }
    .width('100%')
    .height('100%')
    .backgroundColor('#F5F5F5')
  }
}

// pages/ProductDetail.ets
import router from '@ohos.router';

@Entry
@Component
struct ProductDetail {
  @Link productId: number = 0;  // 接收传递的参数
  
  build() {
    Column() {
      // 返回按钮
      Button('返回')
        .margin({ top: 20, left: 20 })
        .onClick(() => {
          router.back();
        })
      
      Text(`商品详情 - ${this.productId}`)
        .fontSize(30)
        .fontWeight(FontWeight.Bold)
        .margin({ top: 30 })
      
      Image($r('app.media.sample'))  // 使用示例图片
        .width('90%')
        .height(300)
        .objectFit(ImageFit.Cover)
        .margin({ top: 20 })
      
      Text('高级智能手机')
        .fontSize(25)
        .margin({ top: 20, left: 20 })
      
      Text('¥999.00')
        .fontSize(30)
        .fontColor('#FF5722')
        .margin({ top: 10, left: 20 })
      
      Text('这是一款功能强大的智能手机,具有高清屏幕、超长续航和顶级相机系统。')
        .fontSize(18)
        .margin({ top: 20, left: 20, right: 20 })
      
      Button('加入购物车')
        .width('90%')
        .height(60)
        .backgroundColor('#FF5722')
        .fontColor('#FFFFFF')
        .fontSize(20)
        .margin({ top: 30 })
    }
    .width('100%')
    .height('100%')
    .backgroundColor('#F5F5F5')
  }
}

这个示例展示了如何在鸿蒙应用中实现多页面导航,包括页面间的参数传递和返回功能。

6. 网络请求与数据处理

鸿蒙应用中可以使用fetch API进行网络请求:

// pages/NewsList.ets
import router from '@ohos.router';
import http from '@ohos.net.http';

@Entry
@Component
struct NewsList {
  @State newsList: Array<{ title: string; content: string; time: string }> = [];
  @State isLoading: boolean = true;
  @State errorMessage: string = '';
  
  aboutToAppear() {
    this.fetchNews();  // 页面加载时获取新闻数据
  }
  
  // 获取新闻数据方法
  fetchNews() {
    this.isLoading = true;
    this.errorMessage = '';
    
    // 创建HTTP请求
    let httpRequest = http.createHttp();
    
    // 配置请求参数
    let requestOptions = {
      method: http.RequestMethod.GET,
      readTimeout: 60000,
      connectTimeout: 60000,
      header: {
        'Content-Type': 'application/json'
      }
    };
    
    // 发送请求
    httpRequest.request(
      'https://api.example.com/news',  // 示例API地址
      requestOptions,
      (err, response) => {
        if (err) {
          this.errorMessage = '获取新闻失败: ' + err.message;
          this.isLoading = false;
          return;
        }
        
        if (response.responseCode === 200) {
          try {
            // 解析响应数据
            const result = JSON.parse(response.result.toString());
            this.newsList = result.data || [];
          } catch (e) {
            this.errorMessage = '解析数据失败';
          }
        } else {
          this.errorMessage = '服务器返回错误: ' + response.responseCode;
        }
        
        this.isLoading = false;
      }
    );
  }
  
  build() {
    Column() {
      // 返回按钮
      Button('返回')
        .margin({ top: 20, left: 20 })
        .onClick(() => {
          router.back();
        })
      
      Text('新闻列表')
        .fontSize(30)
        .fontWeight(FontWeight.Bold)
        .margin({ top: 30 })
      
      // 加载状态显示
      if (this.isLoading) {
        Column() {
          Text('加载中...')
            .fontSize(20)
          
          ProgressBar()  // 进度条组件
            .width('50%')
            .color('#4CAF50')
            .margin({ top: 20 })
        }
        .width('100%')
        .height('50%')
        .justifyContent(FlexAlign.Center)
        .alignItems(HorizontalAlign.Center)
      }
      
      // 错误信息显示
      if (this.errorMessage) {
        Text(this.errorMessage)
          .fontSize(20)
          .fontColor('#F44336')
          .margin({ top: 20 })
          .onClick(() => this.fetchNews())  // 点击重试
      }
      
      // 新闻列表显示
      if (!this.isLoading && !this.errorMessage && this.newsList.length > 0) {
        List() {
          ForEach(this.newsList, (news, index) => {
            ListItem() {
              Column() {
                Text(news.title)
                  .fontSize(22)
                  .fontWeight(FontWeight.Bold)
                  .margin({ top: 10 })
                
                Text(news.content.length > 100 ? news.content.substring(0, 100) + '...' : news.content)
                  .fontSize(18)
                  .margin({ top: 10 })
                
                Text(news.time)
                  .fontSize(16)
                  .fontColor('#757575')
                  .margin({ top: 10 })
              }
              .width('100%')
              .padding(15)
              .backgroundColor(index % 2 === 0 ? '#E0E0E0' : '#FFFFFF')
            }
          })
        }
        .width('90%')
        .height('70%')
        .margin({ top: 20 })
      }
      
      // 空列表显示
      if (!this.isLoading && !this.errorMessage && this.newsList.length === 0) {
        Text('暂无新闻')
          .fontSize(20)
          .margin({ top: 20 })
      }
    }
    .width('100%')
    .height('100%')
    .backgroundColor('#F5F5F5')
  }
}

以上展示了如何在鸿蒙应用中进行网络请求,处理加载状态和错误情况,并将获取的数据展示在界面上。

7. 鸿蒙组件化开发

鸿蒙应用鼓励组件化开发,组件复用的示例:

// components/MyButton.ets
@Component
struct MyButton {
  @Link text: string = '按钮';  // 接收外部传入的文本
  @Link onClick: () => void = () => {};  // 接收外部传入的点击回调
  
  build() {
    Button(this.text)
      .width('80%')
      .height(50)
      .backgroundColor('#4CAF50')
      .fontColor('#FFFFFF')
      .fontSize(18)
      .onClick(() => {
        this.onClick();  // 触发外部传入的回调
      })
  }
}

// components/MyCard.ets
@Component
struct MyCard {
  @Link title: string = '标题';
  @Link content: string = '内容';
  @Link imageSource: ResourceStr = $r('app.media.sample');
  
  build() {
    Stack() {
      // 卡片背景
      Rectangle()
        .width('90%')
        .height(200)
        .radius(10)
        .fill('#FFFFFF')
        .shadow({
          offsetX: 2,
          offsetY: 2,
          blurRadius: 10,
          color: '#888888'
        })
      
      // 卡片内容
      Column() {
        Image(this.imageSource)
          .width('100%')
          .height(120)
          .objectFit(ImageFit.Cover)
          .borderRadius({ topLeft: 10, topRight: 10 })
        
        Text(this.title)
          .fontSize(20)
          .fontWeight(FontWeight.Bold)
          .margin({ top: 10, left: 10 })
          .width('90%')
          .maxLines(1)
          .overflow(TextOverflow.Ellipsis)
        
        Text(this.content)
          .fontSize(16)
          .margin({ top: 5, left: 10, right: 10 })
          .width('90%')
          .maxLines(1)
          .overflow(TextOverflow.Ellipsis)
      }
      .width('90%')
    }
    .width('100%')
    .height(200)
    .margin({ top: 20 })
  }
}

// pages/ComponentDemo.ets
import router from '@ohos.router';
import { MyButton } from '../components/MyButton';
import { MyCard } from '../components/MyCard';

@Entry
@Component
struct ComponentDemo {
  @State count: number = 0;
  
  increment() {
    this.count++;
  }
  
  build() {
    Column() {
      // 返回按钮
      Button('返回')
        .margin({ top: 20, left: 20 })
        .onClick(() => {
          router.back();
        })
      
      Text('组件复用演示')
        .fontSize(30)
        .fontWeight(FontWeight.Bold)
        .margin({ top: 30 })
      
      // 使用自定义按钮组件
      MyButton({
        text: '点击增加',
        onClick: () => this.increment()
      })
      .margin({ top: 20 })
      
      // 显示计数
      Text(`计数: ${this.count}`)
        .fontSize(25)
        .margin({ top: 20 })
      
      // 使用自定义卡片组件
      MyCard({
        title: '新闻标题1',
        content: '这是一条重要的新闻内容,包含了最新的科技动态。',
        imageSource: $r('app.media.sample')
      })
      
      MyCard({
        title: '新闻标题2',
        content: '另一条新闻内容,讨论了人工智能的发展前景。',
        imageSource: $r('app.media.sample')
      })
    }
    .width('100%')
    .height('100%')
    .backgroundColor('#F5F5F5')
  }
}

可复用的组件,并在不同的页面中使用它们,提高代码的可维护性和复用性。

8. 学习建议

  1. 首先熟悉ArkTS语言的基础语法,特别是装饰器和响应式编程的概念
  2. 掌握鸿蒙UI组件的使用方法,了解各种布局容器和控件
  3. 学习状态管理和事件处理,这是构建交互应用的基础
  4. 多做练习,尝试实现各种功能,从简单到复杂
  5. 参考官方文档和示例代码,华为开发者网站提供了丰富的学习资源
  6. 进阶参考文献《鸿蒙 ArkTS 实战!手把手复刻微信全功能页面(含底部导航 / 聊天列表 / 通讯录)》
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

生活De°咸鱼

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值