DoloreMentale
DoloreMentale

Reputation: 11

VueJS: dynamic component loses it`s props after reloading

I have a django rest_framework as a server and vuejs for a client side. There is an index page like '/' where i`m using v-for to iterate an array of objects to show some item's cards. Each card has a button to the '/info'(which is dynamically changed with /:slug in a router) like so:

...
<RouterLink :to="{name: 'contentItemInfo', params: {item: item, slug: item.slug} }">
   <button class="card-button btn fade-in">
      ...
   </button>
</RouterLink>
...

Then, when we press the button, we are going to '/:slug' and passing the item param to props, using it like so:

...
<video class="video" type="video/mp4" autoplay loop :src="item.trailer"/>
<h3 class="video-info-h3 px-5 py-1 rounded">{{ item.title }}</h3>
<h5 class="video-info-h5 px-5 py-1 rounded">{{ item.subtitle }}</h5>
<p class="video-info-p px-5 py-1 text-wrap rounded">{{ item.description }}</p>
...

export default {
  name: "ContentItemInfo",
  components: {Footer, Navbar},
  props: [
    'item'
  ],
}

Works for now, but when i reload the page, all the content disappeare and got undefined of all item`s values

How should i make it work after reloading?

Upvotes: 1

Views: 920

Answers (1)

Phil
Phil

Reputation: 165065

Passing complex objects by route param only works in-memory. Once you reload the page, the only data you have is strings from the URL. You'll have to load the item data from your backend for fresh page loads.

Try something like this, making the item prop optional and loading the data if it's not set

export default {
  name: "ContentItemInfo",
  components: {Footer, Navbar},
  props: {
    item: {
      type: Object,
      default: null
    },
    slug: String // set from the route param
  }
  data: vm => ({
    video: vm.item // initialise a local copy so you can update it if required
  }),
  async created () {
    if (this.video === null) {
      // just guessing with this bit
      const { data } = await axios.get(`/api/video-for-slug/${encodeURIComponent(this.slug)}`)
      this.video = data
    }
  }
}

and your template

<div v-if="video">
  <video
    class="video"
    type="video/mp4"
    autoplay
    loop
    :src="video.trailer"
  />
  <h3 class="video-info-h3 px-5 py-1 rounded">{{ video.title }}</h3>
  <h5 class="video-info-h5 px-5 py-1 rounded">{{ video.subtitle }}</h5>
  <p class="video-info-p px-5 py-1 text-wrap rounded">{{ video.description }}</p>
</div>
<p v-else>Loading...</p>

In the above, I assumed that your routes are passing params as props. If not, see https://router.vuejs.org/guide/essentials/passing-props.html

Upvotes: 1

Related Questions