Vue3 封装el-table组件

封装一个el-table组件:子组件仅负责事件触发,业务逻辑(如API调用、状态更新)由父组件实现

javascript 复制代码
<template>
  <el-table
    :data="tableData"
    border
    stripe
    style="width: 100%; height: calc(100% - 32px);"
    class="data-table"
  >
    <!-- 设备类型列 -->
    <el-table-column prop="name" label="设备类型" width="150">
      <template #default="{ row }">
        <el-text>{{ row.name }}</el-text>
      </template>
    </el-table-column>

    <!-- 价格列 -->
    <el-table-column prop="price" label="价格" width="100">
      <template #default="{ row }">
        <el-text>{{ row.price }}</el-text>
      </template>
    </el-table-column>

    <!-- 电脑SN列 -->
    <el-table-column prop="sn" label="电脑SN" width="220">
      <template #default="{ row }">
        <el-text type="info" copyable>{{ row.sn }}</el-text>
      </template>
    </el-table-column>

    <!-- 供应商列(带筛选) -->
    <el-table-column
      prop="supplier"
      label="供应商"
      width="120"
      :filters="filters.supplier"
      :filter-method="filterData"
    >
      <template #default="{ row }">
        <el-tag effect="plain" :type="supplierTagType[row.supplier]">
          {{ row.supplier }}
        </el-tag>
      </template>
    </el-table-column>

    <!-- 入库日期列 -->
    <el-table-column prop="storageDate" label="入库日期" width="150">
      <template #default="{ row }">
        {{ formatDate(row.storageDate) }}
      </template>
    </el-table-column>

    <!-- 地区列(带筛选) -->
    <el-table-column
      prop="region"
      label="地区"
      width="100"
      :filters="filters.region"
      :filter-method="filterData"
    >
      <template #default="{ row }">
        <el-tag effect="plain">{{ row.region }}</el-tag>
      </template>
    </el-table-column>

    <!-- 备注列 -->
    <el-table-column prop="remark" label="备注" min-width="200"></el-table-column>

    <!-- 操作列 -->
    <el-table-column label="操作" width="180" fixed="right">
      <template #default="{ row }">
        <el-button type="primary" size="small" @click="handleEdit(row)">
          <el-icon><Edit /></el-icon>修改
        </el-button>
        <el-button type="danger" size="small" @click="handleDelete(row)">
          <el-icon><Delete /></el-icon>删除
        </el-button>
      </template>
    </el-table-column>
  </el-table>
</template>

<script setup>
import { defineProps, defineEmits } from 'vue'
import { Edit, Delete } from '@element-plus/icons-vue'
import dayjs from 'dayjs'

const props = defineProps({
  tableData: {
    type: Array,
    required: true,
    default: () => []
  },
  filters: {
    type: Object,
    required: true,
    default: () => ({})
  },
  supplierTagType: {
    type: Object,
    required: true,
    default: () => ({})
  }
})

const emit = defineEmits(['edit', 'delete'])

// 日期格式化
function formatDate(date) {
  return date ? dayjs(date).format('YYYY-MM-DD') : dayjs().format('YYYY-MM-DD')
}

// 筛选方法
const filterData = (value, row, column) => {
  return row[column.property] === value
}

// 操作事件转发
const handleEdit = (row) => {
  emit('edit', row)
}
const handleDelete = (row) => {
  emit('delete', row)
}
</script>

<style scoped>
.data-table {
  margin-top: 20px;
}
</style>

在父组件中使用这个组件,并给他传值:

javascript 复制代码
<BillTable
      :table-data="tableData"
      :filters="filters"
      :supplier-tag-type="supplierTagType"
      @edit="handleEdit"
      @delete="handleDelete"
    />

代码解释:

通过:data="tableData"将数组数据与表格绑定

通过:filters和:filter-method实现筛选功能,数据匹配逻辑在filterData方法中定义

声明组件props的语法,通过defineProps函数定义组件需要接收的三个属性

emit方法‌属于Vue 3的setup语法糖,通过defineEmits声明后使用,用于子组件向父组件跨层级通信

相关推荐
程序视点10 分钟前
Umi-OCR完全指南:开源离线OCR识别软件下载安装使用教程|支持批量PDF/二维码识别
前端·后端·github
瘦瘦的小芝芝11 分钟前
es改动总结
前端
想要学好前端的阿毛13 分钟前
React状态管理库 -- Redux篇
前端
拾光拾趣录14 分钟前
前端宏(微)任务 | 从“为什么我的代码不按顺序执行”说起
前端·javascript
林太白17 分钟前
NestJS-菜单模块
前端·后端·nestjs
程序员ys19 分钟前
微前端(What)
前端·架构
狗都不学爬虫_20 分钟前
JS逆向 - (国外)SHEIN站 - 请求头(armorToken、Anti-in)
javascript·python·ajax·网络爬虫·wasm
用户7974761127321 分钟前
Mysql RR事务隔离级别引发的生产Bug,你中招了吗?
前端
Mintopia23 分钟前
🧠 三分视界:Three.js 离屏渲染与多重视角的艺术
前端·javascript·计算机图形学
JarvanMo32 分钟前
Dart & Flutter DevTools 扩展
前端