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声明后使用,用于子组件向父组件跨层级通信

相关推荐
+VX:Fegn08952 小时前
计算机毕业设计|基于springboot + vue蛋糕店管理系统(源码+数据库+文档)
前端·数据库·vue.js·spring boot·课程设计
半个落月2 小时前
LangChain.js Agent Memory 实战(下):用 Milvus 构建可检索的长期记忆
javascript·langchain
半个落月2 小时前
LangChain.js Agent Memory 实战(上):从内存对话、文件持久化到截断与摘要
javascript·langchain
Nicander3 小时前
我给 Excalidraw 做了一个本地工作区:DrawSpace
前端·开源
linux_cfan5 小时前
17 · 引擎适配器全景:HLS/DASH/Vimeo/Mux/Cast
前端·javascript·音视频
计算机魔术师5 小时前
烧掉2780亿美元还不够?OpenAI的资本豪赌让人头皮发麻
前端
IT_陈寒6 小时前
Java线程池用错参数,我的服务居然悄悄崩溃了
前端·人工智能·后端
卡布鲁6 小时前
React useMemo 与 useCallback 完全指南:原理、场景与避坑
前端·react.js
碳基修炼7 小时前
排查记:本地 devServer 是 http,浏览器却把 302 重定向升级成了 https
前端·http
步行cgn7 小时前
Spring p 命名空间注入详解
java·前端·spring