How to use Vue with Laravel 5.4 (best practice) - php

I'm a software engineer and don't have a lot of experience with PHP or javascript. I will upgrading my skills in this so i started with a PHP framework Laravel which looks very nice in my opinion. I'm familar with the MVC principal so i can find my way in Laravel!
I created some models with corresponding controllers. I also created some blade views to display the data. I give a model object to the blade view as folows:
$person = new \App\Person("Firstname", "Lastname");
return view('personView', compact('person'));
I can get it done to use the person object in the blade view to display his variables with:
{{ $user->name }}
Now i tried to go one step further and want do do some stuff with Vue so i can display and manipulate the object on client side (and dispay dynamic data). Later i want to save the client side object via a action in the controller over a HTTP post or something, but fist things first...
I'm be able to create a vue object with some data in it and display it in HTML controlls for example.
So, summerized
i'm be able to generate my backend objects and manipulate them. I can bring them to my view and display them with {{ $obj->var }}
I'm be able to create Vue objects with data, and manipulating this data and show it with #{{ data }}.
My problem is that i can't get the data from the controller (which i give wat i gave to the view) into the Vue object. What is the best practice to do this? Or is this not the way to go? in that case, what is convinient to do as i read that Laravel has Vue integrated and this sounds for me that there should be a (best practice) way to achieve this?
I looked for a creat tutorial but couln'd find this. So if someone has a good tutorial to learn understanding Laravel in combination with Blade and Vue, please share!
I already tried something like this, unfortunately without any result:
new Vue({
el: '#someElement',
data: {
person: {!! $person!!}
}
})
(Using Laravel 5.4.x and Vue 2.4.x)

You can simply pass the object to the vue component like that:
<my-component :person="{{ $person }}" ></my-component>
And your Vue component
<template>
{{ person.name }}
</template>
<script>
export default {
props: ['person']
}
</script>

Related

How do I pass data from PHP Laravel to Vue.js and re-render a Vue.js component when the data changes?

I'm still a bit new to Vue.js, so I may be fundamentally misunderstanding something about the reactivity of it, but basically, I want to pass some data from PHP Laravel to a Vue.js component and have the Vue.js component automatically update when that data changes.
I've seen several similar posts on SO suggest that I use props to pass the data from a Laravel Blade template to a Vue.js component. Here's an example:
How to pass a PHP variable to Vue component instance in Laravel blade?
I have this working perfectly fine, but now I'm stuck with how to get the component to update when the data dynamically changes after page-load.
Specifically, I have a report table on a particular web page, and when the user clicks certain buttons, etc., I use Ajax to call a Laravel controller action that re-runs a query in my Laravel model to get the new data for the report.
I have the data in a PHP array / JSON, and that data is being properly returned to the client-side and I have access to it in the JS, but now, what do I need to do to force the report component in Vue.js to essentially re-render based on the data I just received? Is there a way to "update props" so that Vue.js detects the change and automatically re-renders the whole report component for me?
This is where I'm stuck, and after quite a bit of research, I can't find how to do this. Thank you.
Are you using Ajax outside of the Vue component? or within it as a method?
I have an example of how I dynamically update the Vue data from within the component itself. I'm not sure how to have external JS update the Vue component directly but I feel this is a good option to look at. I'm using axios instead of Ajax but the principle is the same (Axios is included by default in most Laravel installs past 5.5).
<template>
<div>
<div id="reports">
<!-- Display data -->
{{ reports }}
</div>
<button #click="refreshReports">Refresh</button>
</div>
</template>
<script>
export default {
data() {
return {
endpoint: '/api/MY_ROUTE/'
};
},
props: {
reports: Object
},
methods: {
// Make Axios call to API endpoint
refreshReports() {
// GET version
axios.get(this.endpoint)
.then(({data}) => {
this.reports = data.data;
});
// POST version
axios.post(this.endpoint, {
KEY: 'VALUE',
}).then(({data}) => {
this.reports = data.data;
});
/*
`data.data` assumes the returned response is a JSON Resource
if it's not returning the correct data, put a `console.log(data)` and see how it's getting returned!
*/
}
}
};
</script>
Where in your routes/api.php file you have a route like this:
// GET version
Route::get('MY_ROUTE', 'ReportController#getReports');
// POST version
Route::post('MY_ROUTE', 'ReportController#getReports');
And your Controller would have some method like this:
// app/Http/Controllers/ReportController
public function getReports(Request $request) {
return Reports::all();
}
Does that make sense?
Update:
I'm not sure how to have external JS update the Vue component directly
I know you can import external JS scripts and use their functions in methods but I've never done it that way before.
Something like:
<script>
import { myFunction } from '../external.js'
export default {
methods: {
refreshReports() {
// I have no idea if this is the correct way to do it, just a guess!
this.reports = myFunction();
}
}
};
</script>

how to pass laravel route parameter to vue

