# book
**Repository Path**: Chennile/book
## Basic Information
- **Project Name**: book
- **Description**: 基于HarmonyOS 5.0.0(12)开发的小说应用。包括书城,书架,我的,阅读器。持续更新中~
鸿蒙小说,火炬文学。
- **Primary Language**: Unknown
- **License**: MulanPSL-2.0
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 1
- **Created**: 2026-01-20
- **Last Updated**: 2026-01-20
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
# 火炬文学 鸿蒙小说示例
### 介绍
基于HarmonyOS 5.0.0(12)开发的小说阅读应用。包括书城,书架,我的,阅读器。持续更新中~
### 效果图预览

### 使用说明
1. DevEco Studio 5.0版本导入项目
2. 选择模拟器运行。
3. 项目所使用的数据均是本地模拟数据
如果需要使用自己服务器的数据,src/utils/Config 中 BASE_URL 修改为服务器域名。
src/api/中User.ets 中getUserInfoApi 为例 配置成对应服务端api即可。
### 部分工程结构&模块类型说明
```
src
|-- api //api文件夹
| |-- Book.ets
| |-- Bookcity.ets
| |-- User.ets
| |-- bookData
| |-- BannerData.ets
| |-- BookcityData.ets
| |-- BookData.ets
| |-- RecordsData.ets
|-- commonClass //公用类文件夹
| |-- ComponentRef.ets
| |-- SetValueClass.ets
| |-- User.ets
|-- components //组件文件夹
| |-- NavBar.ets
| |-- NoData.ets
|-- entryability //入口文件夹
| |-- EntryAbility.ets
|-- entrybackupability
| |-- EntryBackupAbility.ets
|-- pages //页面文件夹
| |-- Login.ets
| |-- BookCity
| | |-- BookCity.ets
| | |-- BookList.ets
| |-- BookClass
| | |-- BookClass.ets
| |-- Index
| | |-- Index.ets
| |-- My
| | |-- about.ets
| | |-- bindPhone.ets
| | |-- buylog.ets
| | |-- My.ets
| | |-- policy.ets
| | |-- recharge.ets
| | |-- rechargelog.ets
| | |-- set.ets
| | |-- subscribe.ets
| |-- Read
| | |-- Read.ets
| | |-- components
| |-- Tabs
| |-- Tabs.ets
|-- types //类型定义
| |-- Book.ets
| |-- bookcity.ets
| |-- Data.ets
| |-- Index.ets
| |-- TabBarItem.ets
|-- utils //公用方法
|-- Common.ets
|-- Config.ets //配置文件
|-- MyDataSource.ets
|-- MyWindow.ets
|-- PreferencesUtil.ets
|-- Request.ets //请求封装
```
### 本例涉及的关键特性和实现方案如下:
#### LazyForEach:数据懒加载 实现目录长列表的渲染
源码参考:
[Read.ets](./entry/src/main/ets/pages/Read/Read.ets)
```typescript
class BasicDataSource implements IDataSource {
private listeners: DataChangeListener[] = [];
private originDataArray: T[] = [];
public totalCount(): number {
return 0;
}
public getData(index: number): T {
return this.originDataArray[index];
}
// 该方法为框架侧调用,为LazyForEach组件向其数据源处添加listener监听
registerDataChangeListener(listener: DataChangeListener): void {
if (this.listeners.indexOf(listener) < 0) {
console.info('add listener');
this.listeners.push(listener);
}
}
// 该方法为框架侧调用,为对应的LazyForEach组件在数据源处去除listener监听
unregisterDataChangeListener(listener: DataChangeListener): void {
const pos = this.listeners.indexOf(listener);
if (pos >= 0) {
console.info('remove listener');
this.listeners.splice(pos, 1);
}
}
// 通知LazyForEach组件需要重载所有子组件
notifyDataReload(): void {
this.listeners.forEach(listener => {
listener.onDataReloaded();
})
}
// 通知LazyForEach组件需要在index对应索引处添加子组件
notifyDataAdd(index: number): void {
this.listeners.forEach(listener => {
listener.onDataAdd(index);
})
}
// 通知LazyForEach组件在index对应索引处数据有变化,需要重建该子组件
notifyDataChange(index: number): void {
this.listeners.forEach(listener => {
listener.onDataChange(index);
})
}
// 通知LazyForEach组件需要在index对应索引处删除该子组件
notifyDataDelete(index: number): void {
this.listeners.forEach(listener => {
listener.onDataDelete(index);
})
}
}
export class MyDataSource extends BasicDataSource {
private dataArray: T[] = [];
public totalCount(): number {
return this.dataArray.length;
}
public getData(index: number): T {
return this.dataArray[index];
}
public addData(index: number, data: T): void {
this.dataArray.splice(index, 0, data);
this.notifyDataAdd(index);
}
public pushData(data: T): void {
this.dataArray.push(data);
this.notifyDataAdd(this.dataArray.length - 1);
}
}
// 目录
@Component
struct catalog {
@ObjectLink BookInfo: BookInfo
@Prop CatalogListLength:number
@Link showCatalog:boolean
CatalogList:CatalogItemI[] = []
data:MyDataSource = new MyDataSource()
// 父组件将方法传入子组件。
getRead:Function = (book_id?:number,sort?:number) => {
}
aboutToAppear(){
console.log(JSON.stringify(this.CatalogList),111)
this.CatalogList.forEach((item)=>{
this.data.pushData(new CatalogItem(item))
})
}
build() {
Column() {
Column() {
Row() {
Image($rawfile(this.BookInfo.cover)).height(80).width(60).borderRadius(5)
Column() {
Text(this.BookInfo.title).margin({bottom:8}).maxLines(1).textOverflow({overflow:TextOverflow.Ellipsis}).width('80%')
Text(this.BookInfo.ctitle.length > 0 ? this.BookInfo.ctitle[0] : '')
.fontSize(12)
.fontColor($r('app.color.text2'))
.margin({bottom:8})
Text(this.BookInfo.description).textOverflow({ overflow: TextOverflow.Ellipsis }).maxLines(2).width('80%')
.fontSize(12)
.fontColor($r('app.color.text2'))
}
.padding({left:10,right:20})
.alignItems(HorizontalAlign.Start)
.width('100%')
}.width('100%')
.padding({bottom:20})
Column(){
Text(`共${this.CatalogListLength}章`).fontSize(18).width('100%').textAlign(TextAlign.Start).padding({left:5,bottom:20})
List({ space: 16 }) {
LazyForEach(this.data, (item: CatalogItem, index: number) => {
ListItem() {
catalogChild({data: item})
.onClick(()=>{
this.getRead(item.book_id,item.sort)
animateTo({ duration: 200 }, () => {
this.showCatalog = false
})
})
}
}, (item: CatalogItem, index: number) => index.toString())
}.cachedCount(5)
.width('100%')
.layoutWeight(1)
.padding({left:10,right:10,bottom:110})
}
.height('100%')
.width('100%')
}
.padding(10)
.backgroundColor('#fff')
.height('100%')
.width('55%')
.justifyContent(FlexAlign.Start)
}
.height('100%')
.width('100%')
.backgroundColor('rgba(0,0,0,0.5)')
.alignItems(HorizontalAlign.Start)
.onClick(()=>{
animateTo({ duration: 200 }, () => {
this.showCatalog = false
})
})
}
}
```
### 高性能知识点
本例使用了LazyForEach从提供的数据源中按需迭代数据,并在每次迭代过程中创建相应的组件。
当在滚动容器中使用了LazyForEach,框架会根据滚动容器可视区域按需创建组件,当组件滑出可视区域外时,
框架会进行组件销毁回收以降低内存占用。
### 参考资料
[LazyForEach:数据懒加载](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/arkts-rendering-control-lazyforeach-0000001820879609)
[List](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/ts-container-list-0000001862607449)
[Swiper](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/ts-container-swiper-0000001862607461)
[@Link装饰器:父子双向同步](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/arkts-link-0000001820999565#ZH-CN_TOPIC_0000001820999565__%E7%AE%80%E5%8D%95%E7%B1%BB%E5%9E%8B%E5%92%8C%E7%B1%BB%E5%AF%B9%E8%B1%A1%E7%B1%BB%E5%9E%8B%E7%9A%84link)
[HarmonyOS 5.0.0(12) 版本的配套文档](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/learning-arkts-V5)