基于Element-plus封装的table表格

前言

现如今开发后台管理界面比较多,表格数据展示、表单添加验证、表格查询条件几乎必不可少,但是大都是重复操作,所以封装了表格、表单和表格查询组件来减少代码重复量,后续会发布表单和表格查询组件。


提示:此案例基于element-plus封装,所以确保项目安装element-plus,且项目使用typescript,如果不想使用typescript,请直接移除所有的变量类型定义

以下是表格封装代码,可直接复制使用,具体表格参数可参考element-plus官方文档,如有其他要求,可直接在此基础上修改

<template>
      <el-config-provider :locale="locale">
    <div>
        <el-table ref="table" :data="tableData" :max-height="maxHeight"  v-loading="props.loading"
        :border="border"  highlight-current-row @current-change="currentChange"
      @selection-change="selectionChange"   :row-key="rowKey"
        >
        <el-table-column type="selection" width="55" v-if="selection" />
        <el-table-column
        min-width="50"
        header-align="center"
        align="center"
        label="序号"
        v-if="sort"
      >
        <template #default="scope">
          <span>
            {{
            (Number(pageResult.current) - 1) * Number(pageResult.size) +
            scope.$index +
            1
          }}</span>
        </template>
      </el-table-column>
      <el-table-column
        v-for="(item, index) in column"
        :key="index"
        align="center"
        :label="item.label"
        :prop="item.prop"
        :min-width="item.minWidth"
        :formatter="item.formatter"
        show-overflow-tooltip
      >
      <!-- 如果该数据需要显示其他标签,则使用插槽显示 插槽名称就是column的prop -->
      <template #default="scope" v-if="item.type">
          <slot :name="item.prop" :row="scope.row"></slot>
        </template>
      </el-table-column>
      <el-table-column
        fixed="right"
        label="操作"
        align="center"
        min-width="185"
       v-if="option && !isSlotOption"
      >
        <template #default="scope">
          <el-link
            type="primary"
            size="small"
            @click="edit(scope.row)"
            :underline="false"
            style="margin-right: 5px"
            >编辑</el-link
          >
          <el-popconfirm title="是否删除" @confirm="confirm(scope.row)">
            <template #reference>
              <el-link type="danger" :underline="false">删除</el-link>
            </template>
          </el-popconfirm>
        </template>
      </el-table-column>
      <el-table-column
        v-if=" option && isSlotOption"
        fixed="right"
        label="操作"
        align="center"
        min-width="185"
      >
      <template #default="scope">
          <slot name="option" :row="scope.row"></slot>
        </template>
      </el-table-column>
    </el-table>
    <div class="demo-pagination-block" v-if="props.pagination">
      <el-pagination
        v-model:current-page="pageResult.current"
        v-model:page-size="pageResult.size"
        :page-sizes="[10, 20, 30, 50]"
        layout="total, sizes, prev, pager, next, jumper"
        :total="pageResult.total"
        @size-change="handleSizeChange"
        @current-change="handleCurrentChange"
        
      />
    </div>
    </div>
</el-config-provider>
</template>
<script setup lang="ts">
import {ref,useSlots,computed} from 'vue'
import zhCn from 'element-plus/dist/locale/zh-cn.mjs'
const locale =  zhCn
interface pageObj {
    size:number,
    current:number,
    total:number
}
interface columnObj {
    label:string,
    prop:string,
    type?:string,
    formatter?:Function,
    minWidth?:string,
    [key:string]:any
    
}
const table = ref()
const slots = useSlots()
const isSlotOption = computed(() => {

  return slots.option?true:false
})
const props = withDefaults (
    defineProps <{
        tableData: Array<{ [key:string]:any}>,
        loading?:boolean,
        border?:boolean,
        maxHeight?:string,
        selection?:boolean,
        pageResult?:pageObj,
        sort?:boolean,
        option?:boolean,
        column:Array<columnObj>,
        pagination?:boolean,
        rowKey?:string
}> (), {
    // 表格数据
    tableData: () => {
        return []
    },
    // 表格加载状态
    loading:false,
    // 表格最大高度
    maxHeight:'550px',
    // 是否带有纵向边框
    border:false,
    // 是否多选
    selection:false,
    // 分页页数和每页显示
    pageResult:() => {
        return {size:10,current:1,total:0}
    },
    // 是否显示序号(1,2,3,4,5)
    sort:true,
    // 表格内容
    column:() => {
        return []
    },
    // 是否显示操作模块
    option:true,
    // 是否显示分页
    pagination:() => {
        return true
    },
    rowKey:''
})
const emits = defineEmits(['edit','confirm','handleSizeChange','handleCurrentChange',
'currentChange','selectionChange'
])
// 点击编辑按钮
const edit  = (row) => {
    emits('edit',row)
}
// 确认删除
const confirm = (row) => {
    emits('confirm',row)
}
// 分页
const handleSizeChange = (val:number) => {
    emits('handleSizeChange',val)
}
const handleCurrentChange = (val:number) => {
    emits('handleCurrentChange',val)
}
// 选中单行
const currentChange = (val) => {
  emits('currentChange',val)
}
// 多行    
const selectionChange = (val) => {
  emits("selectionChange", val);
}
defineExpose({table})
</script>
<style  scoped>
.demo-pagination-block {
  display: flex;
  justify-content: flex-end;
  padding: 20px 0;
  padding-right: 20px;
}</style>

