Laravel 5.4 + vue2 click Event Handling not working - laravel-5

I have problem with Event Handling in vue2 with Laravel 5.4 - nothing happen when i use click event on the button. No error or anything else.
My html (in fact its header.blade.php):
<div id="example">
<button v-on:click="exclick">Super btn</button>
</div>
My js (app.js in resources/assets folder)
require('./bootstrap');
new Vue({
el: '#example',
methods: {
exclick: function (event) {
alert("Log 1");
if (event) {
alert("Log 2");
}
}
}
});
const app = new Vue({
el: '#app'
});
JS compiled by gulp
Please help!

Related

Unknown custom element: - did you register the component correctly?

I'm new to vue.js so I know this is a repeated issue but cannot sort this out.
the project works but I cannot add a new component. Nutrition component works, profile does not
My main.js
import Nutrition from './components/nutrition/Nutrition.vue'
import Profile from './components/profile/Profile.vue'
var Vue = require('vue');
var NProgress = require('nprogress');
var _ = require('lodash');
// Plugins
Vue.use(require('vuedraggable'));
// Components
Vue.component('nutrition', Nutrition);
Vue.component('profile', Profile);
// Partials
Vue.partial('payment-fields', require('./components/forms/PaymentFields.html'));
// Filters
Vue.filter('round', function(value, places) {
return _.round(value, places);
});
Vue.filter('format', require('./filters/format.js'))
// Transitions
Vue.transition('slide', {enterClass: 'slideInDown', leaveClass: 'slideOutUp', type: 'animation'})
// Send csrf token
Vue.http.options.headers['X-CSRF-TOKEN'] = Laravel.csrfToken;
// Main Vue instance
new Vue({
el: '#app',
components: {
},
events: {
progress(progress) {
if (progress === 'start') {
NProgress.start();
} else if (progress === 'done') {
NProgress.done();
} else {
NProgress.set(progress);
}
},
'flash.success': function (message) {
this.$refs.flash.showMessage(message, 'success');
},
'flash.error': function (message) {
this.$refs.flash.showMessage(message, 'error');
}
}
});
Profile.vue
<template>
<div class="reddit-list">
<h3>Profile </h3>
<ul>
</ul>
</div>
</template>
<script type="text/babel">
export default {
name: 'profile', // this is what the Warning is talking about.
components: {
},
props: {
model: Array,
}
}
</script>
profile.blade.php
#extends('layouts.app')
#section('title', 'Profile')
#section('body-class', 'profile show')
#section('content')
<script>
window.Laravel.profileData = []
</script>
<profile></profile>
#endsection
Whenever I try to go to this page I get:
[Vue warn]: Unknown custom element: <profile> - did you register the component correctly? For recursive components, make sure to provide the "name" option.
I tried doing a local component such as
Vue.components('profile', {
template: '<div>A custom component!</div>'
});
or even I tried adding the profile into the components in vue but still no luck, can anyone point me in the right direction?
Simply clear the cache on your browser if you run into this problem. Worked pretty well for me
I didn't fixed it but it was fixed by itself it appears some kind of magic called (CACHE). i did have my gulp watch running but i powered off my computer, and then ON again and it works.

Vue.js event emitting from child component to (grand)parent component using global eventbus

