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

鸿蒙ArkTS入门教程:小白实战“易经”Demo,详解@State、@Prop与List组件

文章目录

  • 鸿蒙ArkTS入门:从0到1,我们来“算一卦”!
    • 第一站:万物皆有“模”——定义数据模型
    • 第二站:造个“小卡片”——封装自定义组件 `@Component`
    • 第三站:“投喂”数据——神奇的 `@Prop`
    • 第四站:闪亮登场!——页面入口 `@Entry`
    • 第五站:数据的“魔法”——灵魂核心 `@State`
    • 第六站:搭积木——`build`主函数
    • 第七站:复用大法好——`@Builder`封装UI片段
    • 第八站:魔法联动(上)—— 循环渲染与状态变更
    • 第九站:魔法联动(下)—— 列表筛选与数据传递
    • 收工总结

鸿蒙ArkTS入门:从0到1,我们来“算一卦”!

哈喽,各位未来的鸿蒙大神们!是不是觉得ArkTS的声明式UI看起来很炫,但又不知道从哪下手?别慌,今天我们就用一个充满“玄学”气息的小Demo——《易经初解》,带你轻松拿捏鸿蒙开发的几个核心知识点。

咱们不讲大道理,只看代码和骚操作。上车,发车!

第一站:万物皆有“模”——定义数据模型

在开始盖房子之前,总得有个图纸,对吧?在代码世界里,这个“图纸”就是我们的数据模型。我们要展示“卦象”,就得先定义一个“卦”长什么样。

这里我们用class关键字来创建一个GuaItem类,它就像一个“卦象”的模板,规定了每个卦象都有ID、名字、符号、简介、图片和分类。

// ------------------------------------------
// 1. 数据模型 (Data Model)
// ------------------------------------------
// 定义一个类来描述“卦”的数据结构
// 替代了原来的 NewsItem
class GuaItem {id: number = 0;name: string = '';       // 卦名 (如: 乾)symbol: string = '';     // 卦象 (如: ䷀)description: string = '';// 卦辞简介imageUrl: string = '';   // 图片 URL (这里用占位符代替)category: string = '';   // 分类 (上经 / 下经)constructor(id: number, name: string, symbol: string, description: string, imageUrl: string, category: string) {this.id = id;this.name = name;this.symbol = symbol;this.description = description;this.imageUrl = imageUrl;this.category = category;}
}

第二站:造个“小卡片”——封装自定义组件 @Component

有了“图纸”,我们就要开始造“零件”了。在鸿蒙开发中,UI界面就是由一个个“组件”拼起来的。@Component装饰器就像一个“组件制造机”,它告诉编译器:“嘿,我要造一个新类型的UI零件了!”

我们这个GuaCard组件,就是专门用来显示一个卦象信息的“卡片”。

// ------------------------------------------
// 2. 子组件:卦象卡片 (GuaCard)
// ------------------------------------------
// 这是一个自定义组件,用于显示单个卦象的信息
@Component
struct GuaCard {

第三站:“投喂”数据——神奇的 @Prop

光有卡片模板还不行,卡片上显示啥内容呢?总不能写死吧。

这时候,@Prop就登场了。它就像在组件上开了一个“投喂口”,父组件(后面会讲到)可以通过这个口子,把数据(比如“乾卦”的信息)塞给它。

注意看,我们用Image($r(this.gua.imageUrl))来加载本地图片资源,$r是ArkTS加载资源的“咒语”。你还很皮地把卦象符号Text(this.gua.symbol).position({ x: 220, y: 28 })定位到了右上角,这波操作很风骚!

