介绍
Pagination 是将大型结果分成单独页面的解决方案,并为用户提供导航工具来显示这些页面。
网页资源在Web应用程序中可以非常有用,不仅在性能方面,而且从用户体验的角度。
在本文中,您将学习如何创建一个动态且可重复使用的 Vue.js 页面组件。
前提条件
要完成本教程,您将需要:
- Node.js 本地安装,您可以按照 如何安装 Node.js 和创建本地开发环境进行操作。 *对 设置 Vue.js 项目的一些熟悉。
本教程已通过 Node v16.4.0、npm v7.19.0 和 Vue v2.6.11 进行验证。
步骤 1 - 设置项目
页面组件应该允许用户进入第一页和最后一页,前进和后退,并直接切换到近范围的页面。
我们想渲染一个按钮,进入第一个页面,前一个页面,页面范围,下一个页面和最后一个:
1[first] [next] [1] [2] [3] [previous] [last]
大多数应用程序每次用户更改页面时都会发出API请求,我们需要确保我们的组件允许我们这样做,但我们不希望在组件中发出请求,这样我们就会确保该组件在整个应用程序中可重复使用,并且请求全部在操作 / 服务层中进行。
在 API 终端上实现页面化有几种可能的方法。
如果API只提供记录总数的信息,我们可以通过将结果数以每页的结果数分开来计算页面总数: totalResults / perPage
。
对于这个例子,让我们假设我们的API告诉我们每页的结果数(‘PerPage’)、页面总数(‘TotalPages’)、当前页面(‘currentPage’)。
虽然我们想要渲染一系列页面,但我们不希望渲染所有可用的页面. 让我们也允许在我们的组件中配置最多可见按钮(‘maxVisibleButtons’)。
现在我们知道我们希望我们的组件做什么以及我们需要哪些数据,我们可以设置HTML结构和所需的补丁。
您可以使用@vue/cli
创建一个新的Vue项目:
1npx @vue/cli create --default vue-pagination-example
然后导航到新创建的项目目录;
1cd vue-pagination-example
创建一个Pagination.vue
文件,并使用代码编辑器打开它:
1[label src/components/Pagination.vue]
2<template>
3 <ul>
4 <li>
5 <button
6 type="button"
7 >
8 First
9 </button>
10 </li>
11
12 <li>
13 <button
14 type="button"
15 >
16 Previous
17 </button>
18 </li>
19
20 <!-- Visible Buttons Start -->
21
22 <!-- ... -->
23
24 <!-- Visible Buttons End -->
25
26 <li>
27 <button
28 type="button"
29 >
30 Next
31 </button>
32 </li>
33
34 <li>
35 <button
36 type="button"
37 >
38 Last
39 </button>
40 </li>
41 </ul>
42</template>
43
44<script>
45export default {
46 props: {
47 maxVisibleButtons: {
48 type: Number,
49 required: false,
50 default: 3
51 },
52 totalPages: {
53 type: Number,
54 required: true
55 },
56 perPage: {
57 type: Number,
58 required: true
59 },
60 currentPage: {
61 type: Number,
62 required: true
63 }
64 }
65};
66</script>
在此时,您的组件将在列表中显示四个按钮. 为了获得可见按钮的范围,我们将使用一个为
循环。
我们需要确保这个数字永远不会超过设置可见按钮的最大数目,也不会超过可用的页数。
我们的循环的开始号码取决于当前的页面:
- 当当前页面是第一个时,让我们向用户显示当前页面和下一个页面 2.当当前页面是最后一个页面时,让我们显示最后一页和之前的页面 3.对于之间的一切,让我们显示前一页和下一页(s)。
我们的循环的终结数字也需要一些计算。我们需要在页面总数和我们想要停止的位置之间获得最小的数字。 要计算我们想要停止的位置,我们需要开始位置的总和,加上可见按钮的最大数目。
让我们使用一个计算属性,返回一系列具有可见页面的对象. 每个对象将有页面号码的支持,另一个会告诉我们按钮是否应该被禁用。
对于更复杂的数据结构,建议为每个v-for
提供一个钥匙
。Vue使用钥匙
值来查找需要更新的元素,当这个值不提供时,Vue使用现场补丁
策略。尽管我们使用的数据足够简单,让我们提供钥匙
值 - 如果您使用了eslint-vue-plugin
(LINK1)与vue3-essential
(LINK2)的规则,您将始终需要提供钥匙
的值。
修订Pagination.vue
文件并添加startPage()
和pages()
:
1[label src/components/Pagination.vue]
2<template>
3 <ul>
4 ...
5 <!-- Visible Buttons Start -->
6
7 <li
8 v-for="page in pages"
9 :key="page.name"
10 >
11 <button
12 type="button"
13 :disabled="page.isDisabled"
14 >
15 {{ page.name }}
16 </button>
17 </li>
18
19 <!-- Visible Buttons End -->
20 ...
21 </ul>
22</template>
23
24<script>
25export default {
26 ...
27 computed: {
28 startPage() {
29 // When on the first page
30 if (this.currentPage === 1) {
31 return 1;
32 }
33
34 // When on the last page
35 if (this.currentPage === this.totalPages) {
36 return this.totalPages - this.maxVisibleButtons;
37 }
38
39 // When inbetween
40 return this.currentPage - 1;
41 },
42 pages() {
43 const range = [];
44
45 for (
46 let i = this.startPage;
47 i <= Math.min(this.startPage + this.maxVisibleButtons - 1, this.totalPages);
48 i++
49 ) {
50 range.push({
51 name: i,
52 isDisabled: i === this.currentPage
53 });
54 }
55
56 return range;
57 },
58 }
59};
60</script>
现在,最大可见按钮的逻辑结束了。
步骤 2 — 添加事件听众
现在我们需要通知主组件,用户点击按钮时,用户点击了哪个按钮。
我们需要在每个按钮中添加一个事件倾听器。 v-on
指令允许听到 DOM 事件。
为了通知家长,我们将使用 $emit
方法发出页面点击的事件。
另外,要确保页面定位按钮仅在页面可用时是活跃的,这样做时,我们会使用 v-bind
将 disabled
属性值与当前页面联系起来,我们也会使用 :
缩写为 `v-bind。
为了保持模板清洁,我们将使用计算属性来检查按钮是否应该被禁用. 使用计算属性也将缓存值,这意味着只要当前页面
不会改变,对相同计算属性的其他请求将返回以前计算的结果,而无需再次运行该函数。
查看Pagination.vue
文件,并为当前页面添加检查,然后单击事件方法:
1[label src/components/Pagination.vue]
2<template>
3 <ul>
4 <li>
5 <button
6 type="button"
7 @click="onClickFirstPage"
8 :disabled="isInFirstPage"
9 >
10 First
11 </button>
12 </li>
13
14 <li>
15 <button
16 type="button"
17 @click="onClickPreviousPage"
18 :disabled="isInFirstPage"
19 >
20 Previous
21 </button>
22 </li>
23
24 <!-- Visible Buttons Start -->
25
26 <li
27 v-for="page in pages"
28 :key="page.name"
29 >
30 <button
31 type="button"
32 @click="onClickPage(page.name)"
33 :disabled="page.isDisabled"
34 >
35 {{ page.name }}
36 </button>
37 </li>
38
39 <!-- Visible Buttons End -->
40
41 <li>
42 <button
43 type="button"
44 @click="onClickNextPage"
45 :disabled="isInLastPage"
46 >
47 Next
48 </button>
49 </li>
50
51 <li>
52 <button
53 type="button"
54 @click="onClickLastPage"
55 :disabled="isInLastPage"
56 >
57 Last
58 </button>
59 </li>
60 </ul>
61</template>
62
63<script>
64export default {
65 ...
66 computed: {
67 ...
68 isInFirstPage() {
69 return this.currentPage === 1;
70 },
71 isInLastPage() {
72 return this.currentPage === this.totalPages;
73 },
74 },
75 methods: {
76 onClickFirstPage() {
77 this.$emit('pagechanged', 1);
78 },
79 onClickPreviousPage() {
80 this.$emit('pagechanged', this.currentPage - 1);
81 },
82 onClickPage(page) {
83 this.$emit('pagechanged', page);
84 },
85 onClickNextPage() {
86 this.$emit('pagechanged', this.currentPage + 1);
87 },
88 onClickLastPage() {
89 this.$emit('pagechanged', this.totalPages);
90 }
91 }
92}
93</script>
现在点击按钮的逻辑结束了。
步骤三:添加风格
现在我们的组件检查了我们最初想要的所有功能,我们需要添加一些CSS,使其看起来更像一个页面组件,而不是一个列表。
我们还希望我们的用户能够清楚地识别他们在哪个页面,让我们改变代表当前页面的按钮的颜色。
为了做到这一点,我们可以使用 object syntax将一个HTML class
绑定到我们的活跃页面按钮。当使用对象语法绑定类名称时,Vue 会自动切换类,当值发生变化。
虽然v-for
中的每个块都有访问主范围属性,但我们会使用方法
来检查页面是否活跃,以保持我们的模板清洁。
修订pagination.vue
文件,并添加对活跃页面和 CSS 样式和类的检查:
1[label src/components/Pagination.vue]
2<template>
3 <ul class="pagination">
4 <li class="pagination-item">
5 <button
6 type="button"
7 @click="onClickFirstPage"
8 :disabled="isInFirstPage"
9 >
10 First
11 </button>
12 </li>
13
14 <li class="pagination-item">
15 <button
16 type="button"
17 @click="onClickPreviousPage"
18 :disabled="isInFirstPage"
19 >
20 Previous
21 </button>
22 </li>
23
24 <!-- Visible Buttons Start -->
25
26 <li
27 v-for="page in pages"
28 class="pagination-item"
29 >
30 <button
31 type="button"
32 @click="onClickPage(page.name)"
33 :disabled="page.isDisabled"
34 :class="{ active: isPageActive(page.name) }"
35 >
36 {{ page.name }}
37 </button>
38 </li>
39
40 <!-- Visible Buttons End -->
41
42 <li class="pagination-item">
43 <button
44 type="button"
45 @click="onClickNextPage"
46 :disabled="isInLastPage"
47 >
48 Next
49 </button>
50 </li>
51
52 <li class="pagination-item">
53 <button
54 type="button"
55 @click="onClickLastPage"
56 :disabled="isInLastPage"
57 >
58 Last
59 </button>
60 </li>
61 </ul>
62</template>
63
64<script>
65export default {
66 ...
67 methods: {
68 ...
69 isPageActive(page) {
70 return this.currentPage === page;
71 }
72 }
73}
74</script>
75
76<style>
77.pagination {
78 list-style-type: none;
79}
80
81.pagination-item {
82 display: inline-block;
83}
84
85.active {
86 background-color: #4AAE9B;
87 color: #ffffff;
88}
89</style>
现在,设计活跃按钮的逻辑结束了。
步骤 4 – 使用组件
您需要通过提供总页
和每页
的值来模拟 API 调用。
对于这个示例,‘currentPage’应该设置为‘1’,而‘onPageChange’将登录活跃页面。
1[label src/App.vue]
2<template>
3 <div id="app">
4 <pagination
5 :totalPages="10"
6 :perPage="10"
7 :currentPage="currentPage"
8 @pagechanged="onPageChange"
9 />
10 </div>
11</template>
12
13<script>
14import Pagination from './components/Pagination.vue'
15
16export default {
17 name: 'App',
18 components: {
19 Pagination
20 },
21 data () {
22 return {
23 currentPage: 1,
24 };
25 },
26 methods: {
27 onPageChange(page) {
28 console.log(page)
29 this.currentPage = page;
30 }
31 }
32}
33</script>
在此时,您可以运行应用程序:
1npm run serve
在浏览器中打开应用程序并观察页面组件. 会出现一个 First, Previous, Next和 Last按钮. 在总共10页中,还会显示三个页面按钮. 因为第一个页面是当前页面,所以 1按钮被标记为一个活跃的类别。
结论
在本文中,您了解如何创建一个动态且可重复使用的 Vue.js 页面组件。
如果您想了解有关 Vue.js 的更多信息,请参阅 我们的 Vue.js 主题页面以获取练习和编程项目。