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

相关推荐
像风一样自由20202 小时前
HTML与JavaScript:构建动态交互式Web页面的基石
前端·javascript·html
aiprtem3 小时前
基于Flutter的web登录设计
前端·flutter
浪裡遊3 小时前
React Hooks全面解析:从基础到高级的实用指南
开发语言·前端·javascript·react.js·node.js·ecmascript·php
why技术3 小时前
Stack Overflow,轰然倒下!
前端·人工智能·后端
幽络源小助理3 小时前
SpringBoot基于Mysql的商业辅助决策系统设计与实现
java·vue.js·spring boot·后端·mysql·spring
GISer_Jing3 小时前
0704-0706上海,又聚上了
前端·新浪微博
止观止3 小时前
深入探索 pnpm:高效磁盘利用与灵活的包管理解决方案
前端·pnpm·前端工程化·包管理器
whale fall3 小时前
npm install安装的node_modules是什么
前端·npm·node.js
烛阴3 小时前
简单入门Python装饰器
前端·python
袁煦丞4 小时前
数据库设计神器DrawDB:cpolar内网穿透实验室第595个成功挑战
前端·程序员·远程工作