本文探讨了如何将现有的常用架构理论与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?: stringdesc?: stringlink?: 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中快速预览布局并使用真实数据运行应用。