Skip to content

Commit b8ef9dc

Browse files
committed
new vue3 playgrounds for async, polling, defer
1 parent 0dd8bcd commit b8ef9dc

File tree

5 files changed

+421
-2
lines changed

5 files changed

+421
-2
lines changed

playgrounds/vue3/resources/js/Components/Layout.vue

+6-2
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,17 @@ const appName = computed(() => page.props.appName)
88
</script>
99

1010
<template>
11-
<nav class="flex items-center space-x-6 bg-slate-800 px-10 py-6 text-white">
12-
<div class="rounded-lg bg-slate-700 px-4 py-1">{{ appName }}</div>
11+
<nav class="flex items-center px-10 py-6 space-x-6 text-white bg-slate-800">
12+
<div class="px-4 py-1 rounded-lg bg-slate-700">{{ appName }}</div>
1313
<Link href="/" class="hover:underline">Home</Link>
1414
<Link href="/users" class="hover:underline">Users</Link>
1515
<Link href="/article" class="hover:underline">Article</Link>
1616
<Link href="/form" class="hover:underline">Form</Link>
1717
<Link href="/logout" method="post" as="button" type="button" class="hover:underline">Logout</Link>
18+
<Link href="/goodbye" class="hover:underline">External</Link>
19+
<Link href="/async" class="hover:underline">Async Request</Link>
20+
<Link href="/defer" class="hover:underline">Defer</Link>
21+
<Link href="/poll" class="hover:underline">Poll</Link>
1822
</nav>
1923
<main class="px-10 py-8">
2024
<slot />
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
<script lang="ts">
2+
import Layout from '../Components/Layout.vue'
3+
export default { layout: Layout }
4+
</script>
5+
6+
<script setup lang="ts">
7+
import { Head, router, useForm } from '@inertiajs/vue3'
8+
import { onMounted, onUnmounted, ref, watch } from 'vue'
9+
10+
let timer = null
11+
const reloadCount = ref(0)
12+
13+
const props = defineProps<{
14+
jonathan: boolean
15+
taylor: boolean
16+
joe: boolean
17+
}>()
18+
19+
const form = useForm({
20+
jonathan: props.jonathan,
21+
taylor: props.taylor,
22+
joe: props.joe,
23+
})
24+
25+
watch(form, () => {
26+
router.post(
27+
'/async/checkbox',
28+
{
29+
jonathan: form.jonathan,
30+
taylor: form.taylor,
31+
joe: form.joe,
32+
},
33+
{
34+
async: true,
35+
},
36+
)
37+
})
38+
39+
const simulateConflict = () => {
40+
router.reload({
41+
only: ['sleep'],
42+
})
43+
router.visit('/sleepy/2')
44+
}
45+
46+
const triggerVisitThenReload = () => {
47+
router.visit('/sleepy/1')
48+
router.reload({
49+
only: ['sleep'],
50+
})
51+
}
52+
53+
const triggerLongReload = () => {
54+
router.reload({
55+
only: ['sleep'],
56+
onFinish() {
57+
console.log('finished reload')
58+
reloadCount.value++
59+
console.log('incremented reload count')
60+
},
61+
})
62+
}
63+
64+
watch(reloadCount, () => {
65+
console.log('watched reload count value', reloadCount.value)
66+
})
67+
68+
onMounted(() => {
69+
// timer = setTimeout(() => {
70+
// router.reload({
71+
// only: ['sleep'],
72+
// })
73+
// }, 1000)
74+
})
75+
76+
onUnmounted(() => {
77+
clearInterval(timer)
78+
})
79+
</script>
80+
81+
<template>
82+
<Head title="Async Request" />
83+
<h1 class="text-3xl">Async Request</h1>
84+
<p class="mt-6">Reload Count: {{ reloadCount }}</p>
85+
<div class="grid grid-cols-3 gap-4 mt-6">
86+
<div class="p-4 space-y-4 text-sm text-gray-500 border border-gray-300 rounded">
87+
<p>Trigger an async reload that takes a moment and immediately programatically visit another page</p>
88+
<button @click="simulateConflict" class="px-4 py-2 text-white bg-green-600 rounded">Reload → Visit</button>
89+
</div>
90+
<div class="p-4 space-y-4 text-sm text-gray-500 border border-gray-300 rounded">
91+
<div class="flex flex-col">
92+
<label>
93+
<input v-model="form.jonathan" type="checkbox" class="mr-2" />
94+
Jonathan
95+
</label>
96+
<label>
97+
<input v-model="form.taylor" type="checkbox" class="mr-2" />
98+
Taylor
99+
</label>
100+
<label>
101+
<input v-model="form.joe" type="checkbox" class="mr-2" />
102+
Joe
103+
</label>
104+
</div>
105+
<p>You can check these on and off and then navigate to another page and the requests should still complete.</p>
106+
<p>Toggling "Joe" on will cause a redirect to "Article", simulating an authorized action e.g.</p>
107+
</div>
108+
<div class="p-4 space-y-4 text-sm text-gray-500 border border-gray-300 rounded">
109+
<p>Trigger programatic visit and an async reload one after another</p>
110+
111+
<p>Reload should still happen but won't re-direct back to the reloaded component, we should respect the visit</p>
112+
113+
<button @click="triggerVisitThenReload" class="px-4 py-2 text-white bg-green-600 rounded">Visit → Reload</button>
114+
</div>
115+
<div class="p-4 space-y-4 text-sm text-gray-500 border border-gray-300 rounded">
116+
<p>Simply trigger a 4 second reload so you can navigate or do whatever you'd like during it.</p>
117+
<button @click="triggerLongReload" class="px-4 py-2 text-white bg-green-600 rounded">Trigger Long Reload</button>
118+
</div>
119+
</div>
120+
</template>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
<script lang="ts">
2+
import Deferred from '../../../../../packages/vue3/src/Deferred.vue'
3+
import Layout from '../Components/Layout.vue'
4+
export default { layout: Layout }
5+
</script>
6+
7+
<script setup lang="ts">
8+
import { Head } from '@inertiajs/vue3'
9+
10+
defineProps<{
11+
users?: {
12+
id: number
13+
name: string
14+
email: string
15+
}[]
16+
organizations?: {
17+
id: number
18+
name: string
19+
url: string
20+
}[]
21+
foods?: {
22+
id: number
23+
name: string
24+
}[]
25+
}>()
26+
</script>
27+
28+
<template>
29+
<Head title="Async Request" />
30+
<h1 class="text-3xl">Deferred Props</h1>
31+
<div class="p-4 mt-6 bg-yellow-200 border border-yellow-500 rounded">
32+
<p>Page is loaded!</p>
33+
</div>
34+
35+
<div class="flex mt-6 space-x-6">
36+
<div class="w-1/2 p-4 border border-black rounded">
37+
<Deferred :data="users">
38+
<template #loading>
39+
<p>Loading Users...</p>
40+
</template>
41+
42+
<div v-for="user in users">
43+
<p>#{{ user.id }}: {{ user.name }} ({{ user.email }})</p>
44+
</div>
45+
</Deferred>
46+
</div>
47+
48+
<div class="w-1/2 p-4 border border-black rounded">
49+
<Deferred :data="foods">
50+
<template #loading>
51+
<p>Loading Foods...</p>
52+
</template>
53+
54+
<div v-for="food in foods">
55+
<p>#{{ food.id }}: {{ food.name }}</p>
56+
</div>
57+
</Deferred>
58+
</div>
59+
60+
<div class="w-1/2 p-4 border border-black rounded">
61+
<Deferred :data="organizations">
62+
<template #loading>
63+
<p>Loading Organizations...</p>
64+
</template>
65+
66+
<div v-for="org in organizations">
67+
<p>#{{ org.id }}: {{ org.name }} ({{ org.url }})</p>
68+
</div>
69+
</Deferred>
70+
</div>
71+
</div>
72+
</template>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
<script lang="ts">
2+
import usePoll from '../../../../../packages/vue3/src/usePoll'
3+
import Layout from '../Components/Layout.vue'
4+
export default { layout: Layout }
5+
</script>
6+
7+
<script setup lang="ts">
8+
import { Head, router } from '@inertiajs/vue3'
9+
import { onMounted, ref } from 'vue'
10+
11+
defineProps<{
12+
users: string[]
13+
companies: string[]
14+
}>()
15+
16+
const userPollCount = ref(0)
17+
const hookPollCount = ref(0)
18+
const companyPollCount = ref(0)
19+
20+
const trigegerAsyncRedirect = () => {
21+
router.get(
22+
'/elsewhere',
23+
{},
24+
{
25+
only: ['something'],
26+
async: true,
27+
},
28+
)
29+
}
30+
31+
const { stop } = usePoll(
32+
2000,
33+
{
34+
only: ['asdf'],
35+
onFinish() {
36+
hookPollCount.value++
37+
},
38+
},
39+
false,
40+
)
41+
42+
onMounted(() => {
43+
const stopUserPolling = router.poll(1000, {
44+
only: ['users'],
45+
onFinish() {
46+
userPollCount.value++
47+
},
48+
})
49+
50+
setTimeout(() => {
51+
console.log('stopping user polling')
52+
stopUserPolling()
53+
}, 7000)
54+
55+
router.poll(1500, {
56+
only: ['companies'],
57+
onFinish() {
58+
companyPollCount.value++
59+
},
60+
})
61+
})
62+
</script>
63+
64+
<template>
65+
<Head title="Async Request" />
66+
<h1 class="text-3xl">Poll</h1>
67+
<div class="flex mt-6 space-x-6">
68+
<div>
69+
<div class="mb-2 font-bold">User Poll Request Count: {{ userPollCount }}</div>
70+
<div v-for="user in users">
71+
<div>{{ user }}</div>
72+
</div>
73+
</div>
74+
<div>
75+
<div class="mb-2 font-bold">Companies Poll Request Count: {{ companyPollCount }}</div>
76+
<div v-for="company in companies">
77+
<div>{{ company }}</div>
78+
</div>
79+
</div>
80+
<div>
81+
<button @click="trigegerAsyncRedirect">Trigger Async Redirect</button>
82+
</div>
83+
</div>
84+
</template>

0 commit comments

Comments
 (0)