vue3+ts 结合el-table二次封装表格组件

效果图

 Table组件

<template>
  <el-table :data="tableData" style="width: 80%" v-bind="{ border: true }">
    <el-table-column type="selection" width="50" align="center" />
    <el-table-column type="index" label="序号" width="100" fixed="left" align="center">
      <template #default="{ $index }">
        <i>{{ $index + 1 }}</i>
      </template>
    </el-table-column>
    <el-table-column
      v-for="col in option"
      :key="col.prop"
      :label="col.label"
      :prop="col.prop"
      :width="col.width"
      :align="col.align"
      v-bind="{ ...col.attrs }"
    >
      <template #header>
        <!-- <span v-if="col.editable"><button>可编辑</button></span> -->
        <span>{{ col.label }}</span>
      </template>
      <template #default="{ row, $index }" v-if="col.slot">
        <slot :name="col.slot" :row="row" :index="$index"></slot>
      </template>
    </el-table-column>
  </el-table>
</template>

<script lang="ts" setup>
import { TableOption, TableData } from './tableData'
type Props = {
  option: Array<TableOption>
  tableData: Array<TableData>
}
const props = defineProps<Props>()
watch(props.tableData, (newVal, oldVal) => {
  console.log(newVal, oldVal)
})
</script>
<style></style>

其中表格的勾选列和序号列也可以添加v-if来控制隐藏

Table的类型接口和列

export interface TableOption {
  // 字段名称
  prop?: string
  // 表头
  label: string
  // 对应列的宽度
  width?: string | number
  // 对齐方式
  align?: 'left' | 'center' | 'right'
  // 自定义列模板的插槽名
  slot?: string
  // 是否是操作项
  action?: boolean
  // 是否可以编辑
  editable?: boolean
  // 属性
  attrs?: object
}

export interface TableData {
  date?: string
  name?: string
  address?: string
}

export interface FormData {
  name?: string
}

export const option: TableOption[] = [
  {
    label: 'Date',
    prop: 'date',
    width: 200,
    slot: 'dateSlot',
    editable: true,
    attrs: {
      sortable: ''
    }
  },
  {
    label: 'Name',
    prop: 'name',
    slot: 'nameSlot',
    attrs: {
      sortable: ''
    }
  },
  {
    label: 'Address',
    prop: 'address',
    slot: 'addressSlot',
    attrs: {
      sortable: ''
    }
  },
  {
    label: 'Edit',
    prop: 'edit',
    slot: 'editSlot'
  }
]

 调用

<template>
  <el-row class="mb-4">
    <el-button type="primary" @click="addRow">新增行</el-button>
    <el-button type="success">Success</el-button>
  </el-row>
  <common-table :option="option" :tableData="tableData">
    <template #dateSlot="{ row }">
      <div>{{ row.date }}</div>
    </template>
    <template #nameSlot="{ row }">
      <div>
        {{ row.name }}
      </div>
    </template>
    <template #addressSlot="{ row }">
      <div>
        {{ row.address }}
      </div>
    </template>
    <template #editSlot="{ row, index }">
      <div>
        <el-button @click="deleteRow(row, index)">删除</el-button>
        <el-button @click="viewRow(row)">查看</el-button>
      </div>
    </template>
  </common-table>
</template>
<script setup lang="ts">
import CommonTable from '../commonTable/CommonTable.vue'
import { option, TableData } from './tableData'
const tableData = reactive<TableData[]>([
  {
    date: '2016-05-03',
    name: '1',
    address: '北京'
  },
  {
    date: '2016-05-02',
    name: '2',
    address: '上海'
  },
  {
    date: '2016-05-04',
    name: '3',
    address: '南京'
  }
])
const addRow = () => { // 添加行
  const data = {
    date: '22222',
    name: 'asjdlasjdlad',
    address: 'asjd;sad'
  }
  tableData.push(data)
}
const deleteRow = (row: TableData, index: number) => { // 删除行
  tableData.splice(index, 1)
}
</script>
<style></style>

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值