vp-content.vue 1.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748
  1. <script setup lang="ts">
  2. import { computed, nextTick, onUpdated, ref, watch } from 'vue'
  3. import nprogress from 'nprogress'
  4. import { useData, useRoute } from 'vitepress'
  5. import { useSidebar } from '../composables/sidebar'
  6. import VPHeroContent from './vp-hero-content.vue'
  7. import VPDocContent from './vp-doc-content.vue'
  8. import VPNotFound from './vp-not-found.vue'
  9. import VPFooter from './globals/vp-footer.vue'
  10. const { frontmatter } = useData()
  11. const route = useRoute()
  12. const isNotFound = computed(() => route.component === VPNotFound)
  13. const isHeroPost = computed(() => frontmatter.value.page === true)
  14. const { hasSidebar } = useSidebar()
  15. const props = defineProps<{ isSidebarOpen: boolean }>()
  16. const shouldUpdateProgress = ref(true)
  17. watch(
  18. () => props.isSidebarOpen,
  19. (val) => {
  20. // delay the flag update since watch is called before onUpdated
  21. nextTick(() => {
  22. shouldUpdateProgress.value = !val
  23. })
  24. }
  25. )
  26. onUpdated(() => {
  27. if (shouldUpdateProgress.value) {
  28. nprogress.done()
  29. }
  30. })
  31. </script>
  32. <template>
  33. <main :class="{ 'page-content': true, 'has-sidebar': hasSidebar }">
  34. <VPNotFound v-if="isNotFound" />
  35. <VPHeroContent v-else-if="isHeroPost" />
  36. <VPDocContent v-else>
  37. <template #content-top><slot name="content-top" /></template>
  38. <template #content-bottom><slot name="content-bottom" /></template>
  39. </VPDocContent>
  40. <VPFooter v-if="!isHeroPost" />
  41. </main>
  42. </template>