posva / unplugin-vue-router

Next Generation file based typed routing for Vue Router
https://uvr.esm.is
MIT License
1.59k stars 76 forks source link

Allow defining route options when there is no `component` #318

Open neilmispelaar opened 7 months ago

neilmispelaar commented 7 months ago

Description

First off, absolutely love this project, and there is just one thing that I can't figure out that is preventing me from switching over to this awesomeness. So thank you for building it.

Problem / Opportunity

How might we add a beforeEnter() guard to a dynamic folder entry.

For example - check out the existing vue router setup:

routes: [
    // Splash Page
    {
      path: '/',
      name: 'splash',
      meta: { layout: 'default' },
      component: () => import('../views/Splash.vue')
    },
    // Language folder
    {
      path: '/:lang',
      beforeEnter: (to, from) => {
        // If the language code is not valid then go to the 404 page
        if (to.params.lang === undefined || !langCodes.includes(to.params.lang)) {
          return {
            name: 'not-found'
          }
        }
    }
    ...
]

The dynamic /:lang folder entry in the above routes declaration has a beforeEnter() guard to check if the lang param is valid (en / fr).

The problem then, is, how would I achieve this using the plugin.

Assuming the following directory structure:

/src 
  /pages
    /[lang]
       /index.vue
       /another-page.vue
       /yet-another-page.vue
    /index.vue
    /error.vue

The challenge with the above is that I'm not sure how to add a beforeEnter() route guard to the [lang] dynamic folder entry as there is no corresponding code to add it to.

Option, but not great

One option I thought of was using the https://uvr.esm.is/guide/extending-routes.html Extending Routes feature, however I didn't love the idea of adding this logic in the vite config file.

I think if there was a way to add it to the router/index.js it would be a bit cleaner.

VueRouter({
  extendRoute(route) {
    if (route.name === '/[name]') {
      route.addAlias('/hello-vite-:name')
    }
  },

Alternatively, I could add the route guard code to the global router.beforeEach however I'm not sure how to only limit that function to the specific dynamic path.


router.beforeEach((to, from) => {

  // How to scope this logic to only the dynamic [lang] parameter?

}

Hope that makes sense?

Thanks.

posva commented 6 months ago

I'm glad you enjoy it!

There should be a more generic way to add options to a route that do not have a component. I still need to figure out how this would be present as a file, a special suffix index.options.ts, a new option to enable in the config, etc. Ideas are welcome. This has some overlap and probably super-seeds #107

carrypann commented 3 months ago

I'm glad you enjoy it!

There should be a more generic way to add options to a route that do not have a component. I still need to figure out how this would be present as a file, a special suffix index.options.ts, a new option to enable in the config, etc. Ideas are welcome. This has some overlap and probably super-seeds #107

Looking forward to new progress on it.

posva commented 1 week ago

This is related to

It will likely be allowed with a custom file +route.ts