i m new to vue & i does lots of google but have not found any solution which is match to my current situation so don't know how i can pass route in vue component,
is there any way to pass this laravel route into vue template as below. my vue is location is resource/assets/js
here is code
<template>
<a href={{route('/')}}></a>//i want to pass laravel route
//to view component this line
//throw error
</template>
route(web.php) code
Route::get('/' , function(){
Return view('homepage');
});
i want to pass this url into vue component whose location (vue) is resource/assets/js
You have to pass it as a prop inside your vue component.
They are two different steps.
Laravel spits out the compiled template
Vue parses the components and initializes them.
At step 2 you have to pass a prop with the route parsed at step 1
Something like this
<my-component route="{{ route('my-route') }}"></my-component>
Then within your component
<template>
<a :href="route">CLICK HERE</a>
</template>
<script>
...
props: {
route: { type: String, required: true }
}
...
</script>
Try with
<a :href="{{route('/')}}"> or <a v-bind:href="{{route('/')}}">
Don't use double curly brackets in your Vue components in relation to Blade. They are not functionally equivalent. Instead, pass the url as a string or bind it to a data attribute. The interpolation error you're seeing is a result of using the curly brackets and expecting them to be rendered vie the blade engine.
Your example is quite simple as route('/') is equivalent to just /.
// this is all you need to hit your defined route.
...
Take a look at this package for generating client side routes and helpers in the Laravel fashion. Quite a handy package, I might add. I've used it myself in several larger projects.
https://github.com/aaronlord/laroute
As an aside, you mean the resources location resource/assets/js. Ultimately, that component will be located within your public directory if you use a build tool such as webpack, grunt, gulp, etc. so it's current location within the project directory isn't particularly relevant.
OK, since none of above really worked for me, my solution is:
<my-component route="'{{ route('my-route') }}'"></my-component>
(This is an example of passing a route through component's props, but should work the same when used within <a href=...)
For me looks like Vue doesn't know that you're trying to pass a string so tries to evaluate your route as an expression. Quotes tell Vue that you want this to be a string.
Another solution, which works for passing almost everything (for instance whole objects) to Vue is encoding your variable using JSON format like:
<my-component route="{{ json_encode(route('my-route')) }}"></my-component>
Or Laravel 5.5 and up you can use #json shortcut Blade directive for json_encode:
<my-component route='#json(route('my-route'))'></my-component>
Going further about JSON and objects - if Blade destroys your object data because of escaping the content you can use the following code:
<my-component route="{!! json_encode(route('my-route')) !!}"></my-component>
More on JSON and escaping data in Blade you can find here.

Link to a route with a parameter of Vue.js

I'm using Vue.js and Laravel to render a simple table listing products. From there I want to link to a product detail page like this:
#{{ product.id }}
Since the table is generated on client side base on a data object, I'm looking for the most elegant way to implement that while not bypassing any laravel methods like route() that allows me to link to a named route.
Do I really have to manually merge the result of the route-method with the Vue variable in Javascript?
In my mind is something like:
#{{ product.id }}
which I could probably parse/inject by Vue via data binding?
As Vue it's client side and laravel it's server side you can't accomplish that in that way.
But you can do something like this over the rendered route:
Create a vue method
goto_route: function (param1) {
route = '{{ route("yournamedroute", ["yourparameter" => "?anytagtoreplace?"]) }}'
location.href = route.replace('?anytagtoreplace?', param1)
}
Now in your action element
<div v-for="o in object">
<a v-on:click="goto_route(o.id_key)">press</a>
</div>
Basically you're replacing the... uhmm... let's name it "placehoder" in the rendered route with the required value.
hope it helps.

Print database values in the main layout

I am using laravel 5 for my project. I have a view file layouts/app.blade.php which is extended by all the views. I have stored the application name , email in the database .... Now I need to show those data in my app.blade.php..
How do I do it?
Well as #DutGriff said, it seems to be that you are too new to laravel framework. Just dig in a bit and you get something called Service Injection in blade. Now, answer to your question:
Open you app.blade.php
Go ahead and type the following at very start of app.blade.php
#inject('model_name', 'App\ModelName')
{{{ $model_name = $model_name->where('app_name', 'app')->get() }}}
And then, just access it anywhere like:
{{ $model_name->name }}

Laravel routes and blade templating with reactjs

Is there some way I can use blade type syntax with React to handle my Laravel routes? Let's say I have something like the following:
<div class="card">
Go to your account
</div>
If I try to make this into a Reactjs component, clearly the blade type syntax won't work.
I have looked into React Router, but don't exactly know how it would fit into my application, or if it is even necessary for me to use (I'd much rather use plain Laravel routes).
React code is not executed by Laravel, but by the user's browser. So when the time comes to generate that href, inside the user's browser, the code does not have any more access to Laravel or Blade tools.
What you can do is to pass all the info you need to your React app, beforehand, when you use blade to generate the top level React invocation:
<script>
React.render(
MyApp({
accountShow: "{{ route('account.show', $user->slug) }}",
//etc.
}),
document.getElementById('myContainer')
)
</script>
So then in your React app you can use those properties and pass them down to inner components, e.g:
<CardLink href={this.props.accountShow}>
Go to your account
</CardLink>

Categories