Closed gajosadrian closed 4 years ago
Transforming Props is what you might be looking for: https://inertiajs.com/transforming-props
I think it won't solve my problem.. I have used vuex and mixins.
Using render function pass props
data to layout.
Reference: Inertia.js - Persistent layouts and Vue.js - Render Functions: createElement
Arguments
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! 👍
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.
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]
Can be solved by doing this layout: (h, page) => h(Layout, { somePropDataDefinedInLayout: value }, () => page)
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.
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
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.
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
...
}
Any hints on how to do this in react?
@fnagel I used the Zustand to manage the layout state.
How to pass parameters to Layout and then handle it in the Layout? Is it possible?