Search code examples
vuexnuxt.js

NUXT Passing data to props in dynamic endpoint


this is a question on NUXT and Vuex. I want to get the appropriate item in my dynamic (_id) page.

I have an array in my state:

export const state = () => ({
  events: [
    { id: 1, name: 'Wordpress', price: 100 },
    { id: 2, name: 'VueJS', price: 200 },
    { id: 3, name: 'React', price: 300 },
    { id: 4, name: 'Angular', price: 500 },
    { id: 5, name: 'NodeJS', price: 5000 }
  ]
})

I have a EventList component that loops through the above array as follows:

<template>
  <div class="event-list">
    <nuxt-link v-for="event in events" :key="event.id" :to="'/events/' + event.id">
      <EventPreview
        :id="event.id"
        :name="event.name"
        :price="event.price"
      />
    </nuxt-link>
  </div>
</template>

However, when I click on the nuxt-link it does go to the _id page, however... it does not pass the clicked object.

How do I get that object to the _id page? By object I mean, for example, { id: 1, name: 'Wordpress', price: 100 }.

Should you need additional information (beyond what is below) please ask.


Additional information as follows:

Code for the EventPreview component:

<template>
  <div class="single-event">
    <h1>Name: {{ name }}</h1>
    <h1>Price: {{ price }}</h1>
  </div>
</template>

<script>
export default {
  name: 'EventPreview',
  props: {
    id: {
      type: Number,
      required: true
    },
    name: {
      type: String,
      required: true
    },
    price: {
      type: Number,
      required: true
    }
  }
}
</script>

_id page code:

<template>
  <div class="event-id">
    <EventPreview />
  </div>
</template>

<script>
import EventPreview from '@/components/Event/EventPreview'
export default {
  components: {
    EventPreview
  }
}
</script>

Solution

  • You can create a vuex store to keep the events data, and then create a getter to get the relevant event by ID.

    const store = new Vuex.Store({
      state: {
        events: [{
            id: 1,
            name: 'Wordpress',
            price: 100
          },
          {
            id: 2,
            name: 'VueJS',
            price: 200
          },
          {
            id: 3,
            name: 'React',
            price: 300
          }
        ]
      },
      getters: {
        event: state => id => {
          return state.events.find(event => event.id === id)
        }
      }
    })
    
    new Vue({
      store,
      el: "#app",
      data() {
        return {
          routeId: 2
        }
      },
      computed: {
        myEvent() {
          return this.$store.getters.event(this.routeId)
        }
      }
    })
    <script src="https://cdn.jsdelivr.net/npm/vue"></script>
    <script src="https://unpkg.com/vuex"></script>
    
    <div id="app">
      <h2>event:</h2>
      <p>Name: {{ myEvent.name }}</p>
      <p>Price: {{ myEvent.price }}</p>
    </div>

    You can then get the id from the current page route this.$route.params.id and pass it into the getter

    myEvent() {
        return this.$store.getters.event(this.$route.params.id)
    }