概述
微信官方为小说类小程序提供了专用的阅读器插件,所有小说类目的小程序都必须使用该组件。
快速开始
1. 添加插件配置
在小程序的 app.json 文件中添加插件配置:
json
{
"plugins": {
"novel-plugin": {
"version": "latest",
"provider": "wx293c4b6097a8a4d0"
}
}
}
2. 初始化插件
在 app.js 中初始化插件并监听页面加载事件:
javascript
// app.js
const novelPlugin = requirePlugin('novel-plugin')
App({
onLaunch() {
// 监听阅读器页面加载事件
novelPlugin.onPageLoad(onNovelPluginLoad)
},
})
function onNovelPluginLoad(data) {
// data.id - 阅读器实例ID
const novelManager = novelPlugin.getNovelManager(data.id)
// 设置目录状态
novelManager.setContents({
contents: [
{ index: 0, status: 0 }, // 第一章:免费
{ index: 1, status: 2 }, // 第二章:未解锁
{ index: 2, status: 1 }, // 第三章:已解锁
]
})
// 监听用户行为
novelManager.onUserTriggerEvent(res => {
console.log('用户操作:', res.event_id, res)
})
}
3. 跳转到阅读页面
javascript
// 跳转到阅读器页面
wx.navigateTo({
url: 'plugin-private://wx293c4b6097a8a4d0/pages/novel/index?bookId=书籍ID'
})
核心功能详解
页面跳转参数
跳转到阅读页面时可以传入以下参数:
| 参数 | 必填 | 说明 |
|---|---|---|
| bookId | 是 | 书籍ID |
| chapterIndex | 否 | 跳转章节下标(从0开始) |
| fontSize | 否 | 字体大小(0-9) |
| turnPageWay | 否 | 翻页方式:SWIPE/MOVE/SCROLL |
| backgroundConfigIndex | 否 | 背景色序号(1-5) |
| isNightMode | 否 | 是否夜间模式 |
| showListenButton | 否 | 是否显示听书按钮 |
章节解锁功能
1. 创建解锁组件
首先创建一个自定义组件 charge-dialog:
xml
<!-- charge-dialog.wxml -->
<view class="charge-dialog">
<text>解锁第 {{ chapterIndex + 1 }} 章</text>
<button bindtap="unlock">立即解锁</button>
</view>
javascript
// charge-dialog.js
const novelPlugin = requirePlugin('novel-plugin')
Component({
properties: {
novelManagerId: Number,
bookId: String,
chapterIndex: Number,
chapterId: String
},
methods: {
unlock() {
const novelManager = novelPlugin.getNovelManager(this.properties.novelManagerId)
// 执行解锁逻辑...
// 解锁完成后通知阅读器
novelManager.paymentCompleted()
}
}
})
2. 注册组件
在 app.json 中注册组件:
json
{
"plugins": {
"novel-plugin": {
"version": "latest",
"provider": "wx293c4b6097a8a4d0",
"genericsImplementation": {
"novel": {
"charge-dialog": "components/charge-dialog/charge-dialog"
}
}
}
}
}
消息推送配置
阅读器通过消息推送验证章节解锁状态,需要在服务器端配置消息接收:
javascript
// 服务器接收消息示例
{
"ToUserName": "小程序原始ID",
"FromUserName": "用户openid",
"CreateTime": 时间戳,
"MsgType": "event",
"Event": "wxa_novel_chapter_permission",
"BookId": "书籍ID",
"ChapterIndex": 章节下标,
"ChapterId": "章节ID",
"Source": 1 // 1表示用户实际阅读
}
// 响应格式
{
"ErrCode": 0,
"ErrMsg": "",
"ChapterPerms": [{
"StartChapterIndex": 0,
"EndChapterIndex": 2,
"Perm": 1 // 0-免费 1-已解锁 2-未解锁
}]
}
高级功能
1. 自定义解锁方式
javascript
// 设置不同的解锁方式
novelManager.setChargeWay({
globalConfig: {
mode: 2, // 1:默认 2:广告解锁 3:自定义解锁
buttonText: "解锁"
},
chapterConfigs: [
{
chapterIndex: 10,
mode: 3,
buttonText: "VIP解锁"
}
]
})
// 监听自定义解锁事件
novelManager.onUserClickCustomUnlock(res => {
console.log('自定义解锁章节:', res.chapterIndex)
})
2. 插入自定义段落
javascript
// 在正文中插入自定义内容
novelManager.setParagraphBlock({
chapterConfigs: [{
chapterIndex: 0,
blocks: [{
height: 100, // 高度
position: 1, // 位置(0:标题前,1:第一段前)
ext: "自定义数据",
key: "unique-id"
}]
}]
})
3. 广告插入
javascript
// 插入广告
novelManager.setAdBlock({
chapterConfigs: [{
chapterIndex: 0,
blocks: [{
type: 1, // 1:强制观看 2:banner广告 3:书签广告
position: 10, // 广告位置
duration: 6, // 强制观看时长(秒)
unitId: "广告单元ID"
}]
}]
})
实用API参考
获取阅读器信息
javascript
// 获取当前阅读器实例
const novelManager = novelPlugin.getCurrentNovelManager()
// 获取书籍ID
const bookId = novelManager.getBookId()
// 获取插件信息
const pluginInfo = novelManager.getPluginInfo()
导航控制
javascript
// 设置关闭行为
novelManager.setClosePluginInfo({
url: '/pages/index/index',
mode: 'redirectTo'
})
// 设置返回行为
novelManager.setLeaveReaderInfo({
url: '/pages/bookshelf/index',
mode: 'switchTab'
})
分享配置
javascript
novelManager.setShareParams({
title: '书籍标题',
imageUrl: '封面图片',
args: {
from: 'share',
time: '2024'
}
})
书架功能
javascript
// 设置书架状态
novelManager.setBookshelfStatus({
bookshelfStatus: 1 // 0:未添加 1:已添加
})
// 监听书架点击
novelManager.onClickBookshelf(res => {
// 处理书架逻辑
novelManager.setBookshelfStatus({
bookshelfStatus: res.bookshelfStatus ? 1 : 0
})
})
事件监听
阅读器提供丰富的事件监听:
javascript
novelManager.onUserTriggerEvent(res => {
switch(res.event_id) {
case 'start_read': // 开始阅读
case 'change_chapter': // 切换章节
case 'change_fontsize': // 调整字号
case 'click_listen': // 点击听书
case 'audio_start': // 音频开始
// ... 更多事件
}
})