Я пытаюсь передать реквизит от родительского компонента дочернему компоненту, но кажется, что дочерний компонент не может правильно получить реквизит.
Это родительский компонент:
<template>
<div>
<b-table striped hover :items = "items" :fields = "fields">
<template #cell(actions) = "row">
<b-button
size = "sm"
@click = "openModal(row.item, row.index, $event.target)"
class = "mr-1"
>
Sua
</b-button>
<b-button size = "sm" @click = "row.toggleDetails" variant = "danger">
Xoa
</b-button>
</template>
<template #row-details = "row">
<b-card>
<ul>
<li v-for = "(value, key) in row.item" :key = "key">
{{ key }}: {{ value }}
</li>
</ul>
</b-card>
</template>
</b-table>
<item-update-modal
ref = "itemUpdateModal"
:id = "modalAttributes.id"
:title = "modalAttributes.title"
:propItem = "propItem"
/>
</div>
</template>
<script>
import ItemInfoModal from "@/components/item/ItemInfoModal.vue";
export default {
name: "ItemList",
components: {
"item-update-modal": ItemInfoModal,
},
props: {
items: [],
},
data() {
return {
showModal: false, // Initially, the modal is hidden
fields: [
{
key: "id",
label: "Ma so",
sortable: true,
sortDirection: "desc",
class: "text-center",
},
{
key: "name",
label: "Ten san pham",
sortable: true,
sortDirection: "desc",
},
{
key: "description",
label: "Mo ta",
sortable: true,
},
{
key: "specification",
label: "Quy cach",
sortable: true,
},
{
key: "itemUnit",
label: "Don vi",
sortable: true,
class: "text-center",
},
{ key: "actions", label: "Chi tiet" },
],
modalAttributes: {
id: "itemUpdateModal",
title: "Sua ban thanh pham",
},
propItem: {},
};
},
methods: {
openModal(item, index, button) {
// Show the modal when the button is clicked
this.propItem = JSON.parse(JSON.stringify(item));
this.$root.$emit(
"bv::show::modal",
this.modalAttributes.id,
button
);
},
resetInfoModal() {
this.modalAttributes.propItem = {};
},
onFiltered(filteredItems) {
// Trigger pagination to update the number of buttons/pages due to filtering
this.totalRows = filteredItems.length;
this.currentPage = 1;
},
},
};
</script>
И мой дочерний компонент:
<template>
<div>
<b-modal
:id = "id"
v-model = "showModal"
centered
:title = "title"
@ok = "onSubmit"
@show = "openModal"
>
<b-form @reset = "onReset">
<b-form-group
id = "input-group-item-name"
label = "Ten san pham"
label-for = "input-item-name"
>
<b-form-input
id = "input-item-name"
v-model = "item.name"
type = "text"
required
></b-form-input>
</b-form-group>
<b-form-group
id = "input-group-item-description"
label = "Mo ta san pham"
label-for = "input-item-description"
>
<b-form-input
id = "input-item-description"
v-model = "item.description"
type = "text"
required
></b-form-input>
</b-form-group>
<b-form-group
id = "input-group-item-unit"
label = "Don vi"
label-for = "item-unit"
>
<b-form-select
id = "item-unit"
v-model = "item.itemUnit"
:options = "itemUnitOptions"
></b-form-select>
</b-form-group>
<b-form-group
id = "input-group-item-specification"
label = "Quy cach"
label-for = "input-item-specification"
>
<b-form-textarea
id = "input-item-specification"
v-model = "item.specification"
type = "text"
rows = "4"
required
></b-form-textarea>
</b-form-group>
</b-form>
</b-modal>
</div>
</template>
<script>
import itemApi from "@/api/items";
export default {
name: "ItemInfoModal",
data() {
return {
showModal: false,
item: { ...this.propItem },
itemUnitOptions: [
{ value: "EA", text: "EA" },
{ value: "GR", text: "GR" },
],
};
},
props: {
id: {
type: String,
required: true,
},
title: {
type: String,
required: true,
},
propItem: { type: Object, required: false, default: () => {} },
},
methods: {
openModal() {
console.info(this.propItem);
this.showModal = true;
},
closeModal() {
this.showModal = false;
},
onSubmit(event) {
event.preventDefault();
if (this.item.id) {
console.info("updating");
itemApi.updateItem(this.item);
} else {
console.info("creating");
itemApi.createItem(this.item);
}
this.$router.go(0);
},
onReset(event) {
event.preventDefault();
console.info(this.item);
// Reset the updatedItem object
this.item = {};
},
},
};
</script>
Это пользовательский интерфейс:
Я пытаюсь заполнить форму содержимым выбранного элемента строки, но что-то не получается. Я попытался зарегистрировать реквизиты, но в первый раз, когда я нажал серую кнопку, я получил «{ob: Observer}», затем закрыл модальное окно и снова открыл его, на этот раз я получил свой «propItem», но форма все еще не заполнена, как ожидалось.
Обновление: я скопировал свой проект сюда: https://codesandbox.io/p/sandbox/vue3-371lz2
Пожалуйста помоги. Большое спасибо!
@IVOGELOV, я добавил песочницу для кода
Попробуйте сделать проект без Docker - там написано [CODESANDBOX] Waiting for container build to finish... и после долгого ожидания тайм-аут истекает.
спасибо, @IVOGELOV, теперь все работает





Решение отслеживает изменение предоставленного элемента от родительского компонента к дочернему компоненту. Добавив это к дочернему элементу, это должно работать:
watch: {
propItem: {
handler(currentItem) {
this.item = currentItem
}
}
},
В вашем дочернем компоненте вместо элемента данных попробуйте использовать вычисляемое свойство, например
computed: {
item() {
return {...this.record}
}
}
Я думаю, что дочерний компонент просто присваивает пустое значение вашему элементу данных и не может его обновить. Надеюсь, это поможет!
Есть ли у вас CodeSandbox или CodePen, воспроизводящий проблему?