Введение
Недавно я относительно бездействовал, и закулиса компании захотела пересмотреть текущую систему управления закулисой, сказав, что предыдущая слишком уродлива, и пользоваться ею непросто, а потом кинула мне ссылку на ant-design- pro, говоря, что это довольно хорошо, глядя на него.
Я тогда подумал про себя, в вашем java проекте замешан предыдущий проект, который похож на обычные jsp страницы, это много сразу файлов css и js, и мне страшно на это смотреть (ну я признаться, что я на самом деле не решаюсь на это смотреть), странно, что он может быстро загружаться. ant-design изначально был разработан для реакции, и ant-design-pro тоже использует реакцию, должен сказать, что этот интерфейс выглядит очень удобным.
Посмотрел официальную документацию ant-design-pro, и кажется, что она почти такая же, как если бы я ее не читал? ? ? Забудем, давайте просто посмотрим на код, разберемся с идеями и вообще поймем, кроме react + react-router управление состоянием использует dva, проблема асинхронности редукса решена, или начать писать напрямую page?
Подождите, кажется, я что-то пропустил? О, да, давайте сначала посмотрим на размер упакованных файлов, у меня сердце холодеет, когда я его упаковываю, самый большой js имеет более 900 КБ, а исходные файлы ant-design действительно большие. Я могу писать код только для реакции, но мне немного неловко его упаковывать и оптимизировать. В это время я думал о пропускной способности компании в 1 м и технических возможностях этих бэкендов, иначе стоит ли отказываться от этого стека технологий? не могу рассчитывать наЗаголовок запроса, CORS немного более продвинут для переноса файлов cookie, статический сервер nginxЛюди, которые этого не понимают, сделайте мне статический сервер, а затем, кстати, включите gzip? Забудьте об этом, ищите фоновый шаблон vue + element-ui и находите его без особых усилий.vue-element-admin.
Vue-element-admin можно использовать, но интерфейс не соответствует моей идеальной ситуации, поэтому я немного изменил его для ant-design-pro, и страница списка, вероятно, выглядит следующим образом. Данные списка должны быть разбиты на страницы.Обычная страница списка имеет только один стек страниц, то есть, когда пользователь щелкает резервную адресную строку адресной строки, он вернется к предыдущему стеку страниц вместо данных предыдущая страница, что не соответствует привычкам пользователей. Верно? Ведь традиционные сайты могут вернуться на предыдущую страницу. Ну, без лишних слов, давайте к делу.
Шаг 1. Измените адресную строку
Предполагая, что путь к странице списка — /user/list, параметры, относящиеся к пейджингу,{ page: 1, pagesize: 10 }, При переходе с других страниц наш путь обычно не содержит никаких параметров, а последующие данные списка меняются в зависимости от страницы и размера страницы.Когда компонент keep-alive cache не используется, каждый раз Вход на страницу списка эквивалентно вводу в первый раз, то есть каждый раз можно получить только данные первой страницы.
Поскольку данные списка изменяются по странице и размеру страницы, почему бы не получить страницу и размер страницы непосредственно из адресной строки и не назначить их? Так код для изменения адресной строки пишется прямо на текущей странице илиНезависимый как компонент пагинацииШерстяная ткань? С точки зрения повторного использования лучше быть независимым, ведь другие страницы тоже могут его использовать, нельзя каждый раз копировать и вставлять, какой смысл в компонентизации? Конечно, это не означает, что этот пользовательский компонент пейджинга должен использоваться для пейджинга.главная страница (слой без маски, на некоторых страницах будет отображаться подсписок, когда слой маски щелкнут по строке данных. В этом случае можно использовать компонент подкачки element-ui.) Он используется, когда требуется разбиение по страницам.
При изменении адресной строки мы не хотим, чтобы существовал стек страниц без параметров подкачки, в этом случае заменяем его напрямую на replace.
Начальная структура MyPagination.vue:
<template>
<div class = " flex all-center">
<template v-if="total > 0">
<el-pagination
:page-size="pagesize"
:total="total"
:current-page="page"
background
layout="prev, pager, next, jumper, total"
class="my-pagination"
@current-change="changePage" />
</template>
</div>
</template>
<script>
export default {
name: 'MyPagination',
props: {
total: {
type: Number,
default: 0,
},
page: {
type: Number,
default: 1,
},
pagesize: {
type: Number,
default: 10,
},
totalPages: {
type: Number,
default: 1,
},
},
created() {
this.getCurrentPage();
},
methods: {
changePage(val) {
this.handlePage('push', val, this.pagesize);
this.$emit('change', val, this.pagesize);
},
getCurrentPage() {
var { page, pagesize } = this.$route.query;
if (!page || !pagesize) {
this.handlePage('replace', page || 1, +pagesize || this.pagesize);
return true;
}
return false;
},
handlePage(type, page, pagesize) {
this.$router[type]({
path: this.$route.path,
query: { ...this.$route.query, page, pagesize },
});
}
},
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
.my-pagination {
padding-top: 24px;
}
</style>
Код ключа родительского компонента:
<MyPagination :total = "total" :pagesize = "pagesize" :page="page" :totalPages = "totalPages" @change = "changePage" />
methods: {
changePage(page, pagesize) {
var _page = this.page,
_pagesize = this.pagesize;
this.page = page;
this.pagesize = pagesize;
if (page !== _page && pagesize || _pagesize !== pagesize) this.fetchData(); // 非首次进入页面时再获取分页数据,因为在created钩子中已经获取过一次了。
},
}
Эффект реализации: При первом входе на страницу, если параметр пейджинга отсутствует, сначала будет изменен параметр пейджинга, а затем будут получены данные, после чего нажатие на номер страницы компонента пейджинга также приведет к получению данные после подкачки.
Шаг 2. Наблюдайте за изменениями маршрутизации
На первый взгляд кажется, что нет ничего плохого в эффекте реализации предыдущего шага, но если адресная строка будет изменена напрямую, текущая отображаемая страница и текущие данные не изменятся. Параметры запроса внешней маршрутизации на странице (см.параметры запроса маршрутизатора, а не параметры запроса обычных страниц) меняется, по умолчанию не будет перезагружаться, если только ключ страницы не изменится, это для того, чтобы максимально предотвратить повторный рендеринг страницы, поэтому методом ключа это не решается , непосредственно через обнаружение vue watch$routeизменяется, тем самым изменяя отображение текущей страницы и текущих данных.
Добавлено в MyPagination.vue:
watch: {
'$route'(to, from) {
let { page, pagesize } = to.query;
if (!this.getCurrentPage()) {
this.$emit('change', +page || 1, +pagesize || 10);
}
}
},
Шаг 3. Управляйте размером страницы
В результате предыдущего шага при изменении страницы и размера страницы адресной строки данные страницы списка также изменятся соответствующим образом. Так как он меняется по параметрам адресной строки возникает новая проблема,
Что делать, если страница, введенная пользователем, больше, чем общее количество страниц?
В настоящее время это в основном зависит от того, как оформлен фон.
- Возвращает первую страницу данных.
getCurrentPage() {
var { page, pagesize } = this.$route.query;
/*
(totalPages > 0 && (page > totalPages));满足总页数大于0且当前页大于总页数时,跳转到第一页
*/
if (!page || !pagesize || (totalPages > 0 && (page > totalPages))) {
this.handlePage('replace', page || 1, this.pagesize);
return true;
}
return false;
},
- Вернуть данные последней страницы (думаю, эта операция должна быть более разумной).
getCurrentPage() {
var { page, pagesize } = this.$route.query,
MAX_PAGESIZE = this.max,
totalPages = this.totalPages;
if (!page || !pagesize) {
this.handlePage('replace', page || 1, +pagesize || this.pagesize);
return true;
} else if (totalPages > 0 && (page > totalPages)) {
this.handlePage('replace', totalPages, +pagesize);
return true;
}
return false;
},
Чтобы заменить текущий стек страниц, функция return true состоит в том, чтобы предотвратить последующие операции в режиме наблюдения и отменить этот запрос. После замены страницы запрашивать удаленные данные, обновлять отображение текущей страницы и данных.
- Возвращать пустой массив (возможно, так устроено большинство бэкендов, они не должны были думать, что страница будет больше, чем общее количество страниц). Код тот же, что и в 2.
Вышеупомянутое основано на ситуации, когда было определено totalPages.Если это первый раз, когда вы входите на страницу, ситуация будет другой.
При первом входе на страницу totalPages в первый раз равен 0, то есть параметры адресной строки не изменятся, в это время отображение адресной строки и компонента пейджинга будет несогласованным. В это время вы можете наблюдать за изменением totalPages в компоненте пейджинга.
totalPages(newVal, oldVal) {
if (+oldVal === 0 && newVal > 0) {
this.handlePage('replace', this.page, +this.pagesize);
}
}
Что делать, если размер страницы слишком велик?
Размер страницы должен быть ограничен. Если он слишком велик, данные фонового запроса будут очень медленными, а также могут вызвать нагрузку. Решение на самом деле простое, то есть добавить атрибут max в реквизиты, а затем ограничить его в методе getCurrentPage Код выглядит следующим образом:
props: {
max: {
type: Number,
default: 20,
},
},
methods: {
getCurrentPage() {
var { page, pagesize } = this.$route.query,
MAX_PAGESIZE = this.max,
totalPages = this.totalPages;
if (!page || !pagesize) {
this.handlePage('replace', page || 1, +pagesize || this.pagesize);
return true;
} else if (pagesize > MAX_PAGESIZE) {
this.handlePage('replace', page, MAX_PAGESIZE);
return true;
} else if (totalPages > 0 && (page > totalPages)) {
this.handlePage('replace', totalPages, +pagesize);
return true;
}
return false;
},
},
Шаг 4: Оптимизируйте код
Два запроса генерируются при нажатии на номер страницы компонента пагинации.
При нажатии на компонент подкачки 1. будет прослушивать событие текущего изменения и изменять адресную строку, и в то же время передавать событие изменения родительскому компоненту, 2. Но после изменения адресной строки часы $ route также будет передавать событие изменения родительскому компоненту, тогда просто нужно Merge событие изменения отправки, то есть в событии текущего изменения изменяется только адресная строка.
changePage(val) {
this.handlePage('push', val, this.pagesize);
},
результат
Пока что реализован кастомный компонент пейджинга.Изменив параметры адресной строки, можно увидеть изменение данных пейджинга.При клике на номер страницы адресная строка тоже изменится соответственно, и количество запросов было максимально сокращено.
Пользовательский компонент пагинации:MyPagination.vue
Список:list.vue
Полная демонстрация:front_end
Если у вас есть какие-либо вопросы, пожалуйста, оставьте сообщение для обсуждения.