Harmony OS UI框架探索笔记

发布于:2024-06-28 ⋅ 阅读:(15) ⋅ 点赞:(0)

本文探讨了如何将现有的常用架构理论与Arkts和ArkUI结合起来,使代码更有条理,并利用Previewer快速调整布局,同时在不改变代码的情况下运行显示真实数据。

开发环境

  • Windows 11
  • DevEco Studio 4.0 Release
  • Build Version: 4.0.0.600, built on October 17, 2023

运行环境

  • 华为畅享50Pro
  • HarmonyOS 4.0 API9

初步布局Index

新建一个工程后,首先进入Index页,简单地显示文章列表。

文章数据结构

class Article {
  title?: string
  desc?: string
  link?: string
}

Index组件

@Entry
@Component
struct Index {
  @State articles: Article[] = []
  
  build() {
    Row() {
      Scroll() {
        Column() {
          ForEach(this.articles, (item: Article) => {
            Column() {
              Text(item.title).fontWeight(FontWeight.Bold)
              Text(item.desc)
              Text("----------")
            }
          }, (item: Article) => {
            return item.link
          })
        }
        .width('100%')
      }
    }
    .height('100%')
  }
}

获取数据

异步请求数据

aboutToAppear()中发送GET请求更新articles数组。

aboutToAppear() {
  // 请求网络数据
  axios.get(url).then(response => {
    // 更新this.articles
  })
}

分离数据请求和界面逻辑

创建IndexViewModel

将数据请求逻辑移到IndexViewModel中。

@Observed
export default class IndexViewModel {
  articles?: Array<Article>

  refreshData() {
    // 请求网络数据
    // 更新this.articles
  }
}

更新Index

@State viewModel: IndexViewModel = new IndexViewModel()

aboutToAppear() {
  this.viewModel.refreshData()
}

使用Mock数据进行预览

IndexViewModelInterface

interface IndexViewModelInterface {
  articles: Array<Article>
  refreshData()
}

Mock类

@Observed
export default class IndexViewModelMock implements IndexViewModelInterface {
  articles: Array<Article> = []
  refreshData() {
    this.articles = [{ title: "Mock Title", desc: "Mock Description", link: "mocklink" }]
  }
}

更新Index以支持Mock数据

@State viewModel: IndexViewModelInterface = new IndexViewModel() // 真实数据
@State viewModel: IndexViewModelInterface = new IndexViewModelMock() // 预览数据

进一步分离UI和数据逻辑

重构IndexContent

build() {
  Column() {
    IndexContent({ viewModel: this.viewModel })
  }
}

Index和IndexPreviewer

@Entry
@Component
struct Index {
  model: IndexModelBase = new IndexModel()

  async aboutToAppear() {
    this.model.refreshData()
  }

  build() {
    Column() {
      IndexContent({ viewModel: this.model.viewModel })
    }
  }
}

@Preview
@Component
struct IndexPreviewer {
  model: IndexModelBase = new IndexModelMock()

  async aboutToAppear() {
    this.model.refreshData()
  }

  build() {
    Column() {
      IndexContent({ viewModel: this.model.viewModel })
    }
  }
}

最终架构优化

简化后的Index和IndexPreviewer

@Entry
@Component
struct Index {
  viewModel: IndexViewModelInterface = new IndexViewModel()

  async aboutToAppear() {
    this.viewModel.refreshData()
  }

  build() {
    Column() {
      IndexContent({ viewModel: this.viewModel })
    }
  }
}

@Preview
@Component
struct IndexPreviewer {
  viewModel: IndexViewModelInterface = new IndexViewModelMock()

  async aboutToAppear() {
    this.viewModel.refreshData()
  }

  build() {
    Column() {
      IndexContent({ viewModel: this.viewModel })
    }
  }
}

IndexViewModel和IndexViewModelMock实现

@Observed
export default class IndexViewModel implements IndexViewModelInterface {
  articles: Array<Article> = []
  title: string = "1"

  async refreshData(): Promise<void> {
    this.articles = await this.refreshArticles()
    this.title = "2"
    return new Promise(resolve => { resolve() })
  }

  async refreshArticles(): Promise<Article[]> {
    let articles: Array<Article>
    // 异步请求,返回文章列表
    return new Promise(resolve => {
      resolve(articles)
    })
  }
}

@Observed
export default class IndexViewModelMock implements IndexViewModelInterface {
  articles: Array<Article> = []
  title: string = "1"

  async refreshData(): Promise<void> {
    this.articles = await this.refreshArticles()
    this.title = "2"
    return new Promise(resolve => { resolve() })
  }

  refreshArticles(): Promise<Article[]> {
    return new Promise(resolve => {
      const articles = [{ title: "Mock Title", desc: "Mock Description", link: "mocklink" }]
      resolve(articles)
    })
  }
}

通过这一系列的优化和重构,使得UI界面与数据逻辑解耦,实现了在Previewer中快速预览布局并使用真实数据运行应用。