Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Vue.js "Maximum call stack size exceeded" error. Passing data from parent to child failing

I cannot pass data from parent to child. I am using props, have tried returning data as well - no luck. I have a panel component (which is parent) with data and panelBody component (child)

Panel is as follows:

<template>   <div id="panel">     <div class="panel">       <ul>         <li v-for="shelf in shelfs">           <panel-body :shelf="shelf" :selected.sync="selected"></panel-body>         </li>       </ul>     </div>   </div> </template>  <script> import PanelBody from '../components/PanelBody' export default {   name: 'panel-body',   components: {     'panel-body': PanelBody   },   data: () => ({     shelfs: [{       name: 'shelf 1',       books: [{         title: 'Lorem ipum'       }, {         title: 'Dolor sit amet'       }]     }, {       name: 'shelf 2',       books: [{         title: 'Ipsum lorem'       }, {         title: 'Amet sit dolor'       }]     }],     selected: {}   }) } </script>  <style scoped> a {   color: #42b983; } </style> 

My panelBody is:

<template>   <div id="panel-body">     <a href="#" v-on:click.prevent.stop="select">{{ shelf.name }}</a>     <ul v-show="isSelected">       <li v-for="book in shelf.books">{{ book.title }}</li>     </ul>   </div> </template>  <script> export default {   name: 'panel-body',   props: ['shelf', 'selected'],   computed: {     isSelected: function () {       return this.selected === this.shelf     }   },   methods: {     select: function () {       this.selected = this.shelf     }   } } </script>  <style scoped> a {   color: #42b983; } </style> 

Please help! Can't figure out the error "vue.esm.js?65d7:3877 Uncaught RangeError: Maximum call stack size exceeded". WHen I remove the data everything works like it should.

like image 888
Teoman Kirac Avatar asked Jun 13 '17 11:06

Teoman Kirac


1 Answers

The reason you have the error

Maximum call stack size exceeded

is because of this

import PanelBody from '../components/PanelBody' export default {   name: 'panel-body',   components: {     'panel-body': PanelBody   }, 

You defined your Panel component with name: 'panel-body'. Change that to name: 'panel', and you will remove your circular reference.

The other issues mentioned in comments and the other answer generally apply as well. Here are working versions of your components.

Panel.vue

<template>   <div id="panel">     <div class="panel">       <ul>         <li v-for="shelf in shelfs">           <panel-body :shelf="shelf" :key="shelf.name" :selected.sync="selected"></panel-body>         </li>       </ul>     </div>     {{selected}}   </div> </template>  <script> import PanelBody from './PanelBody.vue' export default {   name: 'panel',   components: {     'panel-body': PanelBody   },   data(){     return {     shelfs: [{       name: 'shelf 1',       books: [{         title: 'Lorem ipum'       }, {         title: 'Dolor sit amet'       }]     }, {       name: 'shelf 2',       books: [{         title: 'Ipsum lorem'       }, {         title: 'Amet sit dolor'       }]     }],     selected: {}      }   } } </script>  <style scoped> a {   color: #42b983; } </style> 

PanelBody.vue

<template>   <div id="panel-body">     <a href="#" v-on:click.prevent.stop="select">{{ shelf.name }}</a>     <ul v-show="isSelected">       <li v-for="book in shelf.books">{{ book.title }}</li>     </ul>   </div> </template>  <script> export default {   name: 'panel-body',   props: ['shelf', 'selected'],   data(){     return {       internalSelected: null     }   },   computed: {     isSelected: function () {       return this.internalSelected === this.shelf     }   },   methods: {     select: function () {       this.internalSelected = this.shelf       this.$emit("update:selected", this.internalSelected)     }   } } </script>  <style scoped> a {   color: #42b983; } </style> 

I wanted to note one more thing. Because of this line in PanelBody, this.selected = this.shelf Vue will throw a warning that you are mutating a prop directly. Generally you should store a local copy of a property that you are going to mutate. I've updated the code above to do that.

like image 142
Bert Avatar answered Sep 17 '22 21:09

Bert