小说阅读器
up-novel-reader 是面向长文本场景的小说阅读组件,提供目录、书签、进度恢复、阅读设置、阅读时长统计和安全区适配。章节内容由业务层提供,组件只负责阅读状态和展示。
基础使用
<template>
<up-novel-reader
:chapters="chapters"
:current-chapter="currentChapter"
book-id="demo-novel"
@chapter-request="handleChapterRequest"
/>
</template>const chapters = ref([
{ id: 'chapter-1', index: 0, title: '第一章', isLocked: false },
{ id: 'chapter-2', index: 1, title: '第二章', isLocked: false }
])
const currentChapter = ref({
id: 'chapter-1',
index: 0,
title: '第一章',
content: ['第一段正文', '第二段正文']
})
function handleChapterRequest(payload) {
// 由业务层请求或切换章节,完成后更新 currentChapter
console.log(payload.targetId, payload.targetIndex)
}章节数据
chapters 用于目录和章节导航,currentChapter 用于渲染当前正文。章节对象至少建议包含以下字段:
| 字段 | 类型 | 说明 |
|---|---|---|
id | String / Number | 稳定的章节 ID |
index | Number | 从 0 开始的章节索引 |
title | String | 章节标题 |
content | String / Array | 当前章节正文;数组项和换行都会被转换为段落 |
isLocked | Boolean | 是否锁定;锁定章节不会触发跳转事件 |
组件不会发起网络请求、鉴权或付费校验。chapter-request 和 chapter-prefetch 由业务层负责处理。
Props
| 参数 | 说明 | 类型 | 默认值 |
|---|---|---|---|
chapters | 章节目录 | Array | [] |
currentChapter | 当前章节对象 | Object | null |
loading | 当前章节是否加载中 | Boolean | false |
error | 当前章节错误对象 | Object | null |
bookId | 书籍 ID,用于生成持久化 key | String / Number | '' |
storageKey | 自定义持久化 key | String | '' |
persist | 是否持久化阅读状态 | Boolean | true |
initialProgress | 初始进度 | Object | null |
progress | 外部控制的进度 | Object | null |
initialBookmarks | 初始书签 | Array | [] |
bookmarks | 外部控制的书签 | Array | null |
defaultSettings | 默认阅读设置 | Object | 见“阅读设置” |
settings | 外部控制的阅读设置 | Object | null |
mode | 阅读模式 | String | 'scroll' |
showBack | 是否显示返回按钮 | Boolean | true |
autoBack | 点击返回后是否自动执行 uni.navigateBack | Boolean | false |
backIcon | 返回图标名称 | String | 'arrow-left' |
safeAreaInsetTop | 顶部工具栏是否适配安全区 | Boolean | true |
safeAreaInsetBottom | 底部工具栏是否适配安全区 | Boolean | true |
preloadThreshold | 预加载阈值;滚动模式按接近底部距离,分页模式按剩余页数 | Number | 2 |
pageAnimation | 是否启用分页动画 | Boolean | true |
controlsAutoHide | 工具栏自动隐藏延时,单位 ms;0 表示不自动隐藏 | Number | 0 |
事件
| 事件 | 参数 |
|---|---|
chapter-request | { direction, targetIndex, targetId, chapter, currentChapter } |
chapter-prefetch | { direction, targetIndex, targetId, chapter, currentChapter } |
progress-change | { chapterId, chapterIndex, pageIndex, pageCount, charOffset, chapterProgress, totalProgress, scrollTop, updatedAt } |
settings-change | 完整阅读设置对象 |
bookmark-change | { bookmarks, bookmark, active } |
reading-time-change | { readingTime, active },时长单位为 ms |
back | 无参数 |
mode-change | 'scroll' 或 'page' |
toolbar-change | { visible } |
layout-ready | { width, height, pageCount, mode } |
retry | { chapter, chapterId } |
插槽
| 插槽 | 说明 |
|---|---|
top | 顶部工具栏返回区域后的自定义内容 |
toolbar-extra | 顶部工具栏右侧扩展按钮 |
bottom | 底部工具栏导航按钮前的自定义内容 |
catalog | 目录面板底部扩展内容 |
settings | 设置面板底部扩展内容 |
loading | 加载状态 |
error | 错误状态,提供 error 和 retry 作用域参数 |
empty | 空正文状态 |
阅读设置
defaultSettings、settings-change 和 settings 支持以下字段:
{
theme: 'day',
fontSize: 18,
lineHeight: 1.8,
paragraphSpacing: 16,
contentWidth: '92%',
fontFamily: 'system',
fontWeight: 400,
animation: true
}fontSize 限制在 12..48,lineHeight 限制在 1..3,paragraphSpacing 限制在 0..80,fontWeight 归一化为 400 或 600。内置主题为 day、paper、green、night、dark。
目录、书签与持久化
目录支持当前章节高亮、锁定章节和书签列表。点击工具栏书签按钮会按 章节 ID:字符偏移 生成稳定 ID,再次点击相同位置会移除书签。
开启 persist 后,默认使用 uview-ultra:novel-reader:${bookId} 保存设置、进度、书签和阅读时长。传入 storageKey 后使用自定义 key。持久化数据使用版本号 1;数据损坏或字段越界时会自动删除并从默认状态恢复。
纵向滚动与横向分页
mode="scroll" 使用 scroll-view,进度根据滚动位置和正文长度计算;mode="page" 使用 swiper,组件会按容器尺寸、字号、行距和段距重新排版,并在布局变化后恢复字符锚点。
<up-novel-reader
:chapters="chapters"
:current-chapter="currentChapter"
mode="page"
:page-animation="true"
:preload-threshold="2"
/>示例源码链接
示例页面位于 pages/componentsD/novelReader/novelReader.uvue,展示六章本地数据、业务层章节切换、模式切换、书签统计、设置摘要和清除持久化记录。
