简体   繁体   中英

Vue.js how to pass props/params from parent to child component with vue-router

I'm working on a simple app that shows a table of Exercises in a Dashboard. From there, a user can click on an ExerciseItem and open up an Exercise component. I've got the Dashboard component working, but cannot data to pass to the child Exercise component.

Here is my Dashboard Code:

<template>
 <div class="">
   <NavDash />
    <div class="container pb-5 pt-5">
        <div class="row">
            <div class="col d-flex align-items-center">
            <h3>Dashboard</h3>
            <p class="ml-auto">{{ $store.state.user.email }}</p>
        </div>
    </div>

  <hr>
  <AddExercise />
  <hr>
  <table class="table">
  <tbody>
    <ExerciseItem
  v-for="(exercise_item, index) in this.$store.state.exercises"
  :exercise="exercise_item"
  key="index"
/>
   </tbody>
 </table>
  </div>
</div>
</template>

<script>
import { firebaseApp, exercisesRef, usersRef } from '../firebaseApp'
import AddExercise from './AddExercise.vue'
import ExerciseItem from './ExerciseItem.vue'
import NavDash from './NavDash.vue'

export default {
  methods: {
    signOut() {
    this.$store.dispatch('signOut')
   firebaseApp.auth().signOut()
 }
},
props: ['exercise'],
components: {
   AddExercise,
    ExerciseItem,
  NavDash
},
mounted() {
exercisesRef.on('value', snap => {
    let exercises = []
    snap.forEach(exercise => {
        exercises.push(exercise.val())
    })
    console.log('exercises', exercises)
    this.$store.dispatch('setExercises', exercises)
  })
 }
}
 </script>

And ExerciseItem.vue:

<template>
 <tr>

<td class="text-left">
  <h4>{{exercise.title}}</h4>
  <p>{{exercise.description}}</p>
</td>
<td>
  {{exercise.categories}}
</td>
<td>
  <button @click="removeExercise(exercise)">X</button>
</td>
<td>
  <router-link to="/exercises/:id">LINK</router-link>
</td>
</tr>
</template>

<script>
 export default {
  props: ['exercise'],
}
</script>

Exercise.vue:

<template>
<div>
<NavDash />
Exercise {{ id }}
<h4>{{title}}</h4>
   <p>{{description}}</p>
</div> 
</template>

<script>
import { firebaseApp, exercisesRef, usersRef } from '../firebaseApp'
import NavDash from './NavDash.vue'

export default {
 props: ['id'],
 components: {
  NavDash
 }
}
</script>

And the router path:

{ path: '/exercises/:id', 
    name: 'Exercise',
    component: Exercise,
    props: {
        default: true
    }
}

Here is my Index.js inside of my Store directory:

import Vue from 'vue'
import Vuex from 'vuex'
import { mutations } from './mutations'
import * as actions from './actions'
import * as getters from './getters'

Vue.use(Vuex)

const state = {
user: {},
exercises: {},
articles: {}
}

export default new Vuex.Store({
state,
 mutations,
actions,
getters
})

I tried following the documentation here: https://router.vuejs.org/en/essentials/passing-props.html

but I can't seem to get the router-link to work properly.

Any help would be greatly appreciated!

Thank you!

Based on your route, the Exercise component receives an id prop, not an exercise prop. I do not think you can pass objects in vue-router through routes, and even if you could, I think it would be a bad practice because it would have to serialize the object in the route.

The Exercise component receives an id prop, and should use that to lookup the exercise. Either through an ajax request, vuex, or some other source of state. Since you are using vuex, you could create a getter that returns an object where the keys are the exercise ids, and the values are the exercises. Then you could lookup the exercise in the Exercise component using the id.

Vuex getter

exercisesById(state) {
    var obj = {};
    state.exercises.forEach(x => {
        obj[x.id] = x;
    });
    return obj;
}

Exercise component

<script>
import { firebaseApp, exercisesRef, usersRef } from '../firebaseApp'
import NavDash from './NavDash.vue'

export default {
 props: ['id'],
 components: {
  NavDash
 },
 computed: {
     exercise() {
         return this.$store.getters.exercisesById(this.id);
     }
 },
}
</script>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM