Files
tunji2/src/components/left-area/NotebookNode.vue
2026-06-01 17:28:00 +08:00

87 lines
2.4 KiB
Vue

<script setup>
import { ref, onMounted } from 'vue'
import { useRouter } from 'vue-router'
import { useNotebooksStore } from '@/stores/notebooks'
import { useNotesStore } from '@/stores/notes'
import { ChevronRight, Folder, FolderOpen } from 'lucide-vue-next'
import NoteItem from './NoteItem.vue'
const props = defineProps({
notebook: { type: Object, required: true },
level: { type: Number, default: 0 },
})
const router = useRouter()
const notebooksStore = useNotebooksStore()
const notesStore = useNotesStore()
const notes = ref([])
const isExpanded = () => notebooksStore.isExpanded(props.notebook.path)
function toggle() {
notebooksStore.toggleExpand(props.notebook.path)
}
async function loadNotes() {
const entries = await window.tunjiAPI.file.list(props.notebook.path)
notes.value = entries
.filter(e => e.isFile && e.name.endsWith('.md'))
.map(e => ({
id: e.name.replace('.md', ''),
title: e.name.replace('.md', ''),
filePath: e.path,
}))
}
function openNote(note) {
router.push({ name: 'note-detail', params: { id: note.id } })
}
onMounted(loadNotes)
</script>
<template>
<div>
<!-- 笔记本节点 -->
<button
class="w-full flex items-center gap-1.5 px-2 py-1.5 rounded-md text-sm transition-colors"
:style="{ paddingLeft: (level * 12 + 8) + 'px', color: 'var(--p-surface-600)' }"
@click="toggle"
@mouseenter="$event.target.style.backgroundColor = 'var(--p-surface-100)'"
@mouseleave="$event.target.style.backgroundColor = 'transparent'"
>
<ChevronRight
:size="14"
class="transition-transform flex-shrink-0"
:class="{ 'rotate-90': isExpanded() }"
:style="{ color: 'var(--p-surface-400)' }"
/>
<component
:is="isExpanded() ? FolderOpen : Folder"
:size="16"
:style="{ color: 'var(--p-primary-500)' }"
/>
<span class="truncate">{{ notebook.name }}</span>
</button>
<!-- 子内容 -->
<div v-if="isExpanded()">
<!-- 子笔记本 -->
<NotebookNode
v-for="child in notebook.children"
:key="child.path"
:notebook="child"
:level="level + 1"
/>
<!-- 笔记列表 -->
<NoteItem
v-for="note in notes"
:key="note.id"
:note="note"
:level="level + 1"
@click="openNote(note)"
/>
</div>
</div>
</template>