Home » vue » How to set dynamic routes with multiple dynamic parameters in Vue 3 (Vue Router)

How to set dynamic routes with multiple dynamic parameters in Vue 3 (Vue Router)

Posted by: admin November 26, 2021 Leave a comment

Questions:

Using Vue 3 and Vue Router, how can I create dynamic routes with multiple dynamic params?
Those params need to be able to be passed in any order.

In our webapp we have more than 500+ views, so we resolve the routes at runtime, loading the component (.vue) when necessary, because it would be crazy to set each one of those 500 views in routes file.

Let’s assume that we have a view called "Products", our clients have multiple filter options, and those filters are passed in the URL when they are filtering something. They can pass 0 parameters or 10+ parameters. It depends on what they are filtering.

Imagine that users can pass URLs like these below:
www.webapp.com/products
www.webapp.com/products/color/red
www.webapp.com/products/brand/myBrand/color/green
www.webapp.com/products/size/36/brand/myBrand
and multiple other dynamic possibilites.

I tried to add the routes using the wildcard *, but it simply didn’t work.
What I tried:
{path: '/products/:(.*)', ...}
{path: '/products/:params(.*)', ...}
{path: '/products/:(.*)*', ...}
{path: '/products/:params(.*)*', ...}
{path: '/products/*', ...}
{path: '/products-*', ...}

None of those attempts worked. Some threw an error, and some simply removed the parameters from the URL, leaving only /products. In all attempts, this.$route.params was empty.

How can I create dynamic routes with multiple dynamic parameters in any order with Vue 3 and Vue Router?

Obs: For the sake of ‘Friendly URL’, we are not able to use queries because they are ugly
(eg.: products?color=red&size=10&brand=my%20brand)

Answers:

Your attempts likely failed because they mixed named parameter syntax (: followed by the param name) with unnamed parameter syntax ((.*)).

For zero or more named parameters (e.g., named myParams), use this pattern:

:myParams*

I recommend using a props function to parse the route params to be passed to the component as props, which lets the params format live in one central place and spares the component from having to examine the route:

const routes = [
  {
    path: '/products/:myParams*',
    component: () => import('@/components/Products.vue'),

    // parse key-value pairs into an object
    props: route => {
      const params = route.params.myParams
      const props = {}
      for (let i = 0; i < params.length; i += 2) {
        const value = i + 1 < params.length ? params[i + 1] : null
        props[params[i]] = value
      }
      return props
    }
  }
]

demo