Skip to content

Commit 0fba680

Browse files
committed
feat: options to disable slide preload, close #102
1 parent f999a94 commit 0fba680

File tree

8 files changed

+76
-61
lines changed

8 files changed

+76
-61
lines changed

docs/guide/animations.md

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,27 @@ Slidev has [@vueuse/motion](https://motion.vueuse.org/) built-in. You can use th
166166
</div>
167167
```
168168

169-
The text `Slidev` will move from `-80px` to its original position on revealing.
169+
The text `Slidev` will move from `-80px` to its original position on initialization.
170+
171+
> Note: Slidev preloads the next slide for performance, which means the animations might start before you navigate to the page. To get it works properly, you can disable the preloading for the particular slide
172+
>
173+
> ```md
174+
> ---
175+
> preload: false
176+
> ---
177+
> ```
178+
>
179+
> Or control the element life-cycle with `v-if` to have fine-grained controls
180+
>
181+
> ```html
182+
> <div
183+
> v-if="$slidev.nav.currentPage === 7"
184+
> v-motion
185+
> :initial="{ x: -80 }"
186+
> :enter="{ x: 0 }">
187+
> Slidev
188+
> </div>
189+
> ```
170190
171191
Learn mode: [Demo](https://sli.dev/demo/starter/7) | [@vueuse/motion](https://motion.vueuse.org/) | [v-motion](https://motion.vueuse.org/directive-usage.html) | [Presets](https://motion.vueuse.org/presets.html)
172192

packages/client/internals/Play.vue

Lines changed: 4 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,16 @@
11
<script setup lang="ts">
2-
import { ref, computed, watch } from 'vue'
3-
import type { RouteRecordRaw } from 'vue-router'
2+
import { ref, computed } from 'vue'
43
import { isPrintMode, showEditor, windowSize, isScreenVertical, slideScale } from '../state'
5-
import { next, prev, currentRoute, clicks, clicksElements, useSwipeControls, rawRoutes, nextRoute } from '../logic/nav'
4+
import { next, prev, useSwipeControls } from '../logic/nav'
65
import { registerShotcuts } from '../logic/shortcuts'
76
import Controls from './Controls.vue'
87
import SlideContainer from './SlideContainer.vue'
98
import Editor from './Editor.vue'
109
import NavControls from './NavControls.vue'
11-
import SlideWrapper from './SlideWrapper.vue'
10+
import SlidesShow from './SlidesShow.vue'
1211
1312
registerShotcuts()
1413
15-
// preload next route
16-
watch(currentRoute, () => {
17-
if (currentRoute.value?.meta)
18-
currentRoute.value.meta.loaded = true
19-
if (nextRoute.value?.meta)
20-
nextRoute.value.meta.loaded = true
21-
}, { immediate: true })
22-
2314
const root = ref<HTMLDivElement>()
2415
function onClick(e: MouseEvent) {
2516
if (showEditor.value)
@@ -37,13 +28,6 @@ function onClick(e: MouseEvent) {
3728
useSwipeControls(root)
3829
3930
const presistNav = computed(() => isScreenVertical.value || showEditor.value)
40-
41-
const getClass = (route: RouteRecordRaw) => {
42-
const no = route?.meta?.slide?.no
43-
if (no != null)
44-
return `slidev-page-${no}`
45-
return ''
46-
}
4731
</script>
4832

4933
<template>
@@ -55,17 +39,7 @@ const getClass = (route: RouteRecordRaw) => {
5539
@click="onClick"
5640
>
5741
<template #>
58-
<template v-for="route of rawRoutes" :key="route.path">
59-
<SlideWrapper
60-
:is="route?.component"
61-
v-show="route === currentRoute"
62-
v-if="route.meta.loaded"
63-
:clicks="route === currentRoute ? clicks : 0"
64-
:clicks-elements="route.meta.clicksElements"
65-
:clicks-disabled="false"
66-
:class="getClass(route)"
67-
/>
68-
</template>
42+
<SlidesShow />
6943
</template>
7044
<template #controls>
7145
<div

packages/client/internals/Presenter.vue

Lines changed: 5 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
<script setup lang="ts">
22
import { useHead } from '@vueuse/head'
3-
import { ref, computed, watch } from 'vue'
3+
import { ref, computed } from 'vue'
44
import { useTimestamp } from '@vueuse/core'
55
import type { RouteRecordRaw } from 'vue-router'
6-
import { total, currentPage, currentRoute, nextRoute, clicks, clicksElements, useSwipeControls, clicksTotal, hasNext, rawRoutes } from '../logic/nav'
6+
import { total, currentPage, currentRoute, nextRoute, clicks, useSwipeControls, clicksTotal, hasNext } from '../logic/nav'
77
import { showOverview } from '../state'
88
import { configs } from '../env'
99
import { registerShotcuts } from '../logic/shortcuts'
@@ -12,18 +12,11 @@ import NavControls from './NavControls.vue'
1212
import SlidesOverview from './SlidesOverview.vue'
1313
import NoteEditor from './NoteEditor.vue'
1414
import Goto from './Goto.vue'
15+
import SlidesShow from './SlidesShow.vue'
1516
import SlideWrapper from './SlideWrapper.vue'
1617
1718
registerShotcuts()
1819
19-
// preload next route
20-
watch(currentRoute, () => {
21-
if (currentRoute.value?.meta)
22-
currentRoute.value.meta.loaded = true
23-
if (nextRoute.value?.meta)
24-
nextRoute.value.meta.loaded = true
25-
}, { immediate: true })
26-
2720
useHead({
2821
title: configs.title ? `Presenter - ${configs.title} - Slidev` : 'Presenter - Slidev',
2922
})
@@ -67,7 +60,7 @@ const nextSlide = computed(() => {
6760
6861
useSwipeControls(main)
6962
70-
const getClass = (route: RouteRecordRaw) => {
63+
const getClass = (route?: RouteRecordRaw) => {
7164
const no = route?.meta?.slide?.no
7265
if (no != null)
7366
return `slidev-page-${no}`
@@ -99,17 +92,7 @@ const getClass = (route: RouteRecordRaw) => {
9992
class="h-full w-full"
10093
>
10194
<template #>
102-
<template v-for="route of rawRoutes" :key="route.path">
103-
<SlideWrapper
104-
:is="route?.component"
105-
v-if="route.meta.loaded"
106-
:style="{ display: route === currentRoute ? null : 'none' }"
107-
:clicks="route === currentRoute ? clicks : 0"
108-
:clicks-elements="route.meta.clicksElements"
109-
:clicks-disabled="false"
110-
:class="getClass(route)"
111-
/>
112-
</template>
95+
<SlidesShow />
11396
</template>
11497
</SlideContainer>
11598
</div>

packages/client/internals/SlideWrapper.vue

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
<script setup lang="ts">
2-
import { useElementSize, useVModel } from '@vueuse/core'
3-
import { computed, defineProps, ref, watchEffect, provide, defineEmit } from 'vue'
4-
import type { RouteRecordRaw } from 'vue-router'
5-
import { slideAspect, slideWidth, slideHeight } from '../constants'
2+
import { useVModel } from '@vueuse/core'
3+
import { defineProps, provide, defineEmit } from 'vue'
64
import { injectionClicks, injectionClicksDisabled, injectionClicksElements } from '../modules/directives'
75
86
const emit = defineEmit()
@@ -18,6 +16,7 @@ const props = defineProps({
1816
},
1917
is: {
2018
type: Object,
19+
default: undefined,
2120
},
2221
})
2322
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
<script setup lang="ts">
2+
import { watch } from 'vue'
3+
import type { RouteRecordRaw } from 'vue-router'
4+
import { currentRoute, clicks, rawRoutes, nextRoute } from '../logic/nav'
5+
import SlideWrapper from './SlideWrapper.vue'
6+
7+
// preload next route
8+
watch(currentRoute, () => {
9+
if (currentRoute.value?.meta && currentRoute.value.meta.preload !== false)
10+
currentRoute.value.meta.__preloaded = true
11+
if (nextRoute.value?.meta && nextRoute.value.meta.preload !== false)
12+
nextRoute.value.meta.__preloaded = true
13+
}, { immediate: true })
14+
15+
const getClass = (route: RouteRecordRaw) => {
16+
const no = route?.meta?.slide?.no
17+
if (no != null)
18+
return `slidev-page-${no}`
19+
return ''
20+
}
21+
</script>
22+
23+
<template>
24+
<template v-for="route of rawRoutes" :key="route.path">
25+
<SlideWrapper
26+
:is="route?.component"
27+
v-show="route === currentRoute"
28+
v-if="route.meta?.__preloaded || route === currentRoute"
29+
:clicks="route === currentRoute ? clicks : 0"
30+
:clicks-elements="route.meta?.__clicksElements || []"
31+
:clicks-disabled="false"
32+
:class="getClass(route)"
33+
/>
34+
</template>
35+
</template>

packages/client/logic/nav.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ export const hasNext = computed(() => currentPage.value < rawRoutes.length - 1)
2222
export const hasPrev = computed(() => currentPage.value > 1)
2323
export const nextRoute = computed(() => rawRoutes.find(i => i.path === `${Math.min(rawRoutes.length, currentPage.value + 1)}`))
2424

25-
export const clicksElements = computed<HTMLElement[]>(() => currentRoute.value?.meta?.clicksElements || [])
25+
export const clicksElements = computed<HTMLElement[]>(() => currentRoute.value?.meta?.__clicksElements || [])
2626
export const clicks = computed<number>({
2727
get() {
2828
let clicks = +query.clicks || 0

packages/client/routes.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,6 @@ export const router = createRouter({
4040
declare module 'vue-router' {
4141
interface RouteMeta {
4242
layout: string
43-
clicksElements: HTMLElement[]
44-
loaded?: boolean
4543
name?: string
4644
class?: string
4745
clicks?: number
@@ -52,5 +50,9 @@ declare module 'vue-router' {
5250
no: number
5351
file: string
5452
}
53+
54+
// private fields
55+
__clicksElements: HTMLElement[]
56+
__preloaded?: boolean
5557
}
5658
}

packages/create-app/template/slides.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,8 @@ theme: seriph
183183
Read more about [How to use a theme](https://sli.dev/themes/use.html) and
184184
check out the [Awesome Themes Gallery](https://sli.dev/themes/gallery.html).
185185

186+
---
187+
preload: false
186188
---
187189

188190
# Animations
@@ -198,7 +200,7 @@ Animations are powered by [@vueuse/motion](https://motion.vueuse.org/).
198200
</div>
199201
```
200202

201-
<div class="w-60 relative mt-6" v-if="$slidev.nav.currentPage === 7">
203+
<div class="w-60 relative mt-6">
202204
<div class="relative w-40 h-40">
203205
<img
204206
v-motion

0 commit comments

Comments
 (0)