Вопрос или проблема
Я пытаюсь обновить булеву переменную, установленную в родительском компоненте, из дочернего компонента.
Я передал переменную в качестве пропса из родительского компонента в дочерний:
<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 являются лишь "читаемыми" и не могут быть изменены непосредственно в дочерних компонентах.
Правильный подход
-
Использование реактивности: Вместо передачи простого булевого значения как свойства, используйте реактивные ссылки, создавая их с помощью функции
ref()
. Это позволяет вам управлять состоянием более гибко. -
v-model
: Использованиеv-model
для синхронизации данных между родителем и дочерним компонентом — это стандартный подход. Это позволяет вам настраивать двунаправленную привязку данных. Вы можете объявитьv-model
с нужным именем, например,finishedCheck
, и позволить дочернему компоненту изменять его значение. -
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, не стесняйтесь обращаться!