Реализация динамической организационной схемы на основе Vue

внешний интерфейс Командная строка Vue.js jQuery
Реализация динамической организационной схемы на основе Vue

Vue-Tree-Chart

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

Щелкнув по узлу, вы откроете меню операций для реализации таких операций, как добавление, удаление, изменение и проверка.После просмотра онлайн-информации было обнаружено, что существующие случаи в основном основаны наorgchartРеализован этот плагин jQuery.Наш проект основан на Vue.Мы не хотим внедрять jQuery из-за этой функции, поэтому реализована упрощенная версия компонента древовидной диаграммы/организационной диаграммы на основе Vue:Vue-Tree-Chart.

Vue-Tree-ChartОн реализовал динамическое рисование основной организационной диаграммы и обратный вызов узла щелчка.Основываясь на этих двух точках, он уже может удовлетворить большинство связанных потребностей.Например, динамическое добавление, удаление и изменение внешнего интерфейса - это не что иное, как редактирование данных компонента.Использование Интерфейс функций Vue, управляемый данными, будет автоматически обновляться, проще добавлять, удалять и изменять сервер. Интерфейсу нужно только запросить рабочий интерфейс, и после завершения операции последние данные могут быть извлечены и синхронизированы с стиль компонента удобно настраивать, что касается менее распространенных требований, таких как перетаскивание, масштабирование и экспорт, компоненты не являются встроенными, но реализовать эти расширения на основе исходного кода относительно просто.

Как нарисовать структурную схему

ненадежные идеи

После того, как я получил это требование, первая идея, которую я подумал, состояла в том, чтобы реализовать DIV layout + JS динамический расчет.Если не учитывать соединение узла, эта идея едва справится с этим.Реализация примерно разделена на три этапа:

1. Разделите данные по «поколению»

Формат необработанных данных может быть только глубоким объектом JSON:

{
    name: 'root',
    children: [{
        name: 'child',
        children: [{
            name: 'grandchild',
            ...
        }]
    }]
}

После разбиения по «поколению» получается так:

[
    [{
        id: 0,
        name: 'root
    }],
    [{
        id: 1,
        name: 'child',
        pid: 0
    }],
    [{
        id: 2
        name: 'grandchild',
        pid: 1
    }]
]

Чтобы немного визуализировать, я хочу на самом деле эту структуру:

2. Нарисуйте узлы по «поколению»

С данными на предыдущем шаге не так просто сгенерировать узлы каждого поколения сверху вниз, а затем центрировать их, древовидная структура в основном отсутствует:

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

3. Рассчитайте расстояние между узлами

Нам нужен вот этот эффект:

Наблюдая за графом, мы видим, что за исключением узла первого поколения, который всегда находится в центре, пространство, занимаемое другими узлами, должно быть равно пространству, занимаемому узлами-потомками, поэтому нам нужно пройти от узла последнего поколения и получить пространство, которое должен занимать родительский узел, чтобы вычислить его потребность вокругmarinзначение, чтобы применить правильное значение ко всем узлам, которые содержат дочерние элементыmarginПосле этого вы должны получить эффект изображения выше.

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

Волшебное использование стола

Позже, обратившись к реализации orgchart, откройте инструмент отладки и посмотрите, почему в нем так много<table>Метка, я подумал что это за хитрая операция, а потом внимательно изучил структуру метки DEMO.Оказалось, что orgchart очень ловко использовал характеристики метки Таблицы.Пока Таблица правильно вложена, браузер будет естественным образом отображать нужные нам результаты.

Давайте добавим сюда базовые знания о таблицах. В эпоху, когда DIV + CSS только стал популярным, макет таблицы коллективно отвергался всеми внешними интерфейсами из-за медленного рендеринга и избыточного кода. Ввод тега, который влияет на его собственный размер, если вы загружаете Полностраничная таблица в соответствии с обычной логикой рендеринга страницы, страница будет часто перерисовываться с загрузкой тега TD.Чтобы избежать этого, браузер будет использовать специальную таблицу для таблицы.Логика отрисовки - ждать для загрузки всего тега Table, а затем снова нарисуйте его на странице. Результатом этого является то, что, когда страница полностью использует макет таблицы, весь процесс загрузки страницы пуст. После загрузки страницы она внезапно появится в один момент времени. Это очень плохой пользовательский интерфейс в случае слабая сеть.Поэтому табличный макет не используется.Самые основные требования для front-end разработки.

Хотя эта функция Table не подходит для макета, она делает Table «самым мощным» тегом в HTML. Например, идея реализации плагина дерева, который мы прочесали ранее, на самом деле является пародией на возможности Table. Отношение организационной структуры -генерации может быть прекрасно реализовано только с помощью тега Table, и даже CSS не требуется:

<table>
    <tr>
        <td colspan="2">
            root
        </td/>
    </tr>
    <tr>
        <td>
            <table>
                <tr>
                    <td>
                        children1
                    </td>
                    <td>
                        <table>
                            <tr>
                                <td colspan="2">
                                    children2
                                </td>
                            </tr>
                            <tr>
                                <td>
                                    grandchild1
                                </td>
                                <td>
                                    grandchild2
                                </td>
                            </tr>
                        </table>
                    </td>
                </tr>
            </table>
        </td>
    </tr>
</table>

Хотя структура многословна, она соответствует требованиям.

Реализация соединения узла также использует адаптируемость таблицы, но реализация более тонкая:

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

Сначала сгенерируйте метки TD в соответствии с количеством дочерних узлов X2, затем «rightLine» и «leftLine» поочередно добавляют классы к каждому TD, «rightLine» показывает правую линию 1px для TD, «leftLine» показывает 1px левую строку для TD, шесть Линии справа и слева объединяются вместе, чтобы сформировать три вертикальные линии по 2 пикселя, соединяющие середину каждого дочернего узла; затем, кроме первого и последнего тегов TD, добавьте класс «topLine» и добавьте к ним 2 пикселя Верхняя линия ТР покажет горизонтальную линию, которая просто соединяет три вертикальные линии, а затем добавит центральную вертикальную линию первой линии ТУ, и будет реализована связь между верхним и нижним уровнями.

Когда я увидел эту часть, я почувствовал, что мой IQ в любом случае сокрушается.

На основе этой идеи он был реализован с помощью Vue, а после стал самостоятельным компонентом.весь файлВ коде всего около ста строк.

Кроме того, действительно важно учиться и применять знания.Знания в этом надо осваивать на начальном уровне фронтенда, но я вообще не задумывался об этой идее при разработке.Возможно это связано с тяжелым опора на js в работе в последние годы.Чувствительность CSS снижена. Людям свойственно всегда использовать свои привычные способы решения проблем, но это определенно не очень хорошая привычка для разработчиков и должна быть отражена.

Вторичное развитие

Vue-Tree-Chart опубликован в npm и может быть добавлен в проект по умолчанию через инструмент управления пакетами:

npm i vue-tree-chart --save

Но npm устанавливает скомпилированную версию.Если вы хотите сделать вторичную разработку в проекте более гибко, вы можете напрямую'lib/components/TreeChart.vue'файлы загружаются в каталог компонентов проекта ('src/components/'), непосредственно изменяяTreeChart.vueфайл в порядке.

библиотека сборки vue-cli 3.0

Наконец, давайте упомянем vue-cli 3.0.построить цельФункция, чтобы облегчить разработчиков компонентов, vue-cli 3.0 предоставляет два отдельных режима сборки для компонентов библиотеки и веб-компонентов в дополнение к обычным сборкам.Теперь при разработке плагинов/компонентов Vue больше не нужно вручную изменять конфигурацию веб-пакета, если как входящая команда сборкиtarget\name\entry, вы можете автоматически скомпилировать входной файл в библиотеку и вывести ряд файлов, необходимых для CommonJS и среды браузера.

Например, файл package.json Vue-Tree-Chart:

"main": "./dist/TreeChart.common.js",
"scripts": {
    "build-bundle": "vue-cli-service build --target lib --name TreeChart ./lib/index.js",
    ...

воплощать в жизньnpm run build-bundleбудет в'/dist'В каталоге создается ряд выходных файлов, среди которых"TreeChart.common.js"Требуется ли пакет CommonJS в среде веб-пакета, настройте этот файл как'main', вы можете использовать его в своем проекте следующим образом:

import TreeChart from "vue-tree-chart";

Импортированный объект TreeChart представляет собой компонент Vue, который можно смонтировать и использовать как глобальный или локальный компонент.

прикрепил

Адрес проекта Vue-Tree-Chart:GitHub.com/tower1229/V…

Оригиналы технических статей по передовой дороге, просьба указывать источник для перепечатки:уточненный-маленький.com/2018/08/03/…