Реквизиты VueJS несовместимы при передаче от родителя к дочернему элементу

Я пытаюсь передать реквизит от родительского компонента дочернему компоненту, но кажется, что дочерний компонент не может правильно получить реквизит.

Это родительский компонент:

<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

Пожалуйста помоги. Большое спасибо!

Есть ли у вас CodeSandbox или CodePen, воспроизводящий проблему?

IVO GELOV 07.10.2023 15:44

@IVOGELOV, я добавил песочницу для кода

Đức Trường Đặng 07.10.2023 16:15

Попробуйте сделать проект без Docker - там написано [CODESANDBOX] Waiting for container build to finish... и после долгого ожидания тайм-аут истекает.

IVO GELOV 07.10.2023 19:00

спасибо, @IVOGELOV, теперь все работает

Đức Trường Đặng 08.10.2023 10:51
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
4
50
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Решение отслеживает изменение предоставленного элемента от родительского компонента к дочернему компоненту. Добавив это к дочернему элементу, это должно работать:

 watch: {
    propItem: {
      handler(currentItem) {
        this.item = currentItem
      }
    }
  },

Ответ принят как подходящий

В вашем дочернем компоненте вместо элемента данных попробуйте использовать вычисляемое свойство, например

computed: { 
  item() {
    return {...this.record}
  }
}

Я думаю, что дочерний компонент просто присваивает пустое значение вашему элементу данных и не может его обновить. Надеюсь, это поможет!

Другие вопросы по теме