Vue3后台管理系统(十八)分页组件 叁歲伎倆 2024-03-26 14:03 30阅读 0赞 **目录** 一、场景效果 二、滑动工具类 三、组件封装 四、全局注册 五、使用案例 -------------------- #### 一、场景效果 #### ![3f262ec3e4bb41149f887de94d73136e.png][] #### 二、滑动工具类 #### 在src/utils文件夹下新建scroll-to.ts // src/utils/scroll-to.ts const easeInOutQuad = (t: number, b: number, c: number, d: number) => { t /= d / 2; if (t < 1) { return (c / 2) * t * t + b; } t--; return (-c / 2) * (t * (t - 2) - 1) + b; }; // requestAnimationFrame for Smart Animating http://goo.gl/sx5sts const requestAnimFrame = (function () { return ( window.requestAnimationFrame || (window as any).webkitRequestAnimationFrame || (window as any).mozRequestAnimationFrame || function (callback) { window.setTimeout(callback, 1000 / 60); } ); })(); /** * Because it's so fucking difficult to detect the scrolling element, just move them all * @param {number} amount */ const move = (amount: number) => { document.documentElement.scrollTop = amount; (document.body.parentNode as HTMLElement).scrollTop = amount; document.body.scrollTop = amount; }; const position = () => { return ( document.documentElement.scrollTop || (document.body.parentNode as HTMLElement).scrollTop || document.body.scrollTop ); }; /** * @param {number} to * @param {number} duration * @param {Function} callback */ export const scrollTo = (to: number, duration: number, callback?: any) => { const start = position(); const change = to - start; const increment = 20; let currentTime = 0; duration = typeof duration === 'undefined' ? 500 : duration; const animateScroll = function () { // increment the time currentTime += increment; // find the value with the quadratic in-out easing function const val = easeInOutQuad(currentTime, start, change, duration); // move the document.body move(val); // do the animation unless its over if (currentTime < duration) { requestAnimFrame(animateScroll); } else { if (callback && typeof callback === 'function') { // the animation is done so lets callback callback(); } } }; animateScroll(); }; #### 三、组件封装 #### 在src/components文件夹下新建Pagination文件夹,并在Pagination文件夹下新建index.vue <!--src/components/Pagination/index.vue--> <template> <div :class="{ hidden: hidden }" class="pagination-container"> <el-pagination :background="background" v-model:current-page="currentPage" v-model:page-size="pageSize" :layout="layout" :page-sizes="pageSizes" :total="total" @size-change="handleSizeChange" @current-change="handleCurrentChange" /> </div> </template> <script setup lang="ts"> import { computed, PropType } from 'vue'; import { scrollTo } from '@/utils/scroll-to'; const props = defineProps({ total: { required: true, type: Number as PropType<number>, default: 0 }, page: { type: Number, default: 1 }, limit: { type: Number, default: 20 }, pageSizes: { type: Array as PropType<number[]>, default() { return [10, 20, 30, 50]; } }, layout: { type: String, default: 'total, sizes, prev, pager, next, jumper' }, background: { type: Boolean, default: true }, autoScroll: { type: Boolean, default: true }, hidden: { type: Boolean, default: false } }); const emit = defineEmits(['update:page', 'update:limit', 'pagination']); const currentPage = computed<number | undefined>({ get: () => props.page, set: value => { emit('update:page', value); } }); const pageSize = computed<number | undefined>({ get() { return props.limit; }, set(val) { emit('update:limit', val); } }); function handleSizeChange(val: number) { emit('pagination', { page: currentPage, limit: val }); if (props.autoScroll) { scrollTo(0, 800); } } function handleCurrentChange(val: number) { currentPage.value = val; emit('pagination', { page: val, limit: props.limit }); if (props.autoScroll) { scrollTo(0, 800); } } </script> <style scoped> .pagination-container { background: #fff; padding: 32px 16px; } .pagination-container.hidden { display: none; } </style> #### 四、全局注册 #### // src/main.ts import Pagination from '@/components/Pagination/index.vue'; app .component('Pagination', Pagination) .mount('#app') #### 五、使用案例 #### <!--src/App.vue--> <script setup lang="ts"> import Pagination from '@/components/Pagination/index.vue' import {onMounted, reactive} from "vue"; const state = reactive({ loading: true, queryParams: { pageNum: 1, pageSize: 10 }, dataList: [] as Data[], total: 0, }); interface Data { id: number name: string } function handleQuery() { state.loading = true; state.dataList = [ {id: 1,name: '张三'}, {id: 2, name: '李四'}, ]; state.total = 1000; state.loading = false; } onMounted(()=>{ handleQuery() }) </script> <template> <div> <div v-for="data in state.dataList" :key="data.id"> <div> 编码:{ { data.id }} </div> <div> 姓名:{ { data.name }} </div> </div> <div> <pagination v-if="state.total > 0" :total="state.total" v-model:page="state.queryParams.pageNum" v-model:limit="state.queryParams.pageSize" @pagination="handleQuery" /> </div> </div> </template> <style> </style> ![9410b8ea30a54507946f11855df589b0.png][] [3f262ec3e4bb41149f887de94d73136e.png]: https://image.dandelioncloud.cn/pgy_files/images/2024/03/26/13f51c64297a4eb6824549228c2e5023.png [9410b8ea30a54507946f11855df589b0.png]: https://image.dandelioncloud.cn/pgy_files/images/2024/03/26/988997ff7e97433a9981d6e7bf163080.png
还没有评论,来说两句吧...