Комментарии 20
Способов взаимодействия компонентов не так много:
props/emits
provide/inject
composable (composition API)
state manager (Vuex/Pinia)
EventBus?
Еще через ref компонента можно коммуницировать или через parent/child, но это более грязные методы
Скажите, а что делать, если реактивность от родителя до дочернего компонена нежелательна?
Т.е. например я передал объект через props, потом сделал несколько input для редактирования того или иного элемента. Но я не хочу, чтобы изменения в родителе его меняли пока я его редактирую.
Локализовать его как-нибудь при получении в другую переменную и передать уже её в соответствующие v-model для редактирования?
Если я вас правильно понял, то да.
Вы получаете props внутри дочернего компонента, копируете его в локальную переменную и её уже изменяете в ваших input. После завершения редактирования, например, по кнопке вызываете emit()
const props = defineProps({ modelValue: Object });
const emit = defineEmits(['update:modelValue']);
const localFormData = ref({ ...props.modelValue });
const save = () => {
emit('update:modelValue, { ...localFormData });
};
Могу ошибаться, но реактивность работает на всю вложенную структуру, не лучше ли тогда через clone deep?
Если у вас внутри объекта есть другие объекты, то да, cloneDeep будет лучше. Или JSON.stringify/parse
Спасибо за ответ. Получается, моё желание нетипично? Я для себя лично пишу фронт (не обладая какими-либо знаниями в этом деле) и там везде такая ситуация.
graphql периодическо возвращает сложный объект (много вложенных объектов). Есть диалоговые окна, в которых какие-то части каких-то вложенных объектов можно отредактировать. Типичная проблема в том, что когда я редактирую, объект обновляется и отредактированное сбрасывается.
Какой правильных подход при таких вводных? Останавливать обновление, пока открыты диалоговые окна? Сложность в том, что объект расползается частями по разными компонентам (обычно это таблицы) и редактор открывается из них и даже если завести props типа editMode, я не могу отредактировать его из дочернего компонента просто так (вся статья об этом)
Я сейчас просто стараюсь успеть отредактировать до обновления, но иногда задумываюсь об улучшениях.
Я не работал с graphql, но мне кажется, что вы должны сохранять свои изменения через сервер. То есть, если вы отредактировали что-то внутри вашей формы, то отправьте эти изменения на сервер, чтобы сохранить их и оставить только один источник истины.
Вам скорее всего нужно отправлять весь измененный объект, поэтом, думаю, что да, каким-то способом вы помечаете, что объект в состоянии изменения и не сохранен. Пока он в таком состоянии, не обновляете данные.
Отправляете новые данные на сервер, включаете обновление.
Могу в чем-то ошибаться, так как не знаком с graphql
Вполне типично практически во всех ситуациях, когда есть действия “сохранить”, “отменить”.
Можно дальше пойти и поговорить об undo/redo.
Вы просто храните где-то два состояния и всё. Как - это уже вопрос к реализации.
Со сложными структурами подходы тоже разные можно придумать, что лучше: зависит от целей.
P.S.: а Вашу проблему я не понял до конца.
А декстуктор пропсов не появилось? Чтобы передать объект , а он разложился по полям defineProps ?
Деструктор пропсов реализовывается через v-bind.
да вспомнил , точнее для v-model такойже декстуктор чтобы не писать портянки атрибутов из всех полей при использование компонента
Я слабо понимаю Вашу задачу.
конечно, такого нет - и не будет.
Дело не в том, как это декомпозировать, а в том, как передать объект через HTML.
Всё, что вы отдаёте в кавычках, преобразуется в обычные HTML-параметры. Поэтому передать число или строку ещё кое-как можно, а с булевыми уже проблема.
Хотя... если у вас объект, чисто теоретически можно бы было передавать json. Т.е., формально передавать строку, потом изнутри компоненты её ловить и раскладывать.
Собственно, это вы можете сами себе организовать: передавать JSON.strignify(ваши_данные), а дальше ловить их как JSON.parse(что_приехало). И вроде всё - на выходе у вас объект.
Рекомендуют или сторонние решения (по сути тот же EventBus), или Vuex/Pinia
https://v3-migration.vuejs.org/breaking-changes/events-api.html#overview
Есть много способов сделать это: Vue 3 и взаимодействие компонентов