Reputation: 51
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>
Upvotes: 2
Views: 943
Reputation: 51
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!
Upvotes: 1
Reputation: 444
I recreated your example here: https://codesandbox.io/s/page-title-from-store-bhw4h
Your approach with the created()
hook worked for me on codesandbox. Could you provide your routes configuration?
It should look similar to this:
const routes = [
{ path: "/child", component: Child },
{ path: "/child2", component: Child2 }
];
Upvotes: 1