-
-
Notifications
You must be signed in to change notification settings - Fork 4
/
+Page.vue
63 lines (57 loc) 路 1.74 KB
/
+Page.vue
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
<template>
<h1>Star Wars Movies</h1>
<ol>
<template v-if="isPending">
<li>Loading...</li>
</template>
<template v-else-if="isError">
<li>Error: {{ error }}</li>
</template>
<template v-else>
<li v-for="item in data!" :key="item.id">
{{ item.title }} ({{ item.release_date }})
</li>
</template>
</ol>
<p>Source: <a href="https://brillout.github.io/star-wars">brillout.github.io/star-wars</a>.</p>
<p>
While initial data is fetched on the server, the client will refresh after rendering.<br>
<code>
Refreshing: {{ isFetching ? 'Yes' : 'No' }}
</code>
</p>
<p>
This page is:
</p>
<ul>
<li>Rendered to HTML.</li>
<li>Interactive. <Counter /></li>
</ul>
</template>
<script lang="ts" setup>
import { onServerPrefetch } from 'vue'
import type { Movie, MovieDetails } from './types'
import { useQuery } from '@tanstack/vue-query'
import Counter from '../../components/Counter.vue'
const components = { Counter }
const { isError, isPending, isFetching, data, error, suspense } = useQuery({
queryKey: ['movies'],
queryFn: fetchMovies,
select: (data) => minimize(data),
})
// this will be called on the server to prefetch the data
onServerPrefetch(suspense)
async function fetchMovies() {
const response = await fetch('https://brillout.github.io/star-wars/api/films.json')
const moviesData = (await response.json()) as MovieDetails[]
// simulate slow network on client
await new Promise((resolve) => setTimeout(resolve, import.meta.env.SSR ? 0 : 3000))
return moviesData
}
function minimize(movies: MovieDetails[]): Movie[] {
return movies.map((movie) => {
const { title, release_date, id } = movie
return { title, release_date, id }
})
}
</script>