【问题标题】:How to solve "TypeError: Cannot read property 'length' of undefined" in vue如何解决 vue 中的“TypeError: Cannot read property 'length' of undefined”
【发布时间】:2020-12-21 05:43:40
【问题描述】:

我正在尝试创建一个自动下拉列表来显示类别列表。我正在使用 autocomplete-vue 来创建它。

我得到的错误是

[Vue 警告]:挂载钩子错误:“TypeError: Cannot read property 'length' of undefined”

TypeError: 无法读取未定义的属性“长度”

我不确定如何修复它,即使我的类别正在加载,并且当我在自动完成中键入时我可以获得我的类别列表,但我在控制台中收到上述错误,所以我没有不知道我会如何得到这些错误。

这是我的代码

我的产品.js

  Vue.component('product-app', require('./ProductApp.vue').default);
  Vue.component('product-create', require('./ProductCreate.vue').default);

  if (document.getElementById('product-app')) {
    const app = new Vue({
      el: "#product-app",
      data(){
        return{
          categories: []
        }
      },
      mounted() {
        axios.get('/categories').then(response => {
          this.categories = response.data;
        })
      }
    });
  }

我的 products.blade.php

  <div id="product-app">
    <product-app :categories="categories"></product-app>
  </div>

我的 ProductApp.vue

  <template>
    <div>
      <div class="row">
        <div class="col-md-6">
          <products :products="products"></products>
        </div>

        <div class="col-md-6">
          <product-create v-if="createProduct" :categories="categories"></product-create>
        </div>
      </div>
    </div>
  </template>

  <script>
    export default {
      props: ['categories'],
      data() {
        return {
          createProduct: false
        }
      },
      mounted() {
        this.bus.$on('create-product', payload => {
          this.createProduct = true;
        });
      }
    }
  </script>

我的 ProductCreate.vue

  <template>
    <div>
      <div class="row">
        <div class="col-lg-6">
          <div class="form-control">
            <label>Product Name</label>
            <input type="text" v-model="product.name" class="form-control">
          </div>

          <div class="form-control">
            <label>Product Description</label>
            <textarea v-model="product.description"></textarea>
          </div>

          <div class="form-control">
            <autocomplete-vue v-if="categoriesReady" :list="allCategories"></autocomplete-vue>
          </div>

          <button class="btn btn-success" @click="saveProduct">Save</button>
        </div>
      </div>
    </div>
  </template>

  <script>
    import AutocompleteVue from 'autocomplete-vue';

    export default {
      props: ['categories'],
      components: {
        AutocompleteVue
      },
      data(){
        return{
          categoriesReady: false,
          allCategories: [],
          product: {
            name: '',
            description: ''
          }
        }
      },
      methods: {
        getAllCategories(){
          for(let i = 0; i < this.categories.length; i++){
            let name = this.categories[i].name;
            this.allCategories.push({name: name});
          }

          this.categoriesReady = true;
        }
      },
      mounted(){
        this.getAllCategories();
      }
    }
  </script>

【问题讨论】:

    标签: vue.js


    【解决方案1】:

    检查你最终挂载的函数。

    属性长度未定义,因为在您的循环尝试运行它之前,还没有从 axios GET 请求返回类别。尝试通过简单地使用 async 并使用 await (或您喜欢解决承诺的任何其他方式)等待请求来使请求成为承诺。然后在循环运行之前加载类别。这应该可以解决问题。

    【讨论】:

    • 它在 ProductCreate 组件中工作很酷。我认为问题仍然是在循环尝试运行之前仍未正确解决的承诺。但我不是 Vue 专家,所以可能是别的东西。
    【解决方案2】:

    我已经通过搬家解决了我的问题

      axios.get('/categories').then(response => {
        this.categories = response.data;
      })
    

    来自我的 product.js

    到我的 ProductCreate.vue,所以我的挂载部分看起来像这样

      mounted(){
        axios.get('/categories').then(response => {
          for(let i = 0; i < response.data.categories.length; i++){
                let name = this.categories[i].name;
                this.allCategories.push({name: name});
              }
    
              this.categoriesReady = true;
        })
      }
    

    执行此操作后,我的 autocomplete-vue 工作正常,并且我的控制台中没有任何错误。

    在将此标记为已回答之前,我想知道你们是否可以告诉我这是否是最佳做法。

    【讨论】:

      【解决方案3】:

      当我没有从父组件传递此组件的“类别”值时,我才收到该错误消息。 'undefined' 对象是 'for(let i = 0; i

      【讨论】:

      • 我不确定你的意思。我已经更新了我的问题以包含所有内容。
      • `mounted() { axios.get('/categories').then(response => { this.categories = response.data; }) }` 将其更改为 created(){} 或beforeCreated(){}
      猜你喜欢
      • 2022-10-18
      • 1970-01-01
      • 2017-04-24
      • 1970-01-01
      • 1970-01-01
      • 2018-01-24
      • 2021-06-25
      • 2020-04-16
      • 1970-01-01
      相关资源
      最近更新 更多