Как стать автором
Обновить

Комментарии 20

Способов взаимодействия компонентов не так много:

  1. props/emits

  2. provide/inject

  3. composable (composition API)

  4. state manager (Vuex/Pinia)

EventBus?

Сорри, живу в 2.6

Еще через 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(что_приехало). И вроде всё - на выходе у вас объект.

(эх, убрала бы комментарий, но время редактирования вышло - явно там не поняла ваш вопрос)

А как в условиях VUE3 решается проблема с реагированием на события компонентами, которые либо находятся далеко по вертикали, либо вообще по горизонтали? Раньше это отлично решалось EventBus-ом в руте (например), а сейчас как? Т.е. например нужно отреагировать на происходящее неизвестно где. Пример — есть корневой компонент, который умеет блокировать весь экран и показывать лоадер. Где-то на каком-то уровне что-то происходит с сетью и я хочу на это время заблокировать приложение. В VUE2 я мог сделать this.$root.emit( «wait» ); и все (нужный компонент сам сядет на прослушивание этого события) — мне не надо заботится чтобы что-то куда-то прокидывать или знать, что там заинклюдить или что-то провайдить. Понятно, что я могу написать свой EventBus, но как это предлагается делать корректно с точки зрения VUE3?

Рекомендуют или сторонние решения (по сути тот же EventBus), или Vuex/Pinia

https://v3-migration.vuejs.org/breaking-changes/events-api.html#overview

Ну вот я, собственно, и не понял, зачем они это убрали? Был стандартный удобный встроенный механизм - нет, вырезали.

Понятно, что его можно внешним скриптом сделать, но события то внутри Vue остались и при этом никакого альтернативного механизма предложено не было...

Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории