137 lines
3.3 KiB
Vue
137 lines
3.3 KiB
Vue
<template>
|
|
<div
|
|
:class="{ 'cata-wrapper': true, visible: popCataVisible }"
|
|
:style="popupTheme"
|
|
>
|
|
<div class="title">目录</div>
|
|
<virtual-list
|
|
style="height: 300px; overflow: auto"
|
|
:class="{ night: isNight, day: !isNight }"
|
|
ref="virtualListRef"
|
|
data-key="index"
|
|
wrap-class="data-wrapper"
|
|
item-class="cata"
|
|
:data-sources="virtualListdata"
|
|
:data-component="CatalogItem"
|
|
:estimate-size="40"
|
|
:extra-props="{ gotoChapter, currentChapterIndex }"
|
|
/>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import VirtualList from 'vue3-virtual-scroll-list'
|
|
import settings from '../config/themeConfig'
|
|
import '../assets/fonts/popfont.css'
|
|
import CatalogItem from './CatalogItem.vue'
|
|
import type { BookChapter } from '@/book'
|
|
|
|
const store = useBookStore()
|
|
|
|
const { catalog, popCataVisible, miniInterface } = storeToRefs(store)
|
|
|
|
//主题
|
|
const isNight = computed(() => store.theme)
|
|
const theme = computed(() => store.theme)
|
|
const popupTheme = computed(() => {
|
|
return {
|
|
background: settings.themes[theme.value].popup,
|
|
}
|
|
})
|
|
|
|
//虚拟列表 数据源
|
|
const virtualListdata = computed(() => {
|
|
const catalogValue = catalog.value
|
|
if (miniInterface.value) return catalogValue
|
|
|
|
// pc端 virtualListIitem有2个章节
|
|
const length = Math.ceil(catalogValue.length / 2)
|
|
const virtualListDataSource = new Array<{
|
|
index: number
|
|
catas: BookChapter[]
|
|
}>(length)
|
|
|
|
let i = 0
|
|
while (i < length) {
|
|
virtualListDataSource[i] = {
|
|
index: i,
|
|
catas: catalogValue.slice(2 * i, 2 * i + 2),
|
|
}
|
|
i++
|
|
}
|
|
return virtualListDataSource
|
|
})
|
|
|
|
//打开目录 计算当前章节对应的虚拟列表位置
|
|
const virtualListRef = ref()
|
|
const currentChapterIndex = computed({
|
|
get: () => store.readingBook.chapterIndex,
|
|
set: value => (store.readingBook.chapterIndex = value),
|
|
})
|
|
const virtualListIndex = computed(() => {
|
|
const index = currentChapterIndex.value
|
|
if (miniInterface.value) return index
|
|
// pc端 virtualListIitem有2个章节
|
|
return Math.floor(index / 2)
|
|
})
|
|
onUpdated(() => {
|
|
// dom更新触发ResizeObserver,更新虚拟列表内部的sizes Map
|
|
if (!popCataVisible.value) return
|
|
virtualListRef.value.scrollToIndex(virtualListIndex.value)
|
|
})
|
|
|
|
// 点击加载对应章节内容
|
|
const emit = defineEmits(['getContent'])
|
|
const gotoChapter = (chapter: BookChapter) => {
|
|
const chapterIndex = catalog.value.indexOf(chapter)
|
|
currentChapterIndex.value = chapterIndex
|
|
store.setPopCataVisible(false)
|
|
store.setContentLoading(true)
|
|
store.saveBookProgress()
|
|
emit('getContent', chapterIndex)
|
|
}
|
|
</script>
|
|
|
|
<style lang="scss" scoped>
|
|
.cata-wrapper {
|
|
margin: -16px;
|
|
padding: 18px 0 24px 25px;
|
|
|
|
/* background: #ede7da url('../assets/imgs/themes/popup_1.png') repeat; */
|
|
.title {
|
|
font-size: 18px;
|
|
font-weight: 400;
|
|
font-family: FZZCYSK;
|
|
margin: 0 0 20px 0;
|
|
color: #ed4259;
|
|
width: fit-content;
|
|
border-bottom: 1px solid #ed4259;
|
|
}
|
|
:deep(.data-wrapper) {
|
|
.cata {
|
|
/*width: 50%;*/
|
|
height: 40px;
|
|
cursor: pointer;
|
|
font:
|
|
16px / 40px PingFangSC-Regular,
|
|
HelveticaNeue-Light,
|
|
'Helvetica Neue Light',
|
|
'Microsoft YaHei',
|
|
sans-serif;
|
|
}
|
|
}
|
|
|
|
.night {
|
|
:deep(.cata) {
|
|
border-bottom: 1px solid #666;
|
|
}
|
|
}
|
|
|
|
.day {
|
|
:deep(.cata) {
|
|
border-bottom: 1px solid #f2f2f2;
|
|
}
|
|
}
|
|
}
|
|
</style>
|