Vue-router: conditional component on route

Created on 14 Aug 2015  ·  14Comments  ·  Source: vuejs/vue-router

how can i set route component conditional. such as when the isLoggedIn data true the "/" route wil be dashboard.

module.exports = function (router) {
  router.map({
    '/': {
      // if isLogged in is true require "dashboard" componen else load home
      component: require('./components/home.vue')
    }})
  })

how can i do it ?

Most helpful comment

I don't see a necessity for this. A simple functional component as a wrapper can easily solve this.

import store from './store' // or wherever you get login status from
export default {
  functional: true,
  render(h) {
    return store.user.loggedIn 
    ? h('dasboard')
    : h('LandingPage')
  }
}

You can even define this small wrapper inline in the routes config, if you wanted to. That would be pretty much the same as the suggested passing of a function.

All 14 comments

You can only have one component for one route, but you can do the conditional check and display other components inside that component. Or - you can do a conditional redirect inside the global before hook or in the canActivate hook using transition.redirect(path)

@yyx990803 first of all, super thanks for vuejs. it is awesome :)

Second, is this comment above still valid with vue 2.0?

@awitherow Generally yes. But the router hooks have changed, please refer to the docs.

Conditional routes could not be a new feature? It would be very useful since most applications have a dynamic root, switching between Landing Page and a first page if the user is logged in.

It seems like this feature could be as simple as accepting a function for the value of the component property of the route definition.

I don't see a necessity for this. A simple functional component as a wrapper can easily solve this.

import store from './store' // or wherever you get login status from
export default {
  functional: true,
  render(h) {
    return store.user.loggedIn 
    ? h('dasboard')
    : h('LandingPage')
  }
}

You can even define this small wrapper inline in the routes config, if you wanted to. That would be pretty much the same as the suggested passing of a function.

In my opinion, this is a "routing problem", this approach seems to me a workaround. This component has no semantic reason to exist, it only there to make a switch between two different purposes components.

it only there to make a switch between two different purposes components.

That's a pretty valid usecase for a functional component - we use a similar example in the guide to explain possible use cases for functional components.

But this approach is more complicated, not simpler.

  1. The true components are hidden from the routes;
  2. Hides and spreads the routing logic across multiple components;

@alexandremagro Actually you don't need to show different component on each route.

It's far simpler and easier to reason to just do:

  1. Make routes static: one route to always render one component
  2. Use router.beforeEach to make redirections

e.g.

if (user.isLoggedIn) next()
else next({ path: '/login', replace: true})

@fnlctrl Yes, this is correct approach today. But is a limitation of Vue Router not being able to use root path (/) for Landing Page and Logged Home Page (ex. Facebook and Instagram), without create a "switch component".

You _can_ pass a function a long as a component. It just has to return a promise with a component

Has a solution been found for this issue yet? I agree that while LinusBorg's approach may work, it feels like a workaround. Is there any way to do this strictly using vue-router?

Was this page helpful?
0 / 5 - 0 ratings