刚开始使用vue3写博客的时候,其相关配套的UI库并没有正式发布,但是我还要用,所以这里我自定义了一个分页组件:最后效果如下图所示:
上代码:
Pagination.vue
<template> <!-- 自定义分页组件 --> <div class="page-bar"> <ul> <li class="first"> <!-- <span>共{{dataNum}}条记录 第 {{cur}} / {{all}} 页</span> --> <span>共{{ dataNum }}条记录 </span> </li> <li v-if="cur > 1" class="prev-next"> <!-- 点击上一页 --> <a v-on:click="cur--, pageClick()"> prev </a> </li> <li v-if="cur == 1" class="prev-next"> <!-- 点击第一页时显示 --> <a class="banclick"> prev </a> </li> <li class="li_a" v-for="index in indexs" v-bind:class="{ active: cur == index }" > <!-- 页码 --> <a v-on:click="btnClick(index)"> {{ index }}</a> </li> <li v-if="cur != all" class="prev-next"> <!-- 点击下一页 --> <a v-on:click="cur++, pageClick()"> next </a> </li> <li v-if="cur == all" class="prev-next"> <!-- 点击最后一页时显示 --> <a class="banclick"> next </a> </li> <li class="last_li"> <!-- 共有多少页 --> 跳至<input type="text" class="page-input" @blur.prevent="changePage()" v-model="jumpPage">页 </li> <li class="last_li"> <!-- 共有多少页 --> <span >共<i>{{ all }}</i >页</span > </li> </ul> </div> </template> <script> // 引入js文件 import Pagination from "/@/assets/js/components/pc/Pagination"; // 使用js对象 export default { ...Pagination, }; </script> <style lang="scss" scoped> @import "../../assets/css/components/pc/Pagination.scss"; </style> 复制代码
Pagination.ts
import { PropType, ref, watch, computed, reactive, toRefs, inject, provide, onMounted } from "vue"; // 引入公共js文件 import utils from "/@/assets/js/public/function"; // 定义返回的类型 interface dataRef { btnClick: (val:number) => void; pageClick: () => void; changePage: () => void; } export default { name: "Pagination", props: { // 总页数 'dataAll': { type: Number, default: 100, required: true }, // 当前页数 'dataCur': { type: Number, default: 1, required: true }, // 页面条数 'datanum': { type: Number, default: 7 }, // 数据总量 'dataDatanum': { type: Number, default: 456 }, }, // VUE3语法 setup函数 // setup官方文档:https://www.vue3js.cn/docs/zh/guide/composition-api-setup.html#参数 setup(props: any, content:any): dataRef { /** * @name: 声明data * @author: camellia * @email: guanchao_gc@qq.com * @date: 2021-01-10 */ const data:any = reactive({ all: props.dataAll, //总页数 cur: Number(props.dataCur),//当前页码 num: props.datanum, //一页显示的数量 奇数 dataNum: props.dataDatanum,//数据的数量 jumpPage:0,// 跳转页码 indexs:computed(()=>{ var left = 1; var right = data.all; var ar = []; if (data.all >= data.num) { if (data.cur > 3 && data.cur < data.all - 2) { left = data.cur - (data.num - 1) / 2; right = Number(data.cur) + Number((data.num - 1) / 2); } else { if (data.cur <= 3) { left = 1 right = data.num } else { right = data.all left = data.all - (data.num - 1); } } } while (left <= right) { ar.push(left) left++ } return ar }) }); /** * @name: 页码点击事件 * @author: camellia * @email: guanchao_gc@qq.com * @date: 2021-01-11 */ const btnClick = (val:Number) => { if (val != data.cur) { data.cur = val content.emit('changePage', data.cur); } }; /** * @name: 点击上一页下一页 * @author: camellia * @email: guanchao_gc@qq.com * @date: 2021-01-11 */ const pageClick = () => { //父组件通过changePage方法来接受当前的页码 //这里是点击下一页执行函数 content.emit('changePage', data.cur) } /** * @name: 跳至 xxx 页 * @author: camellia * @email: guanchao_gc@qq.com * @date: 2021-01-13 */ const changePage = () => { if (data.jumpPage > data.all || data.jumpPage < 1 || isNaN(data.jumpPage) ) { utils.alertMsg(2000,"参数错误!");return; } content.emit('changePage', Number(data.jumpPage)) } /** * @name: 将data绑定值dataRef * @author: camellia * @email: guanchao_gc@qq.com * @date: 2021-01-10 */ const dataRef = toRefs(data); return { btnClick, pageClick, changePage, ...dataRef } }, }
Pagination.scss
.page-bar { text-align: center; width: 100%; height: 36px; margin: 0 auto; position: relative; } .page-bar ul { min-width: 800px; display: block; overflow: hidden; position: absolute; top: 50%; left: 50%; transform: translate(-50%,-50%); } .page-bar li { display: block; border: 1px solid #ddd; width: 36px; height: 36px; border-radius: 4px; list-style: none; overflow: hidden; position: relative; float: left; margin-left: 8px; } .page-bar .first{ display: block; // width: 170px; width: 100px; height: 36px; font-size: 14px; line-height: 36px; text-align: center; } .page-bar .last_li{ width: 100px; height: 36px; border: 1px solid #ddd; line-height: 34px; } .page-bar .last_li span{ width: 100%; height: 100%; line-height: 36px; text-align: center; float: left; } .page-bar li:first-child { margin-left: 0px } .page-bar a { width: 34px; height: 34px; text-decoration: none; position: absolute; top: 50%; left: 50%; transform: translate(-50%,-50%); /*margin-left: -1px;*/ line-height: 34px; color: #333; cursor: pointer } .page-bar .li_a a:hover { background-color: #eee; border: 1px solid #40A9FF; color: #40A9FF; } .page-bar a.banclick { cursor: not-allowed; } .page-bar .active a { color: #fff; cursor: default; background-color: #1890FF; border-color: #1890FF; } .page-bar i { font-style: normal; color: #d44950; margin: 0px 4px; font-size: 14px; } .page-bar .prev-next{ width:50px; } .page-bar input{ background:none; outline:none; border:1px solid #ccc; } .page-bar .page-input{ width: 30px; height: 25px; padding-left: 6px; }
父组件调用:
Index.ts
import { PropType, ref, watch, reactive, toRefs, getCurrentInstance, provide, inject, onBeforeMount,// 在组件挂载之前执行的函数 onMounted, onBeforeUpdate,// 在组件修改之前执行的函数 onUpdated, onBeforeUnmount,// 在组件卸载之前执行的函数 onUnmounted, nextTick } from "vue"; // 引入axios钩子 import axios from "/@/hooks/axios.ts"; // 引入路由 import { useRouter, useRoute } from "vue-router"; // 引入各个自定义组件(懒加载) // const HelloWorld = () => import("/@/components/HelloWorld.v import Pagination from "/@/components/pc/Pagination.vue"; export default { name: "index", components: { Pagination, }, // VUE3 语法 第一个执行的钩子函数 // setup官方文档 :https://www.vue3js.cn/docs/zh/guide/composition-api-setup.html#参数 // setup(props: any, content: any) { setup(props: any, content: any) { const router = useRouter(); const route = useRoute() //获取上下文实例,ctx=vue2的this // const { ctx,proxy } = getCurrentInstance(); /** * @name: 声明data * @author: camellia * @email: guanchao_gc@qq.com * @date: 2021-01-10 */ const data = reactive({ // 文章列表 articleList:[], // 数据页数 articlePage:0, // 当前页 currentPage: route.query.page ? route.query.page : 1, // 分页显示页码数 dataNum:7, // 查询条件 search:'search', // 数据总条数 dataDatanum:'', }); /** * @name: 分页子组件传递值方法 * @author: camellia * @email: guanchao_gc@qq.com * @date: 2021-01-11 * @param: param Number 子组件传递来的页码 */ const changePage = (param: number) => { data.currentPage = param; getData('page'); router.push( { path: '/pc/index', query: { page: JSON.stringify(data.currentPage) } }); } // 初始调用 getData(); /** * @name: 将data绑定值dataRef * @author: camellia * @email: guanchao_gc@qq.com * @date: 2021-01-10 */ const dataRef = toRefs(data); return { getData, changePage, ...dataRef } },//*/ };
代码中有注释,我这里就不做赘述了。
当然,你还可以扩展其他功能。