目录:
1、三层架构项目结构

这里新建三个文件夹不是模块,来构建鸿蒙项目的三层架构。
- common层(主要放一些公共的资源等)

- features层(主要模块定义的组件以及图片等静态资源)
- products层(主要放主页面层和一些主要的资源,内部快速入门,课程学习,知识地图等都是模块放在features层)
2、快速入门模块

QuickStartPage.ets:
typescript
import { TutorialView } from '../view/TutorialView';
import { ArticleClass } from '../model/ArticleClass'
import { ArticleDetailPage } from './ArticleDetailPage';
import { Banner } from '../view/Banner';
import { EnablementView } from '../view/EnablementView';
import { BannerDetailPage } from './BannerDetailPage';
import { BannerClass } from '../model/BannerClass';
@Component
export struct QuickStartPage {
@State message: string = '快速入门';
@Provide('articlePathStack') articlePathStack: NavPathStack = new NavPathStack();
@Builder
quickStartRouter(name: string, param?: ArticleClass | BannerClass) {
if (name === 'articleDetail') {
ArticleDetailPage()
} else if (name === 'bannerDetailPage') {
BannerDetailPage()
}
}
build() {
Navigation(this.articlePathStack) {
Column() {
Text(this.message)
.fontSize(24)
.fontWeight(700)
.width('100%')
.textAlign(TextAlign.Start)
.padding({ left: 16 })
.fontFamily('HarmonyHeiTi-Bold')
.lineHeight(33)
//此处采用Scroll作为外层容器,是由于其内部内容很有可能会超过屏幕高度,为保证内容显示,可以采用Scroll组件来进行滚动显示。scrollBar设置为BarState.Off,表示关闭滚动时的滚动条显示
Scroll() {
Column() {
//轮播图广告组件
Banner()
//赋能组件
EnablementView()
//入门教程
TutorialView()
}
}
.layoutWeight(1)
.scrollBar(BarState.Off)
.align(Alignment.TopStart)
}
.width('100%')
.height('100%')
.backgroundColor('#F1F3F5')
}
.navDestination(this.quickStartRouter)
.hideTitleBar(true)
.mode(NavigationMode.Stack)
}
}
Banner.ets:
typescript
import { BannerClass } from '../model/BannerClass';
import { bufferToString } from '../util/BufferUtil';
@Component
export struct Banner {
@Consume('articlePathStack') articlePathStack: NavPathStack;
@State bannerList: BannerClass[] = [];
aboutToAppear(): void {
this.getBannerDataFromJSON()
}
//通过数据文件BannerData.json读取然后构造bannerList轮播图数组数据
getBannerDataFromJSON() {
getContext(this).resourceManager.getRawFileContent('BannerData.json').then(value => {
this.bannerList = JSON.parse(bufferToString(value)) as BannerClass[];
})
}
clickToDetailPage(item: BannerClass) {
this.articlePathStack.pushPathByName('bannerDetailPage', item);
}
build() {
//Swiper组件作为容器可以使轮播图具有轮播的效果
Swiper() {
ForEach(this.bannerList, (item: BannerClass) => {
Image($r(item.imageSrc))
.objectFit(ImageFit.Contain) //保持宽高比进行缩小或者放大
.width('100%')
.borderRadius(16)
.padding({ top: 11, left: 16, right: 16 })
.onClick(() => {
this.clickToDetailPage(item)
})
}, (item: BannerClass) => item.id)
}
//autoPlay控制是否自动轮播子组件,loop属性控制是否循环播放,indicator属性自定义导航点的位置和样式
.autoPlay(true)
.loop(true)
.indicator(
new DotIndicator()
.color('#1a000000')
.selectedColor('#0A59F7'))
}
}
BannerClass.ets:
typescript
export class BannerClass {
id: string = '';
imageSrc: string = '';
url: string = ''
constructor(id: string, imageSrc: string, url: string) {
this.id = id
this.imageSrc = imageSrc;
this.url = url;
}
}
EnablementView.ets:
typescript
import { ArticleClass } from '../model/ArticleClass';
import { bufferToString } from '../util/BufferUtil';
@Component
export struct EnablementView {
@State enablementList: ArticleClass[] = [];
@Consume('articlePathStack') articlePathStack: NavPathStack;
aboutToAppear(): void {
this.getEnablementDataFromJSON()
}
getEnablementDataFromJSON() {
getContext(this).resourceManager.getRawFileContent('EnablementData.json').then(value => {
this.enablementList = JSON.parse(bufferToString(value)) as ArticleClass[];
})
}
build() {
Column() {
Text('赋能套件')
.fontColor('#182431')
.fontSize(16)
.fontWeight(500)
.fontFamily('HarmonyHeiTi-medium')
.textAlign(TextAlign.Start)
.padding({ left: 16, right: 16 })
.width('100%')
Grid() {
ForEach(this.enablementList, (item: ArticleClass) => {
GridItem() {
EnablementItem({ enablementItem: item })
.onClick(() => {
this.articlePathStack.pushPathByName('articleDetail', item)
})
}
}, (item: ArticleClass) => item.id)
}
.rowsTemplate('1fr')
.columnsGap(8)
.scrollBar(BarState.Off)
.height(169)
.padding({ top: 2, left: 16, right: 16 })
}
.margin({ top: 18 })
}
}
@Component
export struct EnablementItem {
@Prop enablementItem: ArticleClass;
build() {
Column() {
Image($r(this.enablementItem.imageSrc))
.width('100%')
//设置填充效果为cover模式,即保持宽高比进行缩小或者放大,使得图片两边都大于或等于显示边界
.objectFit(ImageFit.Cover)
.height(96)
.borderRadius({
topLeft: 16,
topRight: 16
})
Text(this.enablementItem.title)
.height(19)
.width('100%')
.fontSize(14)
.textAlign(TextAlign.Start)
//textOverFlow属性设置文本超长时的显示方式,在这里我们设置它的值为Ellipsis,表示超长时使用省略号替代
.textOverflow({ overflow: TextOverflow.Ellipsis })
.maxLines(1)
.fontWeight(400)
.padding({ left: 12, right: 12 })
.margin({ top: 8 })
Text(this.enablementItem.brief)
.height(32)
.width('100%')
.fontSize(12)
.textAlign(TextAlign.Start)
.textOverflow({ overflow: TextOverflow.Ellipsis })
.maxLines(2)
.fontWeight(400)
.fontColor('rgba(0, 0, 0, 0.6)')
.padding({ left: 12, right: 12 })
.margin({ top: 2 })
}
.width(160)
.height(169)
.borderRadius(16)
.backgroundColor(Color.White)
}
}
TutorialView.ets:
typescript
import { bufferToString } from '../util/BufferUtil';
import { ArticleClass } from '../model/ArticleClass';
@Component
export struct TutorialView {
@State tutorialList: ArticleClass[] = [];
@Consume('articlePathStack') articlePathStack: NavPathStack;
aboutToAppear(): void {
this.getTutorialDataFromJSON()
}
getTutorialDataFromJSON() {
getContext(this).resourceManager.getRawFileContent('TutorialData.json').then(value => {
this.tutorialList = JSON.parse(bufferToString(value)) as ArticleClass[];
})
}
build() {
Column() {
Text('入门教程')
.fontColor('#182431')
.fontSize(16)
.fontWeight(500)
.fontFamily('HarmonyHeiTi-medium')
.textAlign(TextAlign.Start)
.padding({ left: 16, right: 16 })
.width('100%')
List({ space: 12 }) {
ForEach(this.tutorialList, (item: ArticleClass) => {
ListItem() {
TutorialItem({ tutorialItem: item })
.onClick(() => {
this.articlePathStack.pushPathByName('articleDetail', item)
})
}
}, (item: ArticleClass) => item.id)
}
.scrollBar(BarState.Off)
.padding({ left: 16, right: 16 })
}
.margin({ top: 18 })
.alignItems(HorizontalAlign.Start)
}
}
@Component
export struct TutorialItem {
@Prop tutorialItem: ArticleClass;
build() {
Row() {
Column() {
Text(this.tutorialItem.title)
.height(19)
.width('100%')
.fontSize(14)
.textAlign(TextAlign.Start)
.textOverflow({ overflow: TextOverflow.Ellipsis })
.maxLines(1)
.fontWeight(400)
.margin({ top: 4 })
Text(this.tutorialItem.brief)
.height(32)
.width('100%')
.fontSize(12)
.textAlign(TextAlign.Start)
.textOverflow({ overflow: TextOverflow.Ellipsis })
.maxLines(2)
.fontWeight(400)
.fontColor('rgba(0, 0, 0, 0.6)')
.margin({ top: 5 })
}
.height('100%')
//设置layoutWeight属性,取值为1,表示它们在任意尺寸的设备下自适应占满剩余空间
.layoutWeight(1)
.alignItems(HorizontalAlign.Start)
.margin({ right: 12 })
Image($r(this.tutorialItem.imageSrc))
.objectFit(ImageFit.Cover)
.height(64)
.width(108)
.borderRadius(16)
}
.width('100%')
.height(88)
.borderRadius(16)
.backgroundColor(Color.White)
.padding(12)
.alignItems(VerticalAlign.Top)
}
}
ArticleClass.ets:
typescript
export class ArticleClass {
id: string = '';
imageSrc: string = '';
title: string = '';
brief: string = '';
webUrl: string = '';
constructor(id: string, imageSrc: string, title: string, brief: string, webUrl: string) {
this.id = id;
this.imageSrc = imageSrc;
this.title = title;
this.brief = brief;
this.webUrl = webUrl;
}
}