How can I send data from parent to child component

2019-01-29 07:13发布

问题:

My parent component like this :

<template>
    ...
        <search-result/>
    ...
</template>
<script>
    import {mapActions} from 'vuex'
    ...
    export default {
        ...
        props: ['category'],
        mounted() {
            this.updateCategory(this.category)
        },
        methods: {
            ...mapActions(['updateCategory']),
        }
    }
</script>

My child component like this :

<template>
    ...
</template>
<script>
    import {mapGetters} from 'vuex'
    ...
    export default {
        ...
        mounted() {
            console.log(this.getCategory)
        },
        computed: {
            ...mapGetters(['getCategory'])
        },
    }
</script>

My modules vuex to send data between components like this :

import { set } from 'vue'
...
// initial state
const state = {
    category: null
}
// getters
const getters = {
    getCategory: state =>  state.category
}
// actions
const actions = {
    updateCategory ({commit}, payload) {
        commit(types.UPDATE_CATEGORY, payload)
    }
}
// mutations
const mutations = {
    [types.UPDATE_CATEGORY] (state, payload) { 
        state.category = payload
    }
}
export default {
    state,
    getters,
    actions,
    mutations
}

I try like that, but it does not works

If the code executed, the result of console.log(this.getCategory) in the child component is null

For example category prop in the parent component = 7. Should the result of console.log(this.getCategory) in the child component = 7

Why it does not work? Why the result is null?

Note :

I can just send the category data via prop. But here I do not want to use prop. I want to send data via vuex store. So I want to set and get data only via vuex store

回答1:

Child's mounted hook is executed before parent's mounted hook. (why? See https://forum.vuejs.org/t/order-of-lifecycle-hooks-for-parent-and-child/6681/2?u=jacobgoh101)

console.log(this.getCategory) happens before this.updateCategory(this.category).

Therefore, you get null in the console.

If you put console.log(this.getCategory) in updated hook, you would be getting the right value in the console later on.



回答2:

Jacob goh has pointed out the problem.

To solve this issue you can make use of vm.$nextTick() in the child component's mounted hook to ensure that the entire view has been rendered and the parent's mounted hook is called.

<template>
    ...
</template>
<script>
    import {mapGetters} from 'vuex'
    ...
    export default {
        ...
        mounted() {
            this.$nextTick(() => {
                console.log(this.getCategory);
            })
        },
        computed: {
            ...mapGetters(['getCategory'])
        },
    }
</script>

Here is the working fiddle

You can learn more about why use vm.nextTick() here: Vue updates the DOM asynchronously