I want to pass the data from page pages/index.vue to default layout layouts/default.vue. to set the dynamic breadcrumb according to the current page with the custom breadcrumb segment.
I have tried the vue 3 provide and inject option but not working and return always injection "foo" not found.. Please share ideas to archive this thing.
You can use useState composable link. Which is provided by nuxt to share data across components. Or you can use a state management system like vuex or pinia
From nuxt.com useState is,
Nuxt provides useState composable to create a reactive and SSR-friendly shared state across components.
You can declare any variable with useState like this inside your pages directory
<script setup>
const counter = useState('counter', () => Math.round(Math.random() * 1000));
</script>
<template>
<h1>Index page</h1>
<div>
<button @click="counter++">Inc Counter From Index</button>
<button @click="counter--">Dec Counter From Index</button>
</div>
</template>
Then you can access that variable using useState from your layout like this
<script setup>
const counter = useState('counter');
</script>
<template>
<div>
Some default layout shared across all pages
<h3>Counter value from the default layout = {{ counter }}</h3>
<slot />
</div>
</template>
Overall a minimal example are given in stackBliz here link
I think the best way to share data between pages and layouts would be pinia.
https://pinia.vuejs.org/
https://pinia.vuejs.org/ssr/nuxt.html
You'll create a store (e.g. stores/breadcrumbs.ts):
import { defineStore } from "pinia";
export const useBreadcrumbsStore = defineStore('Breadcrumbs', () => {
const title = ref('')
// include any data you want
return {
title,
}
})
then change the data in pages/index.vue
...
<script setup>
import { useBreadcrumbsStore } from '~/stores/breadcrumbs.ts'
const breadcrumbsStore = useBreadcrumbsStore()
// change the data
breadcrumbsStore.title = 'Some title'
</script>
and use it in your layouts/default.vue:
<template>
<div>
Title: {{ breadcrumbsStore.title }}<hr>
<slot />
</div>
</template>
<script setup>
import { useBreadcrumbsStore } from '~/stores/breadcrumbs.ts'
const breadcrumbsStore = useBreadcrumbsStore()
</script>
One thing to note here though - it will cause a Hydration text mismatch warning, so the title won't be rendered during SSR.
You can get rid of the warning by wrapping it with ClientOnly tag like <ClientOnly>{{ breadcrumbsStore.title }}</ClientOnly>, but it won't solve the SSR issue.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With