Currently , i have a navigation drawer component. So the idea is like this , when user navigate to any navigation such as home page or profile page , the title will change accordingly based on the route. For example , if the user navigate to home page (e.g. "/")
, the title will change to "Home" and if the user navigate to profile page (e.g. /profile)
, the title will change to "Profile". However , if I accessed any of URLs directly e.g /profile , /profile/list
, the title would not change to "Profile" instead the title will use the default value which is "TEST". Should I implement a watch
method on my route to solve this problem ?
index.js
export const state = () => ({
title: 'TEST',
})
export const getters = {
getTitle: (state) => state.title
}
export const mutations = {
setTitle(state, value) {
state.title = value
}
}
export const actions = {
setTitle({ commit }, value) {
commit('setTitle', value)
}
}
NavigationDrawer.vue
<script>
export default {
data: () => ({
drawer: true,
items: [
{
icon: 'mdi-home',
title: 'Home',
to: '/'
},
{
icon: 'mdi-account',
title: 'Profile',
style: 'profile',
links: [
{ title: 'Dashbord', to: '/profile/' },
{ title: 'Staff List', to: '/profile/list' },
{ title: 'Search', to: '/profile/search' },
]
},
{
icon: 'mdi-umbrella-beach',
title: 'E-Leave',
style: 'leave',
to: '/leave',
},
{
icon: 'mdi-calendar-clock',
title: 'Time Attendance',
style: 'attendance',
to: '/attendance'
},
{
icon: 'mdi-car-lifted-pickup',
title: 'Reservation',
style: 'reservation',
to: '/reservation'
},
{
icon: 'mdi-weight-lifter',
title: 'Staff Training',
style: 'training',
links: [
{ title: 'Training Records', to: '/training/records' },
{ title: 'Training Programs', to: '/training/programs' },
]
},
{
icon: 'mdi-medical-bag',
title: 'Medical',
style: 'medical',
links: [
{ title: 'My Balances', to: '/medical/balance/self' },
]
},
],
}),
methods: {
getCurrentPageNameByPath(){
var array = [
{ name:"Profile", value:"/profile/"},
];
const search = what => array.find(element => element.name === what);
const found = search("Profile");
if (found) {
console.log(found.value, found.other);
} else {
console.log('No result found');
}
},
updatePageTitle(title) {
this.$store.dispatch('setTitle', title)
},
toggleDrawer() {
this.drawer = !this.drawer;
},
isAdminChipVisible(link) {
return (link.hasOwnProperty('is_hr') && link.is_hr) || (link.hasOwnProperty('is_hod') && link.is_hod);
},
isVisibleForRegularUser(link, item) {
return item.public || ( this.$auth.user && (!link.hasOwnProperty('is_hod') || link.is_hod == false) && (!link.hasOwnProperty('is_hr') || link.is_hr == false) );
},
isVisibleForHod(link, item) {
return item.public || ( this.$auth.user && (link.hasOwnProperty('is_hod') && link.is_hod) && this.$auth.user.is_hod );
},
isVisibleForHrAdmin(link, item) {
return item.public || ( this.$auth.user && (link.hasOwnProperty('is_hr') && link.is_hr) && this.$auth.user.is_hr_admin );
}
},
mounted() {
const currentPath = this.$router.currentRoute.path
const currentPageName = this.getCurrentPageNameByPath(currentPath)
this.$store.dispatch("setTitle",currentPageName)
this.$nextTick(() => {
if (this.$vuetify.breakpoint.mdAndDown) this.drawer = false
})
},
}
</script>
<template >
<v-navigation-drawer
v-model="drawer"
:width="300"
app
dark
fixed
floating
>
<template v-slot:prepend>
<div >
<div >
<img src="/snet_white.png" height="50" />
</div>
</div>
</template>
<template v-slot:append>
<div ></div>
</template>
<template v-slot:default>
<v-list >
<template
v-for="(item, index) in items"
>
<v-list-group
v-if="item.links"
:append-icon="null"
:group="item.to"
:ripple="false"
v-bind:key="index"
router
>
<template v-slot:activator>
<v-list-item-content>
<v-list-item-title
v-text="item.title.toUpperCase()"
>
</v-list-item-title>
</v-list-item-content>
<v-list-item-action>
<v-icon>{{ item.icon }}</v-icon>
</v-list-item-action>
</template>
<template v-for="(link, l) in item.links">
<!-- for hod -->
<v-list-item
v-if="isVisibleForHod(link, item)"
:key="l"
:
:ripple="false"
:to="link.to"
exact
router
@click="updatePageTitle([item.title, link.title])"
>
<v-list-item-title >
<v-chip v-if="isAdminChipVisible(link)" color="white float-left" x-small>ADMIN</v-chip>
{{link.title.toUpperCase()}}
</v-list-item-title>
</v-list-item>
<!-- for hr admin -->
<v-list-item
v-else-if="isVisibleForHrAdmin(link, item)"
:key="l"
:
:ripple="false"
:to="link.to"
exact
router
@click="updatePageTitle([item.title, link.title])"
>
<v-list-item-title >
<v-chip v-if="isAdminChipVisible(link)" color="white float-left" x-small>ADMIN</v-chip>
{{link.title.toUpperCase()}}
</v-list-item-title>
</v-list-item>
<!-- for regular staff -->
<v-list-item v-else-if="isVisibleForRegularUser(link, item)"
:key="l"
:
:ripple="false"
:to="link.to"
exact
router
@click="updatePageTitle([item.title, link.title])"
>
<v-list-item-title >
{{link.title.toUpperCase()}}
</v-list-item-title>
</v-list-item>
</template>
</v-list-group>
<v-list-item
exact-active-
:ripple="false"
:to="item.to"
v-bind:key="index"
exact
router
v-else
@click="updatePageTitle(item.title)"
>
<v-list-item-content>
<v-list-item-title
v-text="item.title.toUpperCase()"
>
</v-list-item-title>
</v-list-item-content>
<v-list-item-action>
<v-icon>{{ item.icon }}</v-icon>
</v-list-item-action>
</v-list-item>
</template>
</v-list>
</template>
</v-navigation-drawer>
</template>
CodePudding user response:
You can use the beforeRouteEnter hook,
beforeRouteEnter (to, from, next) {
// document.title = to.title; // Optional set page title from here as well
store.dispatch("setTitle",to.title);
next();
}
You have to import store because you can't access $store inside the router hook
CodePudding user response:
I propose for you two ways to do this :
1 - You can dispatch 'setTitle' action on mounted of each page. For example on Profile.vue page you should add this code :
mounted(){
// Current page Name is the page Name, in this case it's Profile
this.$store.dispatch("setTitle",currentPageName)
}
2 - You can extract the page name from the current route url in 'created' or 'mounted' method of the 'NavigationDrawer.vue' file, then dispatch new Action 'setTitle' by passing the page name :
mounted(){
// your code
......
// 1 - Get current path from router
const currentPath = this.$router.currentRoute.path
// 2 - Search for page Name in items array , you can create a method
// (getCurrentPageNameByPath) for doing this task
const currentPageName = getCurrentPageNameByPath(currentPath)
// 3 - dispatch cureent page name
this.$store.dispatch("setTitle",currentPageName)
}
methods : {
getCurrentPageNameByPath(path){
let path = '/profile/'
let currentPageName = ''
for(let item of items){
if(item.links) {
for(let nestdItem of item.links ){
if(nestdItem.to == path) {
currentPageName = item.title;
break;
}
}
}else {
if(item.to == path) {
currentPageName = item.title;
break;
}
}
}
console.log(currentPageName)
return currentPageName
}
}