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

相关推荐
吴声子夜歌1 分钟前
ES6——Calss详解
javascript·es6·原型模式
摇滚侠2 分钟前
HTML CSS 演示小米 logo 的变化 border-radius 属性设置圆角
前端·css·html
❆VE❆3 分钟前
虚拟列表原理与实战运用场景详解
前端·javascript·css·vue.js·html·虚拟列表
weixin_408099676 分钟前
【实战教程】EasyClick 调用 OCR 文字识别 API(自动识别屏幕文字 + 完整示例代码)
前端·人工智能·后端·ocr·api·安卓·easyclick
Bigger8 分钟前
第四章:我是如何扒开 Claude Code 记忆与上下文压缩机制的
前端·claude·源码阅读
还在忙碌的吴小二12 分钟前
在 Mac 上安装并通过端口调用 Chrome DevTools MCP Server(谷歌官方 MCP 服务器)
服务器·前端·chrome·macos·chrome devtools
灵感__idea8 小时前
Hello 算法:贪心的世界
前端·javascript·算法
GreenTea9 小时前
一文搞懂Harness Engineering与Meta-Harness
前端·人工智能·后端
killerbasd11 小时前
牧苏苏传 我不装了 4/7
前端·javascript·vue.js
吴声子夜歌11 小时前
ES6——二进制数组详解
前端·ecmascript·es6