Есть ли способ сохранить ссылку на определенный компонент в DOM? - PullRequest
2 голосов
/ 27 апреля 2019

Проблема:

В настоящее время я работаю над деревом файлов, более конкретно над функциональностью «Выбранная папка». Я делаю это, чтобы иметь конкретную цель для создания новых файлов и папок, кроме корневой папки. (Я использую Vue в Electron, но это не совсем относится к вопросу)

Выбор происходит по клику. Из-за особенностей файловых деревьев я использую рекурсивные компоненты (и это ограничивает мой «простой» доступ к некоторым компонентам).

Хотя достижение этого в бэкэнде тривиально, моя точная проблема заключается в том, что при выделении выбранной папки, скажем, другим цветом фона или жирным текстом (путем привязки идентификатора или класса, который имеет некоторый соответствующий стиль в моей таблице стилей) Мне нужно снять отметку ранее выбранный каталог.

Итак, как мне получить доступ к косвенному (из-за рекурсивных компонентов) дочернему компоненту?

То, что я пробовал и смотрел на:

Теперь я знаю, что в JS вы не можете хранить указатели или ссылки в переменных (в противном случае это было бы легко сделать, сохранив ссылку на предыдущий элемент DOM).

У меня есть несколько решений в рукаве, но они действительно утомительны и не очень просты. Раньше мне приходилось перерисовывать (перечитывать) определенные подкаталоги, основываясь на обновлениях файловой системы. Я добился этого частичного повторного рендеринга, передавая вызовы дочерних функций из корневого каталога, пока не достиг каталога, который необходимо было повторно отрендерить. Я должен был сделать это, так как наблюдатель FS был создан на корневом компоненте.

Точно так же я мог бы сделать это с задачей снятия пометки. Когда я выбираю новую папку, я начинаю с передачи вызовов дочерних функций до тех пор, пока не достигну ранее выбранной папки, и сниму пометку с нее, отменив привязку идентификатора стиля. Сделав это ранее, я знаю, что это не приятный метод.

Так как я могу получить цель события click, я подумал, могу ли я каким-либо образом сохранить какую-либо ссылку на ранее «выбранный» элемент DOM и просто использовать эту ссылку позже, когда мне понадобится «отменить выбор».

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

<folder-comp
          @openFile="openFile"
          v-for="folder of folders" 
          :key="`folder-${folder.shortFolderName}`"
          :folder-name="folder.shortFolderName"
          :ref="folder.shortFolderName"
          :full-folder-path="folder.fullFolderPath"
          :local-directory="recursiveScanDir"
          :indentation-level="indentationLevel + 1">
</folder-comp>

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

РЕДАКТИРОВАТЬ: Ну, как это случилось со мной в прошлом, просто написать о самой проблеме на stackoverflow помог мне найти решение.

В моем проекте Vue настроена глобальная шина событий, поэтому я могу привязать прослушиватель событий к текущей выбранной папке. При щелчке другой папки (выбранной таким образом) она генерирует событие в Global Event Bus, вызывая ранее выбранную папку. Затем следует снятие отметки и отсоединение слушателя события.

Это только одно решение, поэтому вопрос остается в силе. Это хорошее решение? Есть ли недостатки этого подхода? Есть ли лучшее решение?

1 Ответ

0 голосов
/ 27 апреля 2019

Вместо глобальной шины событий вы также можете использовать управление состоянием, например, Vuex . Когда вы меняете папки, вы просто отправляете действие. При этом используется command pattern, в отличие от упомянутого listener pattern. У вас есть выбор сделать это действие asynchronous или synchronous.

Есть несколько способов зарегистрировать ваших слушателей / наблюдателей, внутри компонентов или вне их.

Использование этой архитектуры позволит вам легко добавлять возможности отмены / повтора, а также иметь возможность перемещаться назад и вперед по истории mutations.

Вы также получаете встроенные функции отладки, предоставляемые инструментами Vue в вашем браузере.

Фактически, Vuex был создан именно для таких ситуаций, когда компоненты должны взаимодействовать друг с другом, но родительский / дочерний механизм prop / emit / inject начинает становиться утомительным и разваливаться.

Существует высокая вероятность того, что, начав использовать Vuex, вы никогда не оглянетесь назад.

...