How to give data from laravel to vue.js? - laravel-5

When i start write application i used to laravel blade. But now i have to transfer all to vue js and i don't known how to give data from controllers to vue.js. Also i don't know how to transfer this code
#if(Session::has('error_text'))
<div class="col-md-6 col-md-offset-3 formMessage">
<div class="iw">
<div class="text-error">{{Session::get('error_text')}}</div>
#if(Session::has('with_link'))
<div class="help-text">{{Session::get('link_text')}}</div>
#endif
#if(Session::has('unknown_symbols'))
<div class="help-text">Report a bug</div>
#endif
</div>
</div>
#endif

In the blade file if you want to access the vue data you should use #{{ item }}. With the # sign before the interpolation you escape the blade templating.
To pass data from the laravel to vue itself, you should use JSON which you call from your Vue and assign it to a variabel.

The best way to do this is by creating a component and assign the data with properties
<custom-component data="{{ $bladeVariable }}"></custom-component>

Related

how to pass callback function in component? (laravel alpine.js)

I make a draft implementation for my reusable input component.
The code below obviously throws an error.
Question is how to pass the $event back to register blade to get or log the value of the input?
register.blade.php
<div>
<x-input onChange="(value) => {console.log('value', value)}"></x-input>
<div/>
input.blade.php
#props(['onChange' => 'null'])
<input x-on:change="{{ $onChange($event) }}">
A few things here.
First off, your markup is wrong. You have a the closing slash at the wrong end of the closing div. Should be </div> not <div/>.
Then you're using x-on without x-data. Alpine only picks up components with the x-data attribute.
Finally, events propagate automatically, so you could just listen on the parent instead:
{{-- register.blade.php --}}
<div x-data>
<x-input x-on:change="console.log('value', $event.target.value)" />
</div>
{{-- input.blade.php --}}
<input {{ $attributes }}>
I learned we could just achieve this through Alpine.Js dispatch. I don't need to pass onClick props via Laravel component. I just simply use dispatch to listen the event (x-on).
What I like in this implementation is that,
aside of event information, passing of extra data is easy
you don't have to use Laravel props and assigned unnecessary props in the tag.
register.blade.php
<div>
<x-input x-on:custom-input="console.log('your values =', $event.target.newValue)"
></x-input>
<div/>
input.blade.php
<input x-on:change="$dispatch('custom-input', { newValue: $event.target.value })">
you can pass "key" prop to distinguish each component.

Multiple slots with the same name -Laravel Blade

