Home > Back-end >  Is there any way to display title when redirect a url in VUE JS?
Is there any way to display title when redirect a url in VUE JS?

Time:06-20

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
   }

}

  • Related