Skip to content

Commit ea5a7a4

Browse files
committed
doc: improve confetti tutorial
1 parent dfec3b4 commit ea5a7a4

File tree

2 files changed

+80
-38
lines changed

2 files changed

+80
-38
lines changed

docs/content/docs/1.getting-started/3.confetti-tutorial.md

Lines changed: 55 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,9 @@ useScriptNpm({
8888
file: 'dist/js-confetti.browser.js',
8989
version: '0.12.0',
9090
// tell useScript how to resolve the third-party script
91-
use: () => typeof window.JSConfetti !== 'undefined' && new window.JSConfetti()
91+
use() {
92+
return { JSConfetti: window.JSConfetti }
93+
},
9294
})
9395
</script>
9496
```
@@ -97,35 +99,44 @@ useScriptNpm({
9799

98100
Now that we have a way to resolve the third-party script API, we can start using it.
99101

100-
To use the API we have a couple of options proxied functions or awaiting the script load.
102+
The `js-confetti` library requires us to instantiate a new instance of the `JSConfetti` class everytime it's used,
103+
the most compatible way to handle this is to for the script to load explicitly.
101104

102-
See the [Understanding proxied functions](/docs/guides/script-loading#Understanding-proxied-functions) section for more information.
105+
However, we can also make use of [proxied functions](/docs/guides/script-loading#Understanding-proxied-functions) if we prefer an easier to use API. Note that this will break
106+
when switching between pages as `new window.JSConfetti()` needs to be called between pages.
103107

104108
::code-group
105109

106-
```vue [Proxy Usage]
110+
```vue [Explicit script Load]
107111
<script setup lang="ts">
108-
const { addConfetti } = useScriptNpm({
112+
const { $script } = useScriptNpm({
109113
packageName: 'js-confetti',
110114
file: 'dist/js-confetti.browser.js',
111115
version: '0.12.0',
112-
use: () => typeof window.JSConfetti !== 'undefined' && new window.JSConfetti()
116+
use() {
117+
return { JSConfetti: window.JSConfetti }
118+
},
119+
})
120+
onMounted(() => {
121+
$script.then(({ JSConfetti }) => {
122+
// using the real API instance
123+
const confetti = new JSConfetti()
124+
confetti.addConfetti({ emojis: ['🌈', '⚡️', '💥', '✨', '💫', '🌸'] })
125+
})
113126
})
114-
// using the proxied function that will be called when the script is loaded
115-
addConfetti({ emojis: ['🌈', '⚡️', '💥', '✨', '💫', '🌸'] })
116127
</script>
117128
```
118129

119-
```vue [Await Load]
130+
```vue [Proxy Functions]
120131
<script setup lang="ts">
121-
const { $script } = useScriptNpm({
132+
const { addConfetti } = useScriptNpm({
122133
packageName: 'js-confetti',
123134
file: 'dist/js-confetti.browser.js',
124135
version: '0.12.0',
125136
use: () => typeof window.JSConfetti !== 'undefined' && new window.JSConfetti()
126137
})
127-
$script.then(({ addConfetti }) => {
128-
// using the real API instance
138+
onMounted(() => {
139+
// just works
129140
addConfetti({ emojis: ['🌈', '⚡️', '💥', '✨', '💫', '🌸'] })
130141
})
131142
</script>
@@ -144,23 +155,34 @@ You can use the generic from the `useScriptNpm` composable to add types to the s
144155
```vue [app.vue]
145156
<script setup lang="ts">
146157
export interface JSConfettiApi {
147-
addConfetti: (options?: { emojis: string[] }) => void
158+
JSConfetti: {
159+
new (): {
160+
addConfetti: (options?: { emojis: string[] }) => void
161+
}
162+
}
148163
}
149164
150165
declare global {
151-
interface Window {
152-
JSConfetti: { new (): JSConfettiApi }
153-
}
166+
interface Window extends JSConfettiApi {}
154167
}
155168
156-
const { addConfetti } = useScriptNpm<JSConfettiApi>({
169+
const { $script } = useScriptNpm<JSConfettiApi>({
157170
packageName: 'js-confetti',
158171
file: 'dist/js-confetti.browser.js',
159172
version: '0.12.0',
160-
use: () => typeof window.JSConfetti !== 'undefined' && new window.JSConfetti()
173+
scriptOptions: {
174+
use() {
175+
return { JSConfetti: window.JSConfetti }
176+
},
177+
},
178+
})
179+
onMounted(() => {
180+
$script.then(({ JSConfetti }) => {
181+
const confetti = new JSConfetti()
182+
// fully typed!
183+
confetti.addConfetti({ emojis: ['🌈', '⚡️', '💥', '✨', '💫', '🌸'] })
184+
})
161185
})
162-
// fully typed!
163-
addConfetti({ emojis: ['🌈', '⚡️', '💥', '✨', '💫', '🌸'] })
164186
</script>
165187
```
166188

@@ -173,15 +195,19 @@ In this example we'll combine the [useScriptTriggerElement](/docs/api/use-script
173195
```vue [app.vue]
174196
<script setup lang="ts">
175197
const mouseOverEl = ref<HTMLElement>()
176-
const { addConfetti } = useScriptNpm<{ addConfetti: (options?: { emojis: string[] }) => void }>({
177-
packageName: 'js-confetti',
178-
file: 'dist/js-confetti.browser.js',
179-
version: '0.12.0',
198+
const { $script } = useScriptNpm({
199+
// ..
180200
scriptOptions: {
181201
trigger: useScriptTriggerElement({ trigger: 'mouseover', el: mouseOverEl })
182202
}
183203
})
184-
addConfetti({ emojis: ['🌈', '⚡️', '💥', '✨', '💫', '🌸'] })
204+
// ..
205+
onMounted(() => {
206+
$script.then(({ JSConfetti }) => {
207+
const confetti = new JSConfetti()
208+
confetti.addConfetti({ emojis: ['L', 'O', 'A', 'D', 'E', 'D'] })
209+
})
210+
})
185211
</script>
186212
187213
<template>
@@ -199,15 +225,13 @@ To bundle the script, you can use the `bundle` option.
199225

200226
```vue [app.vue]
201227
<script setup lang="ts">
202-
const { addConfetti } = useScriptNpm<{ addConfetti: (options?: { emojis: string[] }) => void }>({
203-
packageName: 'js-confetti',
204-
file: 'dist/js-confetti.browser.js',
205-
version: '0.12.0',
228+
const { $script } = useScriptNpm({
229+
// ...
206230
scriptOptions: {
207231
bundle: true
208232
}
209233
})
210-
addConfetti({ emojis: ['🌈', '⚡️', '💥', '✨', '💫', '🌸'] })
234+
// ..
211235
</script>
212236
```
213237

@@ -217,6 +241,4 @@ You should see the script loaded in from your apps server.
217241

218242
In this tutorial, you learned how to load the `js-confetti` script using the `useScriptNpm` registry script.
219243

220-
To learn more about the specific concepts you explored, check out the following documentation:
221-
- [Script Loading Concepts](/docs/guides/script-loading)
222-
- [Bundling](/docs/guides/bundling)
244+
To learn more about the specific concepts you explored, check out the documentation for [Key concepts](/docs/guides/key-concepts).

playground/pages/npm/js-confetti.vue

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,41 @@
11
<script lang="ts" setup>
2-
import { ref, useScriptTriggerElement, useScriptNpm } from '#imports'
2+
import { ref, useScriptTriggerElement, useScriptNpm, onMounted } from '#imports'
33
44
const mouseOverEl = ref()
5-
const { addConfetti } = useScriptNpm<JSConfettiApi>({
5+
export interface JSConfettiApi {
6+
JSConfetti: {
7+
new (): {
8+
addConfetti: (options?: { emojis: string[] }) => void
9+
}
10+
}
11+
}
12+
13+
declare global {
14+
interface Window extends JSConfettiApi {}
15+
}
16+
17+
const { $script } = useScriptNpm<JSConfettiApi>({
618
packageName: 'js-confetti',
719
file: 'dist/js-confetti.browser.js',
820
version: '0.12.0',
921
scriptOptions: {
1022
trigger: useScriptTriggerElement({ trigger: 'mouseover', el: mouseOverEl }),
11-
bundle: true,
1223
use() {
13-
return typeof window.JSConfetti !== 'undefined' && new window.JSConfetti()
24+
return { JSConfetti: window.JSConfetti }
1425
},
1526
},
1627
})
1728
18-
addConfetti({ emojis: ['L', 'O', 'A', 'D', 'E', 'D'] })
29+
function addConfetti(options: { emojis: string[] }) {
30+
$script.then(({ JSConfetti }) => {
31+
const confetti = new JSConfetti()
32+
confetti.addConfetti(options)
33+
})
34+
}
35+
36+
onMounted(() => {
37+
addConfetti({ emojis: ['L', 'O', 'A', 'D', 'E', 'D'] })
38+
})
1939
</script>
2040

2141
<template>

0 commit comments

Comments
 (0)