bencodezen / vue-enterprise-boilerplate

An ever-evolving, very opinionated architecture and dev environment for new Vue SPA projects using Vue CLI.
7.78k stars 1.32k forks source link

Folder Based Routing? #90

Closed dephora closed 5 years ago

dephora commented 5 years ago

Everything about this boilerplate looks fantastic, however the folder based routing in Nuxt would be a huge bonus. I don't see anything like that as a plugin, has anyone set that up with this boilerplate?

chrisvfritz commented 5 years ago

I actually don't recommend Nuxt-style routing for large projects, because I've quickly run into edge cases where the magic makes things more complex. For example, if a /dashboard route could redirect to one of several other components (this is a real-life example), Nuxt-style routing would force you to do something like this in its view component:

export default {
  fetch ({ store, redirect }) {
    // Redirect to the login page is the user isn't logged in
    if (!store.state.currentUser) return redirect('/login')

    // Get the current user's roles
    const { roles } = store.state.currentUser

    // Redirect admins to the admin dashboard
    if (roles.includes('admin')) return redirect('/dashboard/admin')
    // Redirect vendors to the vendor dashboard
    if (roles.includes('vendor')) return redirect('/dashboard/vendor')
    // Redirect all other users to the leaderboard
    return redirect('/leaderboard')
  }
}

Now the existence of this dashboard.vue file is a little deceiving, because it isn't actually a view - it doesn't render anything. And because of that, it shouldn't actually work like a nested route, but that's how it'll be interpreted. So then you might add a template with just <router-view/> as a hack. And you only find out that this view file isn't really a view at all by looking inside.

Or if you want an alias, it's time for another hack:

<script>
import ViewToAliasTo from './ViewToAliasTo'
export default ViewToAliasTo
</script>

And it actually becomes impossible to get a single-file overview of how route resolution works throughout your app this way. For example, if I wanted to get a list of all the aliases or unauthenticated routes, I'd have to do a search through all the view files, instead of just taking a brief look through a routes.js file.

Then on top of all this, you'd have to manage your own documentation for how routing works in the app instead of your team just being able to consult the Vue Router docs when they want to know how to do something.

That said, some apps do greatly benefit from building a layer of abstraction on top of Vue Router, but I still much prefer to do this in the routes themselves, e.g.:

{
  path: '/dashboard',
  name: 'dashboard',
  meta: { 
    authRequired: true,
    roleRedirect: {
      admin: '/dashboard/admin', 
      vendor: '/dashboard/vendor',
      DEFAULT: '/leaderboard'
    }
  }
}

Then for each route, we still have an at-a-glance view of its resolution and data requirements, while view files are kept simple. They don't have to worry about authentication, authorization, fetching data, or anything else except their primary purpose: rendering a view.

Does that make sense?

dephora commented 5 years ago

Yeah this makes perfect sense. Your example mirrors something that would have caused me grief. I really appreciate you taking the time to lay that out.

chrisvfritz commented 5 years ago

Glad to hear it! 🙂 I'll close this out for now then, but feel free to continue with follow-up questions if you still have any.