注意:由于element-plus本身显示的文字是英文,所以需要el-config-provider将其转换(详情见官方文档,如果你在路由已经添加el-config-provider,这里可以将其去掉)

使用方式

<template>
    <kt-table :tableData="common.tableData" :column="common.column" :sort="true">
        <template #status="row">
            <!-- 可写其他标签样式,这里只是展示 -->
         <span>{{ row.row }}</span>
        </template>
    <template #option="row">
         <!-- 可写其他操作样式,这里只是展示 -->
            <span>123{{ row.row }}</span>
    </template>
    </kt-table>
</template>

<script setup lang="ts">
interface columnObj {
    label:string,
    prop:string,
    type?:string,
    formatter?:Function,
    minWidth?:string,
    [key:string]:any
    
}
const common = reactive({
    text: '',
    tableData: [{serviceCcicId:'111111',businessStatus:'10'}],
    column: [
        { label: '服务项编号', prop: 'serviceCcicId' },
       
       
        {
            label: '服务项状态', prop: 'businessStatus', formatter: (row) => {
                return row.businessStatus == 0 ? '未开工' : (row.businessStatus == 10 ? '实施中' : (row.businessStatus == 20 ? '完工审核' : (row.businessStatus == '30' ? '已完工' : '其他')))
            }
        },
        { label: '任务单状态', prop: 'status', type: 'html', minWidth: '200px' },
    ] as columnObj[]
})

</script>
<style lang='scss' scoped></style>

注意:使用组件需先引入组件,这里没有引入是因为已经将该组件引入在全局当中
npm下载:npm i cc-element-component

在Vue3和Element Plus中封装表格组件,可以使用以下方法: 1. 首先,在Vue3中创建一个新的组件,可以命名为TableWrapper或者其他你喜欢的名称。 2. 在组件中引入Element Plus的Table组件,并在data中定义需要用到的数据,例如tableData和tableHeader。 3. 在template中使用Table组件,并通过props传递数据。使用v-for循环遍历tableHeader来动态生成表头信息。 4. 在Table组件中,可以通过slot插槽自定义表格中的内容,例如添加操作按钮或其他自定义内容。 5. 可以在Table组件中定义一些方法,例如handleEdit和handleDelete,用于处理编辑和删除操作。 6. 最后,在父组件中使用TableWrapper组件,并传递需要显示的数据和其他配置项。 以下是一个示例代码,供参考: ```vue <template> <Table :data="tableData" :columns="tableHeader" border > <template #ksType="{ row }"> <span>{{ row.type }}</span> </template> <template #isDisabled="{ row }"> <el-switch v-model="row.isDisabled" active-text="是" inactive-text="否" :active-value="0" :inactive-value="1" @change="switchChange(row)" ></el-switch> </template> <template #btn="{ row }"> <el-button v-for="(btn, index) in row.btn" :key="index" :type="btn.btnStyle || 'default'" @click="btn.func(row)" > {{ btn.name }} </el-button> </template> </Table> </template> <script> import { Table } from 'element-plus'; export default { components: { Table, }, data() { return { tableData: [], tableHeader: [ { prop: "name", label: "名称" }, { prop: "type", label: "科室类型", slot: "ksType" }, { prop: "isDisabled", label: "是否禁用", slot: "isDisabled" }, { prop: "btn", label: "操作", slot: "btn" }, ], }; }, methods: { switchChange(row) { // 处理开关切换操作 }, handleEdit(row) { // 处理编辑操作 }, handleDelete(row) { // 处理删除操作 }, }, }; </script> ``` 在这个示例中,我们使用了Element Plus的Table组件,并通过slot插槽自定义了表格中的内容。同时,我们在组件中定义了一些方法来处理具体的操作。你可以根据自己的需求进行修改和扩展。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [vue3+element-plus封装表格](https://blog.csdn.net/weixin_50041614/article/details/126702116)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *3* [go语言恶意代码检测系统-对接前端可视化与算法检测部分](https://download.csdn.net/download/liufang_imei/88222624)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值