Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion examples/vue-pinia/pages/index/+Page.vue
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import TodoList from './TodoList.vue'

const { increment } = useCounterStore()
onServerPrefetch(() => {
// Show that hydration works - the counter should start at 1
// Let the counter start at 1 (and hydration still works)
increment()
})
</script>
2 changes: 1 addition & 1 deletion examples/vue-pinia/pages/index/+onData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,6 @@ function onData(pageContext: PageContext & { data?: Data }) {

// Saving KBs: we don't need pageContext.data (we use the store instead)
// - If we don't delete pageContext.data then Vike sends pageContext.data to the client-side
// - This optimization only works if the page is SSR'd: if the page is pre-rendered then don't do this
// - This optimization only works with SSR: if the page is pre-rendered then don't do this
if (!pageContext.isPrerendering) delete pageContext.data
}
75 changes: 44 additions & 31 deletions packages/vike-vue-pinia/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,14 @@
Integrates [Pinia](https://pinia.vuejs.org) into your [`vike-vue`](https://vike.dev/vike-vue) app.

[Installation](#installation)
[Basic usage](#basic-usage)
[Example](#example)
[Populate store with `+data`](#populate-store-with-data)
[Version history](#version-history)
[See also](#see-also)

<br/>

## Example

See [examples/vue-pinia](https://github.com/vikejs/vike-vue/tree/main/examples/vue-pinia).

<br/>

## Installation

1. `npm install vike-vue-pinia pinia`
Expand All @@ -35,40 +30,58 @@ See [examples/vue-pinia](https://github.com/vikejs/vike-vue/tree/main/examples/v
extends: [vikeVue, vikeVuePinia]
}
```
3. You can now use Pinia in any of your components.
```vue
<template>
<button type="button" @click="counterStore.increment">Counter {{ counterStore.count }}</button>
</template>

<script setup>
import { useCounterStore } from './useCounterStore'
const counterStore = useCounterStore()
</script>
```
```js
import { defineStore } from 'pinia'
import { ref } from 'vue'

export const useCounterStore = defineStore('counter', () => {
const count = ref(0)
const increment = () => count.value++
return { count, increment }
})
```

> [!NOTE]
> The `vike-vue-pinia` extension requires [`vike-vue`](https://vike.dev/vike-vue).

<br/>

# Basic usage

```js
// stores/useCounterStore.ts

import { defineStore } from 'pinia'
import { ref } from 'vue'

export const useCounterStore = defineStore('counter', () => {
const count = ref(0)
const increment = () => count.value++
return { count, increment }
})
```

```vue
<!-- components/Counter.vue -->

<template>
<button type="button" @click="counterStore.increment">
Counter {{ counterStore.count }}
</button>
</template>

<script setup>
import { useCounterStore } from '../stores/useCounterStore'
const counterStore = useCounterStore()
</script>
```

<br/>

## Example

See [examples/vue-pinia/](https://github.com/vikejs/vike-vue/tree/main/examples/vue-pinia).

<br/>

## Populate store with `+data`

To populate your store with data fetched via the [`+data`](https://vike.dev/data) hook, use [`+onData`](https://vike.dev/onData) and [`pageContext.data`](https://vike.dev/pageContext#data).

```ts
// pages/todos/+onData.ts
// Environment: server, client

export { onData }

import type { PageContext } from 'vike/types'
Expand All @@ -81,17 +94,17 @@ function onData(pageContext: PageContext & { data?: Data }) {

// Saving KBs: we don't need pageContext.data (we use the store instead)
// - If we don't delete pageContext.data then Vike sends pageContext.data to the client-side
// - This optimization only works if the page is SSR'd: if the page is pre-rendered then don't do this
// - This optimization only works with SSR: if the page is pre-rendered then don't do this
delete pageContext.data
}
```

See To-Do List example at [examples/vue-pinia](https://github.com/vikejs/vike-vue/tree/main/examples/vue-pinia).
See complete To-Do List example at [examples/vue-pinia](https://github.com/vikejs/vike-vue/tree/main/examples/vue-pinia).

> [!NOTE]
> During [SSR](https://vike.dev/ssr), `+onData` is called only on the server. That's because the store state is sent to the client, so that when the page hydrates, the client has the exact same state as the server — preventing [hydration mismatches](https://vike.dev/hydration-mismatch).
> During [SSR](https://vike.dev/ssr), `+onData` is called only on the serverthe store's initial state (set by `initTodos()`) is automatically sent to the client, so you don't need to populate the store again on the client.
>
> As a result, the store doesn't need to be populated on the client: it's already populated on the server and then sent to the client.
> This approach prevents [hydration mismatches](https://vike.dev/hydration-mismatch), as it ensures the client has the exact same initial state as the server during SSR.

<br/>

Expand Down
112 changes: 63 additions & 49 deletions packages/vike-vue-query/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@
Integrates [TanStack Query](https://tanstack.com/query) into your [`vike-vue`](https://vike.dev/vike-vue) app.

[Installation](#installation)
[Basic usage](#basic-usage)
[Example](#example)
[Settings](#settings)
[Example](https://github.com/vikejs/vike-vue/tree/main/examples/vue-query)
[Version history](https://github.com/vikejs/vike-vue/blob/main/packages/vike-vue-query/CHANGELOG.md)
[See also](#see-also)

Expand All @@ -30,63 +31,72 @@ Integrates [TanStack Query](https://tanstack.com/query) into your [`vike-vue`](h
extends: [vikeVue, vikeVueQuery]
}
```
3. You can now use TanStack Query in any of your components.
```vue
<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>
</template>

<script setup>
import { onServerPrefetch } from 'vue'
import { useQuery } from '@tanstack/vue-query'

const { isError, isPending, isFetching, data, error, suspense } = useQuery({
queryKey: ['movies'],
queryFn: fetchMovies,
staleTime: 1000 * 60 * 5,
select: (data) => minimize(data),
})
> [!NOTE]
> The `vike-vue-query` extension requires [`vike-vue`](https://vike.dev/vike-vue).

// This will be called on the server to prefetch the data
onServerPrefetch(suspense)
<br/>

async function fetchMovies() {
const response = await fetch('https://brillout.github.io/star-wars/api/films.json')
const moviesData = (await response.json())
return moviesData
}
# Basic usage

function minimize(movies) {
return movies.map((movie) => {
const { title, release_date, id } = movie
return { title, release_date, id }
})
}
</script>
```
```vue
<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>
</template>

<script setup>
import { onServerPrefetch } from 'vue'
import { useQuery } from '@tanstack/vue-query'

const { isError, isPending, isFetching, data, error, suspense } = useQuery({
queryKey: ['movies'],
queryFn: fetchMovies,
staleTime: 1000 * 60 * 5,
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())
return moviesData
}

> [!NOTE]
> The `vike-vue-query` extension requires [`vike-vue`](https://vike.dev/vike-vue).
function minimize(movies) {
return movies.map((movie) => {
const { title, release_date, id } = movie
return { title, release_date, id }
})
}
</script>
```

<br/>

## Example

See [examples/vue-query/](https://github.com/vikejs/vike-vue/tree/main/examples/vue-query).

<br/>

## Settings

The query client can receive custom options either by adding `queryClientConfig` to your `+config.ts` or adding a separate `+queryClientConfig.ts` file in your `pages` directory.
You can set TanStack Query client options:

```ts
// pages/+queryClientConfig.ts
Expand All @@ -95,19 +105,23 @@ export { queryClientConfig }

import type { QueryClientConfig } from '@tanstack/vue-query'

// Query client options
const queryClientConfig: QueryClientConfig = {
defaultOptions: {
queries: {
// Retry failed requests once
retry: 1,
// Consider data stale after 2 minutes
staleTime: 1000 * 60 * 2,
// Don't refetch when window loses or gains focus during development
refetchOnWindowFocus: import.meta.env.PROD,
staleTime: 1000 * 60 * 2
// ... more options ...
}
}
}
```

For all available options, see [TanStack Query > API reference > useQuery](https://tanstack.com/query/latest/docs/framework/vue/reference/useQuery).

<br/>


Expand Down