PopCatalog.vue 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. <template>
  2. <div
  3. :class="{ 'cata-wrapper': true, visible: popCataVisible }"
  4. :style="popupTheme"
  5. >
  6. <div class="title">目录</div>
  7. <virtual-list
  8. style="height: 300px; overflow: auto"
  9. :class="{ night: isNight, day: !isNight }"
  10. ref="virtualListRef"
  11. data-key="index"
  12. wrap-class="data-wrapper"
  13. item-class="cata"
  14. :data-sources="virtualListdata"
  15. :data-component="CatalogItem"
  16. :estimate-size="40"
  17. :extra-props="{ gotoChapter, currentChapterIndex }"
  18. />
  19. </div>
  20. </template>
  21. <script setup>
  22. import VirtualList from "vue3-virtual-scroll-list";
  23. import settings from "../config/themeConfig";
  24. import "../assets/fonts/popfont.css";
  25. import CatalogItem from "./CatalogItem.vue";
  26. const store = useBookStore();
  27. const isNight = computed(() => theme.value == 6);
  28. const { catalog, popCataVisible, miniInterface } = storeToRefs(store);
  29. const theme = computed(() => {
  30. return store.config.theme;
  31. });
  32. const popupTheme = computed(() => {
  33. return {
  34. background: settings.themes[theme.value].popup,
  35. };
  36. });
  37. const currentChapterIndex = computed({
  38. get: () => store.readingBook.index,
  39. set: (value) => (store.readingBook.index = value),
  40. });
  41. const virtualListdata = computed(() => {
  42. let catalogValue = catalog.value;
  43. if (miniInterface.value) return catalogValue;
  44. // pc端 virtualListIitem有2个章节
  45. let length = Math.ceil(catalogValue.length / 2);
  46. let virtualListDataSource = new Array(length);
  47. let i = 0;
  48. while (i < length) {
  49. virtualListDataSource[i] = {
  50. index: i,
  51. catas: catalogValue.slice(2 * i, 2 * i + 2),
  52. };
  53. i++;
  54. }
  55. return virtualListDataSource;
  56. });
  57. const emit = defineEmits(["getContent"]);
  58. const gotoChapter = (note) => {
  59. const chapterIndex = catalog.value.indexOf(note);
  60. currentChapterIndex.value = chapterIndex;
  61. store.setPopCataVisible(false);
  62. store.setContentLoading(true);
  63. emit("getContent", chapterIndex);
  64. };
  65. const virtualListRef = ref();
  66. const virtualListIndex = computed(() => {
  67. let index = currentChapterIndex.value;
  68. if (miniInterface.value) return index;
  69. return Math.floor(index / 2);
  70. });
  71. onUpdated(() => {
  72. // dom更新触发ResizeObserver,更新虚拟列表内部的sizes Map
  73. if (!popCataVisible.value) return;
  74. virtualListRef.value.scrollToIndex(virtualListIndex.value);
  75. });
  76. </script>
  77. <style lang="scss" scoped>
  78. .cata-wrapper {
  79. margin: -16px;
  80. padding: 18px 0 24px 25px;
  81. // background: #ede7da url('../assets/imgs/themes/popup_1.png') repeat;
  82. .title {
  83. font-size: 18px;
  84. font-weight: 400;
  85. font-family: FZZCYSK;
  86. margin: 0 0 20px 0;
  87. color: #ed4259;
  88. width: fit-content;
  89. border-bottom: 1px solid #ed4259;
  90. }
  91. :deep(.data-wrapper) {
  92. .cata {
  93. //width: 50%;
  94. height: 40px;
  95. cursor: pointer;
  96. font: 16px / 40px PingFangSC-Regular, HelveticaNeue-Light,
  97. "Helvetica Neue Light", "Microsoft YaHei", sans-serif;
  98. }
  99. }
  100. .night {
  101. :deep(.cata) {
  102. border-bottom: 1px solid #666;
  103. }
  104. }
  105. .day {
  106. :deep(.cata) {
  107. border-bottom: 1px solid #f2f2f2;
  108. }
  109. }
  110. }
  111. </style>