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 { .arco-pagination-total {
color: var(--color-text-2) !important; color: var(--color-text-2) !important;
} }
@ -504,6 +534,20 @@
margin-left: 14px !important; margin-left: 14px !important;
} }
.arco-pagination-size-small .arco-pagination-item { .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); border: 1px solid var(--color-text-input-border);
} }
.arco-pagination-item-active { .arco-pagination-item-active {

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,5 +1,6 @@
<template> <template>
<div class="user-group flex flex-row bg-white"> <MsCard simple>
<div class="flex flex-row">
<div class="user-group-left"> <div class="user-group-left">
<user-group-left v-if="collapse" /> <user-group-left v-if="collapse" />
<div class="usergroup-collapse"> <div class="usergroup-collapse">
@ -28,17 +29,19 @@
</div> </div>
</div> </div>
</div> </div>
</MsCard>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { ref } from 'vue'; import { ref } from 'vue';
import { useI18n } from '@/hooks/useI18n'; import { useI18n } from '@/hooks/useI18n';
import MsCard from '@/components/pure/ms-card/index.vue';
import useUserGroupStore from '@/store/modules/setting/usergroup'; import useUserGroupStore from '@/store/modules/setting/usergroup';
import UserGroupLeft from './components/index.vue'; import UserGroupLeft from './components/index.vue';
import UserTable from './components/userTable.vue'; import UserTable from './components/userTable.vue';
import AuthTable from './components/authTable.vue'; import AuthTable from './components/authTable.vue';
const currentTable = ref('auth'); const currentTable = ref('user');
const collapse = ref(true); const collapse = ref(true);
const { t } = useI18n(); const { t } = useI18n();