Изменить логическое значение в родительском компоненте из дочернего в Vue

Вопрос или проблема

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

Я передал переменную в качестве пропса из родительского компонента в дочерний:

<script>
  let isFinished = false;
</script>

<template>
  <Child
    v-if="isFinished === false"
    :isFinished = isFinished
  />

  <Child2
    v-if="isFinished === true"
    :isFinished = isFinished
  />
 </template>

Я вижу, что он принимается с помощью console.log в дочернем компоненте, но получаю ошибку, когда пытаюсь изменить значение, сообщая, что оно только для чтения:

export default {
    props: {
        isFinished: Boolean
    }, 
    methods: {
        submit: function(e) {
            console.log('полученный проп:', this.isFinished);
            this.isFinished = true;
        }
    }
}

Что еще мне нужно сделать, чтобы изменить булеву переменную в дочернем компоненте так, чтобы она передавалась обратно в родительский компонент для переключения отображаемых компонентов?

Буду признателен за любую помощь, спасибо.

Ладно, я сам разобрался, используя ref() для хранения булевой переменной, а затем используя v-model для отправки её в качестве пропса в дочерний компонент. Затем я мог определить модель defineModel(), что позволило мне изменить её значение в дочернем компоненте.

Родитель

<script>
  import { ref } from 'vue';
  let isFinished = ref(false);
</script>

<template>
  <Child
    v-if="isFinished === false"
    v-model:finishedCheck = isFinished
  />

  <Child2
    v-if="isFinished === true"
    v-model:finishedCheck = isFinished
  />
 </template>

Дочь

<script setup>
    const finishedCheck = defineModel('finishedCheck');

    const submitForm = () => {
        finishedCheck.value = true;        
    };
</script>

И затем просто вызвал функцию submitForm по событию @click

Ответ или решение

Вам удалось решить проблему с изменением булевого значения в родительском компоненте Vue из дочернего компонента, используя реактивные ссылки и v-model. Это хороший подход, и я бы хотел более подробно рассмотреть этот вопрос, чтобы отметить важные моменты и улучшить понимание происходящего.

Основная проблема

Изначально вы пытались изменить значение свойства (prop) в дочернем компоненте, что невозможно, так как свойства в Vue являются лишь "читаемыми" и не могут быть изменены непосредственно в дочерних компонентах.

Правильный подход

  1. Использование реактивности: Вместо передачи простого булевого значения как свойства, используйте реактивные ссылки, создавая их с помощью функции ref(). Это позволяет вам управлять состоянием более гибко.

  2. v-model: Использование v-model для синхронизации данных между родителем и дочерним компонентом — это стандартный подход. Это позволяет вам настраивать двунаправленную привязку данных. Вы можете объявить v-model с нужным именем, например, finishedCheck, и позволить дочернему компоненту изменять его значение.

  3. defineModel: В вашем дочернем компоненте defineModel служит для указания, какое именно состояние будет управляться через v-model. Это позволяет более контролируемо изменять значения внутри дочерних компонентов и автоматически обновлять родительские компоненты.

Пример реализации

Родительский компонент

<script>
import { ref } from 'vue';

export default {
  setup() {
    let isFinished = ref(false);
    return { isFinished };
  }
};
</script>

<template>
  <Child
    v-if="!isFinished"
    v-model:finishedCheck="isFinished"
  />

  <Child2
    v-if="isFinished"
    v-model:finishedCheck="isFinished"
  />
</template>

Дочерний компонент

<script setup>
import { defineModel } from 'vue';

const finishedCheck = defineModel('finishedCheck');

const submitForm = () => {
    finishedCheck.value = true;        
};
</script>

<template>
  <button @click="submitForm">Завершить</button>
</template>

Заключение

Теперь, когда вы нажмете кнопку в дочернем компоненте, вызовется функция submitForm, которая изменит значение finishedCheck на true. Это приведет к тому, что родительский компонент автоматически отобразит другой дочерний компонент (Child2), поскольку реактивное значение isFinished было изменено.

Использование такого подхода делает вашу архитектуру компонентов более чистой и эффективной, а управление состоянием проще и понятнее. Этот метод также способствует лучшему взаимодействию компонентов, что является основополагающим при разработке сложных приложений на Vue.js.

Если у вас будут дополнительные вопросы или потребуется помощь с другими аспектами Vue.js, не стесняйтесь обращаться!

Оцените материал
Добавить комментарий

Капча загружается...