I have a Vue app where I have created a Page Header component which is pulled into the high level view components (Home, Library, Classroom). In each of these ‘higher’ level views I have a router-view where nested ‘children route’ components get loaded. I wanted to change the heading in the Page Header component to match whatever component gets loaded. Naturally after doing some research I saw that I could not use props or slots to get the functionality I needed. I do know I can use route params or queries to get the job done, however I don’t want that extra info cluttering the url.
I decided to use Vuex to store the data needed for Page Header component, as it would be centralized data I could access from anywhere. For my solution I used called a mutation on the created()
hook of a component to update the Page Title store data when one of the pages load. However, this works great on the initial load, but this only fires once (created()
). If I navigate back to a page, the title does not update.
In order to make this work do I need to watch the ‘$route’ for changes? Any help would be appreciated. I can not figure out how to recommit a mutation on a route change.
Code below:
page-header.vue
<template>
<div class="page-header">
<h2>{{ getPageTitle }}</h2>
</div>
</template>
<script>
export default {
name: 'pageHeader',
computed: {
getPageTitle(){
return this.$store.state.pageTitle;
}
}
}
</script>
store/store.js
export const store = new Vuex.Store ({
state: {
pageTitle: '',
},
mutations: {
setPageTitle(state, payload) {
state.pageTitle = payload.pageTitle;
}
}
});
Library.vue
<template>
<div>
<page-header />
<router-view></router-view>
</div>
</template> ....
library-feed.vue (default child route to Library.vue, that populates router-view )
<template>
...
</template>
<script>
export default {
name: 'libraryFeed',
created() {
this.$store.commit('setPageTitle', {pageTitle: 'Library'})
},
}
</script>
Thanks @moritzgvt. I saw that it was working perfectly on your demo. I suspected that it could have been the nested child routes, but I edited your codesandbox and that also worked.
Due to this I went back and looked and realised that I had keep-alive tags around my main router-view in my App.vue ....
I found out here (How to use keep-alive in vuejs?) that using keep alive tags like this:
<keep-alive>
<router-view></router-view>
</keep-alive>
Is that it keeps the router view in memory and the state as well as the lifecycle hooks like created() and mounted() are not reset.
So removing the tags solved it!