Simple Vue Component doesn't work on first div, only on second div - laravel

I'm currently trying to learn basic vue.js component. These are my codes
chat.blade.php
#extends('layouts.app')
#section('content')
<div class="container">
<div class="row">
<div class="col-md-3">
<div id="components-demo">
<div class="card">
<div class="card-header">Users</div>
<div class="card-body">
<ul class="list-group list-group-flush">
<button-counter></button-counter>
</ul>
</div>
</div>
</div>
</div>
<div id="chat-component" class="col-md-9">
{{--<chat-component v-bind:auth-user="{{$user}}" v-bind:other-user="{{ $otherUser }}"></chat-component>--}}
</div>
</div>
</div>
#endsection
#section('js')
<script>
</script>
#endsection
app.js
require('./bootstrap')
window.Vue = require('vue')
// const files = require.context('./', true, /\.vue$/i)
// files.keys().map(key => Vue.component(key.split('/').pop().split('.')[0], files(key).default))
Vue.component(
'chat-component',
require('./components/ChatComponent.vue').default
);
Vue.component('button-counter', {
data: function () {
return {
count: 0
}
},
template: '<button v-on:click="count++">You clicked me {{ count }} times.</button>'
});
const app = new Vue({
el: '#app'
});
new Vue({ el: '#components-demo' });
The problem is when i try to click the button, the count is not working. But if I add another same component div with the same id, it works for the button in the second div.
<div class="col-md-3">
<div id="components-demo">
<div class="card">
<div class="card-header">Users</div>
<div class="card-body">
<ul class="list-group list-group-flush">
<button-counter></button-counter>
</ul>
</div>
</div>
</div>
<div id="components-demo">
<div class="card">
<div class="card-header">Users</div>
<div class="card-body">
<ul class="list-group list-group-flush">
<button-counter></button-counter>
</ul>
</div>
</div>
</div>
</div>
Why is it only working on the 2nd div? Is there something that I'm missing? Thanks in advance.

You are registering multiple Vue instances. You can register many components on single Vue instance.
app.js
require('./bootstrap')
window.Vue = require('vue')
// const files = require.context('./', true, /\.vue$/i)
// files.keys().map(key => Vue.component(key.split('/').pop().split('.')[0], files(key).default))
Vue.component(
'chat-component',
require('./components/ChatComponent.vue').default
);
Vue.component('button-counter', {
data: function () {
return {
count: 0
}
},
template: '<button v-on:click="count++">You clicked me {{ count }} times.</button>'
});
const app = new Vue({
el: '#app'
});
You must make sure that the identifier is app in the app.blade.php file.
layouts/app.blade.php
...
<body>
...
<div id="app">
...
#yield('content')
...
</div>
...
</body>
...
Then, your components should work correctly

Related

TypeError: this.axios is undefined

I'm having this error in browser console, no matter what I did.
First of all I'm new in VueJS. My site is fully functioning, it's build with Laravel. I am trying to convert the frontend to VueJS. I'm trying retrieve data from database and show them in front page using VueJS.
app.js
require('./bootstrap');
window.Vue = require('vue');
//Vue.component('example-component', require('./components/ExampleComponent.vue').default);
Vue.component('title-bar',require('./components/front/titleBar.vue').default);
Vue.component('info-bar',require('./components/front/infoBar.vue').default);
import axios from 'axios';
Vue.use(axios);
const app = new Vue({
el: '#app',
});
infoBar.js
<template>
<div class="container">
<div class="row align-items-center justify-content-between mx-0">
<ul class="list-inline d-none d-lg-block mb-0">
<li class="list-inline-item mr-3">
<div class="d-flex align-items-center">
<i class="ti-email mr-2"></i>
{{ info.email }}
</div>
</li>
<li class="list-inline-item mr-3">
<div class="d-flex align-items-center">
<i class="ti-headphone mr-2"></i>
{{ info.phone }}
</div>
</li>
</ul>
<ul class="list-inline mb-0">
<li class="list-inline-item mr-0 p-3 border-right border-left border-white-0_1">
<span>EIIN: {{ info.eiin }}</span>
</li>
<li class="list-inline-item mr-0 p-3 border-right border-white-0_1">
<span>Institute Code: {{ info.code }}</span>
</li>
</ul>
<ul class="list-inline mb-0">
<li class="list-inline-item mr-0 p-md-3 p-2 border-right border-left border-white-0_1">
Login
</li>
</ul>
</div> <!-- END END row-->
</div> <!-- END container-->
</template>
<script>
export default {
data() {
return {
info: {}
}
},
created() {
this.axios
.get('http://localhost/wpschool/public/api/info-bar')
.then(response => {
this.info = response.data;
console.log(response.data)
});
}
}
</script>
api.php
<?php
use Illuminate\Http\Request;
Route::middleware('auth:api')->get('/user', function (Request $request) {
return $request->user();
});
Route::get('info-bar','FrontController#infoBar');
Route::get('title-bar','FrontController#titleBar');
controller
public function infoBar()
{
$info = [
'email' => siteConfig('email'),
'phone' => siteConfig('phone'),
'eiin' => siteConfig('eiin'),
'code' => siteConfig('institute_code')
];
return response($info);
}
In Vue console the <info-bar> component is returning with empty object. The console is returning with two errors about axios
[Vue warn]: Error in created hook: "TypeError: this.axios is undefined"
found in
---> at resources/js/components/front/infoBar.vue
and
TypeError: this.axios is undefined
Choo 29
I tried reinstalling axios but same result.
Inside app.js add this line of code:
Vue.prototype.axios = axios;
After this statement, you can use this.axios inside every Vue component
On app.js, use
window.axios = require("axios");
// instead of
import axios from 'axios';
Vue.use(axios);
on Vue files, use like this:
axios.get(...)

