首页 > 解决方案 > 传递给子组件的道具在创建的方法中未定义

问题描述

我正在使用 Vue.js 2。

我在将值作为道具传递给子组件时遇到问题。我正在尝试传递cardcard-component.

card-component我可以访问该Card goes here {{card}}部分中的道具。

但是,当我尝试在createdmounted方法中访问它时,它是undefined.

家长:

<template>
    <div class="container">
        <div class="row">
            <div class="col-md-8 col-md-offset-2">

                <card-component :card="place.card"></card-component>

            </div>
        </div>
    </div>
</template>

<script>
    import CostComponent from './CostComponent';
    import CardComponent from './CardComponent';

    export default {
        components: {
            CostComponent, CardComponent
        },

        props: ['id'],

        data() {
            return {
                place: []
            }
        },

        created() {
            axios.get('/api/places/' + this.id)
            .then(response => this.place = response.data);
        }
    }
</script>

孩子:

<template>
    <div class="container">
        <div class="row">
            <div class="col-md-8 col-md-offset-2">
                <ul class="list-unstyled">

                    Card goes here {{card}}

                </ul>
            </div>
        </div>
    </div>
</template>

<script>
    import CardItemComponent from './CardItemComponent';

    export default {
        components: {
            CardItemComponent
        },

        props: ['card'],

        created() {
            console.log(this.card); // undefined
        },

        mounted() {
            console.log(this.card); // undefined
        },
    }
</script>

我做了很多谷歌搜索,但我找到的解决方案都没有解决我的问题。

标签: vue.jsvuejs2

解决方案


这纯粹是时间问题。这就是发生的事情......

  1. 您的父组件已创建。此时它分配了一个空数组place(这也是一个问题,但我稍后会谈到)。异步请求已启动
  2. 您的父组件通过其模板创建一个CardComponent实例

    <card-component :card="place.card"></card-component>
    

    在这个阶段,place仍然是一个空数组,因此place.card是未定义的

  3. CardComponent created钩子运行,记录undefined
  4. CardComponent安装并且它的mounted钩子运行(与 相同的日志记录结果created
  5. 您的父组件已安装
  6. 在此之后的某个时间点,异步请求解析并place从一个空数组更改为一个对象,可能带有一个card属性。
  7. card属性被传递到你的CardComponent,它反应性地更新{{ card }}其模板中显示的值。

如果你想捕捉card道具数据何时发生变化,你可以使用beforeUpdate钩子

beforeUpdate () {
  console.log(this.card)
}

演示

Vue.component('CardComponent', {
  template: '<pre>card = {{ card }}</pre>',
  props: ['card'],
  created () {
    console.log('created:', this.card)
  },
  mounted () {
    console.log('mounted:', this.card)
  },
  beforeUpdate () {
    console.log('beforeUpdate:', this.card)
  }
})
new Vue({
  el: '#app',
  data: {
    place: {}
  },
  created () {
    setTimeout(() => {
      this.place = { card: 'Ace of Spades' }
    }, 2000)
  }
})
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<div id="app">
  <card-component :card="place.card" />
</div>

https://vuejs.org/v2/guide/instance.html#Lifecycle-Diagram


如果place它是一个对象,则不应将其初始化为数组。此外,如果您CardComponent依赖于存在的数据,您可能希望有条件地呈现它。

例如

data () {
  return { place: null }
}

<card-component v-if="place" :card="place.card"></card-component>

thenCardComponent只会在有数据后创建和挂载。 place


推荐阅读