feat: 分页组件集成到表格
This commit is contained in:
parent
79f1594681
commit
d6949aabd5
|
@ -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 {
|
||||
|
|
|
@ -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',
|
||||
},
|
||||
};
|
||||
|
|
|
@ -4,7 +4,7 @@ export default {
|
|||
current: '当前页数 {current}',
|
||||
countPerPage: '条/页',
|
||||
pageSize: '每页条数',
|
||||
goto: '前往',
|
||||
page: '页',
|
||||
goto: '跳至',
|
||||
page: '/{page} 页',
|
||||
},
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
},
|
||||
|
|
|
@ -15,5 +15,6 @@
|
|||
"pageSize": 10,
|
||||
"showPageSize": true,
|
||||
"showTotal": true,
|
||||
"showJumper": true
|
||||
}
|
||||
"showJumper": true,
|
||||
"hideOnSinglePage": false
|
||||
}
|
||||
|
|
|
@ -23,6 +23,10 @@ export interface AppState {
|
|||
currentOrgId: string;
|
||||
currentProjectId: string;
|
||||
pageSize: number;
|
||||
showPageSize: boolean;
|
||||
showTotal: boolean;
|
||||
showJumper: boolean;
|
||||
hideOnSinglePage: boolean;
|
||||
[key: string]: unknown;
|
||||
}
|
||||
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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();
|
||||
|
|
Loading…
Reference in New Issue