Adding new subsections in sub menus using Vue router in VueJS

Scenario

In my greenfield app that I've been working on, Carpe Debitum, I wanted the main pages/sections to also have subsections.  But in order to navigate to those subsections, I wanted to use a separate sub menu instead of a nested-type menu in the main menu.  I also wanted to preserve the active links so that the user knows where they're at in the application when they look at the main menu and sub menu.

Router code

In the file that contains my router configuration, I have the following code that sets up my router object:

  1. let router = new Router({
  2. mode: 'history',
  3. routes: [
  4. {
  5. path: '/',
  6. name: 'Home',
  7. component: Home
  8. },
  9. {
  10. path: '/expenses',
  11. name: 'Expenses',
  12. component: Expenses,
  13. meta: {
  14. requiresAuth: true
  15. },
  16. children: [{
  17. path: 'summary',
  18. alias: '/expenses',
  19. component: ExpenseSummary
  20. },
  21. {
  22. path: 'tracker',
  23. component: ExpenseTracker
  24. },
  25. {
  26. path: 'help',
  27. component: ExpenseHelp
  28. }]
  29. },
  30. {
  31. path: '/user',
  32. name: 'User',
  33. component: User,
  34. meta: {
  35. requiresAuth: true
  36. },
  37. children: [{
  38. path: 'profile',
  39. alias: '/user',
  40. component: UserProfile
  41. }]
  42. },
  43. {
  44. path: '/callback',
  45. name: 'Callback',
  46. component: Callback
  47. },
  48. {
  49. path: '/test',
  50. name: 'TestPage',
  51. component: TestPage,
  52. meta: {
  53. requiresAuth: true
  54. }
  55. },
  56. {
  57. path: '*',
  58. redirect: '/'
  59. }
  60. ]
  61. })

 

Let's look at a section of code from the above snippet and break it down to get a closer look:

  1. {
  2. path: '/expenses',
  3. name: 'Expenses',
  4. component: Expenses,
  5. meta: {
  6. requiresAuth: true
  7. },
  8. children: [{
  9. path: 'summary',
  10. alias: '/expenses',
  11. component: ExpenseSummary
  12. },
  13. {
  14. path: 'tracker',
  15. component: ExpenseTracker
  16. },
  17. {
  18. path: 'help',
  19. component: ExpenseHelp
  20. }]
  21. }

The above section of code is the router configuration for my "Expenses" main section, showing the subsections as children.

  • The root "path" property is the URL path for the main component.
  • The root "name" property is the name of the current route, if it has one, which in this case it does.
  • The root "component" property is refers to the main component variable as it is imported.
    • For example, in this case, it's from the following import that is at the beginning of my router file:
import Expenses from '@/components/Expenses/Expenses'
  • The root "meta" property is a custom property that I inserted so that I can protect certain URL paths from being publicly accessible.  That's a whole blog post or two so I'll leave out the explanation for that for now as it involves Auth0.
  • The root "children" property is an array of RouteConfig objects.
    • When a user clicks on "Expenses" in the main menu, I want the user taken to the "Summary" page.  Therefore, I add the "alias" property and set that value to be the same as the root "path" property, "/expenses".
      • This RouteConfig object is assigned to the ExpenseSummary component.
    • The other 2 RouteConfig objects are fairly simple to understand.  When a user clicks on "Tracker" in the sub menu, we want them taken to the ExpenseTracker component view.  The end of the URL path would then look like the following, "https://.../expenses/tracker".  I'm sure you can probably nest more RouteConfig objects inside of other RouteConfig objects, but for now I only want to go 2 levels deep for navigation.

Sub menu component

The following code is all that's in my sub menu component for the "Expenses" section:

  1. // src/components/Expenses/Summary/ExpenseSubNav.vue
  2.  
  3. <template>
  4. <div class="top-sub-nav">
  5. <div class="col">
  6. <router-link :to="'/expenses'" class="top-sub-nav-link">
  7. Summary
  8. </router-link>
  9. <router-link :to="'/expenses/tracker'" class="top-sub-nav-link">
  10. Tracker
  11. </router-link>
  12. <router-link :to="'/expenses/help'" class="top-sub-nav-link">
  13. Help
  14. </router-link>
  15. </div>
  16. </div>
  17. </template>
  18.  
  19. <script>
  20. export default {
  21. name: 'ExpensesSubNav'
  22. }
  23. </script>

The ":to" properties are assigned with URL paths.  You could also assign a route name too if you declared it like I did earlier.  Here though, I just assign them by paths to make things easier for me.  That's pretty much it for the sub menu component.  The other sub menu components for different sections are the same too.