耗时三个月,我高仿了一个起点小说阅读器

耗时三个月,我高仿了一个起点小说阅读器

前言

起因是最近看小说的APP广告越来越多,但不少书源内容也时常出现问题。正好摆烂太久让我很有负罪感,就想着趁着这个契机学点新的东西。公司里用的都是vue技术栈,所以我想着用vue3做个小项目,顺便熟悉一下vue3的语法。从八月开始,断断续续搞了点Demo,直到年底稍微有点空闲,才开始着手把整个项目完善起来。

支持平台

耗时三个月,我高仿了一个起点小说阅读器

项目介绍

eReader 是一款基于 uni-app 开发的小说阅读器,功能完善,使用便捷,支持跨平台部署。移动端完全由前端实现,无需后端支持,打包后即为一个独立的APP,极大降低了部署和维护成本。H5端由于跨域问题需要启用一个简单的后端服务器,但移动端打包后完全开箱即用。

技术架构与部署

uni-app 的跨平台特性使得该项目在移动端和H5端之间无缝切换,移动端是纯前端实现,不依赖额外的服务器。

H5端需要启用后端服务器来解决跨域问题,但移动端完全是前端应用,避免了额外的服务器负担,极大简化了部署和维护流程。

使用技术栈如下

  • Vue3 + TypeScript: 项目基于Vue3和TypeScript实现。
  • Node + Express: H5端使用Node + Express搭建了一个简单的后台,负责爬取数据。
  • uni.request: 在APP端通过uni.request获取数据,不用启用后端应用。
  • Cheerio: 用Cheerio来解析HTML,提取书籍信息。
  • uni.setStorage: 数据缓存使用了uni.setStorage存储。
  • 阅读引擎: 主要是用 canvas.measureText 来计算文本宽度,通过JS计算宽高分页,支持两端对齐、标点避头等排版优化。
  • 分页: 分页计算用了uni-app的 renderjs 操作Canvas, uni.createCanvasContext 在APP端性能表现不佳,应尽量避免使用。
  • 海报分享: 海报分享功能使用了 limeui-painter 。

平台功能

  • 丰富的书源: 内置多个书源,满足大多数阅读需求,并支持灵活切换。
  • 全面的功能: 包括书架管理、小说搜索、阅读器设置(夜间模式、字体、背景主题、翻页方式)、章节缓存等,功能齐全。
  • 个性化体验: 支持书签、目录跳转、缓存、夜间模式等用户自定义设置。
  • 逻辑闭环: 书源管理、阅读设置、书签等功能平滑切换,确保使用流畅、体验一致。

详细功能列表

  • 书架: 可以加入/移除书架、置顶小说、分享(APP端)、查看详情、搜索、小说排序和浏览历史等功能。
  • 分组: 可以管理小说分组,支持新增、删除、修改、置顶等操作。
  • 精选推荐: 集成了 夸克热搜 的书单推荐,帮助大家发现热门书籍。
  • 我的: 包括书源管理、浏览历史、夜间模式、关于、意见反馈、缓存清除和分享等设置。
  • 小说搜索: 内置了 12 个书源,基本能满足大部分人的阅读需求。
  • 书籍详情: 展示书籍信息、简介、目录等,支持分享功能。
  • 阅读器: 支持添加/移除书架、添加/删除书签、查看目录、白天/夜间模式切换、翻页方式、字号和背景主题切换等多项个性化设置。此外,还支持其余书源切换和章节缓存(包括缓存全部、缓存后20章和缓存当前章节后的所有章节)。
  • 目录: 支持目录查看、缓存状态、书签、章节跳转、快速跳转(比如去当前章节、去底部)等功能。

项目结构