Vue JS component doesn't show on index.blade Laravel project

My vue js component doesnt show on my project. I don't see any errors from my part as I have seen many examples before and this is the right logic to implement it. Can anyone help me?
index.blade.php file
<div id="app">
<div class="d-flex align-items-center pb-3">
<div class="h3">{{ $user->username}}</div>
<follow-button></follow-button>
</div>
</div>
FollowButton.vue file
<template>
<div>
<button class="btn btn-primary ml-4"> Follow Me </button>
</div>
</template>
<script>
export default {
mounted() {
console.log('Component mounted.')
}
}
</script>
app.js file
require('./bootstrap');
window.Vue = require('vue');
Vue.component('example-component', require('./components/ExampleComponent.vue').default);
Vue.component('follow-button', require('./components/FollowButton.vue').default);
const app = new Vue({
el: '#app',
});
ExampleComponent.vue file
<template>
<div class="container">
<div class="row justify-content-center">
<div class="col-md-8">
<div class="card">
<div class="card-header">Example Component</div>
<div class="card-body">
I'm an example component.
</div>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
mounted() {
console.log('Component mounted.')
}
}
</script>
make sure you use <div id="app"> inside write all vuejs code
Add this in app.js
Vue.component('follow-button', require('./components/FollowButton.vue').default);
after register follow-button you can use
<div id="app">
<div class="d-flex align-items-center pb-3">
<div class="h3">{{ $user->username}}</div>
<follow-button> </follow-button>
</div>
</div>
after that run npm run dev
Note: - make sure index.blade.php here you added app.js file
For anyone who might have the same problem with me, somehow I had two divs with the same id="app" and that made sure that my vue.js file not to be implemented on my laravel project.
try to add to index.blade.php file
<script src="{{ mix('/js/app.js') }}"></script>

Not able to mount data on DOM

I am new to vuejs ...I am not able to mount the data of component to the blade file
app.js
Vue.component('example-component',
require('./components/ExampleComponent.vue').default);
const app = new Vue({
el: '#app',
});
home.blade.php
<div id="app">
<example-component></example-component>
</div>
ExampleComponent.vue
<template>
<div class="container">
<div class="row justify-content-center">
<div class="col-md-8">
<div class="card">
<div class="card-header">Example Component</div>
<div class="card-body">
I'm an example component.
</div>
</div>
</div>
</div>
</div>
<script>
export default {
mounted() {
console.log('Component mounted.')
}
}
There was no error but
element example-component
was displayed as it is ..I want to display Component mounted on console?
I have found the thing i have missed while coding is that,
I have not included app.js file...
After including this file i overcome my output..

VueJs With Laravel