Assuming I want o make a new Blade Component called multi-step-form. I want the component to be able to have as many as possible forms slots. How do I achieve this.
I tried this: But it didn't work:
<!--resources/views/multi-step-form.blade.php -->
<div>
#foreach($forms as $form)
<div class="form"> {{ $form }} </div>
#endforeach
<x-next-button> <x-prev-button>
</div>
And in the child:
<x-multi-step-form>
<x-slot name="forms" {{ -- or "forms[], none of them work --}}>
<!-- Some form --->
<x-slot name="forms">
<x-slot name="forms" >
<!-- Some form --->
<x-slot name="forms">
<x-slot name="forms">
<!-- Some form --->
<x-slot name="forms">
</x-multi-step-form>
Am I missing something here?
this is not possible using blade, you can do something like this in vuejs but unfortunately for now it is not possible in laravel blade.
my suggestion would be to make a child component for this component instead of a slot so it would be reusable as much as you want.

2 way binding with Vue3 Inline template (using slots) in laravel blade template files

In Vue3, inline-templates were depreciated and now slots are used. Is it possible to have 2-way binding of variables for Vuejs components written in blade templates?
I want to have 2-way binding for Vue components that's written inline with blade templates. Although I know I can pass data like <example-component name="Hello World"> It is a ton of work to add props everywhere.
Vue recommends using slots as a inline-template replacement since it got removed in v3, however, that documentation makes no sense. I've got the components displayed using the code below. It's a dead simple text field + paragraph to display the name.
home.blade.php (Removed unnecessary HTML for brevity)
<div>
<h1>Dashboard</h1>
<example-component>
<div class="container">
<input v-model="name" placeholder="Change Name"/>
<p> Name is #{{ name }} </p>
</div>
</example-component>
</div>
example-component.vue
<template>
<div>
<slot></slot>
</div>
</template>
<script>
export default {
data() {
return {
name: 'hi',
}
}
}
</script>
Unfortunately, this does not work, the name doesn't start as 'hi' and doesn't update when changing the textfield. When I try something like <slot :name=name></slot>. Which I believe would pass the name into the slots section, the component gets rendered for a second before disappearing.
Is having 2-way binding with vue variables in blade templates even possible? Any help is appreciated.
Vue: 3.0.5
Laravel: 8.29.0
Is there a reason you're storing the data in the child component? The reactivity design works by passing props down and emitting events up, even though (unfortunately) the reactivity is not maintained when passing a variable up to the parent component. Seems a little counter intuitive, but I might be missing something in what you're trying to create.
It will, however, work if you put the data into the app instead of the component.
// app
const app = Vue.createApp({
data() {
return {
name: 'hi',
}
}
})
// component
app.component('example-component', {
template: `
<div>
<slot></slot>
</div>`,
})
app.mount("#app");
<script src="https://unpkg.com/vue#3.0.5/dist/vue.global.prod.js"></script>
<div id="app">
<h1>Dashboard</h1>
<example-component>
<div class="container">
<input v-model="name" placeholder="Change Name"/>
<p> Name is #{{ name }} </p>
</div>
</example-component>
</div>
<!--

Including laravel blade template with button click

I can not find a solution how to include blade template using button click.
For example lets say I have a main view:
<div id="HEREGOESMYTEMPLATES">
</div>
<div class="row">
<button onclick="addTemplate()">ADD TEMPLATE</button>
</div>
Then script, which should include template
<script type="app/js">
function addTemplate()
{
//Get template and include into div with id HEREGOESMYTEMPLATE
}
</script>
And then the template itself (lets say partial.blade.php):
<div>Include me to main blade file</div>
Is there any possible way by including it without creating every tag in JS and then appending to the div?
Thank you.
UPDATE.
As blade template is not supposed to do such work as it is rendered in backend, I used VueJS to this, which I believe is the best solution in this situation.

Can't pass data from blade to vue (Laravel 5.3)

I'm trying to get Vue components working in Laravel 5.3 and I want to pass data from my blade template to a Vue component.
But I'm getting an error and none of the answers I've found so far have worked.
I'm using the example component that comes with the fresh install. In my blade template I have:
<example :testinfo="someinfo"></example>
In my Example.vue I have:
<template>
<div class="container">
<div class="row">
<div class="col-md-8 col-md-offset-2">
<div class="panel panel-default">
<div class="panel-heading">Example Component</div>
<div class="panel-body">
{{testinfo}} I'm an example component!
</div>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
props: ['testinfo'],
mounted() {
console.log('Component ready.')
}
}
</script>
The Vue component does load, but it does not display the testinfo, and it generates this error message:
Property or method "someinfo" is not defined on the instance but
referenced during render. Make sure to declare reactive data
properties in the data option. (found in root instance)
referenced to your error ->
Property or method "someinfo" is not defined on the instance but referenced during render. Make sure to declare reactive data properties in the data option. (found in root instance)
it means that someinfo model is not declared from your vue parent. it should be wrapped in data { someinfo:null } and from there supply him data and pass it in your component example.
regarding passing with data from vue blade. you should called ajax from your vue method like
Vue new(){
data : { someinfo : null },
ready :function() / mounted() vue2
{
this.getSomeInfo();
}
methods : {
getSomeInfo : function(){
var self = this;
your ajax request here then
self .someinfo = (your ajax.response)
}
}
}
you need an sperate ajax call from controller to achieve to get your information from controller.
after ajax call success then time to put the response to your vue model then it will automatically pass to your components re actively because of two way binding.
The answer from Tony Fale wasn't exactly what I was looking for but it did give me a clue that helped me think of the answer.
In this code:
<example :testinfo="someinfo"></example>
I thought "someinfo" would just be treated as a string but Vue treats it as a JavaScript variable. Since someinfo isn't defined anywhere, it causes an error.
If instead I do:
<example :testinfo="{somekey: 'someinfo'}"></example>
and change Example.vue to:
<template>
<div class="container">
<div class="row">
<div class="col-md-8 col-md-offset-2">
<div class="panel panel-default">
<div class="panel-heading">Example Component</div>
<div class="panel-body">
{{testinfo.somekey}} I'm an example component!
</div>
</div>
</div>
</div>
</div>
</template>
It works as expected.

Resources