Dynami c образует фанки поведения в vuejs - PullRequest
2 голосов
/ 07 марта 2020

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

Проблема:

Когда кто-то нажимает кнопку «Новый продукт» раздел Добавить продукт будет создан внутри всех текущих разделов категории. Кроме того, v-модель, кажется, связывается с каждым вводом названия продукта. Когда кто-то нажимает кнопку X для определенного c раздела продукта, один раздел продукта будет удален из всех текущих разделов категории.

Я не совсем уверен, почему это происходит.

codepen : https://codepen.io/d0773d/pen/ExjbEpy

код:

<!-- Bootstrap CSS -->
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">

<title>Create Categories and Products</title>

  <!-- New Category -->
  <button class="btn btn-success mt-5 mb-5"
          @click="addNewCategoryForm">
    New Category
  </button>

  <div class="card mb-3" v-for="(category, index) 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">
        New Product
      </button>

      <div class="card mb-3" v-for="(product, index) in products">
        <div class="card-body">
          <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>
        </div>
      </div>
    </div>
  </div>        
</div>

<!-- Optional JavaScript -->
<!-- jQuery first, then Popper.js, then Bootstrap JS -->
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>

<script>
  var app = new Vue({
    el: '.container',

    data: {
      categories: [
        {
          name: '',
        }
      ],

      products: [
        {
          name: '',
        }
      ]
    },

    methods: {
      addNewCategoryForm () {
        this.categories.push({
          name: '',
        });
      },

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

      addNewProductForm () {
        this.products.push({
          name: '',
        });
      },

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

1 Ответ

3 голосов
/ 07 марта 2020

Общая проблема заключается в том, что вы не указываете, какие продукты относятся к какой категории. Таким образом, в вашем текущем коде все продукты относятся ко всем категориям.

Я бы предложил вместо этого вкладывать продукты в объект категории.

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>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...