Нажмите на меня, чтобы ознакомиться с демо-версией онлайн (для просмотра используйте компьютер)
Протестировано на компьютере Apple, в браузере Chrome нет заикания, другие браузеры не тестировались, если вы столкнулись с заиканием, обратите внимание на систему и браузер, чтобы облегчить мою последующую оптимизацию, спасибо
Первый взгляд на эффект, всего1000 X 100 = 10WКаждая ячейка в основном не застревает, и каждую ячейку можно редактировать, щелкнув по ней, поддерживая фиксированные заголовки и фиксированные столбцы.
Исходный код проекта на гитхабедумаю, ты можешьStarПожалуйста, дайте мне знать, если у вас есть какие-либо вопросы, спасибо
Решите суть проблемы: в соответствии с видимой областью загрузка горизонтальной прокрутки, загрузка вертикальной прокрутки, контроль количества dom
Предыстория проекта
В настоящее время автор работает над функцией планирования рекламы, которую необходимо зарезервировать. Для крупных контрактов может потребоваться планирование нескольких ресурсов, а цикл может составлять несколько лет. Тогда наше взаимодействие со страницей выглядит следующим образом.
30 месяцев поперечных ячеек, самые 3 года, 36 месяцев, в каждом ряду 36*30=1080 ячеек
Ресурсов по вертикали 100, всего около ️10Вт ячеек, а дальше будет поле ввода и общий инвентарь в каждой ячейке, так что общее количество 20Вт, использование интранета, запрос интерфейса не проблема на все, это может рендерить браузер, я терпеть не могу, и после того, как интерфейс вернется, будет белый экран на десятки секунд, и вся страница застрянет.
Это не говоря уже о том, что работа со страницей также очень сильно зависает после загрузки, скользящая задержка серьезна, и страница в основном парализована.
Предыдущая функция была разработана на основе jquery.Vue и пользовательский интерфейс, используемые для реконструкции проекта, используют ElementUI.Таблица в ElmentUI имеет серьезные проблемы с производительностью, когда объем данных велик.Самая непосредственная производительность заключается в том, что время белого экрана долгое, и это будет нарушение рендеринга
Поэтому я подумал о том, чтобы самостоятельно реализовать форму, чтобы решить проблему застревания.
Реализовать идеи
Таблица разделена, динамически загружается
Таблица разделена по месяцам по горизонтали, каждый месяц имеет отдельную таблицу, а заполнитель div помещается вне таблицы месяцев для управления отображением в соответствии с положением горизонтальной прокрутки.
Вертикальное разделение по ресурсам, также оберните div-заполнитель, динамически загружайте в соответствии с положением прокрутки и всегда держите количество dom в сети.
Динамическое редактирование, создание полей ввода по запросу
Разные теги имеют разную производительность при рендеринге в браузере, например, тег input намного тяжелее, чем span и другие теги, поэтому его нельзя вводить на весь экран.
Решение состоит в том, чтобы щелкнуть ячейку, чтобы отобразить поле ввода, фокус теряется и удаляется, отображение здесь не является элементом управления отображением, а v-if контролирует, загружен ли дом.
декомпозиция кода
железы
<div class="table-head">
<div class="module"
v-bind:style="{ transform: 'translateX(' + scrollLeft + 'px)' }"
v-for="(item, index) in monthData" v-bind:key="index">
<table cellspacing="0" cellpadding="0">
<thead>
<tr>
<td colspan="30">{{item.month}}</td>
</tr>
<tr>
<td width="100"
v-for="(d_item, d_index) in item.days" v-bind:key="d_index"
style="min-width:100px">{{d_item}}</td>
</tr>
</thead>
</table>
</div>
</div>
фиксированный столбец
<div class="table-fix-cloumns">
<div class="module fix-left-top">
<table width="100" cellspacing="0" cellpadding="0">
<thead>
<tr>
<td>位置</td>
</tr>
<tr>
<td>position</td>
</tr>
</thead>
</table>
</div>
<div class="module" v-bind:style="{ transform: 'translateY(' + scrollTop + 'px)' }">
<table width="100" cellspacing="0" cellpadding="0">
<thead>
<tr v-for="(item, index) in projectData" v-bind:key="index">
<td>{{item.name}}</td>
</tr>
</thead>
</table>
</div>
</div>
тело
<div class="table-body" @scroll="tableScroll" style="height: 300px">
<div class="module"
style="width:3000px;"
v-for="(item, index) in monthData" v-bind:key="index">
<div class="content"
v-if="Math.abs(index - curModule) < 3">
<div class="row"
style="height:30px"
v-for="(p_item, p_index) in projectData"
v-bind:key="p_index">
<table width="3000"
v-if="Math.abs(p_index - curRow) < 20"
cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td
@click="clickTd(p_index,item.month, d_item, $event)"
v-for="(d_item, d_index) in item.days" v-bind:key="d_index">
<span v-if="!originProjectData[p_index][''+item.month][''+d_item]['show']">{{originProjectData[p_index][''+item.month][''+d_item]['last']}}</span>
<input
@blur="blurTd(p_index,item.month, d_item)"
v-if="originProjectData[p_index][''+item.month][''+d_item]['show']"
v-model="originProjectData[p_index][''+item.month][''+d_item]['last']"
v-focus="originProjectData[p_index][''+item.month][''+d_item]['focus']"/>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
После вышеописанной оптимизации проблема с зависанием стола прекрасно решена, но я не стал инкапсулировать компоненты по следующим причинам
·插件封装后会有很多限制,不能再用vue那种模板写法,用json传入数据,自定义内容不是很灵活
·可以根据自己的应用场景自行修改拓展,代码已经很简洁
·比较懒