Passing Props to Vue.js Route Components with Vue Router

John Au-Yeung - Jan 25 '21 - - Dev Community

Check out my books on Amazon at https://www.amazon.com/John-Au-Yeung/e/B08FT5NT62

Subscribe to my email list now at http://jauyeung.net/subscribe/

Vue.js is an easy to use web app framework that we can use to develop interactive front end apps.

Vue Router is a URL router that maps URLs to components.

In this article, we’ll look at how to pass props to route components with the Vue Router.

Passing Props

Using the $route in our component creates a tight coupling between the $route object and the component. Therefore, it limits the flexibility of the component as it can be only used on certain URLs.

We can decouple the component from the router by using the props option.

For example, instead of writing:

const User = { template: "<div>User {{ $route.params.id }}</div>" };  
const routes = [  
  {  
    path: "/user/:id",  
    component: User  
  }  
];

const router = new VueRouter({  
  routes  
});

new Vue({  
  el: "#app",  
  router  
});
Enter fullscreen mode Exit fullscreen mode

We instead write:

src/index.js :

const User = { template: "<div>User {{ id }}</div>" };  
const routes = \[  
  {  
    path: "/user/:id",  
    component: User,  
    props: true  
  }  
\];const router = new VueRouter({  
  routes  
});new Vue({  
  el: "#app",  
  router  
});
Enter fullscreen mode Exit fullscreen mode

src/index.html :

<!DOCTYPE html>  
<html>  
  <head>  
    <title>App</title>  
    <meta charset="UTF-8" />  
    <script src="https://unpkg.com/vue/dist/vue.js"></script>  
    <script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>  
  </head>  
  <body>  
    <div id="app">  
      <router-view></router-view>  
    </div>  
    <script src="src/index.js"></script>  
  </body>  
</html>
Enter fullscreen mode Exit fullscreen mode

If we have multiple router-views , then we have to define the props on each one as follows:

src/index.js :

const Foo = { props: ["id"], template: "<div>foo {{id}}</div>" };  
const Bar = { props: ["id"], template: "<div>bar {{id}}</div>" };  
const routes = [  
  {  
    path: "/:id",  
    components: { default: Foo, bar: Bar },  
    props: { default: true, bar: true }  
  }  
];

const router = new VueRouter({  
  routes  
});

new Vue({  
  el: "#app",  
  router  
});
Enter fullscreen mode Exit fullscreen mode

index.html :

<!DOCTYPE html>  
<html>  
  <head>  
    <title>App</title>  
    <meta charset="UTF-8" />  
    <script src="https://unpkg.com/vue/dist/vue.js"></script>  
    <script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>  
  </head>  
  <body>  
    <div id="app">  
      <router-view></router-view>  
      <router-view name="bar"></router-view>  
    </div>  
    <script src="src/index.js"></script>  
  </body>  
</html>
Enter fullscreen mode Exit fullscreen mode

Then when we go to /#/1 , we see:

foo 1bar 1
Enter fullscreen mode Exit fullscreen mode

displayed.

As we can see when props is set to true , then $route.params will be set as the component props.

This makes testing easier since we don’t have to worry about the $route object when testing.

Object Mode

We can set the props property to an object. This is handy for static props.

For example, we can do that as follows:

src/index.js :

const Foo = { props: ["id"], template: "<div>foo {{id}}</div>" };  
const routes = [  
  {  
    path: "/foo",  
    component: Foo,  
    props: { id: 1 }  
  }  
];

const router = new VueRouter({  
  routes  
});

new Vue({  
  el: "#app",  
  router  
});
Enter fullscreen mode Exit fullscreen mode

index.html :

<!DOCTYPE html>  
<html>  
  <head>  
    <title>App</title>  
    <meta charset="UTF-8" />  
    <script src="https://unpkg.com/vue/dist/vue.js"></script>  
    <script src=[https://unpkg.com/vue-router/dist/vue-router.js"></script>  
  </head>  
  <body>  
    <div id="app">  
      <router-view></router-view>  
    </div>  
    <script src="src/index.js"></script>  
  </body>  
</html>
Enter fullscreen mode Exit fullscreen mode

Then we see foo 1 displayed when we go to /#/foo .

Function Mode

We can pass in a function that returns props. This lets us do whatever we want to with the route parameters before sending it to the component as props.

src/index.js :

const Foo = { props: ["idString"], template: "<div>foo {{idString}}</div>" };  
const routes = [  
  {  
    path: "/foo/:id",  
    component: Foo,  
    props: route => ({ idString: `id ${route.params.id}` })  
  }  
];  
const router = new VueRouter({  
  routes  
});  
new Vue({  
  el: "#app",  
  router  
});
Enter fullscreen mode Exit fullscreen mode

index.html :

<!DOCTYPE html>  
<html>  
  <head>  
    <title>App</title>  
    <meta charset="UTF-8" />  
    <script src="https://unpkg.com/vue/dist/vue.js"></script>  
    <script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>  
  </head>  
  <body>  
    <div id="app">  
      <router-view></router-view>  
      <router-view name="bar"></router-view>  
    </div>  
    <script src="src/index.js"></script>  
  </body>  
</html>
Enter fullscreen mode Exit fullscreen mode

In the code above, we set a function as the property of props where we returned an object that sets the idString property to `id ${route.params.id}` .

Then our Foo component accepts the idString prop instead of getting id straight from the route parameter. Therefore, we see the ‘id’ before the id route parameter that we passed in since that’s what we returned.

So when we go to /#/foo/1 , we get foo id 1 displayed.

Conclusion

We can pass in route parameter to components as props instead of retrieving route parameters from the $route object.

This makes testing easier and also makes the component more flexible since it decouples the component from the Vue Router.

We can set the props property to true to pass in a route parameter as a prop. For static props, we can set an object as the value of props .

We can also set it as a function to manipulate the route parameter before returning an object where the value will be sent as props to the component and retrieved by the key of the returned object in the component.

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .