Skip to content

Commit

Permalink
add vue-query example
Browse files Browse the repository at this point in the history
Signed-off-by: Chris-Robin Ennen <[email protected]>
  • Loading branch information
4350pChris committed Apr 16, 2024
1 parent e25d832 commit c350480
Show file tree
Hide file tree
Showing 24 changed files with 431 additions and 4 deletions.
2 changes: 2 additions & 0 deletions examples/vue-query/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
/node_modules/
/dist/
36 changes: 36 additions & 0 deletions examples/vue-query/assets/logo.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
9 changes: 9 additions & 0 deletions examples/vue-query/components/Counter.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<template>
<button type="button" @click="state.count++">Counter {{ state.count }}</button>
</template>

<script lang="ts" setup>
import { reactive } from 'vue'
const state = reactive({ count: 0 })
</script>
25 changes: 25 additions & 0 deletions examples/vue-query/components/Link.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<template>
<a :class="{ active: isActive }">
<slot />
</a>
</template>
<style scoped>
a {
padding: 2px 10px;
margin-left: -10px;
}
a.active {
background-color: #eee;
}
</style>
<script lang="ts" setup>
import { useAttrs, computed } from 'vue'
import { usePageContext } from 'vike-vue/usePageContext'
const pageContext = usePageContext()
const { href } = useAttrs() as { href: string }
const isActive = computed(() => {
const { urlPathname } = pageContext
return href === '/' ? urlPathname === href : urlPathname.startsWith(href)
})
</script>
9 changes: 9 additions & 0 deletions examples/vue-query/layouts/HeadDefault.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<template>
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="description" content="Demo showcasing Vike + Vue + Pinia" />
<link rel="icon" :href="logoUrl" />
</template>

<script lang="ts" setup>
import logoUrl from '../assets/logo.svg'
</script>
62 changes: 62 additions & 0 deletions examples/vue-query/layouts/LayoutDefault.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
<template>
<div class="layout">
<div class="navigation">
<a href="/" class="logo">
<img src="../assets/logo.svg" height="64" width="64" />
</a>
<Link href="/">Welcome</Link>
<Link href="/about">About</Link>
<Link href="/star-wars">Data Fetching</Link>
</div>
<div class="content"><slot /></div>
</div>
</template>

<script lang="ts" setup>
import Link from '../components/Link.vue'
</script>

<style>
body {
margin: 0;
font-family: sans-serif;
}
* {
box-sizing: border-box;
}
a {
text-decoration: none;
}
</style>

<style scoped>
.layout {
display: flex;
max-width: 900px;
margin: auto;
}
.content {
padding: 20px;
padding-bottom: 50px;
min-height: 100vh;
flex-grow: 1;
}
.navigation {
padding: 20px;
flex-shrink: 0;
display: flex;
flex-direction: column;
line-height: 1.8em;
border-right: 2px solid #eee;
}
.logo {
margin-top: 20px;
margin-bottom: 10px;
}
.content {
transition: opacity 0.1s ease-in;
}
.content.page-transition {
opacity: 0;
}
</style>
23 changes: 23 additions & 0 deletions examples/vue-query/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"scripts": {
"dev": "vite dev",
"build": "vite build",
"preview": "vite build && vite preview"
},
"dependencies": {
"@vitejs/plugin-vue": "^5.0.4",
"@types/node-fetch": "^2.6.11",
"@tanstack/vue-query": "^5.0.0",
"node-fetch": "^3.3.2",
"vike": "^0.4.165",
"vike-vue-query": "0.0.1",
"vike-vue": "0.6.3",
"vite": "^5.1.1",
"vue": "^3.4.18"
},
"type": "module",
"devDependencies": {
"typescript": "^5.3.3",
"vue-tsc": "^1.8.27"
}
}
14 changes: 14 additions & 0 deletions examples/vue-query/pages/+config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import type { Config } from 'vike/types'
import Layout from '../layouts/LayoutDefault.vue'
import Head from '../layouts/HeadDefault.vue'
import vikeVue from 'vike-vue/config'
import vikeVueQuery from 'vike-vue-query'

// Default configs (can be overridden by pages)
export default {
Layout,
Head,
// <title>
title: 'My Vike + Vue + TanStack Query App',
extends: [vikeVue, vikeVueQuery]
} satisfies Config
25 changes: 25 additions & 0 deletions examples/vue-query/pages/_error/+Page.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<template>
<div class="center">
<p>{{ abortReason }}</p>
</div>
</template>

<script lang="ts" setup>
import { usePageContext } from 'vike-vue/usePageContext'
const ctx = usePageContext()
let { is404, abortReason } = ctx
if (!abortReason) {
abortReason = is404 ? 'Page not found.' : 'Something went wrong.'
}
</script>

