Кто-то порекомендовал мне использовать 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>