鸿蒙应用入门级开发者认证实验四(华为商城应用页面)

举报
黄生 发表于 2025/12/22 19:14:29 2025/12/22
【摘要】 HarmonyOS项目打开时自动执行ohpm install和build init是IDE(如DevEco Studio)的默认行为。通过oh-package.json5管理三方库依赖(如@hw-agconnect/cloud等),这些依赖存储在oh_modules目录。IDE检测到项目包含oh-package.json5文件时,会主动执行ohpm install以确保所有依赖完整安装。bu...

HarmonyOS项目打开时自动执行ohpm installbuild init是IDE(如DevEco Studio)的默认行为。通过oh-package.json5管理三方库依赖(如@hw-agconnect/cloud等),这些依赖存储在oh_modules目录。IDE检测到项目包含oh-package.json5文件时,会主动执行ohpm install以确保所有依赖完整安装。build init用于初始化hvigor构建环境,生成必要的构建缓存和配置文件。验证项目结构合规性(如工程路径不能包含隐藏目录)、加载构建插件、配置内存参数(如NODE_OPTS="--max-old-space-size=10240")。

class NavigationViewModel {
  getLinkData(): Array<NavigationModel> {
    // 代码逻辑...
  }
}
let navigationViewModel = new NavigationViewModel()
export default navigationViewModel as NavigationViewModel

实现了一个商品分类数据处理器,将扁平的商品数据LINK_DATA按父分类ID(superId)分组,生成层级化的商品分类结构

  • 输入:原始商品数据LINK_DATA
  • 输出:NavigationModel[]数组,每个元素包含:
    • superId:父分类ID
    • superName:父分类名称
    • GoodsList:属于该分类的子商品列表
getLinkData(): Array<NavigationModel> {
  let linkDataList: Array<NavigationModel> = []  // 结果数组
  let superId: number = 0  // 跟踪当前父分类ID
  
  LINK_DATA.forEach((item: LinkDataModel) => {
    // 发现新父分类时创建分类节点
    if (superId !== item.superId) {
      let GoodsItem = new NavigationModel(item.superId, item.superName, [])
      linkDataList.push(GoodsItem)
    }
    
    // 创建商品项并添加到当前分类
    let GoodsItem = new GoodsModel(
      superId, 
      item.id,
      item.GoodsName,
      item.imageUrl,
      item.price
    )
    linkDataList[linkDataList.length - 1].GoodsList.push(GoodsItem)
    
    superId = item.superId  // 更新当前父分类ID
  })
  return linkDataList
}
  1. 分类识别:通过比较相邻项的superId检测父分类变化
  2. 分类节点创建:当superId变化时,创建新的NavigationModel实例
  3. 商品挂载:将每个商品挂载到最近创建的父分类节点下
  4. 数据转换:将一维数组转化为树形结构

NavigationViewModel两次出现,第一次出现:类定义

class NavigationViewModel { ... }

第二次出现:

let navigationViewModel = new NavigationViewModel()
export default navigationViewModel as NavigationViewModel

创建单例并导出,单例模式确保全局唯一实例,避免重复创建。通过export default暴露服务接口,as NavigationViewModel确保TS类型推断

但是上面的创建GoodsModel的循环代码可能存在问题:superId初始值为0(let superId:number=0)。(其实初始值-10更能避免真实ID冲突)当第一次执行循环时,item.superId必定不等于0(商品分类ID通常从1开始),此时会创建新的NavigationModel(使用item.superId),但创建GoodsModel时使用的仍是初始值0(而非当前商品的item.superId),这样造成数据不一致风险:商品对象的superId属性(0)与它实际所属的分类ID(item.superId)不匹配,可能导致后续数据关联错误(如父子分类关系断裂)。所以这是我觉得这个实验存在的一个问题。

?符号是可选属性标记

item?: GoodsModel;  // 关键声明

表示item属性是可选的,允许该属性值为GoodsModel类型或undefined,无需在构造函数或初始化时强制赋值,访问该属性时需做空值检查

// 未声明?时(必需属性)
item: GoodsModel; // 必须显式初始化,否则编译报错

// 声明?后(可选属性)
item?: GoodsModel; // 允许延迟初始化(如生命周期函数中赋值)

生命周期配合aboutToAppear()中的实际使用:

aboutToAppear(): void {
  this.item = JSON.parse(this.itemStr); // 安全赋值点
}

利用组件生命周期确保使用前完成初始化、避免在build()等渲染阶段访问未定义值

组件通过层级嵌套形成类似树(Tree)的数据结构,能清晰描述组件间的层级关系(如父子、祖先后代),并高效实现数据传递(从根节点向下流动或跨层级同步)。

  1. 根节点:入口组件(@Entry装饰的组件)作为树的根。
  2. 父节点:包含子组件的组件,如ParentComponent
  3. 子节点:被父组件引用的组件,如ChildComponent
  4. 叶子节点:不包含子组件的底层组件(如按钮、文本)。

用于父子组件数据同步的装饰器及其特性:

装饰器组合 同步方向 适用场景 关键特性
@State@Prop 单向 父→子单向数据流 子组件接收父组件数据,但子组件修改同步回父组件。
@State@Link 双向 父子双向同步 父子组件共享数据源,任意一方修改都会触发同步。
@ObjectLink + @Observed 双向 嵌套对象/复杂类型同步 @Observed装饰类,@ObjectLink监听对象属性变化,支持深层次数据同步。
@Provide@Consume 双向 跨层级传递(祖先→后代) 避免逐层传递,后代组件直接消费祖先提供的数据。
  • 单向 vs 双向
    @Prop仅支持父→子单向同步;@Link@ObjectLink@Provide/@Consume支持双向同步。
  • 数据复杂度
    • 简单类型(string/number/boolean)适用@Prop@Link
    • 对象/数组类型优先用@ObjectLink@Provide/@Consume
  • 层级限制
    @Provide/@Consume突破父子层级,适合跨多级组件传递数据。

设计建议

  • 简单父子通信用@State + @Link
  • 跨代组件用@Provide + @Consume
  • 嵌套对象同步务必搭配@Observed
【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。