Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Passing backend data to Vue #10

Open
diemah77 opened this issue Feb 26, 2019 · 9 comments
Open

Passing backend data to Vue #10

diemah77 opened this issue Feb 26, 2019 · 9 comments

Comments

@diemah77
Copy link

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?

@Juhlinus
Copy link

Juhlinus commented Mar 4, 2019

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>

@diemah77
Copy link
Author

diemah77 commented Mar 4, 2019

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.

@Juhlinus
Copy link

Juhlinus commented Mar 4, 2019

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.

@diemah77
Copy link
Author

diemah77 commented Mar 13, 2019

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
	}
}

@theprobugmaker
Copy link

What this @ means on @json? Is that from blade or Vue?

@reinink
Copy link
Owner

reinink commented Oct 9, 2019

@zefexdeveloper That's a Blade directive for outputting a PHP variable as JSON.

@theprobugmaker
Copy link

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?

@reinink
Copy link
Owner

reinink commented Oct 9, 2019

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.

@theprobugmaker
Copy link

@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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants