vue3中table封装

文章描述了一个使用Vue编写的前端组件,展示了如何创建一个可定制的表格,支持列的动态显示、排序、分页以及数据绑定功能,适用于内容社区或IT项目中数据展示的需求。
摘要由CSDN通过智能技术生成

<template>

    <div class="com-table">

        <div class="header">

            <slot name="header">

                <div>

                    <el-button class="add_btn" size="small" type="success" @click="onAdd">{{ $t('message.form.add') }}</el-button>

                    <el-button size="small" type="danger" class="ml10 del_btn" @click="onBatDel">{{ $t('message.form.delete') }}</el-button>

                </div>

                <div class="layout-flex">

                    <ui-form v-bind="searchForm" :modelValue="queryParams" @updateQueryParams="updateQueryParams"></ui-form>

                    <el-button size="small" type="primary" class="ml10 search_btn" @click="handleSearch">

                        <el-icon>

                            <elementSearch />

                        </el-icon>

                        {{ $t('message.form.search') }}

                    </el-button>

                </div>

            </slot>

        </div>

        <el-table

            class="table"

            style="width: 100%"

            :rowKey="rowKey"

            :data="tableData"

            @sort-change="handleSortChange"

            @selection-change="handleSelectionChange"

            :header-cell-style="headerCellStyle"

        >

            <el-table-column v-if="showSelectColumn" type="selection" width="40" />

            <el-table-column v-if="showIndexColumn" type="index" :index="handleIndex" width="60" label="序号" align="center"></el-table-column>

            <template v-for="item in colList" :key="item.colName">

                <el-table-column v-bind="item" align="left" :show-overflow-tooltip="item.overTip ?? true" :fixed="item.fixed" :sortable="item.sort">

                    <template #default="scope">

                        <slot :name="item.colName" :row="scope.row">{{ scope.row[item.colName] }}</slot>

                    </template>

                </el-table-column>

            </template>

        </el-table>

        <div class="footer">

            <slot name="footer">

                <el-pagination

                    background

                    :currentPage="currPage"

                    :page-size="pageSize"

                    :page-sizes="[10, 50, 100, 500]"

                    layout="total, sizes, prev, pager, next, jumper"

                    :total="total"

                    @size-change="handleSizeChange"

                    @current-change="handleCurrentChange"

                >

                </el-pagination>

            </slot>

        </div>

    </div>

</template>

<script lang="ts">

import { defineComponent, ref, watch, computed } from 'vue';

import UiForm from '/@/components/uiForm/index';

import { useStore } from '/@/store/index';

import { useRoute } from 'vue-router';

export default defineComponent({

    components: {

        UiForm,

    },

    props: {

        tableData: {

            type: Array,

            required: true,

        },

        rowKey: {

            type: String,

        },

        sortVal: {

            type: Object,

            default: {

                prop: 'createTime',

            },

        },

        headerCellStyle: {

            type: Object,

        },

        colList: {

            type: Array,

            required: true,

        },

        queryParams: {

            type: Object,

            default: {

                currPage: 1,

                pageSize: 10,

                totalCount: 0,

                totalPage: 0,

            },

        },

        searchForm: {

            type: Object,

        },

        showIndexColumn: {

            type: Boolean,

            default: false,

        },

        showSelectColumn: {

            type: Boolean,

            default: false,

        },

        currPage: {

            type: Number,

            default: 1,

        },

        pageSize: {

            type: Number,

            default: 10,

        },

        total: {

            type: Number,

            default: 0,

        },

    },

    emits: ['selectionChange', 'paramsChange', 'updateQueryParams', 'btnAdd', 'batDel', 'sortChange'],

    setup(props, { emit }) {

        console.log(props);

        const formData = ref({ ...props.queryParams });

        const store = useStore();

        const route = useRoute();

        // 通过深度侦听formData的值,改变数据时通过emit告诉父组件数据的更新

        // 实现组件的双向绑定

        console.log('查询表单', formData, props);

        watch(

            () => formData.value,

            (newValue) => {

                console.log('表单监听', newValue);

                emit('updateQueryParams', newValue);

            },

            {

                deep: true,

            }

        );

        const handleIndex = (index: Number) => {

            return (props.currPage - 1) * props.pageSize + index + 1;

        };

        const handleSelectionChange = (val: any) => {

            console.log(val);

            emit('selectionChange', val);

        };

        function handleSortChange(val: any) {

            emit('sortChange', val);

        }

        const handleSizeChange = (pageSize: number) => {

            emit('paramsChange', { currPage: props.currPage, pageSize: pageSize });

        };

        const handleCurrentChange = (currentPage: number) => {

            emit('paramsChange', { currPage: currentPage, pageSize: props.pageSize });

        };

        const handleSearch = () => {

            emit('paramsChange', props.queryParams);

        };

        const updateQueryParams = (val) => {

            console.log('查询参数', val);

            emit('updateQueryParams', val);

        };

        const onAdd = () => {

            emit('btnAdd');

        };

        const onBatDel = () => {

            emit('batDel');

        };

        return {

            handleIndex,

            handleSelectionChange,

            handleSizeChange,

            handleCurrentChange,

            handleSearch,

            updateQueryParams,

            handleSortChange,

            onAdd,

            route,

            onBatDel,

        };

    },

});

</script>

<style lang="scss" scoped>

.com-table {

    width: 100%;

}

.header {

    margin-bottom: 15px;

    width: 100%;

    display: flex;

    justify-content: space-between;

    align-items: center;

}

.footer {

    margin-top: 10px;

    width: 100%;

}

.flatType {

    color: #fff;

    span {

        cursor: pointer;

    }

}

.softTitle {

    display: flex;

    align-items: center;

    width: 10rem;

    color: #4a4a4a;

    font-family: PingFang-SC-Heavy;

    .softIcon {

        width: 1.375rem;

        height: 1.4375rem;

        background: url(#{$static-domain}/cubemagic/img/icon/softIcon.jpg) no-repeat;

        background-size: 100% 100% !important;

        margin-right: 0.625rem;

    }

    .softs {

        font-size: 18px;

    }

}

</style>

  • 22
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值