предисловие
всем привет! яlin.
Сегодня я хотел бы поделиться с вами об упаковочных компонентах. В процессе разработки бизнес-требований мы можем столкнуться с новым бизнес-требованием или с существующей функцией для итерации новых функций.
Очевидно, стоит подумать о том, как спроектировать новое значение бизнес-требований.
Точно так же стоит подумать о разработке и итерации на основе исходной функции.
Не простоcommand+cа такжеcommand+v!
Эта статья также представляет собой обзор, в котором кратко излагаются способы проектирования компонентов в соответствии с требованиями.
Резюме написать непросто.Если есть лучшие проекты и идеи, я с нетерпением жду встречи.
Потребности и мышление
Проект требований:
Когда я получил проект требований, я сначала прочитал егоelement-uiКаскадные компоненты не могут соответствовать бизнесу, и трансформироваться на этой основе довольно проблематично. Так что, в конце концов, я планирую сам инкапсулировать каскадный компонент.
Далее я думаю о функциях, которые должны быть реализованы в соответствии с требованиями, следующим образом:
1. Поддержка пользователей для выбора по категориям.
2. Помогите пользователям щелкнуть и выбрать, расширив категорию. (ps: при нажатии на первую панель все панели первого уровня ее дочерних узлов будут развернуты)
3. В состоянии инициализации все узлы в первой позиции первого узла будут расширены по умолчанию.
4. Поддержите положительный и отрицательный выбор узла.
5. Каждое окно поиска панели управляет поиском этой панели.
Как реализовать требование
После уточнения необходимых функций, которые необходимо реализовать, я думаю, что не стоит спешить с написанием кода, а нужно провести глубокий анализ и обдумать.
Я начинаю со структуры данных, которая представляет собой дерево. Что-то вроде этого:
const data=[
{
text: "指南",
id: 2,
children: [
{
text: "设计原则",
id: 2.1,
children: [
{
text: "导航1",
id: 2.112,
},
{
text: "导航2",
id: 2.113,
},
{
text: "导航3",
id: 2.114,
},
],
},
{
text: "设计原则2",
id: 2.2,
children: [
{
text: "导航2",
id: 2.21,
},
],
},
],
},
]
С таким древовидным форматом данных я могу сказать, что для его реализации требуется рекурсивный компонент.
Но теперь возникает ключевой вопрос, как шаблон отображает такой формат данных?
-
Решение 1: При проектировании этого рекурсивного компонента необходимо поместить все
nodeУзел рассматривается как рекурсивный компонент, такой как обходnodeузел, если естьchildrenатрибут, затем продолжайте рекурсию, пока не встретите узел, у которого нетchildrenимущество останавливается. Затем перейдите к следующему узлу... -
Вариант 2: разделить рекурсивный компонент на левую и правую панели и сначала пройти тот же уровень с левой стороны.
nodeУзел, рендеринг данных справа осуществляется путем выбора предыдущего уровняnodeузел для управления следующим уровнемnodeузел. (пс: тот же уровеньnodeобход узла)
На самом деле это можно резюмировать следующим образом: вам нужен обход в глубину или обход в ширину? (пс: оставьте вопрос по окончательному плану, который будет описан ниже...)
Компоненты дизайна
Вот через рекурсивный компонентCascaderItemи поисковый фильтрfilterItemкомпонент и родительский компонентCascaderдля выполнения требования.
Начните с макета
Компоновка компонента Draft — левая и правая панели, я разработал этот компонент с помощьюflexМакет, в итоге я использовал Сценарий 2 для итерации рендеринга данных.
Схема 1 не имеет проблем с реализацией функций, но будут определенные дефекты компоновки, т.к. схема 1 основана наnodeУзел действует как панель.
Шаблон компонента для схемы 2:
leftПанель представляет собой циклический обход одноуровневых узлов,rightДело в том, что сам компонент ссылается сам на себя, а затем становится рекурсивным компонентом.
Дизайн свойств компонента
Дизайн свойств этого компонента, я передаюpropsсвойства передаются.
рекурсивный компонентCascaderItemСвойства:options,level(ps: указывает, какой уровень в настоящее время),changeValToStr,isCheckbox,isInput,reverseChoice
в то время как родительский компонентCascaderВ дополнение к вышеперечисленным свойствам существуют:filterable,value(ps: двухсторонняя привязка, описанная ниже),iptProps.
Конкретное значение каждого атрибута можно посмотреть в комментариях к исходному коду, которые здесь описываться не будут...
Идеи реализации рекурсивного компонента
Вот через вычисляемое свойствоshowRightItemКонтролировать, нужно ли отображать панель скрытых дочерних узлов (ps: условие для рекурсивного завершения). И это вычисляемое свойство зависит от реактивных данныхselectedмассив (ps: выбранные узлы). Судя по тому, имеет ли выбранный узел на этом уровнеchildrenсвойства для управленияshowRightItemвозвращаемое значение.
этоselectedчерез родительский компонентCascaderпередается дочерним компонентамCascaderItem. здесь я прохожуselected.syncпередать атрибут, и когда пользователь нажимаетnodeможет срабатывать, когда узелupdate:selectedСобытия вызывают изменение данных родительского компонента.
зафиксировать поведение пользователя
когда пользователь нажимаетnode, а не только для запускаupdate:selectedмероприятие. Чтобы обработать некоторую дополнительную логику в этой функции действия пользователя. После завершения всей логики инициируйте событие, чтобы уведомить родительский компонент.
Логика здесь следующая:
1. Определите, является ли клик пользователя положительным или отрицательным.
2. ОперацияselectedМассив, данные узла следующего уровня этого узла уровня удаляются. Поскольку узел верхнего уровня переключается, узел нижнего уровня будет удален для достижения того же эффекта переключения представлений данных.
3. Имеет ли выбранный узел на этом уровнеchildrenатрибут, если он есть, он должен быть первым битом подчиненногоpushприбытьselectedмассив, пока первый бит подчиненного не будет иметь ни одногоchildrenимущество до.
Когда пользователь выполняет поиск на каждом уровне, срабатывает триггер.inputмероприятие.要在这个用户行为上做当前级下的数据过滤。
При поиске данных под текущим уровнем данные панели следующего уровня непредсказуемы. Чтобы решить проблему, данные искомого родительского узла не связаны с данными текущей дочерней панели (ps: она также может оставаться на данных дочернего узла предыдущего узла), что сбивает пользователя с толку.
Это управляется переключателем, который скрывает следующую панель, пока пользователь выполняет поиск. Подождите, пока пользователь решит, на что ориентироваться в поиске, прежде чем расширяться.
Что ж, на этом общая логика рекурсивного компонента завершена. Конкретная реализация может просматривать исходный код...
Идея реализации родительского компонента
Родительский компонент — это компонент, доступный пользователю. Это похоже на общий пул для распределения задач по разным подкомпонентам. Вот от пользователяfilterableсвойство, чтобы определить, использовать ли рекурсивные компонентыCascaderItemещеfilterItemкомпоненты.
Придерживаясь идеи высокой сплоченности и низкой связанности, компоненты подвергаются воздействию внешнего мира.onChangeсобытия иv-modelАтрибуты.
Запускается при изменении выбранного узлаonChangeмероприятие.v-modelАтрибут реализует двустороннюю привязку данных с внутренним запускомinputСобытия своевременно обновляют пользовательские данные.
Родительский компонент аналогичен общему пулу, он также отвечает за обработку некоторых данных. Основная логика здесь следующая:
1. Инициализировать данные, добавить данные древовидной структурыpathObjа такжеcheckedАтрибуты. (пс:pathObjАтрибуты используются для записи отношений между верхними и нижними узлами.checkedЭто свойство для рекурсивных компонентовcheckboxРамка)
2. Выровняйте данные дерева, чтобы предоставить полные данные для поиска.
3. ИнициализацияselectedМассив, инициализированный в соответствии со значением, переданным пользователемselectedданные.
Как реализовать конкретную логику обработки данных, чтобы просмотреть исходный код и комментарии к исходному коду...
Использование каскада
Как показано ниже:
Изначально хотел записать небольшое видео работы компонентов, но к сожалению до сих пор не знаю какой именно софт 😢 ̄□ ̄||(пс: больше из-за лени 😝) Загрузите исходный код, чтобы испытать его на себе~
Адрес источника
Рассмотрение
Выполнить бизнес-требование несложно, и может быть много способов выполнить его. Я думаю, что это больше касается размышлений во время разработки, и то, как проектировать, является важной частью написания кода в начале.
При разработке этого компонента произошла небольшая коллизия эпизода с небольшим партнером: необоснованны ли выбранные пользователем данные узла?
Как понять это? Компоненты разработки, как я понимаю, предназначены для работы пользователей.Соответствуют ли данные выбранного узла бизнес-требованиям, я думаю, это проблема бизнес-логики на другом уровне, и следует принять другое суждение и принять другое правило инкапсуляции. (ps: я думаю, что у каждого есть свое понимание и идеи~)
Недостаток: в настоящее время поддерживается только функция одиночного выбора, и компонент также может разрабатывать функцию множественного выбора (ps: в будущем будет время для итерации, так что следите за обновлениями...)
Командная работа не избавит вас от необходимости реализовывать новые функции на основе чужого кода. Расскажите об итерации новых требований на основе существующих функций. Как вы практикуете это каждый день?
Суммировать
В процессе разработки я все еще чувствую, что необходимо инкапсулировать компоненты дизайна компонентов, чтобы добавить разные цвета в управление проектом и последующие итерации.
Это краткоеlinРезюме последней статьи год назад, если это поможет крупным друзьям копать, я надеюсь наградить звездой ~
Наконец, я заранее желаю всем счастливого Нового года и всего наилучшего в новом году~