简体   繁体   中英

Vue: change data of child component from parent component on button click Cannot set property of undefined

I have two components: child Dog and parent App . Inside the App I'm trying to change Dog 's properties hasName and name on button click. However I get an error: hasName is undefined.

Child component:

Dog.vue

<template>
  <div>
    <div>A Dog</div>
    <div v-if="hasName">Name: {{ name }}</div>
  </div>
</template>

<script>
export default {
  data: function () {
    return {
      hasName: false,
      name: "",
    };
  },
};
</script>

Parent component:

App.vue

<template>
<div id = "app">
  <img alt="Vue logo" src="./assets/logo.png" />
  <Dog />
  <button @click="handleClick">Click</button>
</div>
</template>

<script>
import Dog from "./components/Dog.vue";
export default {
  name: "App",
  components: {
    Dog,
  },
  methods: {
    handleClick: function () {
      this.Dog.hasName = true;
      this.Dog.name = "Jerry";
    },
  },
};
</script>

<style>
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
</style>

I get the error:

Cannot set property 'hasName' of undefined

Vue fiddle: https://codesandbox.io/s/upbeat-resonance-b65pd?file=/src/App.vue

You can't access the data of a child component like this.

In your App.vue component, when you access Dog , it's simply a reference to the component itself, not a reference to any mounted version of the component.

Imagine how if you had multiple dog components. How would you be able to tell the component data apart?

You need to use props to pass data from a parent to a child.

For example:

App.vue

<template>
<div id = "app">
  <img alt="Vue logo" src="./assets/logo.png" />
  <Dog :name="dog.name" :has-name="dog.hasName" />
  <button @click="handleClick">Click</button>
</div>
</template>

import Dog from "./components/Dog.vue";
export default {
  name: "App",
  data() {
      return {
          dog: {
              hasName: false,
              name: '',
          },
      }
  },
  components: {
    Dog,
  },
  methods: {
    handleClick: function () {
      this.dog.hasName = true;
      this.dog.name = "Jerry";
    },
  },
};

Dog.vue

<template>
  <div>
    <div>A Dog</div>
    <div v-if="hasName">Name: {{ name }}</div>
  </div>
</template>

<script>
export default {
  props: {
      hasName: {
          required: true,
          type: Boolean,
      },
      name: {
          required: true,
          type: String,
      },
  },
};
</script>

When you modify the parent object dog , the data is automatically passed to the child via props and updated there too.

Please read the VueJS docs here to learn more about props

You need to emit your event listening actions. hasName is not a data object hence it wont be defined

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