feat: 分页组件集成到表格

This commit is contained in:
RubyLiu 2023-08-01 18:48:19 +08:00 committed by fit2-zhao
parent 79f1594681
commit d6949aabd5
11 changed files with 173 additions and 101 deletions

View File

@ -491,6 +491,36 @@
}
/** 分页 **/
.arco-pagination {
display: flex;
justify-content: flex-end;
align-items: center;
gap: 16px;
}
.arco-pagination-list {
display: flex;
flex-direction: row;
}
.arco-pagination-jumper {
padding: 2px 8px;
background: var(--color-text-n9);
}
.arco-pagination-jumper-input {
padding: 3px 8px;
width: 57px;
height: 28px;
border: 1px solid var(--color-text-input-border);
border-radius: 3px;
box-sizing: border-box;
}
.arco-pagination-jumper-total-page {
margin-right: 0;
margin-left: 8px;
color: var(--color-text-2);
}
.arco-pagination-simple .arco-pagination-jumper .arco-pagination-jumper-input {
width: 57px;
}
.arco-pagination-total {
color: var(--color-text-2) !important;
}
@ -504,6 +534,20 @@
margin-left: 14px !important;
}
.arco-pagination-size-small .arco-pagination-item {
display: flex;
justify-content: center;
align-items: center;
padding: 5px 0;
width: 32px;
height: 32px;
box-sizing: border-box;
}
.arco-pagination-item-ellipsis:hover {
width: 32px;
height: 32px;
}
.arco-pagination-size-small
.arco-pagination-item:not(:last-child):not(:first-child):not(.arco-pagination-item-ellipsis) {
border: 1px solid var(--color-text-input-border);
}
.arco-pagination-item-active {

View File

@ -1,10 +1,10 @@
export default {
msPagination: {
total: 'A total of {total} items',
current: 'Current {current}',
current: 'Current page {current}',
countPerPage: 'items/page',
pageSize: 'Page size',
goto: 'Goto',
page: 'Page',
countPerPage: ' / Page',
page: '/{page} pages',
},
};

View File

@ -4,7 +4,7 @@ export default {
current: '当前页数 {current}',
countPerPage: '条/页',
pageSize: '每页条数',
goto: '前往',
page: '页',
goto: '跳至',
page: '/{page} 页',
},
};

View File

