предисловие
Как реализовать таблицу, которая может сворачивать и разворачивать дочерние узлы таблицы? Давайте посмотрим на окончательную диаграмму эффектов:
На самом деле, этот проект был загружен в вышеупомянутом два месяца назад.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. Иерархическое отображение
как показано на рисунке:
- Подготовка значка шрифта: Давайте добавим сюда точку. Здесь задействованы два значка шрифта. На рисунке отмечена красная рамка. Ресурсы хранятся в каталоге 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, если вам нужно перепечатать, пожалуйста, укажите источник.