inertiajs / inertia

Inertia.js lets you quickly build modern single-page React, Vue and Svelte apps using classic server-side routing and controllers.
https://inertiajs.com
MIT License
6.51k stars 435 forks source link

[inertia-vue] How to pass parameters to Layout? #176

Closed gajosadrian closed 4 years ago

gajosadrian commented 4 years ago

How to pass parameters to Layout and then handle it in the Layout? Is it possible?

adrianb93 commented 4 years ago

Transforming Props is what you might be looking for: https://inertiajs.com/transforming-props

gajosadrian commented 4 years ago

I think it won't solve my problem.. I have used vuex and mixins.

ycs77 commented 4 years ago

Using render function pass props data to layout.

Reference: Inertia.js - Persistent layouts and Vue.js - Render Functions: createElement Arguments

reinink commented 4 years ago

So, there are two ways to pass data (props) to layouts, depending on what type of layouts you are using.

If you're using a parent/child layout, meaning the layout is defined with the page component, you can simply pass it as an attribute, just like you would with any prop:

<template>
  <layout title="Welcome">
    <h1>Welcome</h1>
    <p>Hello {{ user.name }}, welcome to your first Inertia app!</p>
  </layout>
</template>

However, if you're using persistent layouts it gets a little more tricky, since there isn't a direct parent/child relationship between the layout and page component. In these situations it's often best to use a global event bus. That sounds confusing, but it's honestly not. Here's a guide that shows how easy it is.

The reason it's more difficult with persistent layouts is because the page and layouts are intentionally decoupled to allow them to be rendered independently of one-another.

I hope that helps! 👍

LucaRed commented 4 years ago

Using persistent layouts, another possible solution for some use cases is by using Portal Vue.

You put the <portal-target> into the main layout, and define the portal content in the children views.

mshamaseen commented 3 years ago

The fast way I found to pass data to persistent layouts is by:

in the child

use this: layout: (h, page) => { return h(Layout, () => page) }

instead of:

// Using the shorthand layout: Layout,

and in the parent layout you can access your child with this.$slots.default()[0]

afolabiabass commented 2 years ago

Can be solved by doing this layout: (h, page) => h(Layout, { somePropDataDefinedInLayout: value }, () => page)

SuperDJ commented 1 year ago

In vue 2.7 based on the docs of createElement you should be able to do the following in the child:

export default {
   layout: ( h, page ) => h( Layout, { props: { foo: 'Some value' } }, [ page ] ),
}

and parent:

export default {
props: {
  foo: {
    type: String,
    required: true
  }
}
}

But somehow the persistent layout only works when using Inertia's Link component. A v-btn from Vuetify with href doesn't seem to keep the persistent layout. Also a plain <a href> doesn't seem to keep the persistent layout. I'm not sure if this is template/ layout related or how Vuetify's buttons handle URLs.

hashstudiobackend commented 1 year ago

In both layout.vue and page.vue I have the same property name:

<script>
import Layout from "../../../Layouts/Layout";

export default {
  layout: Layout,
  props: {
    title: String,
  },
};
</script>

And it was shared to the Layout

I am using

medabkari commented 10 months ago

Transforming Props is what you might be looking for: https://inertiajs.com/transforming-props

The link mentioned above is broken, maybe transforming props is not a thing anymore or it was moved to somewhere else. You might want to update the link. Just wanted to point it out as it may be confusing to people.

IanLuan commented 8 months ago

If the data you want to pass to the layout are props, I think usePage() is the best solution:

import { usePage } from '@inertiajs/react'

export default function Layout({ children }) {
  const { bar } = usePage().props

  ...
}

https://inertiajs.com/shared-data#accessing-shared-data

fnagel commented 3 months ago

Any hints on how to do this in react?

joaopalopes24 commented 1 month ago

@fnagel I used the Zustand to manage the layout state.