I can't get how to initialize a root component data field into a blade view. In particular:
app.js:
import { createApp } from 'vue'
const app = createApp({
data() {
return {
count: 0
}
}
});
blade view:
...html...
<script>
// how can I update count with a blade var (i.e. {{ $count }}) created in my controller?
</script>
In Vue2 actually it was pretty easier, but I'm getting so crazy to get this out that I'm supposing this pattern is not good at all...
Thanks in advance for your kind support.
Related
I'm using Vue with Laravel Mix. In Vue version 2, I was able to do this:
1. resources/js/app.js:
import Vue from 'vue';
import MyComponent from './MyComponent';
Vue.component('my-component', MyComponent);
2. resources/js/MyComponent.vue:
<template>
<p>{{message}}</p>
</template>
<script>
export default {
name: "MyComponent",
props: ['message']
}
</script>
As this Vue 2 document instructed. I know it was not the best practice, but it was the only approach that I have to conveniently pass data from Laravel's Blade template to the component, such as below:
3. anyview.blade.php:
<my-component :message='message' id='app'></my-component>
<script src='public/js/app.js'><script> //include compiled resources/js/app.js
<script>
let app = new Vue({
el: '#app',
data() {
return {
message: 'Hello World';
}
}
})
</script>
In real case, 'Hello World' would be replaced with something like:
message: {{$myMessaGe}}
But since Vue 3, Vue.component is no longer a thing because Vue object is not a default export.
This work flow (1-2-3) has been seamlessly fine, so returning to Vue2 is the last unhappy choice :(
I have tried to work around, just changing Vue.component with the new createApp:
4. resources/js/app.js:
import { createApp } from 'vue';
import MyComponent from './MyComponent';
createApp({
components: {
MyComponent,
}
}).mount('#app');
But instead of adding MyComponent to current instance, it just creates a new one as depicted below - meaning that the prop message can't be passed through.
My question is: Is there any alternative API or workaround to compensate the loss of Vue.component()?
I have only worked with Vue3 so far but what I understand from the documentation is that the components in Vue3 are not that different from components in Vue2.
Try this solution:
import { createApp } from 'vue';
import MyComponent from './MyComponent';
const app = createApp({});
app
.component('MyComponent', MyComponent)
.mount('#app');
You can find more about this in the Vue3 docs.
I want to access a variable $count from my controller and access it to a vue component (frontend). currently have this code on my controller:
public function index()
{
$count = User::where('created_at', Carbon::today())->count();
return view('user.index', compact('count'));
}
i am quite new to laravel and vuejs so please help me out. thank you!
Send count as a prop from blade to component
<your-component-name :count="{{ $count }}"></your-component-name>
And from your component, receive that prop
<template>
<div>
Count is {{ count }}
</div>
</template>
<script>
export default {
props: {
count: {
type: Number
}
}
}
</script>
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>
the above question was answered in below question
Pass data from blade to vue component
I haven't really used this method before and I'm confused where I'm going wrong.
I set the data in the controller, I added the mycourses entry but it's not coming through, everything else is coming in fine
$data['user'] = Auth::user()->load('userType');
$data['courses'] = StudentSchedule::where('instructor_id',Auth::user()->id)
->with('course', 'package.packageCourses', 'user', 'location')->get();
$data['mycourses'] = Course::all();
$data['locations'] = Location::all();
return view('home', $data);
After this I go to the blade and add this
<script>
const user = {!! json_encode($user) !!};
const mycourses = {!! json_encode($mycourses) !!};
const courses = {!! json_encode($courses) !!};
const locations = {!! json_encode($locations) !!};
</script>
Then this goes to the .js, but whats happening there is that its calling the vue
In the vue file I add this to the data()
courses: [],
mycourses: [],
locations: [],
In the vue file I add this to the mounted
this.courses = courses;
this.mycourses = mycourses;
this.locations = locations;
And the mycourses is giving me this error
Error in mounted hook: "ReferenceError: mycourses is not defined"
ReferenceError: mycourses is not defined
I added mycourses after all the other ones were added before, I have everything the same as the courses one and I'm still getting this error. What am I missing?
I'm not sure if this will be helpful or not, meaning perhaps there is a reason this method won't work given your circumstances.
I've found this method of setting/passing data to be pretty helpful. It's less overhead to have to parse in your blade templates (or wherever needed).
Controller
public function myFunction() {
...
$user = Auth::user()->load('userType');
$courses = StudentSchedule::where('instructor_id', $user->id)->with('course', 'package.packageCourses', 'user', 'location')->get();
$mycourses = Course::all();
$locations = Location::all();
// Verify the data is correct.
// dd($courses);
return view('example', compact('user', 'courses', 'mycourses', 'locations');
}
You can verify each is returning the value needed by checking what it's returning using dd().
If you have a vue component you are passing data to that exists in your blade template, you could do something like this to pass the data in as props
example.blade.php
<p>Example content...</p>
<p>Hello, {{ $user->name }}</p>
<example-component :courses="courses" :mycourses="mycourses"></example-component>
<p>...</p>
Now we have passed courses and mycourses to the view component. You can access them there:
<script>
export default {
name: 'ExampleComponet',
data() {
return {
//
}
},
methods: {
//
},
props: {
courses: {
type: Object,
required: true
},
mycourses: {
type: Object,
required: true
},
},
}
</script>
You'll need to update the property type for each of the props you pass in. Perhaps courses isn't an object, but rather a string.
I'm not sure if I've exactly solved your issue, but hope this helps get you in the right direction.
I am using Vue Components in my blade file. Whenever I need to 'refresh' my customer object, I emit an event to the parent (shown below) and customer is refreshed and any props it passed to children will be shown with their updated values.
This is all well and good so far but I am now using some PHP values. I am passing a prop automatic-payments-enabled and it's using a php value. How can I have that value refresh after making an API call that changes it?
Blade file
<div id="app">
<Account
:customer="customer"
:automatic-payments-enabled={!! json_encode($customer->automaticPaymentsEnabled()) !!}
>
</div>
app.js
Vue.component('Account',
require('./components/Account.vue').default);
new Vue({
el: "#app",
data() {
return {
customer: null
}
}
mounted() {
this.getCustomer();
}
methods: {
getCustomer: function() {
//api call to server
this.customer = response.data
}
}
}
I suppose $customer is actually a Model. If so, you can use
$customer->fresh()->automaticPaymentsEnabled()
in my blade.php use one component
<loading :prop_show_loading="show_loading"></loading>
Still in my blade.php
This Doesn't work
<script>
var show_loading = true;
</script>
this Does't work too
<script>
window.event = new Vue();
window.event.$emit('prop_show_loading', 'true');
</script>
and my component doing this (window is not defined)
created(){
let App = this;
console.log(global.event);
window.event.$on('close-modal', (event) => {
this.prop_show_loading = true;
})
},
Any idea?
if you need pass the prop_show_loading value from laravel to loading vue component.
you don't use ":" in the head:
<loading prop_show_loading="show_loading"></loading>
and in the loading component use:
export default {
props: ['prop_show_loading'],
...
and than you can use this.prop_show_loading to get the value.