I am learning Vuejs. I am making a system where users can set a message as favourite.
But i am getting the below error. Any help to resolve would be appreciated.
[Vue warn]: Failed to mount component: template or render function not
defined. found in
---> Favorite Root
Below is my code =>
Favorite.vue
<template>
<span>
<a href="#" v-if="isFavorited" #click.prevent="unFavorite(post)">
<i class="fa fa-heart"></i>
</a>
<a href="#" v-else #click.prevent="favorite(post)">
<i class="fa fa-heart-o"></i>
</a>
</span>
</template>
<script>
export default {
name: 'favorite',
props: ['post', 'favorited'],
data: function() {
return {
isFavorited: '',
}
},
mounted() {
this.isFavorited = this.isFavorite ? true : false;
},
computed: {
isFavorite() {
return this.favorited;
},
},
methods: {
favorite(post) {
axios.post('/favorite/'+post)
.then(response => this.isFavorited = true)
.catch(response => console.log(response.data));
},
unFavorite(post) {
axios.post('/unfavorite/'+post)
.then(response => this.isFavorited = false)
.catch(response => console.log(response.data));
}
}
};
</script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
app.js
require('./bootstrap');
window.Vue = require('vue');
/**
* Next, we will create a fresh Vue application instance and attach it to
* the page. Then, you may begin adding components to this application
* or customize the JavaScript scaffolding to fit your unique needs.
*/
Vue.component('Favorite', require('./components/Favorite.vue'));
const app = new Vue({
el: '#app'
});
index.blade.php
#extends('layouts.app')
#section('content')
<div class="container">
<div class="row">
<div class="col-md-8 col-md-offset-2">
<div class="panel">
<h3>All Posts</h3>
<hr>
</div>
#forelse ($posts as $post)
<div class="card">
<div class="card-header">
{{ $post->title }}
</div>
<div class="card-body mb-2">
{{ $post->body }}
</div>
#if (Auth::check())
<div class="card-footer mb-2">
<favorite
:post={{ $post->id }}
:favorited={{ $post->favorited() ? 'true' : 'false' }}
></favorite>
</div>
#endif
</div>
#empty
<p>No post created.</p>
#endforelse
{{ $posts->links() }}
</div>
</div>
</div>
#endsection
Try Vue.component('Favorite', require('./components/Favorite.vue').default); with .default at the end.

VueJS inside Laravel, can't pass data using props

This is the code (very simple)
<div class="container" id="vueApp">
<div class="content">
<div class="title animated flipInX">BIG TITLE</div>
<p><strong>Some subtitle</strong></p>
<custom-button fa-icon="fa-home"></custom-button>
<custom-button fa-icon="fa-envelope"></custom-button>
<custom-button fa-icon="fa-info"></custom-button>
</div>
</div>
<template id="btn-template">
<span class="btn fa #{{ fa-icon ? fa-icon : 'fa-star-o' }} font-size-40"></span>
</template>
<script src="http://cdnjs.cloudflare.com/ajax/libs/vue/1.0.14/vue.min.js"></script>
<script>
Vue.component('custom-button', {
template: '#btn-template',
props: ['fa-icon'],
});
</script>
This is returnig fa-star-o and not the desired fa-icon. I really don't see any errors but I'm new to this so I'm hoping its something trivial.
I'm following this tutorial.
----SOLUTION----
<div class="container" id="vueApp">
<div class="content">
<div class="title animated flipInX">BIG TITLE</div>
<p><strong>Some subtitle</strong></p>
<custom-button fa-icon="fa-home"></custom-button>
<custom-button fa-icon="fa-envelope"></custom-button>
<custom-button fa-icon="fa-info"></custom-button>
</div>
</div>
<template id="btn-template">
<span class="btn fa #{{ faIcon }} font-size-40"></span>
</template>
<script src="http://cdnjs.cloudflare.com/ajax/libs/vue/1.0.14/vue.min.js"></script>
<script>
Vue.component('custom-button', {
template: '#btn-template',
props: {
faIcon: {
type: String,
default: 'fa-star-o'
}
}
});
</script>
The prop name should be faIcon (camelCased).
http://vuejs.org/guide/components.html#camelCase_vs-_kebab-case
https://jsfiddle.net/asccyLus/
Also, it is better to use a default value for the faIcon instead of the inline if like this:
props: {
faIcon: {
type: String,
default: 'fa-star-o'
}
},
https://jsfiddle.net/asccyLus/1/

Resources