组件
<template> <div :class="{ hidden: hidden }" class="pagination-container"> <el-pagination :background="background" v-model:current-page="currentPage" v-model:page-size="pageSize" :page-sizes="pageSizes" :pager-count="5" :layout="layout" :total="total" v-bind="$attrs" @size-change="handleSizeChange" @current-change="handleCurrentChange" > <span v-if="selected >= 0" class="text"> 已选择 {{ selected }} 条 </span> </el-pagination> </div> </template> <script setup lang="ts"> import { computed } from 'vue' import { scrollTo } from '@/utils/libs/scroll-to' const props = defineProps({ total: { type: Number, required: true }, page: { type: Number, default: 1 }, limit: { type: Number, default: 20 }, pageSizes: { type: Array as PropType<Array<number>>, default: () => [10, 20, 30, 40, 50] }, layout: { type: String, default: 'total , slot , -> , sizes, prev, pager, next, jumper ' }, background: { type: Boolean, default: true }, autoScroll: { type: Boolean, default: true }, hidden: { type: Boolean, default: false }, selected: { type: Number, default: 0 } }) const childEmit = defineEmits(['update:page', 'update:limit', 'pagination']) const currentPage = computed({ get: () => props.page, set: (val) => { childEmit('update:page', val) } }) const pageSize = computed({ get: () => props.limit, set: (val) => { childEmit('update:limit', val) } }) const handleSizeChange = (val) => { childEmit('pagination', { pageNum: currentPage, pageSize: val }) if (props.autoScroll) scrollTo(0, 800) } const handleCurrentChange = (val) => { childEmit('pagination', { pageNum: val, pageSize: props.limit }) if (props.autoScroll) scrollTo(0, 800) } </script> <style lang="scss"></style>
hook
import { ref, reactive, nextTick } from 'vue' export default function ( ajaxRequest, // 请求接口 multipleTable, // table ref paging, // 分页大小 parameter, // 搜索参数 multipleTableKey = '', isMultipleTable = false ) { const mixinsLoading = ref<boolean>(false) const tableData = ref([]) const selectCodes = ref([]) // 选中的数据 const originalData = ref(null) // 原始数据 /* 集中处理筛选数据 */ function filterFrom() { const para = JSON.parse(JSON.stringify(parameter.value)) for (const key in para) { if (para[key] === '' || para[key] === null) delete para[key] // 如果属性为空 删除掉 } parameter.value = para getList() } // 重新搜索 function reload(parameters = {}) { paging.pageNum = 1 parameter.value = parameters // 保证响应式 filterFrom() } function handleCurrentChange(paging) { Object.assign(paging, paging) getList() } async function getList() { mixinsLoading.value = true parameter.value = Object.assign(parameter.value, paging) parameter.value.page = parameter.value.pageNum parameter.value.page_size = parameter.value.pageSize delete parameter.value.totalCount delete parameter.value.pageNum delete parameter.value.pageSize try { const { data } = await ajaxRequest(parameter.value) // const body = [] originalData.value = data // 保持响应式 tableData.value.length = 0 for (const iterator of data?.datalist) { tableData.value.push(iterator) } paging.totalCount = +data?.total || 0 if (isMultipleTable) { tableSelect() } else { mixinsLoading.value = false } } catch (err) { // console.log('err:', error) tableData.value.length = 0 mixinsLoading.value = false } } /* 重置 */ function reset(paramete = {}) { paging = reactive({ pageNum: 1, pageSize: 20, totalCount: 0 }) for (const item in paramete) paramete[item] = '' parameter.value = paramete // 本地赋值 filterFrom() selectCodes.value = [] } // 表格勾选 function tableSelect() { if (!tableData.value && !tableData.value.length) { mixinsLoading.value = false return } tableData.value.forEach((element) => { if (selectCodes.value.join().includes(element[multipleTableKey])) { nextTick(() => { multipleTable.value.toggleRowSelection(element, true) }) } }) mixinsLoading.value = false } return { mixinsLoading, selectCodes, originalData, tableData, handleCurrentChange, reload, reset } }
param
import { ref, reactive } from 'vue' export default function ( tableRefVal, parameterVal, pagingVal = { pageNum: 1, pageSize: 20, totalCount: 0 }, paginationLayoutVal = 'total , slot , -> , sizes, prev, pager, next, jumper ' ) { const tableRef = ref(tableRefVal) // table DOM const paging = reactive(pagingVal) // 分页大小 const parameter = ref(parameterVal) // 查询参数 const paginationLayout = paginationLayoutVal // 页码设置 return { tableRef, paging, parameter, paginationLayout } }
使用
<template> <div class="index-table pr-20px pl-20px"> <list-pagination class="mt-20px" :total="paging.totalCount" v-model:page="paging.pageNum" v-model:limit="paging.pageSize" :layout="paginationLayoutVal" @pagination="handleCurrentChange" /> </div> </template> <script setup lang="ts"> import ListPagination from '@/components/ListPagination/index.vue' import useListPagination from '@/hooks/list-pagination/useListPagination' import { onMounted } from 'vue' import usePagParam from '@/hooks/list-pagination/usePagParam' import { scanList } from '@/api/home' import { TABLE_BORDER_RADIUS } from '@/config/style' import tableHeightHook from '@/hooks/table-height/tableHeight' const handleSelectionChange = () => {} const { tableRef, paging, parameter } = usePagParam(null, {}) const paginationLayoutVal = 'total , -> , sizes, prev, pager, next, jumper ' let { mixinsLoading, tableData, handleCurrentChange, reload } = useListPagination( scanList, tableRef, paging, parameter ) const topHeightValCom = tableHeightHook(tableRef) // 获取 table 的高度 onMounted(() => { reload() // 初始化数据 }) defineExpose({ reload }) // 共父组件使用 </script> <style lang="scss" scoped> .index-table { margin-top: 0; &__content { width: 100%; height: 200px; } } @mixin state-modify { height: 5px; width: 5px; border-radius: 50%; margin-right: 10px; } .modify-orange { @include state-modify; background: orange; } .modify-green { @include state-modify; background: green; } </style>