Home > Software engineering >  How can I refresh a route every time it is accessed in Vue Router 4?
How can I refresh a route every time it is accessed in Vue Router 4?

Time:10-03

I have setup a route in vue-router 4 that should load a component dynamically depending on whether the user is logged in or not. I did it like this (there may be a better way?):

import Personal from '../views/Personal.vue';
import Public from '../views/Public.vue';
routes: [
    {
        path: '/',
        component: async () => {
            const isLoggedIn = await authenticateUser();
            if (isLoggedIn == true) {
                return Personal
            } else {
               return Public
            }
        }
    }
]

The App.vue file is this:

<template>
  <div id="app">
      <Site-Header></Site-Header>
          <router-view></router-view>
    <Site-Footer></Site-Footer>
  </div>
</template>

The problem is that if a user logs in from the homepage route with path of '/', he doesn't navigate away from this route. Instead I would like vue-router to just load the Personal component instead.

The switch between Personal and Public only seems to work if I hard refresh the page, otherwise no changes happen. So if a user logs in, they still see the Public.vue component, then after a page refresh they see the Personal.vue component. If they then logout, they still see the Personal.vue component until they refresh the page.

How could I force vue-router to analyse the route after log-in/log-out and load the correct component?

CodePudding user response:

To have multiple routes utilizing the same path, your best bet is using Named Views. You can define the default component for your index, or / path to be your Public component, while conditionally selecting a different component using v-if in your template.

You could define your routes as:

routes: [
  {
    components: {
      default: Public,
      Personal: Personal
    },
    name: "index",
    path: "/"
  }
]

Important to note that the syntax here differs. The component field here has to be pluralized in order for this to work, so it has to be components.

Then in your root template that's calling the views, you can then use a simple v-if to switch between them, depending on whether the user is logged in or not. How you store that information is up to you, so just adapt the below code to reflect your own app's logic

<!-- The default is Public, so you don't have to provide the name here -->
<router-view v-if="!user.loggedIn" />
<router-view v-else name="Personal" />

You can see this in this codesandbox

  • Related