How to pass an object from Laravel to Vue without using props - laravel

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.

Related

Laravel fetchi API Data + vue

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

how to pass laravel trans strings to vue component

In the event that you are developing your software using the Laravel framework and need to use the Vue library, you will face some obstacles, including how to access the files translation system provided by Laravel .
like how to access trans('home.var')
Add Language file like this
<messagings v-bind:language="{{ json_encode(trans('messages')) }}"></messagings>
then in vue component print like this
<h4>{{ this.language.messaging }}</h4>
1: pass trans as prop in blade normally just you need to encoding with json used json_encode() method :
<component :trans="{{json_encode(trans('home'))}}"></component>
2: in vue component page you need to decode json data first and set the translation data in some var :
export default {
props:['trans'],
data () {
return {
translation:[],
};
},
created(){
this.setTranslation()
},
methods:{
setTranslation(){
let decoded_trans = JSON.parse(this.trans);
this.transaction = decoded_trans;
}
}
3: Now you can access laravel trans normaly just be careful because vue will not detect if you call last node or first.
<template>
<div>
<h2>{{translation.header.login}}</h2> // this line in laravel mean : trans('home.header.login')
</div>
<template>
Finally I recently started learning vue , so this method may have some flaws, but We all strive to benefit :)

Best practice to pass data from Laravel to Vue component

This is my blade code
<div id="app">
<Testcomponent bam-wam="ham" />
</div>
This is my VueJS Component code
<script>
export default {
name: "ExampleComponent",
props: [
'bamWam'
],
data () {
return {
};
},
created() {
console.log(this.bamWam);
}
}
</script>
Question is
This code runs good but I am asking what is better using Axios and Vuex to fetch data from my Laravel app or simply Pass data throw props like I did in this code?
Pass data through props is the best way.
<my-component my-data="yourData"></my-component>
If you want to use laravel variable for data from blade then,
<my-component my-data="'{{ $data->id }}'"></my-component>
<my-component :my-data="'{!! json_encode($data) !!}'"></my-component>
Avoid api call as much as possible. It will reduce the total number of request to server and expose fewer number of api endpoint.
If the data is available to the view where the component is added. Then the best way to pass php arrays from laravel to a vue component is to utilize json encoding like so:
<my-component :needed-data='#json($laravelCollection)'></my-component>
This will make you will be easily to perform actions to the php array in the Vue controller as if it was a JS object. Keep in mind that you have to use single quotes for #json.
For simple strings you can just directly pass it as props without the encoding.
This approach is better than creating a new API specifically for this component.
This was the only way that works for me:
<my-component :data="{{ $collection }}"></my-component>
JSON parsed solutions prints data in HTML.

Pass data from blade to vue component

I'm trying to learn vue and with that I want to integrate it with laravel too..
I simply want to send the user id from blade to vue component so I can perform a put request there.
Let's say I have this in blade:
<example></example>
How can I send Auth::user()->id into this component and use it.
I kept searching for this but couldn't find an answer that will make this clear.
Thanks!
To pass down data to your components you can use props. Find more info about props over here. This is also a good source for defining those props.
You can do something like:
<example :userId="{{ Auth::user()->id }}"></example>
OR
<example v-bind:userId="{{ Auth::user()->id }}"></example>
And then in your Example.vue file you have to define your prop. Then you can access it by this.userId.
Like :
<script>
export default {
props: ['userId'],
mounted () {
// Do something useful with the data in the template
console.dir(this.userId)
}
}
</script>
If you are serving files through Laravel
Then here is the trick that you can apply.
In Your app.blade.php
#if(auth()->check())
<script>
window.User = {!! auth()->user() !!}
</script>
#endif
Now you can access User Object which available globally
Hope this helps.
Calling component,
<example :user-id="{{ Auth::user()->id }}"></example>
In component,
<script>
export default {
props: ['userId'],
mounted () {
console.log(userId)
}
}
</script>
Note - When adding value to prop userId you need to use user-id instead of using camel case.
https://laravel.com/docs/8.x/blade#blade-and-javascript-frameworks
Rendering JSON
Sometimes you may pass an array to your view with the intention of rendering it as JSON in order to initialize a JavaScript variable. For example:
<script>
var app = <?php echo json_encode($array); ?>;
</script>
However, instead of manually calling json_encode, you may use the #json Blade directive. The #json directive accepts the same arguments as PHP's json_encode function. By default, the #json directive calls the json_encode function with the JSON_HEX_TAG, JSON_HEX_APOS, JSON_HEX_AMP, and JSON_HEX_QUOT flags:
<script>
var app = #json($array);
var app = #json($array, JSON_PRETTY_PRINT);
</script>
Just to add for those who still get error.
For me this <askquestionmodal :product="{{ $item->title }}"></askquestionmodal> still gives error in console and instead showing html page I saw white screen.
[Vue warn]: Error compiling template:
invalid expression: Unexpected identifier in
Coupling to connect 2 rods М14 CF-10
Raw expression: :product="Coupling to connect 2 rods М14 CF-10"
Though in error I can see that $item->title is replaced with its value.
So then I tried to do like that <askquestionmodal :product="'{{ $item->title }}'"></askquestionmodal>
And I have fully working code.
/components/askquestionmodal.vue
<template>
<div class="modal-body">
<p>{{ product }}</p>
</div>
</template>
<script>
export default {
name: "AskQuestionModal",
props: ['product'],
mounted() {
console.log('AskQuestionModal component mounted.')
}
}
</script>

How to pass javascript variable from laravel controller to vuejs component

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

Resources