Search code examples
javascriptvue.jsvue-routervue-cli-3

How to extract Route Params via Props


I am learning VueJs and trying to understand how to extract route params via props.

I was looking at the following documentation, where it seems to have three options to have this done, but I cannot understand it quite well so far - https://github.com/vuejs/vue-router/tree/dev/examples/route-props.

I have tried adding props: true to my router object array (routes.js file posted below) with no success as well.

As this is vue-cli study project I will post the separate pertinent blocks of code in order to try to illustrate this properly.

Main - App.vue below:

 <template>
    <div class="container">
        <div class="row">
            <div class="col-xs-12 col-sm-8 col-sm-offset-2 col-md-6 col-md-offset-3">
                <h1>Routing</h1>
                <hr>
                <app-header></app-header>
                <router-view></router-view>
            </div>
        </div>
    </div>
</template>

<script>
    import Header from './components/Header.vue'
    export default {
        components: {
            appHeader: Header
        }
    }
</script>

<style>
</style>

Component - Header.vue below:

<template>
    <ul class="nav nav-pills">
        <router-link to="/" tag="li" active-class="active" exact><a>Home</a></router-link>
        <router-link to="/user/10" tag="li" active-class="active"><a>User 1</a></router-link>
        <router-link to="/user/5" tag="li" active-class="active"><a>User 2</a></router-link>

    </ul>
</template>

Component - User.vue below:

<template>
    <div>
        <h1>The User Page</h1>
        <hr>
        <br>
        <p>Route ID: {{id}}</p>
        <button class="btn btn-primary" @click="goHome">Go to Home</button>
    </div>
</template>
<script>
    export default {
        data(){
            return {
                id: this.$route.params.id
            }
        },
        watch: {
          '$route'(to, from) {
              this.id = to.params.id;
          }
        },
        methods: {
            goHome(){
                this.$router.push('/')
            }
        }

    }

</script>

main.js below:

import Vue from 'vue'
import VueRouter from 'vue-router'
import App from './App.vue'
import {routes} from "./routes";

Vue.use(VueRouter)

export const router = new VueRouter({
  routes,
  mode: 'history'
})

new Vue({
  el: '#app',
  router,
  render: h => h(App)
})

routes.js below (located at SRC folder):

import User from './components/user/User.vue'
import Home from './components/Home.vue'

export const routes = [
    {path: '', component: Home},
    {path: '/user/:id', component: User}
]

Do I need to also set Props at User.vue component as well in order to make it work and quit using watch?

In other words, I would like to see my user route being listened at <p>Route ID: {{id}}</p> from this hardcoded 10 to 5 using this new method which I cannot understand, mentioned at the top of this post.

Could anyone please walk me through this issue in this specific situation?

Thanks in advance to all.


Solution

  • According to the docs on passing Props to Route components, you can decouple it, with the props option on the router config.

    import User from './components/user/User.vue'
    import Home from './components/Home.vue'
    
    export const routes = [
        {path: '', component: Home},
        {path: '/user/:id', component: User, props: true}
    ]
    
    <template>
      <div>
        <h1>The User Page</h1>
        <hr>
        <br>
        <p>Route ID: {{id}}</p>
        <button class="btn btn-primary" @click="goHome">Go to Home</button>
      </div>
    </template>
    
    <script>
      export default {
        props: ['id'],
    
        methods: {
          goHome() {
            this.$router.push('/')
          }
        }
      }
    </script>