Iam bulding a multi-page app using Laravel and Vue.Now, for example lets say I want to use some Laravel helper function like {{ trans('messages.welcome') }} inside a Vue component (which is in a separate .vue file) .. how to do that ?
Access the Laravel helper function from your Blade template, passing the result to your Vue component as a prop:
// app.blade.php
<message-component :message="{{ trans('messages.welcome') }}"></message-component>
// MessageComponent.vue
<template>
<div>{{ message }}</div>
</template>
<script>
export default {
props: [ 'message' ],
}
</script
In fact there is a way, kind of.
Inside data I called Laravel helper method with php tags. Code:
<script>
let app = new Vue({
el: '#app',
data: {
app_url: "<?php echo app_url(); ?>"
});
</script>
Here is another way to do what I believe #rook99
is trying to accomplish. This is working great for me.
Set up your Helper Functions in a a new folder in the app folder. I created a new folder in the app folder called CustomStuff. Then I set up a file called FormHelper.php . Add your Helper function to this file. This is the path to the Helper function file: app\CustomStuff\FormHelper.php
// This is my Helper Function. Create an array of states
public static function States()
{
$states =['AL', 'AK', 'AZ', 'AR', 'CA', 'CO', 'CT', 'DE', 'DC', 'FL', 'GA',
'HI', 'ID', 'IL', 'IN', 'IA', 'KS', 'KY', 'LA', 'ME', 'MH', 'MD', 'MA', 'MI',
'MN', 'MS','MO', 'MT', 'NE', 'NV', 'NH', 'NJ', 'NM', 'NY', 'NC', 'ND', 'OH',
'OK', 'OR','PA', 'PR', 'RI', 'SC', 'SD', 'TN', 'TX', 'UT', 'VT', 'VA', 'WA',
'WV', 'WI', 'WY',];
return $states;
}
Set up a new controller. In the Controllers folder. Call it AppUtilityController Do not forget to add
use FormHelper;
at the top of the controller file. The following command in the command line will create the controller.
php artisan make:controller AppUtilityController
In the AppUtilityController add a function to be called from a root and return the Helper function data.
public function getHelperFunctions()
{
$data['states'] = FormHelper::States();
return $data;
}
set up a new route in your routes folder to call the getHelperFunctions
Route::get('/app-utilities/get-helper-functions',
'Admin\AppUtilityController#getHelperFunctions');
Next go to Vuejs component where you need the Helper Function.
Set up a function using created method so the function will get called when component loads.
Have the function make an api request to the url in the route. Which would be app-utilities/get-helper-functions. I am using axios to make the request.
The FormHelper functions will be returned as a javascript object. Simply use the object anywhere in the component.
In the future, whenever you want to add Helper function just add the new function to the FormHelper.php and AppUtilityController.php files and insert the method to grab the data in your Vuejs component.
I wrote a blog [post]: https://david.dukesnuz.com/blog/8/how-to-use-laravel-helper-functions-with-vuejs on this topic.
Just add script into blade template:
<script>
window.laravel_helper_result1 = '{{laravel_helper_function_1()}}';
window.laravel_helper_result2 = #json(laravel_helper_function_2());
</script>
Then you can use these js variables in your Vue.
Related
Getting to know Laravel a bit more and I was wondering what's the best way to pass my data from my controller into my Vue component?
I have understood how to actually pass it as a prop, however, I can't seem to get it to render the way I want. my props in my Vue component are. My controller here:
{
public function fetch() {
$data = Http::get('https://jsonplaceholder.typicode.com/albums')->json();
return view('welcome', ['data' => $data]);
}
}
My view then passes on the data to my vue component like this.
<example-component :albums="#json($data)" />
My Vue props structure is below.
props: {
albums: {
type: Array,
default: []
},
}
Heres how im trying to render the data in my vue component:
<div>
<h1 v-for="album in albums" :key="album.id">
{{ album.title }}
</h1>
</div>
</template>
Results here enter link description here
I have verified the output from my controller is an array containing arrays. Am I handling the data wrong from the perspective of my Vue component?
you dont need to convert it to json :albums="#json($data)" it's already json ->json();
try replace
:albums="#json($data)"
with this
:albums="{{ $data }}"
I'm basically using VueRouter to create all my routes which is working really well. However, my application is built using Laravel. So if I refresh any of the routes I get an error that the route is not defined. So at the minute in every controller I've had to add an index function. This just returns the view of my app.blade which is just the usual tags etc and the to load my single page app. I'm just wondering if there is a cleaner solution? I guess I could move the return view into a single Controller and make my Controllers extend this. But I'm just wondering if there is a better way I'm missing?
i.e. one of my routes via VueRouter:
{
path: "/clients",
name: "clients",
component: () => import(/* webpackChunkName: "clients" */ "../resources/js/components/Views/Clients/Clients.vue")
},
The route in my clients.php file
Route::get('/clients', [App\Http\Controllers\ClientController::class, 'index'])->name('clients');
Then the ClientController index function
public function index()
{
return view('app');
}
It would just be nice to have the loading of the app.blade done somewhere else and not need to be specified per controller. Any help would be appreciated to ensure it's all done efficiently!
Thanks!
Here is how I solved this issue for one of my projects which is also single page application in Vue and Laravel: https://github.com/lyyka/laravel-vue-blog-spa/blob/master/routes/web.php
Simply, in your routes file, you put this code:
Route::get('/{any}', function () {
return view('welcome');
})->where("any", ".*");
And in my welcome view I have:
#extends('layouts.app')
#section('content')
<div class = "container">
<router-view></router-view>
</div>
#endsection
Basically this will return your app view for any URL and so your Vue SPA should work properly. Generally, it is not a good practice to put callback functions inside your routes file, but in this case, you won't even be using your routes file as it is a SPA, so this solution can pass! :)
You should use your single html file and make a controller.
On your controller
public function index(){
return view('index');
}
on your web.php
basically, you should make the same route on your laravel and vue
Route::get('/products', [ProductsController::class,'index']);
in my vue-routes
import Products from './components/Products.vue'
{
path:'/products'
component: Products
}
I'm setting up some Vue Components in my Laravel 5.8 application, that require user information available through Auth::user(), most importantly, the api_token that I must use in my axios requests. I want to pass the Auth::user() object from Laravel to Vue in a secure and private method.
I initially passed the object as props, but I don't want private information on the object to be easily exposed using browser extensions such as Vue DevTools. Now, I've been searching for a way to define global variables inside the Blade Template and access them in Vue:
Pass data from blade to vue component
https://forum.vuejs.org/t/accessing-global-variables-from-single-file-vue-component/638
https://zaengle.com/blog/layers-of-a-laravel-vue-application
Based on those links above, it seems like what I need to do is set the variables to the window object, but I'm unsure on what I'm doing something wrong to achieve this. When I define the variable in the Blade Template, I can see the variable is assigning properly by doing console.log() but the problem comes when I try to use it in Vue.
app.blade.php
#if(Auth::user())
<script>
window.User = {!! json_encode(Auth::user()) !!}
console.log(window.User)
</script>
#endif
component.vue
<script>
export default {
data: function() {
return {
user: window.User
}
}
}
</script>
I've tried setting the data as window.User, this.User, and simply just User but it always comes up as undefined. What am I missing? Or is there any other/better way to do this?
Try the following Vue Component:
<template></template>
<script>
export default {
data: function() {
return {
user: window.User
}
},
created(){
console.log(this.user)
},
}
</script>
I could see the user data from the console.log in Vue component.
On my laravel home page I have a vue component like this
<new-tutor area-id="{{ $area->slug }}" tutor-id="{{ $tutor->slug }}" route="{{ route('tutor.show', [$area, $tutor]) }}"></new-tutor>
it returns all new tutors in a given area in individual bootstrap cards, and uses this controller
public function index(Request $request, Area $area, Profile $profile, Tutor $tutor)
{
$newTutors = Tutor::with(['user', 'area'])->inArea($area)->latestfirst()->get();
return response()->json($newTutor, 200);
}
I would like to be able to click on the tutors name and be sent to that tutors page, but I can't seem to get the tutor slug to pass though properly, and I am not sure why.
In my vue component I set the link like
<a :href="route">{{newTutor.name}}</a>
and I have props set up like this
props: {
areaId: null,
tutorId: null,
route: { type: String, required: true }
},
the slug does come through in a dd on newTutors, and Tutor.
Also note, I am using the same web route
tutor.show
in other blade templates, so I am mostly confident that that is not where the issue is.
if you using laravel + vuejs,You need add #{{}}
<a :href="route">#{{newTutor.name}}</a>
I'm trying to build a page on Laravel 5.4 which contains few data which needs to be manipulated and then sent across the views. My view contains components of the vuejs v2.0. I want those data to be implemented in the components. I tried using the laracasts PHP Vars to JS transformer but unable to get it. I followed the steps by placing "laracasts/utilities": "~2.0" in my composer.json then I added the serviceprovider as mentioned in the documentation, I published the vendor and added the following in config/javascript.php,
'bind_js_vars_to_this_view' => 'Nitseditor.show',
I'm having a dynamic views folder which is currently inside my Nitseditor\home\resources\views Now in my controller I'm having following codes:
public function show()
{
JavaScript::put([
'foo' => 'bar',
'age' => 29
]);
return view(Nitseditor.show);
}
Now first of all it was throwing an error as I see that it was including use MongoDB\BSON\Javascript; then I removed and tried using use JavaScript
Now in the app.js file which is present in my asset folder, I'm including each components and trying to do console.log(foo); but its throwing an error foo not defined.
There are a few ways to do this depending on what you are trying to achieve and how your project is set up. The simplest way is to make a request to your controller from inside your component that returns json. Laravel 5.4 comes with axios so you can use that:
methods: {
getData(){
axios.get('/controller/route')
.then(response => {
// set your variables from the response
this.myData = response.data;
})
.catch(error => {
console.log(error);
});
},
data(){
return {
myData: {}
}
}
If you need child components to access the data then you would need to put that in the parent and pass myData" using props.
You could also create a directive and pass your variable down directly from your blade template:
Vue.directive('init', {
bind: function(el, binding, vnode) {
vnode.context[binding.arg] = binding.value;
}
});
Then you would just need to do:
<div v-init:vars="{foo: 'foo', age: 29}"></div>
And pass vars as props to any component that needs them:
Here's the JSFiddle: https://jsfiddle.net/3e05qwLh/
If you have multiple descendants that rely on your variables you will probably want to look at using vuex.
Dunno if it helps but I use this method for passing variables to javascript:
// in master layout (head section)
<meta name="foo" content="{{ $foo }}">
// in javascript (included or in the template)
foo = $('meta[name=foo]').attr('content');
If you have javascript in the blade template you can use directly this method:
foo = "{{ $foo }}";