  // 知识点: @Prop// @Prop 装饰的变量允许父组件向本组件传递数据。// 这是父子组件通信的“单向”数据流。@Prop gua: GuaItembuild() {// 垂直布局,卡片内的元素竖着排Column({ space: 10 }) {// 区域1: 图片// Stack 允许组件堆叠,我们把卦象符号(symbol)叠在图片(imageUrl)上Stack() {Image($r(this.gua.imageUrl)).width('100%').height(490).objectFit(ImageFit.Cover) // 图片裁剪以覆盖区域.borderRadius(10).backgroundColor('#ECECEC') // 占位图的背景色// 叠加在图片左上角的“卦象符号”Text(this.gua.symbol).fontSize(60).fontColor(Color.Red).backgroundColor('#00000080') // 半透明黑底.padding(5).borderRadius(5).position({ x: 220, y: 28 }) // 定位在右上角}// 区域2: 卦名 (如: 乾 (qián))Text(this.gua.name).fontSize(20).fontWeight(FontWeight.Bold).width('100%').textAlign(TextAlign.Start) // 文本左对齐// 区域3: 简介 (卦辞)Text(this.gua.description).fontSize(14).fontColor(Color.Gray) // 灰色字体.width('100%').maxLines(2) // 最多显示2行.textOverflow({ overflow: TextOverflow.Ellipsis }) // 超出部分显示省略号.textAlign(TextAlign.Start)}.padding(12) // 卡片内边距.backgroundColor(Color.White) // 卡片背景色.borderRadius(12) // 卡片圆角.shadow({ radius: 6, color: '#1A000000', offsetX: 0, offsetY: 2 }) // 卡片阴影.onClick(() => {// 知识点: 点击事件// 整个卡片都可以点击,点击时打印日志console.info(`你点击了: ${this.gua.name}`);// 提示:未来可以在这里使用 router.pushUrl(...) 实现页面跳转})}
}

第四站:闪亮登场!——页面入口 @Entry

零件造好了,得有个“舞台”来展示它们。@Entry装饰器就是这个“舞台”的入口大门,它告诉鸿蒙系统:“老铁,从这里开始加载页面!”

一个页面(Page)通常只有一个@Entry

// ------------------------------------------
// 3. 主页面 (YiJingDemo)
// ------------------------------------------
// 知识点: @Entry
// @Entry 标记的组件是这个页面的入口
@Entry
@Component
export struct YiJingDemo {

第五站:数据的“魔法”——灵魂核心 @State

来了来了,鸿蒙开发(或者说声明式UI)的灵魂核心——@State

@State装饰的变量,就像是被施了魔法。一旦它的值发生改变,所有用到它的UI都会自动、立刻、马上重新刷新!

我们用它来保存“卦象列表”(guaList)和“当前选中的分类”(selectedCategory)。后面你会看到,当我们点击分类按钮时,只需要改一下selectedCategory的值,下面的列表就会自动筛选,简直不要太爽!

  // --- 3.1 状态数据 (State Data) ---// 知识点: @State// @State 标记的变量是“状态变量”。// 当这个变量的值发生变化时,所有使用到它的UI都会自动重新渲染。// 《易经》数据列表@State guaList: GuaItem[] = [// 注意:请将 imageUrl 替换为你自己的真实图片 URL// 这里使用的是占位符图片服务new GuaItem(1, '乾 (qián)', '䷀', '元、亨、利、贞。象征天,刚健不息。', 'app.media.qian', '上经'),new GuaItem(2, '坤 (kūn)', '䷁', '元、亨、利、牝马之贞。象征地,厚德载物。', 'app.media.kun', '上经'),new GuaItem(3, '屯 (zhūn)', '䷂', '元、亨、利、贞。勿用有攸往。象征初生,艰难。', 'app.GuaItemmedia.zhun', '上经'),new GuaItem(4, '蒙 (méng)', '䷃', '亨。匪我求童蒙,童蒙求我。象征启蒙,教育。', 'app.media.meng', '上经'),new GuaItem(60, '节 (jié)', '䷻', '亨。苦节不可贞。象征节制,适度。', 'app.media.jie', '下经'),new GuaItem(61, '中孚 (zhōng fú)', '䷼', '豚鱼吉,利涉大川,利贞。象征诚信,中正。', 'app.media.zhongfu', '下经'),new GuaItem(62, '小过 (xiǎo guò)', '䷽', '亨,利贞。可小事,不可大事。飞鸟遗之音,不宜上,宜下,大吉。象征小过错,适度。', 'app.media.xiaoguo', '下经'),new GuaItem(63, '既济 (jì jì)', '䷾', '亨,小利贞,初吉终乱。象征完成,成功。', 'app.media.jiji', '下经'),];// 当前选中的分类@State selectedCategory: string = '全部';// 所有的分类(这是一个普通变量,因为它不需要改变)categories: string[] = ['全部', '上经', '下经'];

第六站:搭积木——build主函数

每个组件都有一个build()函数,它就是这个组件的“搭建图纸”。我们的主页面YiJingDemobuild函数非常简洁:一个垂直布局Column,里面按顺序放上“标题栏”、“分类筛选”和“卦象列表”。

