Element-Plus表格:Table自定義合併行資料的最佳實踐

代码喵仔發表於2024-12-01

“ 知行合一 ” —— 王陽明

在開發專案中,我們時常會用到表格,許多需求可能會要求自定義特定的行或列。
接下來,我們將探討在實際開發中如何應對這一挑戰。

本文案例採用的技術:

名稱 版本
Vue3 ^3.5.12
element-plus ^2.8.8

知識點

我們先來複習下2個知識點,來自element-plus文件 table

1、自定義表頭

透過設定 slot 來自定義表頭。(只貼出重點程式碼)

<el-table :data="filterTableData" style="width: 100%">
    <el-table-column label="Date" prop="date" />
    <el-table-column label="Name" prop="name" />
    <el-table-column align="right">
      <template #header>
        <el-input v-model="search" size="small" placeholder="Type to search" />
      </template>
      <template #default="scope">
        <el-button size="small" @click="handleEdit(scope.$index, scope.row)">
          Edit
        </el-button>
        <el-button
          size="small"
          type="danger"
          @click="handleDelete(scope.$index, scope.row)"
        >
          Delete
        </el-button>
      </template>
    </el-table-column>
  </el-table>

其中可以看出,透過 <template #header> 自定義表頭,<template #default="scope"> 自定義內容。

2、合併行或列

多行或多列共用一個資料時,可以合併行或列。
透過給 table 傳入span-method方法可以實現合併行或列, 方法的引數是一個物件,裡面包含當前行 row、當前列 column、當前行號 rowIndex、當前列號 columnIndex 四個屬性。 該函式可以返回一個包含兩個元素的陣列,第一個元素代表 rowspan,第二個元素代表 colspan。 也可以返回一個鍵名為 rowspan 和 colspan 的物件。

 <el-table
      :data="tableData"
      :span-method="arraySpanMethod"
      border
      style="width: 100%"
    >
      <el-table-column prop="id" label="ID" width="180" />
      <el-table-column prop="name" label="Name" />
      <el-table-column prop="amount1" sortable label="Amount 1" />
      <el-table-column prop="amount2" sortable label="Amount 2" />
      <el-table-column prop="amount3" sortable label="Amount 3" />
    </el-table>

<script lang="ts" setup>
// 省略其他程式碼...
const arraySpanMethod = ({
  row,
  column,
  rowIndex,
  columnIndex,
}: SpanMethodProps) => {
  if (rowIndex % 2 === 0) {
    if (columnIndex === 0) {
      return [1, 2]
    } else if (columnIndex === 1) {
      return [0, 0]
    }
  }
}
</script>

實戰開發

假設一個需求:在最後一行新增一條自定義的行資料。
結合上述2個知識點,我們可以進行改進:

<template>
  <el-table :data="tableData" :span-method="arraySpanMethod" border style="width: 500px">
    <el-table-column prop="id" label="ID" width="100">
      <template #default="scope">
        <span v-if="scope.$index === tableData.length - 1">
          <span>是否確認資訊:</span>
          <el-radio-group v-model="scope.row.confirmFlag">
            <el-radio :value="true">確認</el-radio>
            <el-radio :value="false">未確認</el-radio>
          </el-radio-group>
        </span>
        <template v-else>{{ scope.row.id }}</template>
      </template>
    </el-table-column>
    <el-table-column prop="name" label="姓名" />
    <el-table-column prop="age" label="年齡" />
  </el-table>
</template>

<script setup lang="ts">
import type { TableColumnCtx } from 'element-plus'

interface User {
  id?: string
  name?: string
  age?: number
  confirmFlag?: boolean
}

interface SpanMethodProps {
  row: User
  column: TableColumnCtx<User>
  rowIndex: number
  columnIndex: number
}

const arraySpanMethod = ({ row, column, rowIndex, columnIndex }: SpanMethodProps) => {
   // 最後一行
  if (rowIndex === tableData.length - 1) {
  // [1,3] 佔一行三列
    return [1, 3]
  }
}

const tableData: User[] = [
  {
    id: '1',
    name: 'Tom1',
    age: 20,
  },
  {
    id: '2',
    name: 'Tom2',
    age: 30,
  },
  {
    id: '3',
    name: 'Tom3',
    age: 40,
  },
  // 新增一條自定義的資料
  {
    confirmFlag: true,
  },
]
</script>

<style scoped></style>

結語

根據文件中所提供的2個知識點,可以結合進行其他自定義操作。
還有其他好玩的操作,小夥伴可以留言哈~

相關文章