I want to use a global eventbus to emit events from a child up to a (grand)parent.
In My main.js: I make a global eventbus available to all components.
import Vue from 'vue'
import App from './App'
const eventHub = new Vue()
new Vue({
el: '#app',
template: '<App/>',
components: { App }
})
Vue.mixin({
data: function () {
return {
eventHub: eventHub
}
}
})
Then, in my Childcomponent.vue: I emit an event to the eventbus on a click event
<template>
<button #click="save">Save</button>
</template>
<script>
let data = {
columnName: '',
order: 0
}
export default {
...
name: 'init-column',
methods: {
save: function () {
this.eventHub.$emit('newColumn', data)
}
}
...
}
</script>
Then, in a Parentcomponent.vue I want to catch this event and do something with the data that the child had transmitted:
<template>
<div id="app">
<column v-for="column in allData"></column>
<init-column v-if="newColumn"></init-column>
</div>
</div>
</template>
<script>
import initColumn from './components/Init-column'
let newColumn = false
export default {
...
name: 'project',
ready: function () {
this.eventHub.$on('newColumn', (event) => {
console.log(event)
})
}
...
}
</script>
I'm not sure where to put the $on listener, I saw examples where they put $on in the ready hook. The code above does nothing, however I get no error in the console.
The ability to do this goes away with Vue 3. The RFC below mentions the motivation and links to some issues for further help.
https://github.com/vuejs/rfcs/blob/master/active-rfcs/0020-events-api-change.md
I don't think data is the right place for the event bus. I definitely wouldn't use a global mixin for it either.
What I've done in the past is have a simple bus.js file like:
import Vue from 'vue'
export default new Vue()
Then, in any component that needs the bus I just
import bus from './bus.js'
Then I normally do this to emit events.
bus.$emit('foo', whatever)
and this to catch them
created () {
bus.$on('foo', this.someMethod)
}
I prefer to do it in created since that's the earliest step in the lifecycle you can do this.
Also, this issue on github has some very nice examples: https://github.com/vuejs/vuejs.org/pull/435
I got the desired effect with a custom event: #newColumn="event"
<init-column #newColumn="event" v-if="newColumn"></init-column>
...
methods: { event: function(e) { console.log(e) }
So whenever I $emit from the child it does call the event method.
This works well, but for some strange reason the listener $on does not. Maybe I am missing something with the $on method.
You can put the $on listener in the created hook as specified in the docs: https://v2.vuejs.org/v2/guide/components.html#Non-Parent-Child-Communication
You cannot use ready hook in Vue 2.0. ready hook was originally available in Vue 1.x, but now deprecated.

Vue/Laravel 5.3 - component template not showing in the view

I am trying to use a Vue component in my view for the first time. I have created a file assets/js/components/ImageUpload.vue that looks like this:
<template>
<div>
<div v-if="!image">
<h2>Select an image</h2>
<input type="file" #change="onFileChange">
</div>
<div v-else>
<img :src="image" />
<button #click="removeImage">Remove image</button>
</div>
</div>
</template>
<script>
export default {
data: { image: '' },
methods: {
onFileChange: function onFileChange(e) {
var files = e.target.files || e.dataTransfer.files;
if (!files.length)
return;
this.createImage(files[0]);
},
createImage: function createImage(file) {
var image = new Image();
var reader = new FileReader();
var vm = this;
reader.onload = function (e) {
vm.image = e.target.result;
};
reader.readAsDataURL(file);
},
removeImage: function removeImage(e) {
this.image = '';
}
}
}
</script>
My app.js looks like this:
require('./bootstrap');
var VueResource = require('vue-resource');
Vue.component('image-upload', require('./components/ImageUpload.vue'));
Vue.use(VueResource);
const app = new Vue({
el: 'body'
});
In my view I am inserting the component like this:
<image-upload></image-upload>
My gulpfile looks like this:
const elixir = require('laravel-elixir');
require('laravel-elixir-vue-2');
elixir(mix => {
mix.copy('resources/assets/img', 'public/img');
mix.copy('resources/assets/css', 'public/css');
mix.copy('resources/assets/js', 'public/js');
mix.sass('app.scss')
.webpack('app.js');
});
But nothing happens in the view. There is an element <image-upload></image-upload> but nothing from the template is being shown and the only error in the console is:
[Vue warn]: Do not mount Vue to or -
mount to normal elements instead.
Since I am a not a javascript expert and a total Vue beginner I have no idea where can I change the mounting of Vue and why the template is not being displayed.
You are mounting Vue into the body which is not recommended.
From the Vue docs:
The provided element merely serves as a mounting point. Unlike in Vue 1.x, the mounted element will be replaced with Vue-generated DOM in all cases. It is therefore not recommended to mount the root instance to <html> or <body>.
Try to mount it in some other HTML element like a wrapper <div>

Laracast Video(Push Events to the Client) error?

I try to create event handling...so i followed this video tutorial ..everything working perfect. but in last minute video when i try to show user name in list view its not updating in real time as list view but i checked console.log('users') each object i can get it from my console.... but in view no updates or no errors ......... what is error ?
This is video tutorial - LINK
<body>
<ul id="users">
<li v-repeat="user: users">#{{ user.name }}</li>
</ul>
<script src="https://js.pusher.com/3.0/pusher.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/1.0.20/vue.min.js"></script>
<script>
// (function () {
// var pusher = new Pusher('82355e6cc93e7a15d7d5', {
// encrypted: true
// });
//
// var channel = pusher.subscribe('test');
// channel.bind('App\\Events\\UserHasRegistered', function(data) {
// console.log(data);
// });
// })();
new Vue({
el: '#users',
data:{
users:[]
},
ready: function(){
var pusher = new Pusher('82355e6cc93e7a15d7d5', {
encrypted: true
});
pusher.subscribe('test')
.bind('App\\Events\\UserHasRegistered',this.addUser);
},
methods: {
addUser: function(user){
this.users.push(user);
}
}
})
</script>
</body>
The v-repeat directive is deprecated in version 1.0 and replaced with the v-for.
1.0 replaces the old v-repeat directive with v-for. In addition to providing the same functionality and more intuitive scoping, v-for provides up to 100% initial render performance boost when rendering large lists and tables!
http://vuejs.org/2015/10/26/1.0.0-release/#Faster-Initial-Rendering

Vuejs Single File organization with Gulp

I've followed the laracast tutorial about Vue Workflow with Laravel.
So I have a main.js:
var Vue =require('vue');
import Tournament from '../components/Tournament.vue';
new Vue({
el: 'body',
components: {Tournament},
ready(){
alert('Ready To Go');
}
});
And then I have my Tournament.vue:
<template>
I can't see this text on screen
</template>
<script>
export default {
props: ['list'],
}
</script>
And then, in my HTML, I have that:
<tournament></tournament>
<script src="/js/tournaments.js"></script>
/js/tournament.js is generated by gulp.
I can see the alert, so Vue works fine.
What I cant see is my template.
I never see the sentence:
I can't see this text on screen
I also tried to display dynamic data with data(), but with no success.
Any idea what am I forgetting?
var Vue = require('vue');
import Tournament from '../components/Tournament.vue';
new Vue({
el: 'body',
components: {template: Tournament},
ready() {
alert('Ready To Go');
}
});
Does that work??

Resources