Home > Software engineering >  Vue js - Change navbar button class when on that page
Vue js - Change navbar button class when on that page

Time:02-25

I have a navbar at the bottom of my page which is in the App.vue component so that it sits on top of every page. What I would like to happen is that when a user navigates to a page, this page's button in the navbar highlights/changes class.

I am using composition API, but thought their may be a way of doing this in HTML without having to write in the script.

I can't seem to find a best practice online, please can someone help?. This was my attempt but it doesn't work. There must be a simpler way! Thank you.

HTML:

 <ul >
            <li >
                <router-link to="/" ><i  :></i></router-link>
            </li>
            <li >
                <router-link :to="{ name: 'Rooms' }" ><i  :></i></router-link>
            </li>
            <li >
                <router-link :to="{ name: 'Rooms' }" ><i  :></i></router-link>
            </li>
            <li >
                <router-link :to="{ name: 'Rooms' }" ><i  :></i></router-link>
            </li>
            <li >
                <router-link :to="{ name: 'Rooms' }" ><i  :></i></router-link>
            </li>
        </ul>

Script:

<script>
import { computed, ref, onUpdated } from 'vue'
import { useStore } from 'vuex'
import { useRoute } from 'vue-router'

export default {

  setup(){
    const store = useStore()
    const route = useRoute()
    const pageParams = computed(() => store.state.pageParams)

    const currentRouteName = computed(() => route.name)
    var currentRouteId = ref(null)

    //
    onUpdated(() => {
      if(currentRouteName.value === 'Home'){console.log('Home'); currentRouteId=1;}
      if(currentRouteName.value === 'Rooms' || currentRouteName.value === 'Room'){console.log('Rooms'); currentRouteId=2;}
      if(currentRouteName.value === 'CCTV'){console.log('CCTV'); currentRouteId=3;}
      if(currentRouteName.value === 'Security'){console.log('Security'); currentRouteId=4;}
      if(currentRouteName.value === 'Door Entry'){console.log('Door Entry'); currentRouteId=5;}

      console.log(currentRouteId)
    })


    return { pageParams, currentRouteName, currentRouteId }
  },
}

</script>

CodePudding user response:

This is a similar issue that I had awhile ago. The solution is similar to what you already have. The change I would make is moving the routes down into your data and v-forring that array you made down there. Then, I would create a wrapper component around the components. Inside the new wrapper component, I would just set up a computed watcher, then if(route.name === prop.name) return "class" I can whip up a quick sandbox for you to look at how I would do it. Though, I figure you can probably get it on your own. It's just making a quick wrapper component to watch the route change and adjusting the class accordingly. Alternatively, and probably a better option would be to possibly use CSS :active on the class. I believe router-link has active-class prop, which you might be able to add a custom class for being active. But, I'm not sure if that's meaning that it's CSS "active" or being active as in it is the current route. (Css would be "active" while it's actively being clicked, then disappear after the event)

CodePudding user response:

Why not use the active-class prop of RouterLink? Then you can use whatever Bootstrap class you want to make it appear highlighted (ie: active, border-dark, etc..)

   <ul >
           <li >
                <router-link to="/"  active-><i ></i></router-link>
           </li>
           <li >
                <router-link :to="{ name: 'Rooms' }" active- ><i ></i></router-link>
           </li>
           <li >
                <router-link :to="{ name: 'More' }" active- ><i ></i></router-link>
           </li>
   </ul>

Vue 3 Demo

  • Related