<style>
.center {
height: calc(100vh - 100px);
display: flex;
font-size: 1.3em;
justify-content: center;
align-items: center;
}
</style>
4 changes: 4 additions & 0 deletions examples/vue-query/pages/about/+Page.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<template>
<h1>About</h1>
<p>Example of using Vike.</p>
</template>
5 changes: 5 additions & 0 deletions examples/vue-query/pages/about/+config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import type { Config } from 'vike/types'

export default {
title: 'About - My Vike + Vue App'
} satisfies Config
15 changes: 15 additions & 0 deletions examples/vue-query/pages/index/+Page.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<template>
<h1>My Vike + Vue app</h1>
This page is:
<ul>
<li>Rendered to HTML.</li>
<li>Interactive.</li>
</ul>
<Counter />
<hr />
<Counter />
</template>

<script lang="ts" setup>
import Counter from '../../components/Counter.vue'
</script>
53 changes: 53 additions & 0 deletions examples/vue-query/pages/star-wars/index/+Page.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
<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">
<a :href="'/star-wars/' + item.id">{{ item.title }}</a> ({{ 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>
</template>

<script lang="ts" setup>
import { onServerPrefetch } from 'vue'
import type { Movie, MovieDetails } from '../types'
import { useQuery } from '@tanstack/vue-query'
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
await new Promise((resolve) => setTimeout(resolve, 3000))
return moviesData
}
function minimize(movies: MovieDetails[]): Movie[] {
return movies.map((movie) => {
const { title, release_date, id } = movie
return { title, release_date, id }
})
}
</script>
9 changes: 9 additions & 0 deletions examples/vue-query/pages/star-wars/index/+title.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
export { title }

import type { PageContext } from 'vike/types'

function title(pageContext: PageContext) {
const movies = pageContext.data
// return `${movies.length} Star Wars Movies`
return "Star Wars Movies"
}
14 changes: 14 additions & 0 deletions examples/vue-query/pages/star-wars/movie/+Page.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<template>
<h1>{{ movie.title }}</h1>
Release Date: {{ movie.release_date }}
<br />
Director: {{ movie.director }}
<br />
Producer: {{ movie.producer }}
</template>

<script lang="ts" setup>
import type { Data } from './+data'
import { useData } from 'vike-vue/useData'
const movie = useData<Data>()
</script>
24 changes: 24 additions & 0 deletions examples/vue-query/pages/star-wars/movie/+data.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// https://vike.dev/data
export { data }
export type Data = Awaited<ReturnType<typeof data>>

import fetch from 'node-fetch'
import type { PageContextServer } from 'vike/types'
import type { MovieDetails } from '../types'

const data = async (pageContext: PageContextServer) => {
const response = await fetch(
`https://brillout.github.io/star-wars/api/films/${pageContext.routeParams?.movieId}.json`
)
let movie = (await response.json()) as MovieDetails
// We remove data we don't need because the data is passed to the client; we should
// minimize what is sent over the network.
movie = minimize(movie)
return movie
}

function minimize(movie: MovieDetails): MovieDetails {
const { id, title, release_date, director, producer } = movie
movie = { id, title, release_date, director, producer }
return movie
}
1 change: 1 addition & 0 deletions examples/vue-query/pages/star-wars/movie/+route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export default '/star-wars/@movieId'
9 changes: 9 additions & 0 deletions examples/vue-query/pages/star-wars/movie/+title.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
export { title }

import type { Data } from './+data'
import type { PageContext } from 'vike/types'

function title(pageContext: PageContext<Data>) {
const movie = pageContext.data
return movie.title
}
9 changes: 9 additions & 0 deletions examples/vue-query/pages/star-wars/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
export type Movie = {
id: string
title: string
release_date: string
}
export type MovieDetails = Movie & {
director: string
producer: string
}
9 changes: 9 additions & 0 deletions examples/vue-query/readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
Example of using [TanStack Query](https://tanstack.com/query/latest) with the `vike-vue-query` extension.

```bash
git clone [email protected]:vikejs/vike-vue
cd vike-vue/
pnpm install
cd examples/vue-query/
pnpm run dev
```
12 changes: 12 additions & 0 deletions examples/vue-query/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"compilerOptions": {
"strict": true,
"module": "ES2020",
"moduleResolution": "Node",
"target": "ES2020",
"lib": ["DOM", "DOM.Iterable", "ESNext"],
"types": ["vite/client"],
"skipLibCheck": true,
"esModuleInterop": true
}
}
Loading

0 comments on commit c350480

Please sign in to comment.