Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
161 views
in Technique[技术] by (71.8m points)

javascript - VueJs Phonebook app with nested table data Error: "Maximum call stack size exceeded" when trying to .push()

Im trying to build simple Phonebook app, with table and nested data in it. I'm using element ui.

Main thing this app must do is to add a new contact and a new nested contact, when you choosing contact "leader". New contact and new nested contact for preset contacts are added correctly.

But when i'm trying to add nested contact to just created contact in trows an error "Maximum call stack size exceeded".

Here is code:

App.vue

<template>
  <div id="app">
    <ContactsTable :list="list"/>
    <ModalForm :list="list" @submitForm="onFormSubmit"/>
  </div>
</template>

<script>
import ContactsTable from "@/components/ContactsTable";
import ModalForm from "@/components/ModalForm";

export default {
  name: 'App',
  components: {
    ContactsTable,
    ModalForm,
  },
  data: () => ({
    list: [{
      leader: '',
        name: 'Silvia',
        number: +54321236576,
        id: 17,
        children: [{
          leader: 17,
          name: 'Joe',
          number: +87653459809,
          id: 191,
          children: []
        }]
      },
      {
        leader: '',
        name: 'Victor',
        number: +98765434560,
        id: 42,
        children: [{
          leader: 42,
          name: 'Sam',
          number: +14573564378,
          id: 202,
          children: [{
            leader: 202,
            name: 'Mona',
            number: +77774352309,
            id: 2092,
          }]
        }]
      }],
  }),
  methods: {
    onFormSubmit(data) {
      const newObj = {
        ...data,
        id: Math.random()
      };
      if (!(data.leader)) {
        this.list.push(newObj);
      } else {
        for(let i = 0; i < this.list.length; i++) {
          if(this.list[i].id === data.leader) {
            this.list[i].children.push(newObj)
          }
        }
      }
    }
  }
}
</script>

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

ModalForm.vue

<template>
    <el-card class="modal-wrap" shadow="never">
      <el-button type="primary" @click="dialogVisible = true">New contact</el-button>

      <el-dialog class="dialog" :visible.sync="dialogVisible">
        <el-form :model="form" :data="list" :rules="rules" ref="addItemForm" label-position="left" label-width="120px">
          <el-form-item label="Name" prop="name">
            <el-input v-model="form.name" autocomplete="off"/>
          </el-form-item>

          <el-form-item label="Phone number" prop="number">
            <el-input v-model="form.number" autocomplete="off"/>
          </el-form-item>

          <el-form-item label="Team leader" prop="leader">
            <el-select v-model="form.leader">
              <el-option v-for="item in list" :key="item.id" :label="item.name" :value="item.id"/>
            </el-select>
          </el-form-item>

          <el-form-item class="form-action-buttons">
            <el-button>Cancel</el-button>
            <el-button type="primary" @click="onSubmit">Save</el-button>
          </el-form-item>
        </el-form>
      </el-dialog>
    </el-card>
</template>

<script>
export default {
  name: "ModalForm",
  props: {
    list: {
      type: Array,
      default: () => ({})
    }
  },
  data() {
    return {
      dialogVisible: false,
      form: {
        id: '',
        name: '',
        number: '',
        leader: '',
        children: []
      },
      rules: {
        name: [
          { required: true, message: 'Name required', trigger: 'blur' },
        ],
        number: [
          { required: true, message: 'Phone number required', trigger: 'blur' },
        ],
      }
    };
  },
  methods: {
    onSubmit() {
      this.$emit("submitForm", { ...this.form });
      this.$refs.addItemForm.resetFields();
    }
  }
}
</script>

<style scoped>
.modal-wrap {
  max-width: 40%;
  margin: auto;
  border: none;
}
.dialog {
  margin: auto;
  max-width: 70%;
}
.form-action-buttons {
  display: flex;
}
</style>

ContactsTable.vue

<template>
  <div class="contacts-list-wrap">
    <el-card :header="header" shadow="never">
      <el-table :data="list" row-key="id" :tree-props="{children: 'children', hasChildren: 'hasChildren'}" border stripe>
        <el-table-column prop="name" label="Name" sortable/>
        <el-table-column prop="number" label="Phone" sortable/>
      </el-table>
    </el-card>
  </div>
</template>

<script>
export default {
  name: "ContactsTable",
  props: {
    list: {
      type: Array,
      default: () => ({})
    }
  },
  data: () => ({
    header: "Phonebook"
  }),
}
</script>

<style scoped>
.contacts-list-wrap {
  max-width: 40%;
  margin: auto;
}
</style>

Please help me figure out what could be the reason?

I also need to understand how to add child contacts to all nesting levels...

Thank you for your responses!

question from:https://stackoverflow.com/questions/65907710/vuejs-phonebook-app-with-nested-table-data-error-maximum-call-stack-size-excee

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I'm not sure if this fixes anything, but in your onFormSubmit function you check if (!(data.leader)) which I think is intended to catch if leader is not empty string, leader: '' in your list. Empty string is not null, I think you should check if (data.leader != '')


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...