Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Breadcrumbs component: passing data between page and layout

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.

like image 986
Kishan Bhensadadiya Avatar asked Mar 17 '26 02:03

Kishan Bhensadadiya


2 Answers

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

like image 89
nur_riyad Avatar answered Mar 20 '26 22:03

nur_riyad


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.

like image 38
res0 Avatar answered Mar 20 '26 21:03

res0



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!