Reputation: 4665
I have a child component which emits an event in the created function
created: function(){
this.$emit('onPageTitleChange', this.pageTitle);
this.updateList()
}
i have this inside the #app div (that I'm assinging the vue instance to):
<h2 class="no-margin-bottom" v-on:onPageTitleChange="updatePageTitle">{{ pageTitle }}</h2>
and the vue app (the parent) has the upatePageTitle defined as:
methods: {
updatePageTitle(title){
this.pageTitle = title;
}
},
The page title is not changing - what am I missing?
Upvotes: 1
Views: 4137
Reputation: 82459
There were two issues here. First, the listener needs to be defined in the parent on the component that is emitting the event. Given a router is being used (as pointed out in comments) the listener can be added to the router-view
.
<router-view @on-page-title-change="updatePageTitle"></router-view>
Second, when a template is defined in DOM, meaning, not a string or single file component template, then you need to be aware of camelCase vs kebab-case issues. Attributes in HTML are case-insensitive. I find it best simply to avoid ever emitting camelCased events. That being the case, emit a kebab-cased event.
this.$emit('on-page-title-change', this.pageTitle);
And listen to it as shown above.
Here is a working example.
console.clear()
const Foo = {
template: '<div>foo</div>',
created() {
this.$emit("on-page-title-change", "This is the Foo title")
}
}
const Bar = { template: '<div>bar</div>' }
const routes = [
{ path: '/', component: Foo },
{ path: '/bar', component: Bar }
]
const router = new VueRouter({
routes // short for `routes: routes`
})
new Vue({
el: "#app",
router,
data:{
pageTitle: "This is the original title"
},
methods: {
updatePageTitle(title){
this.pageTitle = title;
}
},
})
<script src="https://unpkg.com/[email protected]"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue-router/3.0.1/vue-router.js"></script>
<div id="app">
<h2>{{pageTitle}}</h2>
<router-view @on-page-title-change="updatePageTitle"></router-view>
</div>
Upvotes: 6