三、阅读器–标题菜单、字号字体及主题设置功能开发
3.1阅读器解析和渲染
准备工作:将电子书资源文件放在resource文件夹下
将App.vue中之前的测试代码移除
设置div充满全屏:
<style lang="scss" scoped>
#app {
width: 100%;
height: 100%;
overflow: hidden;
}
</style>
删掉原有的About.vue和Home.vue,同时在view下建立ebook文件夹并在文件夹中建立新文件index.vue作为入口文件
写入一个class为ebook的div,接下来让路由指向index
routes: [
{
path: '/',
redirect: '/ebook' //重定向
},
{
path: '/ebook', //建立ebook路由
component: () => import('./views/ebook/index.vue')
}
实现动态路由:
首先创建动态路由组件:components—>ebook—>EbookReader.vue
在router.js中配置动态路由
children: [
{
path: ':fileName',
component: () => import('./components/ebook/EbookReader.vue')
}
]
接下来在父组件也就是index.vue中引入ebookreader
<template>
<div class="ebook">
<ebook-reader></ebook-reader>
</div>
</template>
<script>
import EbookReader from '../../components/ebook/EbookReader.vue'
export default {
components: {
EbookReader
}
}
</script>
在EbookReader.vue中接收
<template>
<div class="ebook-reader">
{
{
$route.params.fileName}}
</div>
</template>
这时我们的动态路由就配置完成了。
接下来我们在钩子函数mounted中接收动态路由
mounted () {
const baseUrl='http://192.168.0.106:8081/epub/'
//本地地址
const fileName=this.$route.params.fileName.split('|').join('/')
console.log(`${
baseUrl}${
fileName}.epub`)
//字符串拼接,``不是单引号
}
这时已经能正确的链接到电子书的地址。
在EbookReader.vue中引入epub.js
import Epub from 'epubjs'
global.ePub = Epub
export default {
methods: {
initEpub () {
}
}
接下来我们使用vuex进行参数传递
fileName在后续会多次用到,这里我们把它写入book.js的数据中
const book = {
state: {
fileName: ''
},
mutations: {
'SET_FILENAME': (state, fileName) => {
state.fileName = fileName
}
},
actions: {
setFileName: ({
commit }, fileName) => {
return commit('SET_FILENAME', fileName)
}
}
}
export default book
并在getters.js中
const book = {
fileName: state => state.book.fileName
}
export default book
使用mapGetters快速调用vuex的对象
import {
mapGetters } from 'vuex'
...
export default {
computed: {
...mapGetters(['fileName'])
}
...
}
在initEpub中拼出url,在mounted中异步调用
initEpub () {
const url = 'http://192.168.0.106:8081/epub/' + this.fileName + '.epub'
}
mounted () {
this.$store.dispatch('setFileName', this.$route.params.fileName.split('|').join('/'))
.then(() => {
this.initEpub()
})
}
到这里,我们已经成功的获取到链接。
接下来,进行渲染
initEpub () {
...
// 实例化
this.book = new Epub(url)
// 进行渲染
this.rendition = this.book.renderTo('read', {
width: innerWidth,
height: innerHeight,
// 微信兼容性配置
method: 'default'
})
this.rendition.display()
...
}
到这里,一本完整的电子书就展示出来了!
3.2 阅读器翻页功能实现
通过绑定touchstart和touchend事件来判断手势,从而实现翻页功能
this.rendition.on('touchstart', event => {
this.touchStartX = event.changedTouches[0].clientX
this.touchStartTime = event.timeStamp
// console.log(event)
})
this.rendition.on('touchend', event => {
// console.log(event)
const offsetX = event.changedTouches[0].clientX - this.touchStartX
const time = event.timeStamp - this.touchStartTime
// console.log(offsetX, time)
if (time < 500 && offsetX > 40) {
this.prevPage() // 向前翻页事件
} else if (time < 500 && offsetX < -40) {
this.nextPage() // 向后翻页事件
} else {
this.toggleTitleAndMenu() // 显示标题和菜单
}
event.preventDefault() // 禁用事件默认方法调用
event.stopPropagation() // 禁止事件传播
})
接下来,定义prevPage()和nextPage()方法
methods: {
prevPage () {
// 进入上一页
if (this.rendition) {
this.rendition.prev()
}
},
nextPage () {
// 进入下一页
if (this.rendition) {
this.rendition.next()
}
},
...
}
3.3标题栏和菜单栏实现
首先我们将标题栏和菜单栏两个组件创建出来,与EbookReader.vue同级,创建EbookTitle.vue和EbookMenu.vue。
首先先来完成标题栏
在EbookTitle.vue中写出结构和样式
<transition name="slide-down">
<div class="title-wrapper" v-show="menuVisible">
<div class="left">
<span class="icon-back" @click="back"></span>
</div>
<div class="right">
<div class="icon-wrapper">
<span class="icon-shelf"></span>
</div>
<div class="icon-wrapper">
<span class="icon-cart"></span>
</div>
<div class="icon-wrapper">
<span class="icon-more"></span>
</div>
</div>
</div>
</transition>
...
<style lang='scss' scoped>
@import "../../assets/styles/global.scss";