|-- undefined
    |-- .prettierignore
    |-- .prettierrc.js
    |-- index.html
    |-- package.json
    |-- tsconfig.json
    |-- vite.config.ts
    |-- src
        |-- App.vue
        |-- env.d.ts
        |-- main.ts
        |-- manifest.json
        |-- pages.json
        |-- type.d.ts
        |-- uni.scss
        |-- api  #请求接口
        |   |-- common.ts
        |-- components
        |   |-- BookTip.vue  #阅读页第一次打开提示
        |   |-- Expand.vue  #书籍详情简介收起与展开
        |   |-- share.vue  #分享组件
        |   |-- TabBar.vue  #重写tabbar,没使用uni自带tabbar
        |   |-- global  #全局组件
        |   |   |-- g-confirm.vue  #确认和输入弹窗
        |   |   |-- g-icon-fonts.vue  #图标
        |   |   |-- g-page.vue  #每个页面根元素,主要是做主题切换,设置全局css样式(uniapp的APP.vue没有根元素)
        |   |   |-- g-popup.vue  #底部和中间弹窗封装
        |   |   |-- g-statusbar.vue  #顶部statusbar占位组件,h5端高度为0,app端有默认高度
        |   |-- painter  #海报绘制组件
        |   |-- popover  #书架排序气泡窗
        |-- directives   #vLongPress指令封装
        |   |-- index.ts
        |-- pages
        |   |-- blank  #我的-跳转页面
        |   |   |-- about.vue  #关于我们
        |   |   |-- agreement.vue  #用户协议
        |   |   |-- feedback.vue   #意见反馈
        |   |   |-- history.vue  #浏览历史
        |   |   |-- origin.vue  #书源管理
        |   |   |-- policy.vue  #隐私政策
        |   |-- bookDetail  #书籍详情页
        |   |-- catalogs  #目录页
        |   |-- groupDetail  #分组详情页
        |   |-- reader  #阅读器
        |   |   |-- index.vue
        |   |   |-- index_v1.vue  #第一版,使用columns布局分页
        |   |   |-- index_v2.vue  #第二版,使用canvas.measureText计算宽度,js计算宽高进行分页(算法不完善,可以看看思路)
        |   |   |-- readerLayout.ts #第三版,感谢 [@前端一锅煮] 大佬的分享
        |   |   |-- components
        |   |       |-- Origin.vue  #换源组件
        |   |       |-- Renderjs.vue  #使用uniapp的rendejs获取 document 文档对象
        |   |       |-- Renderjs_v2.vue #第二版renderjs
        |   |-- search  #搜索页
        |   |-- tabBar  #自定义tabbar
        |       |-- book.vue  #精选
        |       |-- home.vue  #书架
        |       |-- personal.vue  #我的
        |       |-- components
        |           |-- addGroup.vue  #书架、分组详情里[移至分组]功能
        |           |-- bookDetail.vue  #书架、分组详情里长按展示详情功能
        |           |-- groupItem.vue  #分组项
        |-- parser  #app端数据解析
        |   |-- catalog.ts  #目录解析
        |   |-- content.ts  #章节内容解析
        |   |-- index.ts 
        |   |-- search.ts  #搜索内容解析
        |   |-- source.ts  #内置书源
        |   |-- top.ts  #精选内容解析
        |-- static
        |-- store  #store
        |   |-- AppOption.ts  #app的系统信息
        |   |-- index.ts  #一些缓存相关数据处理:书架、历史、缓存章节、搜索历史等
        |-- styles
        |-- types
        |-- utils
            |-- Config.ts
            |-- Control.ts
            |-- index.ts
            |-- request.ts  #请求处理和响应拦截
            |-- RequestHeader.ts  #最初是想伪造请求头的,但是uni的app端ua固定了

后续功能优化

  • 错误处理: 当前未处理极端情况下的错误请求,导致产品在特定条件下可能不够健壮,后续会加强异常处理。
  • 网络字体支持: 项目打包后APK约15MB,内置字体包增大了文件体积,后续会考虑支持网络字体加载以实现更丰富的阅读体验。
  • 书源导入与更新: 第三方书源存在不稳定性,网站变动可能导致解析错误。后续会考虑支持书源离线导入和在线更新,有助于解决此问题。
  • 听书功能: 作为干眼症患者,听书功能对我来说还是非常重要的,未来计划加入该功能。
  • 去除广告: 第三方书源可能包含广告和无关链接,影响阅读体验。后续考虑支持长按选择内容去除,并应用到所有章节,将极大提升阅读质量。

项目展示

h5表现

  • 书架

耗时三个月,我高仿了一个起点小说阅读器

  • 精选

耗时三个月,我高仿了一个起点小说阅读器

  • 我的

耗时三个月,我高仿了一个起点小说阅读器

  • 搜索

耗时三个月,我高仿了一个起点小说阅读器

  • 详情

耗时三个月,我高仿了一个起点小说阅读器

  • 阅读器

耗时三个月,我高仿了一个起点小说阅读器

app端表现(IOS)

Android端未完整测试,可能存在部分兼容问题

  • 书架(亮)
耗时三个月,我高仿了一个起点小说阅读器
  • 搜索(亮)
耗时三个月,我高仿了一个起点小说阅读器
  • 书源管理(亮)
耗时三个月,我高仿了一个起点小说阅读器
  • 我的(亮)
耗时三个月,我高仿了一个起点小说阅读器
  • 浏览历史(亮)
耗时三个月,我高仿了一个起点小说阅读器
  • 分组(暗)
耗时三个月,我高仿了一个起点小说阅读器
  • 分组详情(暗)
耗时三个月,我高仿了一个起点小说阅读器
  • 我的(暗)
耗时三个月,我高仿了一个起点小说阅读器
  • 意见反馈(暗)
耗时三个月,我高仿了一个起点小说阅读器
  • 详情(暗)
耗时三个月,我高仿了一个起点小说阅读器
  • 分享
耗时三个月,我高仿了一个起点小说阅读器
  • 阅读器

耗时三个月,我高仿了一个起点小说阅读器

总结

  • 最初只是为了学习新技术栈,项目框架、组件设计没考虑太多。但随着功能的增加,组件复用和方法抽象的需求变得明显,过程中也渐渐感觉到有些力不从心。

  • 尽管仍有一些缺漏,但是整体来看来这个项目已经勉强算得上是一个完整的、功能闭环的产品。作为一个人独立完成,自己也算是比较满意了。

  • 开发过程中遇到了不少挑战,比如阅读器排版引擎就经历了三次重构,才最终达到了理想效果。那段时间搞得头都要秃了(本来所剩无几的发量越加稀少)。后续会写写教程,记录下开发过程中遇到的坑。

来源:juejin.cn/post/7460023342592901183
后端专属技术群

构建高质量的技术交流社群,欢迎从事编程开发、技术招聘HR进群,也欢迎大家分享自己公司的内推信息,相互帮助,一起进步!

文明发言,以交流技术职位内推行业探讨为主

广告人士勿入,切勿轻信私聊,防止被骗

耗时三个月,我高仿了一个起点小说阅读器

加我好友,拉你进群

     点“在看”支持我们,共同成长

原文始发于微信公众号(极客之家):耗时三个月,我高仿了一个起点小说阅读器

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/309722.html

(0)
小半的头像小半

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!