Технологии устареют, дизайн-мышление останется навсегда
1. Сценарии использования
Сценарии делового использования перетаскивания проникли во все наши аспекты, особенно на мобильный терминал. Боковое меню перетаскивания, взаимодействие с картой перетаскиванием, оценка перетаскиванием и т. д.
Такое взаимодействие позволяет нам предоставлять пользователям более удобные интерактивные операции в ограниченных сценариях событий. Это значительно улучшает пользовательский опыт и беглость продукта.
2. Введение в React-DnD
React-DnDЭто набор утилит реагирования, чтобы помочь вам построить сложный интерфейс перетаскивания, сохраняя соединение между компонентами. Это очень подходитTrelloа такжеStorifyТакие приложения, как перетаскивание, передают данные между различными частями приложения, а компоненты могут изменять свой внешний вид и состояние приложения в ответ на события перетаскивания.
Показанная выше платформа для совместной работы над командными задачами используется многими компаниями.React-DnDЭто отличное решение с открытым исходным кодом для такого типа бизнес-сценариев.
Далее давайте представим, как его использовать.
3. Как использовать
3.1 Установка
Когда нам нужно установить установкуbackendа такжеreact-dnd.
Причина такой конструкции будет подробно объяснена позже при анализе исходного кода.
3.2 Инъекция DndProvider
DndProviderКомпоненты обеспечивают функциональность React-DnD для вашего приложения. Его необходимо внедрить в серверную часть через параметр backendc, но его также можно внедрить в объект окна.
Бэкэнд-бэкенд — очень хороший метод проектирования в React-DnD. Это можно понимать как реализацию конкретного перетаскивания.
DndProvider api
- серверная часть: обязательна, серверная часть dnd может использоваться для предоставления двух официальныхHTML5Backend or TouchBackend, или вы можете написать свой собственный бэкенд.
- контекст: необязательный, пользователь настраивает контекст бэкенда, который зависит от реализации бэкенда.
- параметры: Настройте объект бэкэнда, который можно передать в бэкэнд при настройке. Примеры следуют.
3.3 useDrag объявляет источник перетаскивания
userDragХук для использования текущего компонента в качестве источника перетаскивания.
Параметры, возвращаемые useDrag,
- arguments [0]: объект, содержащий атрибуты, собранные функцией сбора. Если вы собираете неопределенную функцию, возвращается нулевой объект.
- arguments[1]: функция соединителя источника перетаскивания. Это должно быть прикреплено к перетаскиваемой части DOM.
- arguments[2]: Функция коннектора для предварительного просмотра перетаскивания. Это может быть прикреплено к разделу предварительного просмотра DOM.
Затем параметры, переданные useDrag,
- предмет: обязательный. Простой объект JavaScript, описывающий данные для перетаскивания. Это единственная информация об источнике перетаскивания, доступная для цели перетаскивания.
- item.type: Обязательный и должен быть строкой, нотация ES6. На этот элемент будут реагировать только цели перетаскивания, зарегистрированные как один и тот же тип.
- Параметры предварительного просмотра: необязательно. Простой объект JavaScript, описывающий параметры предварительного просмотра перетаскивания
- варианты: необязательный, простой объект. Если некоторые реквизиты компонента не являются скалярными (т. е. не являются примитивными значениями или функциями), то arePropsEqual(props, otherProps), указав пользовательскую функцию внутри объекта параметров, может повысить производительность. Не беспокойтесь, если у вас нет проблем с производительностью.
- begin(monitor): необязательный, срабатывает при запуске операции перетаскивания. Ничего возвращать не нужно, но если возвращается объект, он переопределяет свойства по умолчанию спецификации элемента.
- end(item, monitor): необязательно, end будет вызываться при остановке перетаскивания.
- canDrag(монитор): необязательно. Используйте это, чтобы указать, разрешено ли в данный момент перетаскивание. Разрешено по умолчанию
- isDragging(монитор): необязательно. По умолчанию только источник перетаскивания, который инициирует операцию перетаскивания, считается перетаскиванием.
- собирать: необязательный, функция сбора.
3.4 оператор useDrop с размещенным источником
useDropХук для использования текущего компонента в качестве цели перетаскивания.
Параметры, возвращаемые useDrop:
- arguments[0]: объект, содержащий свойства, собранные функцией сбора. Если collect не определяет функцию, возвращается пустой объект.
- arguments[1]: функция соединителя источника перетаскивания. Это должно быть прикреплено к перетаскиваемой части DOM.
Затем параметры, переданные useDrag,
- принять: требуется. Строка, нотация ES6, массив одного из них или свойство функции, которое возвращает один из заданных компонентов. Эта цель перетаскивания будет реагировать только на элементы, созданные источниками перетаскивания указанного типа.
- варианты: опционально. обычный предмет. Если некоторые реквизиты компонента не являются скалярными (т. е. не являются примитивными значениями или функциями), то arePropsEqual(props, otherProps), указав пользовательскую функцию внутри объекта параметров, может повысить производительность. Не беспокойтесь, если у вас нет проблем с производительностью.
- падение (предмет, монитор): необязательно. Вызывается, когда на цель помещается совместимый предмет. Вы можете вернуть неопределенный или обычный объект. Если объект возвращается, он становится результатом перетаскивания и доступен методу endDrag monitor.getDropResult() в его источнике перетаскивания. Это полезно, если вы хотите выполнять разные действия в зависимости от того, какая цель была получена. Если у вас есть вложенные цели перетаскивания, вы можете проверить, обработала ли уже вложенная цель перетаскивание, проверив monitor.didDrop() и monitor.getDropResult(). И этот метод, и исходный метод endDrag являются хорошими местами для запуска действий Flux. Этот метод не будет вызываться, если функция canDrop() определена и возвращает false.
- наведение (элемент, монитор): необязательно. Вызывается при наведении элемента на компонент. Вы можете проверить monitor.isOver({ small: true }), чтобы проверить, произошло ли наведение курсора непосредственно над текущей целью или путем ее вложения. В отличие от drop() этот метод будет вызываться, даже если функция canDrop() определена и возвращает false. Вы можете проверить monitor.canDrop(), если это так.
- canDrop(предмет, монитор): необязательно. Используйте это, чтобы указать, может ли цель перетаскивания принять элемент. Если вы хотите всегда разрешать это, просто игнорируйте этот метод.
- собирать: необязательный, функция сбора.
3.5 Отображение эффекта
Как показано в приведенном выше коде, эффект, который может быть достигнут, показан на картинке gif ниже.
Полный демонстрационный пример:портал
В-четвертых, анализ исходного кода.
Из исходного кода я объясню отличные шаблоны и принципы проектирования в React-DnD.
4.1 Архитектура дизайна
Давайте сначала проанализируем его из исходного каталога.
разделен на три части
- backend Бэкэнд часть. (то есть операция dom конкретной сцены)
- ядро dnd-core.
- react-dnd инкапсулирует реагирующие плагины.
Таким образом, давайте начнем с API, используемого в приведенном выше примере, чтобы увидеть, как инкапсулируется исходный код, а затем медленно углубимся в ядро.
4.2 Исходный код DndProvider
Код в целом такойtypescriptнаписано. Давайте посмотрим на модули.
отDndProviderИз компонента видно, что ядро возвращает компонент DndContext. Как и другие компоненты контейнера, он инкапсулирует слойРеагировать на контекст, чтобы передать общее значение вниз. Это напоминает мне, что Provider Redux - это тот же шаблон проектирования.
(React.useEffect) Здесь также есть логика оптимизации, если глобальное обнаружение уже имеет экземпляр, то очищаем этот экземпляр.
Провайдер передает значение manager, а менеджер получается с помощью метода getDndContextValue.
Как показано в приведенном выше коде,getDndContextValueМетод создан на примере одного gacre, атрибут имеет backend (бэкэнд) Context, Options (бэкенд-опции), DebugMode.
Далее, чтобы проверить наше предположение, взглянем на код компонента DndContext.
действительно черезReact.createContextСоздайте контекст.
И создал экземпляр перетаскивания, который можно понимать как общий экземпляр, я буду использовать его позже.общий экземплярвместо этого имени
можно увидеть здесьdnd-coreОсновные компоненты, проанализированные из dnd-core, за исключениемDragDropManager (всего экземпляров),BackendFactory,createDragDropManager (создать общий экземпляр)
Исходный код dnd-core будет упомянут позже, но сначала мы объясним его подробно в соответствии с используемым API.
4.3 useDrag
useDragПеретащите источник. Когда вы используете useDrag выше, вы можете видеть, что возвращаются три параметра. Давайте посмотрим на функцию.
Три параметрарезультат, connectDragSource (соединитель источника перетаскивания), connectDragPreview (функция предварительного просмотра ссылки);
Давайте сначала поговорим о функции предварительного просмотра.Это API (ragPreviewImage), предоставляемый React-DnD для оптимизации процесса перетаскивания.Этот API описывается как:
Компонент, который визуализирует элементы HTML-изображения в виде сломанного предварительного просмотра перетаскивания.
Используйте демо как:
Эффект отображения:
Изображение головы лошади, отображаемое при перетаскивании выше,previewФункционал, предоставляемый модулем.
Давайте продолжим, в части useDrag мы вступим в контакт сconnectorМодуль коннектора, что такое коннектор, можно сначала представить как крючок шины данных. в приведенном выше коде черезuseDragSourceMonitorметод получен.
На картинке выше есть способ совмещения двух разных мест.Для удобства совместного просмотра видно, чтоuseDragSourceMonitorМетод возвращает два модуля, монитор (прослушивание), коннектор (коннектор, и получает данные бэкэнда manager.getBackend).
Экземпляр менеджера передается черезuseContextполучается, вышеProviderВсего внедренных экземпляров.
Чтобы мы могли это знать,dragSourceИсходный экземпляр перетаскивания получается через хук в коннекторе соединителя, а коннектор получается через внутренний экземпляр в общем экземпляре, переданном в sourceConnector в useDragSourceMonitor.
существуетsourceConnectorпрошедшийReact.Refпараметры полученыdragSourceRefто есть узлы DOM.
В то же время существует множество методов обработки частных границ, таких как:
Увидев здесь, некоторые люди могут заметить использование,reconnect, этот режим более интересен, перелинковка, каждый раз при обновлении данных хук ссылки должен быть переустановлен.Эта часть может быть упомянута в объяснении модуля dnd-core.Личное предположение, потому чтоdnd-coreмодуль используетredux.
Приведенный выше набор проходит через экземпляр drag source-backend-total.
4.4 useDrop
useDropПоместите исходник, или из используемого апи, функция возвращает два параметра, давайте посмотрим на метод.
Исходный код возвращает результат, connectDropTarget. Это то же самое, что и useDrag, за исключением того, что на один экземпляр предварительного просмотра меньше, и этот параметр не требуется для источника размещения.
connectDropTarget работает так же, как connectDragSource..
Открытый исходный код - серверная часть - общий экземпляр.
Далее мы продолжим углубленный анализ модуля исходного кода dnd-core.
4.5 DragDropManager
React-DnD использует данные, а не представления в качестве источника правды, и когда вы перетаскиваете что-то на экране, вы не перетаскиваете компоненты или узлы DOM. Вместо этого он имитирует предварительный просмотр данных, так что источник перетаскивания «перетаскивается». dnd-core официально ориентирован на данные, и React-DnD использует его для внутренних целей.Redux. Продолжаем анализ.
dnd-coreСамой важной частью основного модуля является общий экземпляр.Давайте посмотрим на функцию построения общего экземпляра.
где передается общий экземплярDragDropManagerImpl (класс реализации всего экземпляра)унаследовано и переданоdebugModeвыключатель.
Экземпляр бэкэнда Backedn создается фабрикой. Диспетчер экземпляров серверной части установки.
посмотриDragDropManagerImplЧасть исходного кода немного длинная, я хотел немного удалить, но это действительно суть.
Разделить сверху вниз.
makeStoreInstance, Создайте экземпляр Redux, вы должны увидеть его здесь, но вы должны знать принцип управления состоянием redux. Существует параметр debugMode, используемый для отладки избыточности, который передается при создании всего экземпляра.reduxDevToolsЭто расширение Google, и его необходимо установить отдельно.
DragDropManagerImplчерезDragDropManagerИнтерфейс строго наследуется.
Взгляните на конструктор в классе реализации
Во-первых, создайте экземпляр redux, чтобы получить хранилище и привязать его к свойству члена, унаследовать класс реализации прослушивания DragDropMonitorImpl, передать хранилище и передать класс реализации регистрации. Получите регистрационную информацию и привяжите ее к магазину. подпискаhandleRefCountChangeфункция.
подписалсяhandleRefCountChangeФункция выглядит следующим образом
Подсчет здесь — это общее количество раз, когда бэкэнд перетаскивает источник перетаскивания.
Далее процессactionsлогика и добавитьDragDropActions.
связыватьdispatchфункция-член
Таким образом, набор из трех частей Redux обрабатывается и может нормально работать.
Все остальные местоположения являются связанными функциями свойств-членов.
Продолжаем добавлятьDragDropActionsУглубленная логика, какие действия связаны? Давайте взглянем.
Видно, что связанные Действия имеют
- beginDrag (начать перетаскивание)
- publishDragSource (опубликовать текущий источник перетаскивания)
- парить (независимо от того, проходит ли он мимо)
- уронить
- EndDrag (задний конец)
Сфокусируйся наbeginDragмодуль.
Как можно заметитьbeginDragЭто в формате действия.
Среди них мы видим React-DnDуправляемый даннымиосновные концепцииКоординаты XYCoord, изменить метод координатsetClientOffset.
посмотриsetClientOffsetметод также является действием.
Координатный интерфейс (interface)
Подводя итог фрагментам, которые мы проанализировали выше,ReactDnDПозиция предварительного просмотра источника перетаскивания управляется через интерфейс в виде координат.Если предполагается, что он может упасть, то источник перетаскивания можно перемещать.
С пограничными функциями и большинством логических суждений он инкапсулирует основную логику dnd-core (управляемый данными).
Так где конкретно обрабатываются реализации и события перетаскивания?
4.6 backend
React DnD построен наAPI перетаскивания HTML5над. Это разумный вариант по умолчанию, так как он делает снимок экрана DOM-узла, который был перетащен, и использует его как «предварительный просмотр перетаскивания» из коробки. Удобно, что вам не нужно рисовать, пока курсор движется. Этот API также является единственным способом обработки событий удаления файлов.
К сожалению, API перетаскивания HTML5 также имеет некоторые недостатки. Он не работает на сенсорных экранах и предлагает меньше возможностей для настройки в IE, чем в других браузерах.
Вот почему вReact DnDПричины для реализации поддержки перетаскивания HTML5 подключаемым способом. Вы не должны использовать его. Вы можете написать другие реализации, основанные на событиях касания, событиях мыши или чем-то еще. Эта подключаемая реализация называется бэкендом в React DnD. Библиотека поставляется только с серверной частью HTML5, но в будущем может быть добавлено больше.
Бэкенды действуют как всеобъемлющая система событий React: они абстрагируются от различий браузеров и обрабатывают нативные события DOM. Несмотря на сходство, бэкэнд React DnD не зависит от React или его синтетической системы событий. За кулисами все бэкенды переводят события DOM во внутренние действия Redux, которые может обработать React DnD.
Шаблон проектирования серверной части предназначен для обработки описанных выше сценариев.React-DnDПоддержка настройкиbackend, если ваш бизнес-сценарий достаточно специфичен, вы можете сами написать бэкэнд.
Бэкэнд — это реализация события
5. КОНЕЦ
Существуют различные формы перетаскивания и бесконечные типы плагинов. Я вижу, что есть и искусственные колеса React-DnD, которые очень хороши. Если эта статья была вам полезна, ставьте лайк 👍 support~, Ваши лайки мотивируют меня продолжать творить~
Спасибо разработчикам, которые вносят свой вклад в проекты с открытым исходным кодом.
Рекомендуемые статьи из прошлого:
- «Поговорите о том, как повысить производительность команды с помощью интеллектуальной генерации кода пользовательского интерфейса»
- «Разработка программы в лотерее Jiugongge»
- «Как построить платформу захвата исключений | Воспроизведение сценария»
- «Как создать платформу захвата исключений|Статистика данных»