Open diemah77 opened 5 years ago
In your app/Providers/AppServiceProvider.php
you can do something along the following:
View::composer('*', function ($view) {
if (Auth::user()) {
$view->with('shared', [
'auth' => [
'user' => [
'id' => Auth::user()->id,
'name' => Auth::user()->name,
'email' => Auth::user()->email,
],
],
]);
}
});
And in your resources/views/app.blade.php
just below your <body>
tag:
<script>
window.shared = @json($shared ?? []);
</script>
That's all true and correct for the authenticated user, as the shared data doesn't change for all admin routes. But the issue arises when passing breadcrumbs to the window object. In this case turbolinks doesn't override the breadcrumbs for each route, but creates an addditional script tag within the head tag.
By now I'm passing the breadcrumbs collection to each page component and then to the root layout component where breadcrumbs are rendered. Ideally I would like to access them globally.
That would be more clean approach, yes. As far as I understood it from Twitter @reinink is dropping Turbolinks entirely and going with a straight Vue and Laravel approach. Previously he mentioned something along the lines of "TurboVue", but I swear I saw a tweet stating that it will be dropped for a more favorable and straightforward solution.
Using this repository as a base seems a bit clunky when it comes to issues like this. I'm currently using this in one of my projects, but have prepared myself for a refactor when the aforementioned solution comes.
For those interested, I now do something like this:
render: h => h(
Vue.component('admin'), {
props: JSON.parse(root.dataset.props)
}
)
I'm creating the layout component and passing the page component name as prop:
ViewFactory::macro('component', function ($name, $data = []) use ($auth)
{
$data['name'] = $name;
$data['auth'] = $auth;
return View::make('dashboard', [
'data' => $data,
]);
});
In the layout component I have a dynamic component that renders the passed page component:
<transition tag="div" name="fade" appear>
<component :is="data.name" :parentData="childProps" @title="setTitle"></component>
</transition>
where props
and childProps
look like this:
props: {
data: {
type: Object,
required: true
}
},
computed: {
childProps()
{
let props = Object.assign({}, this.data)
delete props.auth
delete props.breadcrumbs
delete props.name
return props
}
}
What this @
means on @json
? Is that from blade or Vue?
@zefexdeveloper That's a Blade directive for outputting a PHP variable as JSON.
The same for @title
? I'm asking this cause It's kinda confusing. I mean, if I have an array being passed down to the view I could just do something like :tags="{{ $tags }}"
and then Vue can traversal it, right?
No, @title
is in a Vue component, and that's an event. And yes, that is confusing...two different languages/frameworks.
If you're looking at this repo, I highly recommend checking out my Inertia.js project. That's really where the thinking from this repo (blog post) lead me.
@reinink Thank you very much, I heard about Inertia.js before and it looks amazing, I will definitely take a look and probably refactor the project later.
Right now I'm using inline components with Vue because it sucks to pass down localization information down from Laravel to Vue components. It will do the trick now, gotta get things done but later I will definitely refactor and make it better.
I wonder what is the best way to pass some data like logged-in user or breadcrumbs created by laravel to Vue. By now I'm merging all of the data and passing it through props to each of the page components. But it feels like a hack and I think there might be a better solution. What would you suggest?