简体   繁体   English

Vue.js“超出最大调用堆栈大小”错误。 将数据从父母传递给孩子失败

[英]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)我有一个带有数据的面板组件(它是父组件)和 panelBody 组件(子组件)

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:我的 panelBody 是:

<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".无法找出错误“vue.esm.js?65d7:3877 Uncaught RangeError: Maximum call stack size exceeded”。 WHen I remove the data everything works like it should.当我删除数据时,一切正常。

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' .您使用name: 'panel-body'定义了Panel组件。 Change that to name: 'panel' , and you will remove your circular reference.将其更改为name: 'panel' ,您将删除循环引用。

The other issues mentioned in comments and the other answer generally apply as well.评论中提到的其他问题和其他答案通常也适用。 Here are working versions of your components.这是您的组件的工作版本。

Panel.vue面板.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面板体.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.由于 PanelBody 中的这一行, this.selected this.selected = this.shelf Vue 将发出警告,表明您正在直接改变道具。 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.我已经更新了上面的代码来做到这一点。

The name of the Vue you are in should not equal the name of the component you are importing.您所在的 Vue 的名称不应等于您正在导入的组件的名称。

In my case就我而言

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

<script>
    import SingleStandard from '../components/SingleStandard';

    export default {
      name: 'SingleStandard',
      components: { SingleStandard },
    };
</script>

The above code was causing the same issue, but when i changed the name of the exported component it worked.上面的代码导致了同样的问题,但是当我更改导出组件的名称时它起作用了。

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

<script>
    import SingleStandard from '../components/SingleStandard';

    export default {
      name: 'SingleStandardView', <-------------
      components: { SingleStandard },
    };
</script>

Please check your naming conventions for all future people :)请为所有未来的人检查您的命名约定:)

Try to disable vue dev-tools extension...尝试禁用 vue dev-tools 扩展...

I had this erratic error for months in my app, and it drove me crazy !几个月来我的应用程序中出现了这个不稳定的错误,这让我发疯了! I just realized that it never happen again if I disable vue dev-tool chrome extension.我刚刚意识到,如果我禁用 vue dev-tool chrome 扩展,它就再也不会发生了。

Not perfect but it could help.不完美,但它可以提供帮助。

the sync has changed in vue2. vue2 中的同步发生了变化。

https://v2.vuejs.org/v2/guide/components.html#sync-Modifier https://v2.vuejs.org/v2/guide/components.html#sync-Modifier

you should use it this way你应该这样使用它

<panel-body :shelf="shelf" :selected="selected" @update:selected="val => selected = val"></panel-body>

and on child和孩子

this.$emit('update:selected', shelf)

OR you could do just this或者你可以这样做

<panel-body :shelf="shelf" :selected="shelf == selected" @select="selected = shelf"></panel-body>

and on child和孩子

this.$emit("select")

In my case, it happened when store overflow就我而言,它发生在商店溢出时

const auth =  function({ next, store }){
    if(!store.getters.auth.loggedIn){
      return next('/login')
    }
    return next()
}
  
export {auth};

I updated like this and fixed up this issue.我像这样更新并修复了这个问题。 hope this would help you.希望这会对你有所帮助。

const auth =  function({ next, store }){
    if(store.getters.auth.loggedIn){
      return next('/login')
    }
    return next()
}
  
export {auth};

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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