antdv自定义分页组件

63 阅读3分钟

创建自定义样式的分页

基于antdvue4

基础元素结构,包含页码选择,页数切换

<div class="custom-pagination">
    {/* <span>显示</span>
    <a-select
        v-model:value={pageSize.value}
        style="width: 80px"
        onChange={(value:any) => {
            pageSize.value = value;
            getWorkflows();
        }}
    >
        <a-select-option value="2">2</a-select-option>
        <a-select-option value="5">5</a-select-option>
        <a-select-option value="10">10</a-select-option>
        <a-select-option value="15">15</a-select-option>
    </a-select> */}
    <span>共</span>
    <span class="text-[15px] font-semibold text-[#2D2F33]">{total.value}</span>
    <span></span>
    <a-dropdown 
    trigger={['click']}
    overlay = {
        <a-menu onClick={(e:any) => {
            pageSize.value = parseInt(e.key);
            getWorkflows();
        }}>
            <a-menu-item key="2">2</a-menu-item>
            <a-menu-item key="10">10</a-menu-item>
            <a-menu-item key="20">20</a-menu-item>
            <a-menu-item key="50">50</a-menu-item>
            <a-menu-item key="100">100</a-menu-item>
        </a-menu>
        }
        >
        <a class="ant-dropdown-link" onClick={(e) => {e.preventDefault()}}>
            显示 <span class="text-[15px] font-semibold text-[#2D2F33]">{pageSize.value}</span>&nbsp;
            <DownOutlined/>
        </a>
    </a-dropdown>
    {/* 上一页按钮 */}
    <button
        disabled={cuPage.value === 1}
        onClick={() => {
            cuPage.value -= 1;
            getWorkflows();
        }}
        id="prevbtn"
    >
    <LeftOutlined id="prev" title="上一页" class="cursor-pointer h-[24px] text-[#2d2f33]"></LeftOutlined>
    </button>

    {/* 页码选项 */}
    {pageRange.value.map((page:any,index:any) => (
        <button
            onClick={(e:any) => {
                if(page == '···' && index == 1){
                    console.log(Math.max(cuPage.value-5,1));

                    cuPage.value = Math.max(cuPage.value-5,1);
                }
                else if (page == '···') {
                    console.log(Math.min(total.value,cuPage.value+5));

                    cuPage.value = Math.min(total.value,cuPage.value+5);
                }
                else {
                    cuPage.value = parseInt(page);
                }
                getWorkflows();
            }}
            key={page}
            class={
                page === '···'
                ? index === 1
                    ? "previous-page w-[26px] h-[26px] text-center rounded-[4px] outline-none hover:after:relative hover:after:left-0 hover:after:top-0 hover:after:-translate-x-1/2"
                    : "next-page w-[26px] h-[26px] text-center rounded-[4px] outline-none hover:after:relative hover:after:left-0 hover:after:-translate-x-1/2"
                : page == cuPage.value ?"selected-pagenumber": page > 999 ?"page-number w-[36px]":"page-number w-[26px]"
            }
        >
            <span>{page}</span>
            {page === '···' ? (index === 1 ? <span><DoubleLeftOutlined /></span> :<span><DoubleRightOutlined /></span>) : null}
        </button>
    ))}
    {/* 下一页按钮 */}
    <button
        disabled={cuPage.value === totalPage.value}
        onClick={() => {
            cuPage.value += 1;
            getWorkflows();
        }}
        id="nextbtn"
    >
        <RightOutlined id="next" title="下一页" class="cursor-pointer h-[24px] text-[#2d2f33]"></RightOutlined>
    </button>
</div>

页码渲染数组

// 计算页码范围(例如:显示当前页前后各2页)
const pageRange = computed(() => {
    const totalPages = totalPage.value;
    const range:Array<any> = [1]; // 显示的分页数组
    if(totalPages == 1){
        return range;
    }
    let start = Math.max(2, cuPage.value - 2);
    if(totalPages - cuPage.value < 2){
        start = Math.max(2, cuPage.value - (4 - (totalPages - cuPage.value)));
    }
    let end = Math.min(totalPages-1, cuPage.value + 2);
    if(cuPage.value < 3){
        end = Math.min(totalPages-1, 5- cuPage.value + 1);
    }
    for (let i = start; i <= end; i++) {
        if(totalPages>7 && cuPage.value > 4 && i == start){
            range.push("···");
        }
        range.push(i);
    }
    range.push(totalPages);
    if(totalPages - cuPage.value > 3 && totalPages>7){
        let len = range.length;
        range.splice(len - 1,0, "···");
    }

    return range;
});

css样式

/** 自定义分页pagination */
.custom-pagination {
  justify-content: right;
  /* align-items: center; */
}
.custom-pagination .previous-page,.custom-pagination .next-page,
.custom-pagination .selected-pagenumber,.custom-pagination .page-number,
 .custom-pagination .ant-dropdown-link {
  cursor:pointer;
 }
#prev>span>svg, #next>span>svg {
  height:11px
}
.previous-page:hover, .next-page:hover {
  color: #2A87FF;
}
.previous-page:hover span:first-child,.next-page:hover span:first-child {
  display: none;
}
.previous-page:hover span:last-child,.next-page:hover span:last-child {
  display: inline;
}
.previous-page span:last-child, .next-page span:last-child {
  display: none;
}
.previous-page span:first-child, .next-page span:first-child {
  display: inline;
}
.selected-pagenumber {
  background: #E9F3FF;
  box-shadow: 0px 2px 6px 0px rgba(31,35,41,0.08);
  border-radius: 6px;
  font-family: PingFangSC-Medium;
  font-size: 13px;
  color: #2A87FF;
  font-weight: 500;
  width: 26px;
  height: 26px;
}
#prevbtn, #nextbtn {
  width: 26px;
  height: 26px;
  text-align: center;
  border: 1px solid #E9ECF3;
  box-sizing: border-box;
  border-radius: 6px;
}
.page-number:hover, #prevbtn:hover, #nextbtn:hover {
  background: #FFFFFF;
  border: 1px solid rgba(82,157,255,1);
  box-shadow: 0px 2px 6px 0px rgba(31,35,41,0.06);
  border-radius: 6px;
  font-family: PingFangSC-Regular;
  font-size: 13px;
  color: #529DFF;
  font-weight: 400;
}
.page-number {
  /* width: 26px; */
  height: 26px;
  background: #FFFFFF;
  border: 1px solid rgba(232,235,242,1);
  box-shadow: 0px 2px 6px 0px rgba(31,35,41,0.06);
  border-radius: 6px;
  font-family: PingFangSC-Regular;
  font-size: 13px;
  color: #2D2F33;
  font-weight: 400;
}
.custom-pagination .ant-dropdown-link {
  line-height: 26px;
  padding: 0 8px;
}
.custom-pagination .ant-dropdown-link:hover,
.custom-pagination .ant-dropdown-link:hover * {
  color: #529DFF;
}
.custom-pagination .ant-dropdown-link:active,
.custom-pagination .ant-dropdown-link:active * {
  color: #0E6DED;
}
.custom-pagination .ant-dropdown-link>span>svg {
  padding-top: 2px;
}

/* 修复table组件的overflow-y不对齐问题 */
/* 现代浏览器 */
.ant-table-cell-fix-right-first:has(~ .ant-table-cell-scrollbar) {
    right: 8px !important;
}
/* 旧版浏览器备用方案 */
.ant-table-cell-fix-right-first + .ant-table-cell-scrollbar ~ .ant-table-cell-fix-right-first {
    right: 8px !important;
}