Bladeren bron

重构文档目录组件

Kevin Jiang 3 jaren geleden
bovenliggende
commit
cb4936e80e
4 gewijzigde bestanden met toevoegingen van 86 en 50 verwijderingen
  1. 27 1
      src/stores/doc-detail.ts
  2. 8 0
      src/types/doc.types.ts
  3. 6 5
      src/views/detail/DetailView.vue
  4. 45 44
      src/views/detail/components/DocCatalog.vue

+ 27 - 1
src/stores/doc-detail.ts

@@ -1,4 +1,4 @@
-import type { Doc } from "@/types/doc.types";
+import type { CatalogNode, Doc } from "@/types/doc.types";
 import type { Response } from "@/types/response.types";
 import { defineStore } from "pinia";
 import { ref, type Ref } from "vue";
@@ -8,6 +8,31 @@ import type { AxiosResponse } from "axios";
 export const useDocDetailStore = defineStore("docDetail", () => {
   const doc: Ref<Doc | null> = ref(null);
 
+  const catalog: Ref<CatalogNode[]> = ref([
+    {
+      title: '第一章 前言',
+      children: [
+        {
+          title: '第一节 概述'
+        },
+        {
+          title: '第二节 现状'
+        }
+      ]
+    },
+    {
+      title: '2 工业与民用建筑工程施工管理的主要内容',
+      children: [
+        {
+          title: '2.1 工业与民用建筑工程质量管理'
+        },
+        {
+          title: '2.2 工业与民用建筑工程施工进度管理'
+        }
+      ]
+    }
+  ]);
+
   function fetch(id: Object) {
     return docService.fetch(id).then((resp: AxiosResponse<Response<Doc>>) => {
       doc.value = resp.data.data;
@@ -15,6 +40,7 @@ export const useDocDetailStore = defineStore("docDetail", () => {
   }
 
   return {
+    catalog,
     doc,
     fetch,
   }

+ 8 - 0
src/types/doc.types.ts

@@ -2,3 +2,11 @@ export interface Doc {
   id: number;
   title: string;
 }
+
+/**
+ * 文档章节
+ */
+export interface CatalogNode {
+  title: string;
+  children?: CatalogNode[];
+}

+ 6 - 5
src/views/detail/DetailView.vue

@@ -1,7 +1,7 @@
 <script setup lang="ts">
+import { onMounted, onUnmounted, computed } from 'vue';
 import { useDocDetailStore } from '@/stores/doc-detail';
 import { useSideBarStore } from '@/stores/side-bar';
-import { onMounted, onUnmounted, computed } from 'vue';
 import { useRoute } from 'vue-router';
 import DocCatalog from './components/DocCatalog.vue';
 
@@ -24,19 +24,20 @@ onMounted(() => {
   }
 });
 
+const catalog = computed(() => docDetailStore.catalog);
+
 onUnmounted(() => {
   sideBarStore.setCollapse(false);
 });
-
 </script>
 
 <template>
   <a-row type="flex" :gutter="24">
-    <a-col :span="4">
+    <a-col :span="5">
       <h2>目录</h2>
-      <DocCatalog></DocCatalog>
+      <DocCatalog :catalog="catalog"></DocCatalog>
     </a-col>
-    <a-col :span="20">
+    <a-col :span="19">
       <div v-if="doc" class="doc-wrap">
         <h2 class="title">{{ doc.title }}</h2>
         <p>文档详情</p>

+ 45 - 44
src/views/detail/components/DocCatalog.vue

@@ -1,50 +1,51 @@
 <script setup lang="ts">
-import type { TreeProps } from "ant-design-vue";
-import { ref } from "vue";
+import { ref, type Ref, type PropType } from "vue";
+import type { CatalogNode } from "@/types/doc.types";
 
-const expandedKeys = ref<string[]>([]);
-const selectedKeys = ref<string[]>([]);
-const treeData = ref<TreeProps['treeData']>([
-  {
-    title: 'parent 0',
-    key: '0-0',
-    children: [
-      {
-        title: 'leaf 0-0',
-        key: '0-0-0',
-        isLeaf: true,
-      },
-      {
-        title: 'leaf 0-1',
-        key: '0-0-1',
-        isLeaf: true,
-      },
-    ],
-  },
-  {
-    title: 'parent 1',
-    key: '0-1',
-    children: [
-      {
-        title: 'leaf 1-0',
-        key: '0-1-0',
-        isLeaf: true,
-      },
-      {
-        title: 'leaf 1-1',
-        key: '0-1-1',
-        isLeaf: true,
-      },
-    ],
-  },
-]);
+const props = defineProps({
+  catalog: {
+    type: Object as PropType<CatalogNode[]>,
+    default() {
+      return [];
+    }
+  }
+});
+
+const activeKey: Ref<string[]> = ref([]);
+
+function onChapterClick(e: MouseEvent, index: number, subIndex?: number) {
+  e.stopPropagation();
+  const catalogNode = props.catalog[index];
+  if (subIndex === undefined) {
+    console.log('点击了第一级章节标题', catalogNode.title);
+  } else {
+    const subCatalogNode = catalogNode.children![subIndex];
+    console.log('点击了第二级标题', subCatalogNode.title);
+  }
+}
 </script>
 
 <template>
-  <a-directory-tree
-    v-model:expandedKeys="expandedKeys"
-    v-model:selectedKeys="selectedKeys"
-    :tree-data="treeData"
-    :show-icon="false"
-  ></a-directory-tree>
+  <a-collapse v-model:activeKey="activeKey">
+    <a-collapse-panel
+      v-for="(item, index) in catalog"
+      :header="item.title"
+      :key="index"
+      @click="onChapterClick($event, index)"
+    >
+      <div v-for="(subItem, subIndex) in item.children" :key="index+'-'+subIndex" class="sub-catalog">
+        <a href="javascript:void(0)" @click="onChapterClick($event, index, subIndex)">{{ subItem.title }}</a>
+      </div>
+    </a-collapse-panel>
+  </a-collapse>
 </template>
+
+<style scoped lang="scss">
+.sub-catalog {
+  margin-top: 6px;
+
+  &:first-child {
+    margin-top: 0;
+  }
+}
+</style>