TablePage 介绍
该组件是基于 Element-plus 框架的 Table 和 Pagination 的二次封装,用于更方便的展示表格和分页。
基本使用
包含基本的 tableConfig pageConfig 配置。相关的属性配置可参考 element-plus 官网。
可通过 emptyCellContent 设置单元格占位符,默认为 ‘-’。
NOTE
此 table 样式仅供参考,因为 vitepree 的样式有覆盖 element-plus 样式,具体展示样式情况已实际项目为准,或参考 element-plus 官网样式。
共 0 条前往
- 1
页
<template>
<ZpTablePage
:tableConfig="tablePageData.tableConfig"
:pageConfig="tablePageData.pageConfig"
emptyCellContent="--"
@onSelectionChange="changeTableSelection"
@onChangePageCurrent="changePageCurrent"
@onChangePageSize="changePageSize"
>
<template #operationColumn>
<el-table-column width="120" fixed="right">
<template #header>操作</template>
<template #default="{ row }">
<el-button type="primary" link @click="goDetail(row)"> 详情 </el-button>
</template>
</el-table-column>
</template>
</ZpTablePage>
</template>
<script setup lang="ts">
import { reactive, onMounted } from 'vue';
import { resData } from './utils/const';
const tablePageData = reactive<{ [key: string]: any }>({
tableConfig: {
loading: false,
columns: [
{ label: '全选', type: 'selection', width: 60, align: 'center', fixed: 'left' },
{ label: 'id', prop: 'id', minWidth: 100 },
{ label: '姓名', prop: 'aa', minWidth: 100 },
{ label: '手机号', prop: 'bb', minWidth: 100 },
],
data: [],
},
pageConfig: {
currentPage: 1,
pageSize: 10,
total: 0,
},
});
// 获取数据
const getData = async () => {
const { currentPage, pageSize } = tablePageData.pageConfig;
const _params = {
index: currentPage,
sise: pageSize,
};
console.log('参数', _params);
try {
tablePageData.tableConfig.loading = true;
setTimeout(() => {
tablePageData.tableConfig.data = resData;
tablePageData.pageConfig.total = 100;
tablePageData.tableConfig.loading = false;
}, 1000);
} catch (error) {
tablePageData.tableConfig.loading = false;
console.log(error);
}
};
// change-分页页码
const changePageCurrent = (val) => {
tablePageData.pageConfig.currentPage = val;
getData();
};
// change-分页条数
const changePageSize = (val) => {
tablePageData.pageConfig.pageSize = val;
tablePageData.pageConfig.currentPage = 1;
getData();
};
// change-表格复选框
const changeTableSelection = (data) => {
console.log('选中的数据', data);
};
// 跳转详情
const goDetail = (row) => {
console.log('当前行数据:', row);
};
onMounted(() => {
getData();
});
</script>
<style lang="less" scoped></style>点击查看代码
ts
const resData = [
{
id: 1,
aa: '张三',
bb: '18258261040',
cc: 1,
dd: true,
ee: 1,
ff: 1,
gg: '2024-01',
hh: 1,
},
{
id: 2,
aa: '李四',
bb: '18258261041',
cc: 2,
dd: false,
ee: 2,
ff: 2,
gg: null,
hh: 1,
},
{
id: 3,
aa: '王五',
bb: '18258261042',
cc: 3,
dd: true,
ee: 3,
ff: 3,
gg: null,
hh: 2,
},
{
id: 4,
aa: '赵六',
bb: null,
cc: 1,
dd: null,
ee: 4,
ff: 4,
gg: null,
hh: 2,
},
];
export { resData };列值转换
根据接口返回的值,前端转换成相应的数据。对于圆点状态列,需自己项目安装view-ui-plus,自己书写slotColumns.vue组件即可。
失败
共 0 条前往
- 1
页
<template>
<ZpTablePage
:tableConfig="tablePageData.tableConfig"
:pageConfig="tablePageData.pageConfig"
@onChangePageCurrent="changePageCurrent"
@onChangePageSize="changePageSize"
>
<template #dd="{ scope: { row } }">
<SlotColumns slotType="text" :value="row.dd" :options="['成功', '失败']" />
</template>
<template #ee="{ scope: { row } }">
<SlotColumns
slotType="text"
:value="row.ee"
:options="[
{ text: '状态1', type: 'primary', value: 1 },
{ text: '状态2', type: 'success', value: 2 },
{ text: '状态3', type: 'warning', value: 3 },
{ text: '状态4', type: 'danger', value: 4 },
]"
/>
</template>
<!--<template #ff="{ scope: { row } }">
<SlotColumns
slotType="badge"
:value="row.ff"
:options="[
{ text: '通过', color: 'green', value: 1 },
{ text: '不通过', color: 'red', value: 2 },
{ text: '进行中', color: 'orange', value: 3 },
{ text: '审核中', color: 'purple', value: 4 },
]"
/>
</template>-->
</ZpTablePage>
</template>
<script setup lang="ts">
import { reactive, onMounted } from 'vue';
import { resData } from './utils/const';
import { getLabelByValue, progressStatusDict } from './utils/dicts';
import SlotColumns from './components/slotColumns.vue';
const tablePageData = reactive<{ [key: string]: any }>({
tableConfig: {
loading: false,
columns: [
{ label: '姓名', prop: 'aa', minWidth: 100 },
{ label: '手机号', prop: 'bb', minWidth: 100 },
{ label: '进度状态', prop: '_cc', minWidth: 100 },
{ label: '简单状态', prop: 'dd', minWidth: 100, slotName: 'dd' },
{ label: '复杂状态', prop: 'ee', minWidth: 100, slotName: 'ee' },
{ label: '圆点状态', prop: 'ff', minWidth: 100, slotName: 'ff' },
],
data: [],
},
pageConfig: {
currentPage: 1,
pageSize: 10,
total: 0,
},
});
// 获取数据
const getData = async () => {
const { currentPage, pageSize } = tablePageData.pageConfig;
const _params = {
index: currentPage,
sise: pageSize,
};
console.log('参数', _params);
try {
tablePageData.tableConfig.loading = true;
setTimeout(() => {
tablePageData.tableConfig.data = resData.map((item: { [key: string]: any }) => {
item._cc = getLabelByValue(progressStatusDict, item.cc);
return item;
});
tablePageData.pageConfig.total = 100;
tablePageData.tableConfig.loading = false;
}, 1000);
} catch (error) {
tablePageData.tableConfig.loading = false;
console.log(error);
}
};
// change-分页页码
const changePageCurrent = (val) => {
tablePageData.pageConfig.currentPage = val;
getData();
};
// change-分页条数
const changePageSize = (val) => {
tablePageData.pageConfig.pageSize = val;
tablePageData.pageConfig.currentPage = 1;
getData();
};
onMounted(() => {
getData();
});
</script>
<style lang="less" scoped></style>点击查看代码
ts
const resData = [
{
id: 1,
aa: '张三',
bb: '18258261040',
cc: 1,
dd: true,
ee: 1,
ff: 1,
gg: '2024-01',
hh: 1,
},
{
id: 2,
aa: '李四',
bb: '18258261041',
cc: 2,
dd: false,
ee: 2,
ff: 2,
gg: null,
hh: 1,
},
{
id: 3,
aa: '王五',
bb: '18258261042',
cc: 3,
dd: true,
ee: 3,
ff: 3,
gg: null,
hh: 2,
},
{
id: 4,
aa: '赵六',
bb: null,
cc: 1,
dd: null,
ee: 4,
ff: 4,
gg: null,
hh: 2,
},
];
export { resData };ts
// 字典集合
/**
* @description 默认获取label值
* @param {Array} options 字典数组
* @param {Number} value value值,(如果是多个用','隔开,如:value:'1,2')
* @param {String} label 取某个key的值,默认label
* @returns {String} 返回value对应的文本汉字值
*/
export const getLabelByValue = (options, value, label = 'label') => {
if ([null, undefined, ''].includes(value)) {
return '-';
}
const _list = options.filter((item) => String(value).split(',').includes(String(item.value)));
const _label = _list.map((item) => item[label]).join('、');
return _label;
};
// 【进度状态】
export const progressStatusDict = [
{ value: 1, label: '进行中' },
{ value: 2, label: '失败' },
{ value: 3, label: '成功' },
];vue
<template>
<template v-if="slotType === 'text'">
<!--简单文本-->
<el-text :type="!!Number(value) ? 'success' : 'danger'" v-if="isSimpleTextStatus">
{{ !!Number(value) ? options[0] : options[1] }}
</el-text>
<!--复杂文本-->
<el-text :type="getItemByValue(value).type" v-else>
{{ getItemByValue(value).text }}
</el-text>
</template>
<!--<template v-if="slotType === 'badge'">
<Badge :color="getItemByValue(value).color" :text="getItemByValue(value).text" />
</template>-->
</template>
<script setup lang="ts">
import { computed } from 'vue';
//import { Badge } from 'view-ui-plus';
const props = defineProps({
// 插槽模板类型
slotType: {
type: String,
default: () => 'text', // text-文字 badge-小圆点+文字
},
// 值
value: {
type: [Boolean, String, Number],
default: () => null,
},
// 选项-数组
options: {
type: Array,
default: () => ['成功', '失败'],
},
});
// 是否为简单文本状态(即只有2种状态)
const isSimpleTextStatus = computed(() => {
return isStringArray(props.options);
});
// 是否是字符串数组
const isStringArray = (arr) => {
if (!Array.isArray(arr)) {
return false;
}
return arr.every((item) => typeof item === 'string');
};
// 获取某项,通过value
const getItemByValue = (value: string | number | boolean): any => {
const _list: any[] = props.options.filter((item: any) => item.value === value);
return _list.length > 0 && _list[0];
};
</script>自定义列模板
自定义列的展示形式,通过插槽的形式,插入到表格中。
共 0 条前往
- 1
页
<template>
<ZpTablePage
:tableConfig="tablePageData.tableConfig"
:pageConfig="tablePageData.pageConfig"
@onChangePageCurrent="changePageCurrent"
@onChangePageSize="changePageSize"
>
<template #gg="{ scope: { row } }">
<el-date-picker
v-model="row.gg"
type="month"
placeholder="请选择"
format="YYYY-MM"
valueFormat="YYYY-MM"
class="yp-picker"
@change="(val) => changeMonth(val, row)"
/>
</template>
</ZpTablePage>
</template>
<script setup lang="ts">
import { reactive, onMounted } from 'vue';
import { resData } from './utils/const';
const tablePageData = reactive<{ [key: string]: any }>({
tableConfig: {
loading: false,
columns: [
{ label: '姓名', prop: 'aa', minWidth: 100 },
{ label: '手机号', prop: 'bb', minWidth: 100 },
{ label: '月份', prop: 'gg', minWidth: 100, slotName: 'gg' },
],
data: [],
},
pageConfig: {
currentPage: 1,
pageSize: 10,
total: 0,
},
});
// 获取数据
const getData = async () => {
const { currentPage, pageSize } = tablePageData.pageConfig;
const _params = {
index: currentPage,
sise: pageSize,
};
console.log('参数', _params);
try {
tablePageData.tableConfig.loading = true;
setTimeout(() => {
tablePageData.tableConfig.data = resData;
tablePageData.pageConfig.total = 100;
tablePageData.tableConfig.loading = false;
}, 1000);
} catch (error) {
tablePageData.tableConfig.loading = false;
console.log(error);
}
};
// change-分页页码
const changePageCurrent = (val) => {
tablePageData.pageConfig.currentPage = val;
getData();
};
// change-分页条数
const changePageSize = (val) => {
tablePageData.pageConfig.pageSize = val;
tablePageData.pageConfig.currentPage = 1;
getData();
};
// change-月份
const changeMonth = (val, row) => {
console.log('value&当前行数据:', val, row);
};
onMounted(() => {
getData();
});
</script>
<style lang="less" scoped></style>点击查看代码
ts
const resData = [
{
id: 1,
aa: '张三',
bb: '18258261040',
cc: 1,
dd: true,
ee: 1,
ff: 1,
gg: '2024-01',
hh: 1,
},
{
id: 2,
aa: '李四',
bb: '18258261041',
cc: 2,
dd: false,
ee: 2,
ff: 2,
gg: null,
hh: 1,
},
{
id: 3,
aa: '王五',
bb: '18258261042',
cc: 3,
dd: true,
ee: 3,
ff: 3,
gg: null,
hh: 2,
},
{
id: 4,
aa: '赵六',
bb: null,
cc: 1,
dd: null,
ee: 4,
ff: 4,
gg: null,
hh: 2,
},
];
export { resData };整合:查询表单+表格分页
SearchForm 查询表单和 TablePage 表格分页,一起整合使用。
共 0 条前往
- 1
页
<template>
<ZpSearchForm :formList="formList" @onSubmit="onSubmit" @onReset="onReset" ref="zpSearchFormRef" />
<ZpTablePage
:tableConfig="tablePageData.tableConfig"
:pageConfig="tablePageData.pageConfig"
@onChangePageCurrent="changePageCurrent"
@onChangePageSize="changePageSize"
>
<template #operationColumn>
<el-table-column width="120" fixed="right">
<template #header>操作</template>
<template #default="{ row }">
<el-button type="primary" link @click="goDetail(row)"> 详情 </el-button>
</template>
</el-table-column>
</template>
</ZpTablePage>
</template>
<script setup lang="ts">
import { ref, reactive, onMounted } from 'vue';
import { resData } from './utils/const';
const zpSearchFormRef = ref<any>(null);
const formList = reactive([
{ type: 'input', label: '输入框', prop: 'aa' },
{
type: 'select',
label: '下拉框',
prop: 'bb',
value: 'hangzhou',
options: [
{ label: '上海', value: 'shanghai' },
{ label: '杭州', value: 'hangzhou' },
{ label: '北京', value: 'beijing' },
],
},
{
type: 'cascader',
label: '级联',
prop: 'cc',
options: [
{
label: '安徽',
value: 'anhui',
children: [
{
label: '合肥',
value: 'hefei',
},
],
},
{
label: '福建',
value: 'fujian',
children: [
{
label: '厦门',
value: 'xiamen',
},
],
},
],
},
]);
const tablePageData = reactive<{ [key: string]: any }>({
tableConfig: {
loading: false,
columns: [
{ label: 'id', prop: 'id', minWidth: 100 },
{ label: '姓名', prop: 'aa', minWidth: 100 },
{ label: '手机号', prop: 'bb', minWidth: 100 },
],
data: [],
},
pageConfig: {
currentPage: 1,
pageSize: 10,
total: 0,
},
});
// 获取数据
const getData = async () => {
const formData = zpSearchFormRef.value.getFormData();
const { currentPage, pageSize } = tablePageData.pageConfig;
const _params = {
...formData,
index: currentPage,
sise: pageSize,
};
console.log('参数', _params);
try {
tablePageData.tableConfig.loading = true;
setTimeout(() => {
tablePageData.tableConfig.data = resData;
tablePageData.pageConfig.total = 100;
tablePageData.tableConfig.loading = false;
}, 1000);
} catch (error) {
tablePageData.tableConfig.loading = false;
console.log(error);
}
};
// 查询
const onSubmit = () => {
tablePageData.pageConfig.currentPage = 1;
getData();
};
// 重置
const onReset = () => {
tablePageData.pageConfig.pageSize = 10;
tablePageData.pageConfig.currentPage = 1;
getData();
};
// change-分页页码
const changePageCurrent = (val) => {
tablePageData.pageConfig.currentPage = val;
getData();
};
// change-分页条数
const changePageSize = (val) => {
tablePageData.pageConfig.pageSize = val;
tablePageData.pageConfig.currentPage = 1;
getData();
};
// 跳转详情
const goDetail = (row) => {
console.log('当前行数据:', row);
};
onMounted(() => {
getData();
});
</script>
<style lang="less" scoped></style>点击查看代码
ts
const resData = [
{
id: 1,
aa: '张三',
bb: '18258261040',
cc: 1,
dd: true,
ee: 1,
ff: 1,
gg: '2024-01',
hh: 1,
},
{
id: 2,
aa: '李四',
bb: '18258261041',
cc: 2,
dd: false,
ee: 2,
ff: 2,
gg: null,
hh: 1,
},
{
id: 3,
aa: '王五',
bb: '18258261042',
cc: 3,
dd: true,
ee: 3,
ff: 3,
gg: null,
hh: 2,
},
{
id: 4,
aa: '赵六',
bb: null,
cc: 1,
dd: null,
ee: 4,
ff: 4,
gg: null,
hh: 2,
},
];
export { resData };主体内容插槽
在表格和分页之间插入自定义内容。
你好,这是自定义内容
共 0 条前往
- 1
页
<template>
<ZpTablePage
:tableConfig="tablePageData.tableConfig"
:pageConfig="tablePageData.pageConfig"
@onChangePageCurrent="changePageCurrent"
@onChangePageSize="changePageSize"
>
<template #main>
<div>你好,这是自定义内容</div>
</template>
</ZpTablePage>
</template>
<script setup lang="ts">
import { reactive, onMounted } from 'vue';
import { resData } from './utils/const';
const tablePageData = reactive<{ [key: string]: any }>({
tableConfig: {
loading: false,
columns: [
{ label: 'id', prop: 'id', minWidth: 100 },
{ label: '姓名', prop: 'aa', minWidth: 100 },
{ label: '手机号', prop: 'bb', minWidth: 100 },
],
data: [],
},
pageConfig: {
currentPage: 1,
pageSize: 10,
total: 0,
},
});
// 获取数据
const getData = async () => {
const { currentPage, pageSize } = tablePageData.pageConfig;
const _params = {
index: currentPage,
sise: pageSize,
};
console.log('参数', _params);
try {
tablePageData.tableConfig.loading = true;
setTimeout(() => {
tablePageData.tableConfig.data = resData;
tablePageData.pageConfig.total = 100;
tablePageData.tableConfig.loading = false;
}, 1000);
} catch (error) {
tablePageData.tableConfig.loading = false;
console.log(error);
}
};
// change-分页页码
const changePageCurrent = (val) => {
tablePageData.pageConfig.currentPage = val;
getData();
};
// change-分页条数
const changePageSize = (val) => {
tablePageData.pageConfig.pageSize = val;
tablePageData.pageConfig.currentPage = 1;
getData();
};
onMounted(() => {
getData();
});
</script>
<style lang="less" scoped></style>合并单元格
合并列的单元格。
共 0 条前往
- 1
页
<template>
<ZpTablePage
:tableConfig="tablePageData.tableConfig"
:pageConfig="tablePageData.pageConfig"
@onChangePageCurrent="changePageCurrent"
@onChangePageSize="changePageSize"
/>
</template>
<script setup lang="ts">
import { reactive, onMounted } from 'vue';
import { resData } from './utils/const';
import { transToMergeCellList } from '../../../packages/utils/util.tool';
const tablePageData = reactive<{ [key: string]: any }>({
tableConfig: {
loading: false,
columns: [
{ label: '编号', prop: 'hh', minWidth: 100 },
{ label: '姓名', prop: 'aa', minWidth: 100 },
{ label: '手机号', prop: 'bb', minWidth: 100 },
],
data: [],
spanMethod: ({ row, columnIndex }) => {
switch (columnIndex) {
case 0:
return [row['hh'] ? row['hhRowSpan'] : 1, 1];
}
},
},
pageConfig: {
currentPage: 1,
pageSize: 10,
total: 0,
},
});
// 获取数据
const getData = async () => {
const { currentPage, pageSize } = tablePageData.pageConfig;
const _params = {
index: currentPage,
sise: pageSize,
};
console.log('参数', _params);
try {
tablePageData.tableConfig.loading = true;
setTimeout(() => {
tablePageData.tableConfig.data = transToMergeCellList(resData, ['hh']);
tablePageData.pageConfig.total = 100;
tablePageData.tableConfig.loading = false;
}, 1000);
} catch (error) {
tablePageData.tableConfig.loading = false;
console.log(error);
}
};
// change-分页页码
const changePageCurrent = (val) => {
tablePageData.pageConfig.currentPage = val;
getData();
};
// change-分页条数
const changePageSize = (val) => {
tablePageData.pageConfig.pageSize = val;
tablePageData.pageConfig.currentPage = 1;
getData();
};
onMounted(() => {
getData();
});
</script>
<style lang="less" scoped></style>API
Attributes
| 属性名 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| tableConfig | 设置表单表格的属性,继承至 element-plus 的 Table API | object | {} |
| pageConfig | 设置分页的属性,继承至 element-plus 的 Pagination API | object | {} |
| isHasPage | 是否有分页 | boolean | true |
| emptyCellContent | 空单元格内容 | string | - |
Events
| 方法名 | 说明 | 类型 |
|---|---|---|
| onSelectionChange | 勾选表格前面的复选框时触发 | Function |
| onRowClick | 点击表格行时触发 | Function |
| onChangePageCurrent | 切换分页页码时触发 | Function |
| onChangePageSize | 切换分页条数时触发 | Function |
Slot
| 插槽名 | 说明 |
|---|---|
| main | 在表格和分页之间插入自定义内容 |
