我有一个名为 NewIngredientInput 的组件,我在新菜谱页面上使用它。该组件由 3 个输入组成:amount、unit 和 name。我正在使用 Nuxt 3,使用 Formkit 以及消费和外部 API 处理表单。
当我将数据从表单发送到端点进行发布时,它仅捕获来自输入amount的信息,对于其他两个输入(unit和name),它发送一个空字符串,因此 POST 请求成功。我指定对于不在 NewIngredientInput 组件内的其他输入,信息已成功捕获。
这是我的新菜谱页面代码:
<template>
<div class="container">
<UserMenu />
<SideNavUser />
<div class="new-recipe-container">
<div class="title">Crear Receta</div>
<div class="form">
<FormKit type="form" @submit="createRecipe">
<FormKit
v-model="recipeData.name"
type="text"
name="name"
label="Título de la Receta"
validation="required"
/>
<div
class="new-ingredient"
v-for="(row, index) in inputRows"
:key="index"
>
<NewIngredientInput
v-model="row.amount"
v-model:unit_measure="row.unit_measure"
v-model:name="row.name"
:showRemoveButton="index > 0"
@removeRow="removeRow(index)"
/>
<button @click="addRow" class="add">+</button>
</div>
<FormKit
v-model="recipeData.description"
type="textarea"
rows="10"
name="description"
label="Instrucciones"
placeholder="Escribe oraciones o párrafos."
validation="required"
/>
<div class="triple">
<FormKit
v-model="recipeData.region"
type="text"
name="region"
label="Región"
validation="required"
/>
<FormKit
v-model="recipeData.keywords"
type="text"
name="keywords"
label="Palabras Clave"
placeholder="pollo, ajo, ..."
help="Ingresa palabras claves separadas por comas."
validation="required"
/>
<div class="photo">
<FormKit
type="file"
name="photo"
accept=".jpg,.png"
label="Imagen"
help="Solo puedes incluir imagenes con extensión .jpg o .png"
validation="required"
/>
</div>
</div>
<FormKit type="submit" label="Crear" />
</FormKit>
</div>
</div>
</div>
</template>
<script>
import NewIngredientInput from "../components/NewIngredientInput.vue";
import axios from "axios";
export default {
components: {
NewIngredientInput,
},
data() {
return {
inputRows: [{ amount: "", unit_measure: "", name: "" }],
recipeData: {
name: "",
description: "",
region: "",
keywords: "",
},
};
},
methods: {
addRow() {
this.inputRows.push({ amount: "", unit_measure: "", name: "" });
},
removeRow(index) {
this.inputRows.splice(index, 1);
},
async createRecipe() {
try {
const photoInput = document.querySelector('input[name="photo"]');
if (photoInput && photoInput.files && photoInput.files.length > 0) {
const photoForm = new FormData();
photoForm.append("photo", photoInput.files[0]);
const imageResponse = await axios.post(
"API endpoint for upload newImage",
photoForm,
{
headers: {
"Content-Type": `multipart/form-data; boundary=${photoForm._boundary}`,
},
}
);
const ingredient = this.inputRows.map((row) => {
return {
amount: row.amount.amount,
unit: row.unit_measure,
name: row.name,
};
});
const recipeForm = {
name: this.recipeData.name,
ingredients: ingredient,
description: this.recipeData.description,
region: this.recipeData.region,
keywords: this.recipeData.keywords,
photo: imageResponse.data,
};
console.log(recipeForm);
const recipeResponse = await axios.post(
"API endpoint for upload the entire recipe",
recipeForm
);
console.log("Receta creada exitosamente: ", recipeResponse.data);
} else {
console.error("No se seleccionó ninguna imagen");
}
} catch (error) {
console.error(error);
}
},
},
};
</script>
如果我不在 NewIngredientInput 上使用
v-model:unit_measure="row.unit_measure"
和 v-model:name="row.name"
,当我为新成分添加一行时,它会继承旧成分的信息并被覆盖,从而产生单行而不是包含多种成分的数组.
我还附上了 NewIngredientInput 组件的脚本以获取更多上下文:
<template>
<FormKit type="form" name="ingredients">
<div class="newIngredient">
<FormKit
v-model="ingredient.amount"
type="number"
name="amount"
id="amount"
label="Cantidad"
min="1"
validation="required"
/>
<FormKit
v-model="ingredient.unit_measure"
type="text"
name="unit"
id="unit"
label="Unidad"
validation="required"
/>
<div class="ingredient">
<FormKit
v-model="ingredient.name"
type="text"
name="name"
id="name"
label="Ingrediente"
validation="required"
/>
</div>
<button class="remove" @click="removeRow" v-show="showRemoveButton">
-
</button>
</div>
</FormKit>
</template>
<script>
export default {
props: {
showRemoveButton: {
type: Boolean,
default: false,
},
// Pass the ingredient object as a prop
ingredientValue: Object,
},
data() {
return {
ingredient: { amount: "", unit_measure: "", name: "" },
};
},
watch: {
// When the prop value (ingredient object) changes, update the local ingredient data
ingredientValue: {
handler(newValue) {
this.ingredient.amount = newValue.amount;
this.ingredient.unit_measure = newValue.unit_measure;
this.ingredient.name = newValue.name;
},
deep: true,
},
},
methods: {
removeRow() {
this.$emit("removeRow");
},
},
};
</script>
如果我正确理解问题,问题在于您如何在 NewIngredientInput 组件上使用 v-model。它应该绑定到单个模型,但您要绑定到多个模型(金额、单位度量、名称)。这是简化的解决方案:
在
NewIngredientInput
页面中更改您的 newrecipe
,如下所示:
<NewIngredientInput
:value="row"
:showRemoveButton="index > 0"
@removeRow="removeRow(index)"
/>
并且:
<template>
<!-- Your existing template code -->
</template>
<script>
export default {
props: {
showRemoveButton: Boolean,
value: { type: Object, required: true },
},
data() {
return { ingredient: { ...this.value } };
},
watch: {
ingredient: {
handler() { this.$emit('update', this.ingredient); },
deep: true
},
value: {
handler(newValue) { this.ingredient = { ...newValue }; },
deep: true
}
},
methods: {
removeRow() { this.$emit("removeRow"); },
},
};
</script>
希望这有帮助!