I'm working Vue with Laravel, creating a component (nested view), and try to handle the user event in the root (Laravel blade file).

But the problem is, in the root view, the event listener never get called.

See the code 👇

Sample code

MyFolder.vue is a nested component

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
<template>
<div :data-level="level" :style="level > 0 ? 'margin-left: 20px;' : ''">
<div v-for="folder in folders">
<div class="folder-item">
<input :name="name"
type="checkbox"
:value="folder.id"
@change="folderChanged(folder)"
v-model="folder.checked">
</div>
<my-folder v-if="folder.children && folder.children.length"
type="checkbox"
:name="name"
:folders="folder.children"
v-on:checkboxToggled="folderChanged"
:level="level+1"></my-folder>
</div>
</div>
</template>

<script>
export default {
props: {
name: {
required: true,
type: String,
},
level: {
required: true,
type: Number,
},
folders: {
required: true,
type: Object,
},
},
data: function() {
return { }
},
methods: {
folderChanged: function (folder) {
console.log('in level ' + this.level + ', folder changed ' + folder.id);
this.$emit('checkboxToggled', folder);
},
},
computed: {
}
}
</script>

index.html Use the component, and pass the root folders

1
2
3
4
5
6
<my-folder :folders="rootFolders"
:name="'folders[]'"
v-on:checkboxToggled="folderCheckboxHandler"
:level="0"></my-folder>

<script src="/path/to/app.js"></script>

In app.js, define a handling method for folder checkbox toggle event.

1
2
3
4
5
6
7
8
9
10
11
Vue.component('my-folder', require('./vue/MyFolder.vue'));

var app = new Vue({
el: '#app',
...
methods: {
folderCheckboxHandler: function (folder) {
console.log('in root level, folder changed ' + folder.id);
},
},
});

Try it out

When check or uncheck the checkbox in level 2, the console output will be

1
2
in level 1, folder changed 15
in level 0, folder changed 15

The event from the inner child, passed to outer child, but never reach the root event handler folderCheckboxHandler.

I was struggled for half day.

At the end, I figured out that the event name can't be camelCase (see reference below), then I change to kebab-case, it works just fine.

Update

In index.html

1
2
3
4
<my-folder :folders="rootFolders"
:name="'folders[]'"
v-on:checkbox-toggled="folderCheckboxHandler" // <-------- CHANGE THIS
:level="0"></my-folder>

In MyFolder.vue

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<template>
...
<my-folder v-if="folder.children && folder.children.length"
type="checkbox"
:name="name"
:folders="folder.children"
v-on:checkbox-toggled="folderChanged" // <-------- CHANGE THIS
:level="level+1"></my-folder>
...
</template>
...
methods: {
folderChanged: function (folder) {
console.log('in level ' + this.level + ', folder changed ' + folder.id);
this.$emit('checkbox-toggled', folder); // <-------- CHANGE THIS
},
},

References: