предисловие
Как реализовать таблицу, которая может сворачивать и разворачивать дочерние узлы таблицы? Давайте посмотрим на окончательную диаграмму эффектов:
На самом деле, этот проект был загружен в вышеупомянутом два месяца назад.github, но подробного процесса реализации на тот момент не было написано. Технический пост, который я опубликовал несколько дней назадКогда данные выпадающего списка слишком велики, как с этим бороться?Получите большую поддержку от всех, как и слова в песне «Красное солнышко».Как огонь красного солнца, зажги настоящего меня.~ Так что продолжайте посвящать свою незначительную силу сообществу Nuggets ~~
Слушать привет песни и писать тексты на выходных по-прежнему очень приятно~ привет~~
- адрес проекта::портал исходного кода
- demo:демо-портал
- Кстати:Зачем переупаковывать AJAX?
стек технологий:
- vue
- javascript
руки вверх
Подготовьте предварительный просмотр каталога планов для заинтересованных студентов. Чтобы не дать студентам быть очарованными, пусть план будет для васуказать путь вперед!
Предварительный просмотр схемы
- четкие потребности
- подготовка данных древовидной структуры
- выравнивание данных(акцент)
- Иерархический дисплей
- Свернуть и развернуть реализацию функции
1. Определите потребности
Реализуйте сворачиваемую и расширяемую таблицу, что выглядит очень запутанно. Но это на самом деле:
- существуетtableнажмите здесьПодмножествопровестиСпрятатьилипоказывать
- Выражайте иерархические отношения с помощью отступов расстояний
Многие вещи в коде на самом деле замаскированы, например, эта бесконечно сворачиваемая таблица, которую мы хотим реализовать. Но когда пользователь работает с ним, похоже, так оно и есть~~
2. Подготовка данных древовидной структуры
Данные в древовидной структуре были подготовлены здесь и сохранены вdata.jsфайл, узел проходит черезChildren
соединять. Как следует из названия, его можно сворачивать бесконечно, независимо от того, сколько существует уровней данных дерева, это можно сделать правильно. Давайте сначала поговорим об этом, а потом посмотрим, как это реализовать.
3. Сведение данных
Состояние расчесывания
Свести данные с древовидной структурой несложно, но трудность заключается в обработке, которая должна быть выполнена при сведении данных. Вот более пристальный взгляд:
- Мы называем все родительские узлы узла дерева какfamily, например, нам нужно знать своих больших лидеров, вторых лидеров, прямых лидеров... потому что мы должны выполнять их приказы. В этой форме, когда родительский узел или вышестоящий узел-предок отдает приказ, разумный дочерний узел, конечно, должен быть послушным.
__family
Поля — это массивы, используемые для хранения всех родительских узлов. Сглаженные данные выполняются черезполе массива__family
собрать всеродительский узел. Таким образом, как в генеалогическом древе, все родительские узлы узла четко известны.Что касается термоусадочной пленки Ruhe?мы проезжаемfoldList
массив для записисвернутый узел, также известен каксписок смертников. Таким образом, покаВключить идентификатор родительского узлаизузелПросто послушно спрячьте это.
- Каждый член должен быть уникальным, поэтому мы должны добавить уникальный идентификатор для каждого члена при обходе.
__identity
. Именно то, что было сказано на предыдущем шагефлаг узла.
- Чтобы четко знать иерархическую связь между каждым узлом, передайте
__level
Четкая иерархия. Затем мы оговариваем__level
Чем меньше значение, тем выше уровень.__level=0
Представляет узел первого уровня.
- Поскольку это бесконечный уровень, он должен быть реализован с рекурсией.
formatConversion()
Метод реализует рекурсию.Когда выпрыгнуть из рекурсии текущего обхода?? Когда текущий узел не имеет подмножестваChildren.length = 0
Когда выпрыгнете из этой рекурсии, перейдите к следующей рекурсии. Этот метод может занять некоторое время, чтобы понять. Комментарии в коде были подробно написаны. Если у вас есть какие-либо вопросы, пожалуйста, оставьте сообщение для связи~~
выравнивание данных
/*********************************
** Fn: formatConversion
** Intro: 将树形接口数据扁平化
** @params: parent 为当前累计的数组 也是最后返回的数组
** @params: children 为当前节点仍需继续扁平子节点的数据
** @params: index 默认等于0, 用于在递归中进行累计叠加 用于层级标识
** @params: family 装有当前包含元素自身的所有父级 身份标识
** @params: elderIdentity 父级的 唯一身份标识
** Author: zyx
*********************************/
formatConversion (parent, children, index = 0, family = [], elderIdentity = 'x') {
// children如果长度等于0,则代表已经到了最低层
// let page = (this.startPage - 1) * 10
if (children.length > 0) {
children.map((x, i) => {
// 设置 __level 标志位 用于展示区分层级
Vue.set(x, '__level', index)
// 设置 __family 为家族关系 为所有父级,包含本身在内
Vue.set(x, '__family', [...family, elderIdentity + '_' + i])
// 本身的唯一标识 可以理解为个人的身份证咯 一定唯一。
Vue.set(x, '__identity', elderIdentity + '_' + i)
parent.push(x)
// 如果仍有子集,则进行递归
if (x.Children.length > 0) this.formatConversion(parent, x.Children, index + 1, [...family, elderIdentity + '_' + i], elderIdentity + '_' + i)
})
} return parent
}
Сравним данные для плоских слов
- необработанные данные
- Сведенные данные
До и после сравнения данных сначала проясните (родительский узел:
Name: "App"
), (дочерние узлы:Name: "企业查询"
). Давайте сначала посмотрим на поле __level, которое соответствует 0 и 1 соответственно, без проблем.__family
Содержит собственный узел.__identity
Форматпрефикс хдобавить вместо в данных. например узелAppПозиция в данных — это первый узел, который соответствует__identity
то естьx_0
.Запрос предприятияродыAppпервый элемент под узлом,Затем добавьте 0 к идентификатору родительского узла., что соответствует__identity
то естьx_0_0
. Другие следуют и так далее. Все готово~~
4. Иерархическое отображение
как показано на рисунке:
Как насчет уровней отображения? Это может быть достигнуто с помощью css- Подготовка значка шрифта: Давайте добавим сюда точку. Здесь задействованы два значка шрифта. На рисунке отмечена красная рамка. Ресурсы хранятся в каталоге iconfont в каталоге src.Не показывать значок, когда вам не нужно отображать значок при выравнивании нижнего поля.,Как судить?Судя по тому, есть ли у текущего узла подмножество
params.Children.length === 0
можно судить. Если нет подмножества, нельзя установить значок шрифта.при нажатиитакже нужноЗначок для переключения, как этого можно добиться? упоминается на стойке регистрациисписок смертниковfoldList
, если он есть в списке, значит данные свернуты, то верните значок сворачивания. В противном случае верните значок расширения. Например, код:
// html
<i :class="toggleFoldingClass(scope.row)"></i>
// js methods:
/*********************************
** Fn: toggleFoldingClass
** Intro: 如果子集长度为0,则不返回字体图标。
** Intro: 如果子集长度为不为0,根据foldList是否存在当前节点的标识返回相应的折叠或展开图标
** Intro: 关于class说明:permission_placeholder返回一个占位符,具体查看class
** @params: params 当前行的数据对象
** Author: zyx
*********************************/
toggleFoldingClass (params) {
return params.Children.length === 0 ? 'permission_placeholder' : (this.foldList.indexOf(params.__identity) === -1 ? 'iconfont icon-minus-square-o' : 'iconfont icon-plussquareo')
},
- Иерархическое отображение:
__level
Здесь в игру вступают поля.__level
Чем больше значение, темmargin-left
значение увеличивается. Например, код:
<p :style="`margin-left: ${scope.row.__level * 20}px;`">...
Базовый вид уже есть, а дальше реализована функция щелчка.
5. Реализация функции складывания и раскладывания
Запишите идентификатор узла клика
пройти черезсписок смертниковfoldList
для записи кликов. Событие щелчка срабатывает при нажатии свернутого значка развертывания.toggleFoldingStatus(scope.row)
события, как упоминалось ранее,foldList
Существующие флаги скрыты для всех дочерних узлов. еслиfoldList
Если данных нет, то все развернется и все будет хорошо. Код такой, как показано, он такой простой.
// html
<i @click="toggleFoldingStatus(scope.row)" class="permission_toggleFold" :class="toggleFoldingClass(scope.row)"></i>
// js methods
/*********************************
** Fn: toggleFoldingStatus
** Intro: 切换展开 还是折叠
** @params: params 当前点击行的数据
** Author: zyx
*********************************/
toggleFoldingStatus (params) {
this.foldList.includes(params.__identity) ? this.foldList.splice(this.foldList.indexOf(params.__identity), 1) : this.foldList.push(params.__identity)
},
Свернуть и развернуть реализацию функции
Все готово, кроме возможности. Последнее, что нужно сделать, этосписок смертниковfoldList
для отображения и скрытия данных.
Вот с помощью эл-таблицыrow-style
выполнить. Студенты также могут реализовать свои собственные. Посмотрите официальное объяснение
/*********************************
** Fn: toggleDisplayTr
** Intro: 该方法会对每一行数据都做判断 如果foldList 列表中的元素 也存在与当前行的 __family列表中 则该行不展示
** @params:
** Author: zyx
*********************************/
toggleDisplayTr ({row, index}) {
for (let i = 0; i < this.foldList.length; i++) {
let item = this.foldList[i]
// 如果foldList中元素存在于 row.__family中,则该行隐藏。 如果该行的自身标识等于隐藏元素,则代表该元素就是折叠点
if (row.__family.includes(item) && row.__identity !== item) return 'display:none;'
}
return ''
},
- Посмотрим на эффект
глазурь на торте
Если данных слишком много, искать на одном уровне очень проблематично, поэтому добавим еще две кнопкисвернуть всеа такжеРасширить всеОтлично.
Консультация и анализ, на самом деле, эта функция очень проста. или о вышеупомянутомсписок смертниковfoldList
.
-
Расширить все: если
foldList
Если он пустой, все будет хорошо и все данные будут расширены. -
свернуть все: Наш дизайн заключается в том, чтобы скрывать, пока все узлы, содержащие этот флаг, существуют в списке смерти. Затем просто добавьте в него все узлы первого уровня.
this.foldList = this.tableListData.map(x => x.__identity)
То есть выносится идентификатор узла первого уровня.
Эпилог
Более сложное требование — совместить пагинацию: при возврате на предыдущую страницу с другой страницы все равно должно сохраняться свернутое состояние предыдущей страницы. Здесь это не объясняется, потому что сценариев применения немного.
- Ставьте лайки и подбадривайте~
- Снова 3 часа дня и пора возвращаться на обед.
- Уведомление об авторских правах: Эта статья была впервые опубликована в Nuggets, если вам нужно перепечатать, пожалуйста, укажите источник.