Нужна помощь в рефакторинге моего vuejs кода. Ошибка v-on обработчик: «Ошибка типа: не удается прочитать свойство 'products' of undefined" - PullRequest
0 голосов
/ 09 марта 2020

Кто-то порекомендовал мне использовать bootstrap - vue, потому что я использую bootstrap 4 и vue вместе; Я считаю, что правильно установил bootstrap - vue для laravel.

Моя цель: я использую VueJS 2.6.11 и bootstrap 4 для создания двух динамических c секций (Категория и Product), которые содержат div и поля ввода. Раздел продукта вложен в раздел категории. Когда кто-то нажимает кнопку «Новая категория», создается другая категория. То же самое должно происходить, когда кто-то нажимает кнопку «Новый продукт», должен создаваться другой раздел «Продукт», но только внутри раздела текущей категории.

При нажатии на кнопку «Новый продукт» появляется следующая ошибка:

[Vue warn]: Error in v-on handler: "TypeError: Cannot read property 'products' of undefined"

found in

---> <CreateProductAndCategory> at resources/js/components/admin/CreateProductAndCategory.vue
       <Dashboard> at resources/js/views/admin/DashBoard.vue
         <App> at resources/js/components/App.vue
           <Root>

Оригинальный код:

var app = new Vue({
  el: ".container",

  data: {
    categories: [{
      name: "",
      products: [{
        name: ""
      }]
    }]
  },

  methods: {
    addNewCategoryForm() {
      this.categories.push({
        name: "",
        products: []
      });
    },

    deleteCategoryForm(index) {
      this.categories.splice(index, 1);
    },

    addNewProductForm(index) {
      this.categories[index].products.push({
        name: ""
      });
    },

    deleteProductForm(categoryIndex, index) {
      this.categories[categoryIndex].products.splice(index, 1);
    }
  }
});

<!-- Bootstrap CSS -->
<link rel="stylesheet" href="https://unpkg.com/bootstrap@4.4.1/dist/css/bootstrap.min.css">
<!-- Vue -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>

<title>Create Categories and Products</title>
<div class="container">
  <!-- New Category -->
  <button class="btn btn-success mt-5 mb-5" @click="addNewCategoryForm">
        New Category
      </button>

  <div class="card mb-3" v-for="(category, catIndex) in categories">
    <div class="card-body">
      <span class="float-right" style="cursor:pointer" @click="deleteCategoryForm">
            X
          </span>

      <h4 class="card-title">Add Category</h4>

      <div class="category-form">
        <input type="text" class="form-control mb-2" placeholder="Category Name" v-model="category.name">
      </div>

      <!-- New Product -->
      <button class="btn btn-success mt-5 mb-5" @click="addNewProductForm(catIndex)">
            New Product
          </button>

      <div class="card mb-3" v-for="(product, index) in category.products">
        <div class="card-body">
          <span class="float-right" style="cursor:pointer" @click="deleteProductForm(catIndex, index)">
                X
              </span>

          <h4 class="card-title">Add Product</h4>

          <div class="product-form">
            <input type="text" class="form-control mb-2" placeholder="Product Name" v-model="product.name">
          </div>
        </div>
      </div>
    </div>
  </div>
</div>

Рефакторированный код (код, для которого я получаю ошибки):

<template>
    <div>
        <!-- New Category -->
        <b-button variant="success" class="mt-1 mb-2"
                @click="addNewCategoryForm">
            New Category
        </b-button>

        <b-card class="mb-3" v-for="(category, catIndex) in categories">
            <span class="float-right"
                style="cursor:pointer"
                @click="deleteCategoryForm">
                X
            </span>

            <h4 class="card-title">Add Category</h4>

            <div class="category-form">
                <input 
                    type="text"
                    class="form-control mb-2"
                    placeholder="Category Name"
                    v-model="category.name">
            </div>

            <!-- New Product -->
            <b-button variant="success" class="mt-2 mb-2"
                    @click="addNewProductForm">
                New Product
            </b-button>

            <b-card class="mb-3" v-for="(product, index) in category.products">
                <span class="float-right" 
                    style="cursor:pointer"
                    @click="deleteProductForm">
                    X
                </span>

                <h4 class="card-title">Add Product</h4>

                <div class="product-form">
                    <input 
                    type="text" 
                    class="form-control mb-2" 
                    placeholder="Product Name"
                    v-model="product.name">
                </div>
            </b-card>

        </b-card>
    </div>
</template>

<script>
export default {
    name: "create-product-and-category",

    data: () => {
        return {
            categories: [{
                name: "",
                products: [{
                    name: ""
                }]
            }]
        }
    },

    methods: {
        addNewCategoryForm() {
            this.categories.push({
                name: "",
                products: []
            });
        },

        deleteCategoryForm(index) {
            this.categories.splice(index, 1);
        },

        addNewProductForm(index) {
            this.categories[index].products.push({
                name: ""
            });
        },

        deleteProductForm(categoryIndex, index) {
            this.categories[categoryIndex].products.splice(index, 1);
        }
    }
}
</script>

<style scoped>

</style>

1 Ответ

0 голосов
/ 09 марта 2020

Я исправил свою проблему. Мне нужно уделять больше внимания при копировании и вставке.

Это правильный фрагмент кода:

 <!-- New Product -->
            <b-button variant="success" class="mt-2 mb-2"
                    @click="addNewProductForm(catIndex)">
                New Product
            </b-button>

            <b-card class="mb-3" v-for="(product, index) in category.products">
                <span class="float-right" 
                    style="cursor:pointer"
                    @click="deleteProductForm(catIndex, index)">
                    X
                </span>
...