Skip to main content

分页按钮重新布局并实现跳转功能

我们已成功实现了页面的上一页和下一页跳转功能,并确保页码的正确展示。现在,我们将进一步展示具体的页码信息。在Vue中,我们可以通过计算属性computed来实现这一功能。让我们定义一个变量pages,用于获取所有的页码。首先,初始化pages为一个空数组。然后,我们通过循环遍历来填充pages数组,从1遍历至最后一页this.lastPage。每次循环中,我们将页码加入pages数组。

frontend/src/components/Page.vue
<template>
<div class="flex items-center justify-center text-gray-500 pb-4 mb-12">
<!-- 上一页 -->
<span v-if="info.previous" @click="goToPage(prePage)" class="page-link">
<button class="w-8 h-8 rounded mx-1 my-1 text-gray-600 bg-gray-300">
<svg
xmlns="http://www.w3.org/2000/svg"
class="h-5 w-5 mx-auto"
viewBox="0 0 20 20"
fill="currentColor"
>
<path
fill-rule="evenodd"
d="M12.707 5.293a1 1 0 010 1.414L9.414 10l3.293 3.293a1 1 0 01-1.414 1.414l-4-4a1 1 0 010-1.414l4-4a1 1 0 011.414 0z"
clip-rule="evenodd"
/>
</svg>
</button>
</span>
<!-- 遍历每一页 -->

<a v-for="page in pages" :key="page" class="page-link">
<button v-if="page === '...'" class="w-8 h-8 rounded mx-1 my-1 bg-gray-300">
{{ page }}
</button>
<button
v-else-if="page === current"
class="w-8 h-8 rounded mx-1 my-1 bg-blue-500 text-white"
>
{{ page }}
</button>
<button
v-else
@click="goToPage(page)"
class="w-8 h-8 rounded mx-1 my-1 bg-gray-300"
>
{{ page }}
</button>
</a>

<!-- 下一页 -->
<a v-if="info.next" @click="goToPage(nextPage)" class="page-link" href="javascript:;">
<button class="w-8 h-8 rounded mx-1 my-1 bg-gray-300">
<svg
xmlns="http://www.w3.org/2000/svg"
class="h-5 w-5 mx-auto"
viewBox="0 0 20 20"
fill="currentColor"
>
<path
fill-rule="evenodd"
d="M7.293 14.707a1 1 0 010-1.414L10.586 10 7.293 6.707a1 1 0 011.414-1.414l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414 0z"
clip-rule="evenodd"
/>
</svg>
</button>
</a>
</div>
</template>

<script>
export default {
name: "Page",
data: function () {
return {
current: 1,
};
},
props: ["info"],
computed: {
lastPage() {
let pageSize = 12;
return Math.ceil(this.info.count / pageSize);
},

prePage() {
if (this.current > 1) {
return this.current - 1;
}
return 1;
},

nextPage() {
if (this.current < this.lastPage) {
return this.current + 1;
}
return this.current;
},
pages() {
const pages = [];
for (let i = 1; i <= this.lastPage; i++) {
if (
i === 1 ||
i === this.lastPage ||
(i >= this.current - 1 && i <= this.current + 1)
) {
pages.push(i);
} else if (pages[pages.length - 1] !== "...") {
pages.push("...");
}
}
return pages;
},
},
mounted() {
this.current = this.getPageFromUrl();
},
methods: {
getPageFromUrl() {
const page = Number(this.$route.query.page);
return page ? page : 1;
},

goToPage(page) {
this.current = page;
this.$router.push({ query: { page } });
},
},
};
</script>

上面代码中,在computed中添加了pages()。

代码解析

在这段Vue代码中,pages是一个计算属性,它的主要作用是生成一个表示分页器页码的数组,这个数组不仅包含所有页码,还包括逻辑处理后的省略符号(...),用于在用户界面上显示。下面是对pages计算属性具体逻辑的详细解释:

  1. 初始化页码数组 pages初始化为空数组。这个数组将被用来存储页面上显示的页码以及省略符号。

  2. 遍历页码 通过一个for循环遍历所有页码,从1到最后一页this.lastPage

  3. 添加页码逻辑 在遍历过程中,以下情况下页码或省略符号会被添加到pages数组:

  • 第一页和最后一页:无论当前页是什么,第一页和最后一页总是显示,以确保用户可以直接跳转到这两页。
  • 当前页的前一页和后一页:为了让用户了解当前页的上下文,显示当前页的前一页(this.current - 1)和后一页(this.current + 1)。
  • 省略符号(...):当页码不连续时(即上一个页码与当前页码不是相邻的),添加省略符号来表示中间缺失的页码。这里使用了一个条件判断,只有当数组的最后一个元素不是省略符号时才添加省略符号,以避免连续出现多个省略符号。
  1. 返回页码数组 最终,pages数组会包含用于在页面上显示的页码和省略符号。这个数组会被用在模板的v-for指令中,动态生成页码按钮。

最后,我们需要确保当用户点击页码时,URL和页面内容能够正确更新。在Vue中,我们可以使用watch来监听路由变化。当检测到路由变化时,我们可以调用getMovieData方法来重新获取数据,并将新数据渲染到页面上。 MovieList.vue页面中添加watch监听页面,添加watch,代码如下:

<script>
import axios from "axios";
import Page from "@/components/Page.vue";

export default {
name: "MovieList",
data: function () {
return {
info: "",
};
},
components: { Page },
mounted() {
this.get_movie_data();
},
methods: {
get_movie_data: function () {
let url = "/api/movie"; // /api/movie/?page=3&movie_name=我
// 获取page参数值
const page = Number(this.$route.query.page);
if (!isNaN(page) && page !== 0) {
url = url + "/?page=" + page;
}

axios
.get(url)
.then((response) => (this.info = response.data))
.catch((error) => {
console.log(error);
});
},
},
watch: {
// 监听路由的变化
$route() {
this.get_movie_data();
},
},
};
</script>

代码解析

在这段Vue代码中,watch是一个Vue实例的选项,用于观察Vue实例上的数据变化,并执行相应的函数。这里,它用于监视路由对象$route的变化。

具体来说:

  1. $route: 这是Vue Router的路由对象,它包含了路由的各种信息,如当前路径、查询参数、哈希等。在Vue组件中使用$route时,可以获取到当前路由的详细信息。

  2. watch: { $route() {...} }: 这段代码表示Vue实例正在监视$route对象。一旦$route对象发生变化(例如,用户通过链接导航到一个不同的路径),Vue会自动调用这个watcher函数。

  3. this.get_movie_data();: 这是watcher函数的内容。每当路由发生变化时,都会调用get_movie_data方法。通常,这种模式用于在用户导航到新页面时重新获取数据,例如,当用户从一个电影的详情页面导航到另一个电影的详情页面时,你可能需要重新获取新电影的数据来更新页面内容。

总结来说,这段代码的意思是:当Vue Router的路由发生变化时,自动调用get_movie_data方法。这通常用于根据当前路由的变化来更新页面数据,保持界面与URL的同步。

页面效果如下图所示。

图22-分页完整效果

至此,我们完成了分页功能的实现。在这个过程中,我们运用了Vue的核心概念,包括数据绑定、计算属性、方法定义、条件渲染、事件处理和路由监听等。通过这节课的学习,相信大家对Vue有了更深入的理解和认识。

谢谢大家的观看,希望大家能通过实践来巩固所学知识。如果在学习过程中遇到问题,不妨参考官方手册或寻求帮助。本节课程就到这里,我们下节课再见。