JOKER
JOKER

Reputation: 75

How to redirect to the selected user's page VueJS?

I have a clone of Twitter, I added a real-time search there, but I can't figure out how to send the required ID to another component. So that i can load the page of selected user.

Flowchart to make it clearer:

Flowchart

There is example of my code:

<template>
<input type="search" placeholder="Search Twitter" v-model="search" />
<div v-if="search.length > 0">
  <ul v-for="user in filteredUsers" :key="user.id">
    <li @click="userPageLink(user.id)">
      {{ user.firstName + " " + user.lastName }}
    </li>
  </ul>
</div>
</template>

<script>
computed: {
    users() {
      return this.$store.getters["user/user"];
    },
    filteredUsers() {
      return this.users.filter(
        (user) =>
          user.firstName.toLowerCase().indexOf(this.search) !== -1 ||
          user.lastName.toLowerCase().indexOf(this.search) !== -1
      );
    },
  },
methods: {
    userPageLink(id) {
      const url = `${this.$route.path}/${id}`;
      this.$router.push(url);
    },
  },
</script>

Something tells me that I'm doing something completely wrong, do I need to get the id from the url?

Upvotes: 1

Views: 2115

Answers (2)

Vanishdark
Vanishdark

Reputation: 170

All other answers are right. I will write some code for future users that come to this question.

For your particular question, the answer from @kissu is enough. But you can complete your code in different ways.

So let's get into the code.

Let's assume we have this router code

{
    path: 'user/:id',
    name: 'user',
    params: {id: 0} //no need to set this here
    component: Component,
}

If you do a $router.push parsing the params, the router should be able to change your :id in the path for your desire path for example localhost:8080/user/12345. The following code does the job.

this.$router.push({name: 'user', params: {id: '12345'}})

But you can tell to Vue Router that your params are props too. To achieve that you can change your router code to this

{
    path: 'user/:id',
    name: 'user',
    props: true // see that we replace the params with props
    component: Component,
}

the key props means that you can work with params as they are props in your component. You can learn more about this here

Now in your component, you need to set those props

export default {
  name: 'User',
  components: {},
  props: {
    id: { // This is the param that we are putting in our url
      type: Number,
      default() {
        return 0
      }
    },
  },
  data(){
    return{
           user: {}
          }
  },
  created(){
    this.fetchUser();
  }
  methods: {
    fetchUser(){
      if (this.id){
        console.log(this.id)
      }
    }
  }
}

When you create the component you will fetch the user if the id from the params exists he prints it.

This is a basic example of router implementation, but you can go further and hide the user id in the URL if you don't want to show it and parse it to the component, the downside of this approach is every time you reload the page that information is lost. But if you want to do that you just need to change your path and your $router.push()

Router File

{
    path: 'user/:name', // we change the id to name (can be anything)
    name: 'user',
    props: true 
    component: Component,
}

Route Push

this.$router.push({name: 'user', params: {id: '12345', name: 'Joe'}})

User Component

props: { // Both Params are present in $route but only name is in path
    id: {
      type: Number,
      default() {
        return 0
      }
    },
    name: { // This is the param that we are putting in our url
     type: String,
     default(){
        return ''
        }
    }
  },

This way your user only see in his URL <nameWebSite>/user/joe.

If you for any reason want to navigate from '/user/:id' to '/user/:id' and don't want to keep the navigation history I suggest you using $router.replace() works the same way as $router.push() but replace the current entry

I hope this answer helps you with more details and other people that come later with the same type of question.

Tip: If you want to avoid at all parse params throw your router you can check the Vuex

Upvotes: 4

kissu
kissu

Reputation: 46814

As explained in the official docs of vue-router, the clean way of doing is:

router.push({ name: 'user', params: { userId } }) // -> /user/123

But your interpolation is good too, maybe not the most explicit way of writing it.
I don't see anything wrong with the code so far at least.

Upvotes: 2

Related Questions