  // --- 3.2 页面构建 (UI Build) ---build() {// 页面总布局: 垂直排列Column({ space: 0 }) {// 3.2.1 顶部标题this.buildTitleBar()// 3.2.2 分类筛选this.buildCategoryFilter()// 3.2.3 卦象列表this.buildGuaList()}.width('100%').height('100%').backgroundColor('#F4F4F4') // 页面背景色}

第七站:复用大法好——@Builder封装UI片段

你可能会问,buildTitleBar()这些是啥?它们是“构建函数”,被@Builder装饰器标记。

@Builder就像是帮你把一小块UI(比如标题栏)封装成一个“UI配方”,在build函数里喊一声(this.buildTitleBar()),它就把这块UI给“煮”出来了。这样做能让你的build函数保持清爽,可读性up up!

  // --- 3.3 UI 构建函数 (Builder Functions) ---// 知识点: @Builder// @Builder 标记的函数用于构建可复用的UI片段,使 build() 主体更清晰。// 3.3.1 构建标题栏 (简化版)@BuilderbuildTitleBar() {Row() {Text('易经初解').fontSize(22).fontWeight(FontWeight.Bold).fontColor(Color.Black)}.width('100%').height(56) // 标题栏高度.padding({ left: 16, right: 16 }).backgroundColor(Color.White).justifyContent(FlexAlign.Start) // 标题居左.shadow({ radius: 4, color: '#1A000000', offsetY: 1 }) // 底部加一点阴影}

第八站:魔法联动(上)—— 循环渲染与状态变更


buildCategoryFilter这里是第一个魔法发生地。

  1. 我们用Scroll实现横向滚动。
  2. ForEach遍历categories数组,把“全部”、“上经”、“下经”都造出来。
  3. 看重点fontColorbackgroundColor会根据this.selectedCategory === category来动态改变。
  4. 看重点onClick事件里,我们执行了this.selectedCategory = category;

当你点击“上经”时,@State变量selectedCategory被改成了“上经”。魔法启动!所有用到selectedCategory的地方都会刷新!

  // 3.3.2 构建分类筛选@BuilderbuildCategoryFilter() {// Scroll 用于创建可横向滚动区域Scroll() {Row({ space: 12 }) { // 横向排列,间距12// 知识点: ForEach 循环渲染列表// 遍历 this.categories 数组ForEach(this.categories, (category: string) => {Text(category).fontSize(14)// 知识点: 动态样式// 根据 selectedCategory 是否等于当前 category,来决定文字和背景颜色.fontColor(this.selectedCategory === category ? Color.White : Color.Black).backgroundColor(this.selectedCategory === category ? '#007DFF' : '#EAEAEA').padding({ left: 16, right: 16, top: 8, bottom: 8 }).borderRadius(20).onClick(() => {// 知识点: 点击事件更新 @State 变量// 当点击时,更新 selectedCategory 的值// @State 变量一变,UI会自动刷新this.selectedCategory = category;})})}.padding(16) // 整个横向滚动区域的内边距}.scrollBar(BarState.Off) // 关闭滚动条显示.backgroundColor(Color.White).margin({ top: 1 }) // 和标题栏留一点点空隙}

第九站:魔法联动(下)—— 列表筛选与数据传递

buildGuaList是第二个魔法发生地。

  1. 我们用List来创建一个可滚动的列表。
  2. 看重点ForEach的数据源不是完整的this.guaList,而是this.guaList.filter(...)
  3. 这个.filter()函数会检查我们刚刚改变的@State变量this.selectedCategory
  4. 如果selectedCategory是“全部”,它就不过滤;如果是“上经”,它就只返回category === '上经'的卦象!
  5. ForEach拿到了筛选后的数据,循环创建ListItem,并在里面放上了我们之前造的GuaCard({ gua: gua }),同时把数据通过@Prop“投喂”了进去。

整个过程全自动!我们只改了一个变量,UI就自动完成了“高亮新分类”+“筛选列表”两个操作!

  // 3.3.3 构建卦象列表@BuilderbuildGuaList() {// 知识点: List 是一个可滚动的列表容器List({ space: 12 }) { // 列表项之间的间距// 知识点: ForEach 循环渲染列表// .filter(...) 用于根据分类筛选ForEach(// 筛选逻辑:如果选中的是“全部”,则显示所有;否则只显示匹配分类的this.guaList.filter(item =>this.selectedCategory === '全部' || item.category === this.selectedCategory),// 遍历筛选后的数组(gua: GuaItem) => {// ListItem 是 List 的列表项ListItem() {// 使用我们自定义的 GuaCard 组件// 知识点: 父组件向子组件传递数据// 把遍历到的 gua 对象,通过 @Prop 传递给 GuaCardGuaCard({ gua: gua })}},// 优化: 为每一项提供一个唯一的 key (id)(gua: GuaItem) => gua.id.toString())}.width('100%').layoutWeight(1) // 知识点: 占满父组件(Column)的剩余空间.padding(16) // 列表的内边距}
}

收工总结

恭喜你!你已经掌握了鸿蒙开发的几大金刚:

  1. @Component:造零件。
  2. @Entry:App入口。
  3. @Prop:父传子,“投喂”数据。
  4. @State:灵魂核心,数据一变,UI自动刷新。
  5. @Builder:封装“UI配方”,让代码更整洁。
  6. List/ForEach + .filter():动态列表和筛选的黄金搭档。

是不是感觉鸿蒙开发也没那么“玄学”了?赶紧动手试试吧!

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

相关文章:

  • 扩散模型与UNet融合的创新路径
  • 从入门到精通的鸿蒙学习之路——基于鸿蒙6.0时代的生态趋势与实战路径
  • 704.力扣LeetCode_二分查找
  • 如何做企业网站宣传wordpress 显示空白
  • 机器学习库的线性回归预测
  • 旅游网站开发研究背景北京欢迎您
  • 做网站要学什么东西企业网站运维
  • Orleans Grain Directory 系统综合分析文档
  • 从PN结到GPIO工作模式
  • 面向社科研究者:用深度学习做因果推断(三)
  • 深度学习-MNIST手写数字识别(MLP)
  • K8s 静态持久化存储详解
  • wordpress seo 能提高网站速度吗
  • GitHub等平台形成的开源文化正在重塑特尔恩恩
  • 追根索源:换不同的词嵌入(词向量生成方式不同,但词与词关系接近),会出现什么结果?
  • 视频与音频碰撞,谷歌 Veo 3.1,生成“有声电影”,人物对话超震撼
  • 【PID】基本PID控制 chaprt1 学习笔记
  • 【大语言模型 103】推理服务监控:性能指标、故障诊断与自动恢复实战
  • 网站广东海外建设集团有限公司做网站工资多钱
  • Julia 字符串处理指南
  • volatile关键词探秘:从咖啡厅的诡异订单到CPU缓存之谜
  • 嵌入式Lua脚本编程核心概念
  • VScode开发环境搭建(本文为个人学习笔记,内容整理自哔哩哔哩UP主【非学者勿扰】的公开课程。 > 所有知识点归属原作者,仅作非商业用途分享)
  • 基于springboot的车辆管理系统设计与实现
  • WPF GroupBox 淡入淡出
  • Dify从入门到精通 第33天 基于GPT-4V构建图片描述生成器与视觉问答机器人
  • 网页制作与网站建设实战教程视频网站一般用什么数据库
  • React 05
  • srpingboot 推rtsp/rtmp等流地址给前端播放flv和ws
  • 游戏任务简单设计