@ -1,6 +1,6 @@
<template>
<span :class="cls">
<span v-if="!simple" :class="[`${prefixCls}-prepend`, `${prefixCls}-text-goto`]">
<span :class="[`${prefixCls}-prepend`, `${prefixCls}-text-goto`]">
<slot name="jumper-prepend">{{ t('msPagination.goto') }}</slot>
</span>
<a-input-number
@ -15,15 +15,12 @@
@change="handleChange"
/>
<span v-if="$slots['jumper-append']" :class="`${prefixCls}-append`"><slot name="jumper-append" /></span>
<template v-if="simple">
<span :class="`${prefixCls}-separator`">/</span>
<span :class="`${prefixCls}-total-page`">{{ pages }}</span>
</template>
<span :class="`${prefixCls}-total-page`">{{ t('msPagination.page', { page: pages }) }}</span>
</span>
</template>
<script lang="ts" setup>
import { computed, nextTick, ref, watch } from 'vue';
import { computed, ref, watch } from 'vue';
import { useI18n } from '@/hooks/useI18n';
import { getPrefixCls } from './utils';
@ -56,17 +53,12 @@
};
const handleChange = () => {
emit('change', inputValue.value as number);
nextTick(() => {
if (!props.simple) {
inputValue.value = undefined;
}
});
};
watch(
() => props.current,
(value) => {
if (props.simple && value !== inputValue.value) {
if (value !== inputValue.value) {
inputValue.value = value;
}
}

View File

@ -49,13 +49,21 @@
</a-table-column>
</template>
</a-table>
<div v-if="selectCurrent > 0 && attrs.showSelectAll" class="mt-[21px]">
<div class="ms-table-footer" :class="{ 'batch-action': showBatchAction }">
<batch-action
v-if="showBatchAction"
:select-row-count="selectCurrent"
:action-config="props.actionConfig"
@batch-action="(item: BatchActionParams) => emit('batchAction', item)"
@clear="selectionChange([], true)"
/>
<ms-pagination
v-else-if="attrs.showPagination"
size="small"
v-bind="attrs.msPagination"
@change="pageChange"
@page-size-change="pageSizeChange"
/>
</div>
</div>
</template>
@ -74,7 +82,7 @@
MsTableColumn,
} from './type';
import BatchAction from './batchAction.vue';
import MsPagination from '@/components/pure/ms-pagination/index';
import type { TableData } from '@arco-design/web-vue';
import ColumnSelector from './columnSelector.vue';
@ -90,6 +98,8 @@
const emit = defineEmits<{
(e: 'selectedChange', value: (string | number)[]): void;
(e: 'batchAction', value: BatchActionParams): void;
(e: 'pageChange', value: number): void;
(e: 'pageSizeChange', value: number): void;
}>();
const isSelectAll = ref(false);
const attrs = useAttrs();
@ -145,6 +155,19 @@
}
};
// change
const pageChange = (v: number) => {
emit('pageChange', v);
};
// size change
const pageSizeChange = (v: number) => {
emit('pageSizeChange', v);
};
const showBatchAction = computed(() => {
return selectCurrent.value > 0 && attrs.showSelectAll;
});
//
const getBatchLeft = () => {
if (attrs.enableDrag) {
@ -196,5 +219,17 @@
.title {
color: var(--color-text-3);
}
.ms-table-footer {
display: flex;
justify-content: flex-end;
align-items: center;
padding: 16px 0;
width: 100%;
height: 62px;
flex-flow: row nowrap;
}
.batch-action {
justify-content: flex-start;
}
}
</style>

View File

@ -4,7 +4,11 @@ export interface MsPaginationI {
current: number;
pageSize: number;
total: number;
showPageSize: boolean;
showPageSize?: boolean;
showTotal?: boolean;
showJumper?: boolean;
hideOnSinglePage?: boolean;
simple?: boolean;
}
export interface MsTableColumnData extends TableColumnData {
@ -50,10 +54,11 @@ export interface MsTableProps {
// loading
loading?: boolean;
bordered?: boolean;
// 分页配置
pagination: MsPaginationI | boolean;
msPagination?: MsPaginationI;
// 展示列表选择按钮
showSetting?: boolean;
// 分页是否是简单模式
pageSimple?: boolean;
[key: string]: any;
}

View File

@ -13,7 +13,6 @@ export interface Pagination {
current: number;
pageSize: number;
total: number;
showPageSize: boolean;
}
const appStore = useAppStore();
@ -37,14 +36,6 @@ export default function useTableProps(
loading: true,
data: [] as MsTableData,
columns: [] as MsTableColumn,
pagination: {
current: 1,
pageSize: appStore.pageSize,
total: 0,
showPageSize: appStore.showPageSize,
showTotal: appStore.showTotal,
showJumper: appStore.showJumper,
} as Pagination,
rowKey: 'id',
selectedKeys: [],
selectedAll: false,
@ -52,6 +43,9 @@ export default function useTableProps(
showSelectAll: true,
showSetting: true,
columnResizable: true,
// 禁用 arco-table 的分页
pagination: false,
pageSimple: false,
...props,
};
@ -59,10 +53,14 @@ export default function useTableProps(
const propsRes = ref(defaultProps);
const oldPagination = ref<Pagination>({
current: 1,
pageSize: 20,
pageSize: appStore.pageSize,
total: 0,
showPageSize: true,
});
showPageSize: appStore.showPageSize,
showTotal: appStore.showTotal,
showJumper: appStore.showJumper,
hideOnSinglePage: appStore.hideOnSinglePage,
simple: defaultProps.pageSimple,
} as Pagination);
// 排序
const sortItem = ref<object>({});
@ -74,8 +72,17 @@ export default function useTableProps(
const keyword = ref('');
// 是否分页
if (!propsRes.value.showPagination) {
propsRes.value.pagination = false;
if (propsRes.value.showPagination) {
propsRes.value.msPagination = {
current: 1,
pageSize: appStore.pageSize,
total: 0,
showPageSize: appStore.showPageSize,
showTotal: appStore.showTotal,
showJumper: appStore.showJumper,
hideOnSinglePage: appStore.hideOnSinglePage,
simple: defaultProps.pageSimple,
};
}
// 是否可选中
@ -105,10 +112,10 @@ export default function useTableProps(
}
const setPagination = ({ current, total }: SetPaginationPrams) => {
if (propsRes.value.pagination && typeof propsRes.value.pagination === 'object') {
propsRes.value.pagination.current = current;
if (propsRes.value.msPagination && typeof propsRes.value.msPagination === 'object') {
propsRes.value.msPagination.current = current;
if (total) {
propsRes.value.pagination.total = total;
propsRes.value.msPagination.total = total;
}
}
};
@ -134,7 +141,7 @@ export default function useTableProps(
// 加载分页列表数据
const loadList = async () => {
const { current, pageSize } = propsRes.value.pagination as Pagination;
const { current, pageSize } = propsRes.value.msPagination as Pagination;
setLoading(true);
try {
const data = await loadListFunc({
@ -168,9 +175,9 @@ export default function useTableProps(
// 重置页码和条数
const resetPagination = () => {
if (propsRes.value.pagination && typeof propsRes.value.pagination === 'object') {
propsRes.value.pagination.current = 1;
propsRes.value.pagination.pageSize = appStore.pageSize;
if (propsRes.value.msPagination) {
propsRes.value.msPagination.current = 1;
propsRes.value.msPagination.pageSize = appStore.pageSize;
}
};
@ -195,18 +202,19 @@ export default function useTableProps(
},
// 修改每页显示条数
pageSizeChange: (pageSize: number) => {
if (propsRes.value.pagination && typeof propsRes.value.pagination === 'object') {
propsRes.value.pagination.pageSize = pageSize;
if (propsRes.value.msPagination && typeof propsRes.value.msPagination === 'object') {
propsRes.value.msPagination.pageSize = pageSize;
}
loadList();
},
// 选择触发
selectedChange: (arr: (string | number)[]) => {
if (arr.length === 0) {
propsRes.value.pagination = oldPagination.value;
propsRes.value.showPagination = true;
propsRes.value.msPagination = oldPagination.value;
} else {
oldPagination.value = propsRes.value.pagination as Pagination;
propsRes.value.pagination = false;
oldPagination.value = propsRes.value.msPagination as Pagination;
propsRes.value.showPagination = false;
}
propsRes.value.selectedKeys = arr;
},

View File

@ -15,5 +15,6 @@
"pageSize": 10,
"showPageSize": true,
"showTotal": true,
"showJumper": true
}
"showJumper": true,
"hideOnSinglePage": false
}

View File

@ -23,6 +23,10 @@ export interface AppState {
currentOrgId: string;
currentProjectId: string;
pageSize: number;
showPageSize: boolean;
showTotal: boolean;
showJumper: boolean;
hideOnSinglePage: boolean;
[key: string]: unknown;
}

View File

@ -1,31 +1,11 @@
<template>
<div>BugManagement is waiting for development </div>
<div class="continer">
<ms-pagination
v-modal:page-size="pageSize"
size="small"
:total="100"
show-total
show-jumper
show-more
show-page-size
/>
</div>
<MsCard simple>
<h1>BugManagement is waiting for development </h1>
<ms-pagination size="small" :total="100" show-jumper />
</MsCard>
</template>
<script setup>
import { ref } from 'vue';
import MsPagination from '@/components/pure/ms-pagination/index';
const pageSize = ref(10);
import MsCard from '@/components/pure/ms-card/index.vue';
</script>
<style lang="less" scoped>
.continer {
margin-top: 200px;
padding: 50px;
width: 100%;
height: 500px;
background-color: #ffffff;
}
</style>

View File

@ -1,44 +1,47 @@
<template>
<div class="user-group flex flex-row bg-white">
<div class="user-group-left">
<user-group-left v-if="collapse" />
<div class="usergroup-collapse">
<icon-double-left v-if="collapse" class="icon" @click="collapse = false" />
<icon-double-right v-else class="icon" @click="collapse = true" />
</div>
</div>
<div class="grow-1 w-[100%] overflow-x-scroll p-[24px]">
<div class="grow-1 flex flex-row items-center justify-between">
<div class="title">{{ store.userGroupInfo.currentName }}</div>
<div class="flex items-center">
<a-input class="w-[240px]" :placeholder="t('system.userGroup.searchPlacehoder')">
<template #prefix>
<icon-search />
</template>
</a-input>
<a-radio-group v-model="currentTable" class="ml-[14px]" type="button">
<a-radio value="auth">{{ t('system.userGroup.auth') }}</a-radio>
<a-radio value="user">{{ t('system.userGroup.user') }}</a-radio>
</a-radio-group>
<MsCard simple>
<div class="flex flex-row">
<div class="user-group-left">
<user-group-left v-if="collapse" />
<div class="usergroup-collapse">
<icon-double-left v-if="collapse" class="icon" @click="collapse = false" />
<icon-double-right v-else class="icon" @click="collapse = true" />
</div>
</div>
<div class="grow-1 mt-[16px]">
<user-table v-if="currentTable === 'user'" />
<auth-table v-if="currentTable === 'auth'" />
<div class="grow-1 w-[100%] overflow-x-scroll p-[24px]">
<div class="grow-1 flex flex-row items-center justify-between">
<div class="title">{{ store.userGroupInfo.currentName }}</div>
<div class="flex items-center">
<a-input class="w-[240px]" :placeholder="t('system.userGroup.searchPlacehoder')">
<template #prefix>
<icon-search />
</template>
</a-input>
<a-radio-group v-model="currentTable" class="ml-[14px]" type="button">
<a-radio value="auth">{{ t('system.userGroup.auth') }}</a-radio>
<a-radio value="user">{{ t('system.userGroup.user') }}</a-radio>
</a-radio-group>
</div>
</div>
<div class="grow-1 mt-[16px]">
<user-table v-if="currentTable === 'user'" />
<auth-table v-if="currentTable === 'auth'" />
</div>
</div>
</div>
</div>
</MsCard>
</template>
<script lang="ts" setup>
import { ref } from 'vue';
import { useI18n } from '@/hooks/useI18n';
import MsCard from '@/components/pure/ms-card/index.vue';
import useUserGroupStore from '@/store/modules/setting/usergroup';
import UserGroupLeft from './components/index.vue';
import UserTable from './components/userTable.vue';
import AuthTable from './components/authTable.vue';
const currentTable = ref('auth');
const currentTable = ref('user');
const collapse = ref(true);
const { t } = useI18n();