Как изменить состояние родительского компонента из дочерних компонентов во Vue
Что проверяют
Понимаете ли вы односторонний поток данных во Vue: пропсы идут вниз, изменения поднимаются событиями, а дочерний компонент не трогает чужое состояние напрямую. Следом обычно просят объяснить, как устроен v-model на компоненте и что делать, если между родителем и потомком три уровня вложенности.
Как отвечать
Основной способ во Vue 3 это событие. Потомок объявляет его через defineEmits(['update']) и вызывает emit('update', value), родитель слушает @update="onUpdate" и сам меняет своё состояние. Изменение остаётся в компоненте, который данными владеет, и видно во Vue Devtools.
Дальше варианты по ситуации:
v-modelна компоненте: сахар над пропсомmodelValueи событиемupdate:modelValue. Именованные модели пишутся какv-model:title, они заменили модификатор.syncиз Vue 2. С версии 3.4 в<script setup>есть макросdefineModel(), который прячет эту пару за одним ref;provide/inject: когда потомок глубоко. Родитель отдаётreadonly-версию ref и функцию для её изменения, потомок вызывает функцию, а не мутирует данные;- стор на Pinia: если состояние на самом деле общее для нескольких веток дерева. Pinia сейчас официальная рекомендация, Vuex в режиме поддержки и в новых проектах не нужен;
- функция в пропсе: работает, но для Vue это непривычный стиль. События видны в
emits, валидируются и отслеживаются инструментами.
Покажите и границу: если одно состояние меняют пять компонентов в разных местах, его пора выносить в стор, а не тянуть цепочку emit через промежуточные компоненты.
Где спотыкаются
Присваивают значение пропсу в потомке. Vue в режиме разработки выдаёт предупреждение, а мутация поля внутри переданного объекта проходит молча, и родитель меняется без всякого события. Это работает, пока не начнёшь искать, кто испортил данные.
Лезут в родителя через $parent или дёргают методы потомка через ref. Компонент намертво привязывается к конкретному месту в дереве.
Отвечают кодом на Vuex и Options API как единственным вариантом. Для текущего Vue это устаревший ответ, стоит хотя бы назвать Composition API и Pinia.