3

I'm working on a SPA website and I'm trying to pass some data between two components using a router-link.

Basically I have an "Album" component (here called Polaroid) which contains in its 'data' all the album songs' lyrics. Then I have a Song component (here called Canzone) where I want to pass dynamically the lyrics for each song, based on the clicked song obviously.

This is my code:

routes.js

import Polaroid from './components/albums/Polaroid'
import Canzone from './components/songs/Canzone.vue'

export default {

    mode: 'history',
    linkActiveClass: 'font-bold',

    routes: [

        {
            path: '/polaroid',
            component: Polaroid
        },

        {
            path: '/polaroid/:canzone',
            name: 'polaroid',
            component: Canzone
        },
    ]
};

Polaroid.vue (this is the Album component where I show the songs' list)

<template>
<div>
  <ul class="leading-7">
    <li v-for="canzone in this.canzoni" :key="canzone.nome" >
      <router-link :to="{ name: 'polaroid', params: { name: canzone.path } }"> {{ canzone.nome }} </router-link>
    </li>
  </ul>
</div>
</template>

<script>
    export default {
         data(){
             return {
                canzoni: [            // all the songs
                    {
                    nome: 'Song1',
                    path: 'song-1',
                    numero: 1,
                    testo: 'lyrics1'
                    },
                    {
                    nome: 'Song2',
                    path: 'song2',
                    numero: 2,
                    testo: 'lyrics2'
                    },
                    {
                    nome: 'Song3',
                    path: 'song3',
                    numero: 3,
                    testo: 'lyrics3'
                    },
                ],


            };
        },
    }
</script>

Canzone.vue (this is the Song component where I want to show the song lyric dinamically)

<template>
<div>
     
    LYRICS HERE

    {{ $route.params.canzone }}      // not working

</div>
</template>

<script>
    export default {
        
    }
</script>

How can I pass the data through the router-link? Thanks!

Thanks!

2
  • first, you don't need to use this. in v-for Commented Jul 27, 2020 at 9:10
  • Yeah thanks but that is not the point of my question Commented Jul 27, 2020 at 9:16

3 Answers 3

1

You should use the canzone instead of name in the params of the Polaroid.vue

  <router-link :to="{ name: 'polaroid', params: { canzone: canzone.path } }"> {{ canzone.nome }} </router-link>

Sign up to request clarification or add additional context in comments.

4 Comments

It works but the URL is not correct, it's always like this: 127.0.0.1:8000/polaroid/%5Bobject%20Object%5D instead of 127.0.0.1:8000/polaroid/name-of-the-song
it's because you are sending an object in the router. path: '/polaroid/:canzone', @nicoblue
Is there a way to avoid this? a way to pass the object not in the URL?
Did you use the canzone.path? It's the string, not the object :to="{ name: 'polaroid', params: { canzone: canzone.path } }"
1

you don't need to use this in v-for let's fix that part first.

UPDATED

router.js

We need to fix router.js as well to get a proper path.

    {
        path: '/polaroid/:id', // I gave a ID
        name: 'polaroid',
        component: Canzone
    },

So after giving the ID, we need to pass the id as well in params. Using index for the id

main template

<template>
<div>
  <ul class="leading-7">
    <li v-for="(canzone,index) in canzoni" :key="conzone.nome" >
      <router-link :to="{ name: 'polaroid', params: {id: index, canzone: canzone} }"> {{ canzone.nome }} </router-link>
    </li>
  </ul>
</div>
</template>

As you see I am sending the params as a object. I guess it has much more benefits with this way. But of course you can send just the path as a string as well...

the other template

<template>
<div>
     
    LYRICS HERE

    {{ canzone }}      // should work

</div>
</template>

<script>
    export default {
        props:{
          id:{
            type: String|Number,
            required: true,
          },
          canzone:{
            type: Object,
            required: true,
          }
        }
    }
</script>

PS: If your params: {canzone: canzone.path} then this means you are sending a string. So you should change the primitive prop type to string too...

5 Comments

it gives me this error: [Vue warn]: Missing required prop: "canzone" found in ---> <Canzone> at resources/js/components/songs/Canzone.vue <Root>
what about changing the required to false?
if I change it to false, canzone is undefined
No man, it continues to give me errors, I would just do it in a static way and patience.
hmm, awkward. It should be okay with the code i provided. Double check my code and yours. Maybe you are missing something. Because with my last update, I changed more then one place.
0

set props: true in your routes like this

routes: [
    {
        path: '/polaroid',
        component: Polaroid,
        props:true
    }
]

to get that data you shouldn't write {{$route.params.canzone}} but {{$route.params.name}} as 'name' is what you are passing through the route

also you don't need to create another route passing canzone as a query

but if you want to do it that way, you need to get that data like this.$route.query.canzone

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.