slidev
slidev copied to clipboard
Slide export doesn't handle `v-if` in `global-top` or `global-bottom` based on conditional using `currentPage`, `currentLayout`
Describe the bug
The exporter seems to fail to handle v-if
conditionals in global-top
or global-bottom
that use currentPage
, currentLayout
, and other navigation composables.
My global bottom is intended to only be displayed on non-cover
slides after the first. This functions properly in browser view but fails to display properly on export.
<script setup lang="ts">
// import { computed } from "vue";
import { useNav, useSlideContext } from "@slidev/client"
// const { $slidev, $route } = useSlideContext()
const { currentPage, currentLayout } = useNav()
</script>
<template>
<div v-if="currentPage.value > 1 && currentLayout !== 'cover'" class="slide-footer absolute w-full bottom-0 left-0 p-0 text-sm" style="display: grid; grid-template-columns: 33.33% 33.33% 33.34%; color: #ffffff">
<div class="footer-comp justify-start" style="display: flex; flex-direction: row; gap: 7px; padding-left: 10px">
<Item text="Ani Perumalla">
<carbon:user-avatar-filled-alt />
</Item>
<Item text="ani-per.gitlab.io">
<carbon:link />
</Item>
</div>
<div class="footer-comp justify-center" style="display: flex; flex-direction: row; gap: 4px; padding-top: 4px; padding-bottom: 4px;">
<img src="./img/logos/PSU_Engineering.png" alt="PSU Mark">
<img src="./img/logos/PSU_Aero.png" alt="PSU Mark">
</div>
<div class="footer-comp justify-end" style="display: flex; flex-direction: row; gap: 7px; padding-right: 10px">
<Item text="PSU UAS Research Lab">
<carbon:drone />
</Item>
<Item text="<a href='https://purl.psu.edu'>purl.psu.edu</a>">
<carbon:link />
</Item>
</div>
</div>
</template>
This produces a proper global bottom in browser view, but no global bottom in the exported pdf:
When I remove the conditional v-if="currentPage.value > 1 && currentLayout !== 'cover'"
from the first div
in the template, the exporter displays the global bottom correctly:
Desktop
- OS: Windows 11
- Browser: Brave, Firefox, Edge
- Slidev version: 0.48.8
useNav()
is the global navigation API, which is a singleton.
useNav().currentPage
is the page displayed in the main area, while $page.value
is the page this component is rendered on. (Refer to https://sli.dev/custom/vue-context#page)
If you want to get the current layout, you can use $nav.currentLayout.value
.
$page
and $nav
are available without importing manually. See https://sli.dev/custom/vue-context .
useNav()
is the global navigation API, which is a singleton.
useNav().currentPage
is the page displayed in the main area, while$page.value
is the page this component is rendered on. (Refer to https://sli.dev/custom/vue-context#page)If you want to get the current layout, you can use
$nav.currentLayout.value
.
$page
and$nav
are available without importing manually. See https://sli.dev/custom/vue-context .
Thank you for the clarification. However, I'm having a few issues when trying to correct based on this information.
- I can't use
$page
and$nav
inglobal-top/bottom
in the conditional without importing fromuseSlideContext()
. I tried without and the conditional failed like before. Is there an exception for root-level files likeglobal-top/bottom
? - Even when I ignore this and use
$page
and$nav
inglobal-top/bottom
imported fromuseSlideContext()
in the conditional, the global top/bottom still did not show up on the exported slides even though they were rendered properly in browser view.
I can't use
$page
and$nav
inglobal-top/bottom
in the conditional without importing fromuseSlideContext()
. I tried without and the conditional failed like before. Is there an exception for root-level files likeglobal-top/bottom
?
After some debugging I found this is because there is a "useSlideContext()
" in the source code (even it's commented out), and then Slidev won't inject const { $page, ...} = useSlideContext()
automatically in this condition.
- Even when I ignore this and use
$page
and$nav
inglobal-top/bottom
imported fromuseSlideContext()
in the conditional, the global top/bottom still did not show up on the exported slides even though they were rendered properly in browser view.
This is a bug. In print mode, the global-top
is rendered before injectionCurrentPage
is provided, so the value fallbacks to the global one. I will fix this ASAP.
I can't use
$page
and$nav
inglobal-top/bottom
in the conditional without importing fromuseSlideContext()
. I tried without and the conditional failed like before. Is there an exception for root-level files likeglobal-top/bottom
?After some debugging I found this is because there is a "
useSlideContext()
" in the source code (even it's commented out), and then Slidev won't injectconst { $page, ...} = useSlideContext()
automatically in this condition.
- Even when I ignore this and use
$page
and$nav
inglobal-top/bottom
imported fromuseSlideContext()
in the conditional, the global top/bottom still did not show up on the exported slides even though they were rendered properly in browser view.This is a bug. In print mode, the
global-top
is rendered beforeinjectionCurrentPage
is provided, so the value fallbacks to the global one. I will fix this ASAP.
Thank you for the very quick response! I really appreciate your help, and I'm glad to have helped identify the bugs.
I've opened #1492 for this. However, as antfu pointed out in https://github.com/slidevjs/slidev/pull/1492#issuecomment-2031616230, #1492 is currently not mergable, and the --per-slide
flag as a workaround currently.
Now we have slide layers for this use case. You can simply migrate global layers to slide layers, which is also described in https://sli.dev/features/global-layers.