Skip to content

TablePage 介绍

该组件是基于 Element-plus 框架的 TablePagination 的二次封装,用于更方便的展示表格和分页。

基本使用

包含基本的 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-plusTable APIobject{}
pageConfig设置分页的属性,继承至 element-plusPagination APIobject{}
isHasPage是否有分页booleantrue
emptyCellContent空单元格内容string-

Events

方法名说明类型
onSelectionChange勾选表格前面的复选框时触发Function
onRowClick点击表格行时触发Function
onChangePageCurrent切换分页页码时触发Function
onChangePageSize切换分页条数时触发Function

Slot

插槽名说明
main在表格和分页之间插入自定义内容