Skip to content

Table

Basic Usage

1Li Xiaoying5224
15Du Xiaohao46218
18Tang Xiaoqing48212
28Tian Xiaofeng47515
35Wu Xiaohao37241
41Wu Xiaoke40433
46Mu Xiaoyi40940
43Zou Xiaohui29353
vue
<template>
  <bp-table
    :data="list"
    border
    row-key="seat"
    :row-selection="rowSelection"
    v-model:selectedKeys="selectedKeys"
    v-model:selectedKey="selectedKey"
  >
    <template #columns>
      <bp-table-column title="Seat" data-index="seat" :width="100">
        <template #cell="{ record }">
          <span style="font-weight: bold">{{ record.seat }}</span>
        </template>
      </bp-table-column>
      <bp-table-column title="Name" data-index="name" align="center" />
      <bp-table-column title="Score" data-index="results" :width="100" />
      <bp-table-column title="Class rank" data-index="ranking" :width="100" />
    </template>
  </bp-table>
</template>

<script setup lang="ts">
import { ref } from "vue";

const list = [
  { seat: "1", name: "Li Xiaoying", results: "522", ranking: "4" },
  { seat: "15", name: "Du Xiaohao", results: "462", ranking: "18" },
  { seat: "18", name: "Tang Xiaoqing", results: "482", ranking: "12" },
  { seat: "28", name: "Tian Xiaofeng", results: "475", ranking: "15" },
  { seat: "35", name: "Wu Xiaohao", results: "372", ranking: "41" },
  { seat: "41", name: "Wu Xiaoke", results: "404", ranking: "33" },
  { seat: "46", name: "Mu Xiaoyi", results: "409", ranking: "40" },
  { seat: "43", name: "Zou Xiaohui", results: "293", ranking: "53" },
];

const selectedKey = ref("");
const selectedKeys = ref([]);
const rowSelection = {
  type: "radio",
  // type: "checkbox",
};
</script>

Header scroll sync test

Test header/body scroll sync and column alignment

Fixed column widths + horizontal scroll (container 600px, table ~1000px)

1Zhang San28BeijingFrontend Engineerzhangsan@example.comActive
2Li Si32ShanghaiBackend Engineerlisi@example.comActive
3Wang Wu26ShenzhenUI Designerwangwu@example.comResigned
4Zhao Liu30GuangzhouProduct Managerzhaoliu@example.comActive

Fixed columns (ID fixed left, Status fixed right)

1Zhang San28BeijingFrontend Engineerzhangsan@example.com13800138001Active
2Li Si32ShanghaiBackend Engineerlisi@example.com13800138002Active
3Wang Wu26ShenzhenUI Designerwangwu@example.com13800138003Resigned
4Zhao Liu30GuangzhouProduct Managerzhaoliu@example.com13800138004Active
5User 525BeijingSoftware Engineeruser5@example.com138001380005Resigned
6User 626ShanghaiDesigneruser6@example.com138001380006Active
7User 727ShenzhenProduct Manageruser7@example.com138001380007Active
8User 828GuangzhouQA Engineeruser8@example.com138001380008Resigned
9User 929HangzhouOperationsuser9@example.com138001380009Active
10User 1030BeijingSoftware Engineeruser10@example.com138001380010Active
11User 1131ShanghaiDesigneruser11@example.com138001380011Resigned
12User 1232ShenzhenProduct Manageruser12@example.com138001380012Active
13User 1333GuangzhouQA Engineeruser13@example.com138001380013Active
14User 1434HangzhouOperationsuser14@example.com138001380014Resigned
15User 1525BeijingSoftware Engineeruser15@example.com138001380015Active
16User 1626ShanghaiDesigneruser16@example.com138001380016Active
17User 1727ShenzhenProduct Manageruser17@example.com138001380017Resigned
18User 1828GuangzhouQA Engineeruser18@example.com138001380018Active
19User 1929HangzhouOperationsuser19@example.com138001380019Active
20User 2030BeijingSoftware Engineeruser20@example.com138001380020Resigned
21User 2131ShanghaiDesigneruser21@example.com138001380021Active
22User 2232ShenzhenProduct Manageruser22@example.com138001380022Active
23User 2333GuangzhouQA Engineeruser23@example.com138001380023Resigned
24User 2434HangzhouOperationsuser24@example.com138001380024Active

Mixed widths (some fixed + flexible)

1Zhang San28BeijingFrontend Engineerzhangsan@example.comActive
2Li Si32ShanghaiBackend Engineerlisi@example.comActive
3Wang Wu26ShenzhenUI Designerwangwu@example.comResigned
4Zhao Liu30GuangzhouProduct Managerzhaoliu@example.comActive

Vertical + horizontal scroll

1Zhang San28BeijingFrontend Engineerzhangsan@example.com13800138001Active
2Li Si32ShanghaiBackend Engineerlisi@example.com13800138002Active
3Wang Wu26ShenzhenUI Designerwangwu@example.com13800138003Resigned
4Zhao Liu30GuangzhouProduct Managerzhaoliu@example.com13800138004Active
5User 525BeijingSoftware Engineeruser5@example.com138001380005Resigned
6User 626ShanghaiDesigneruser6@example.com138001380006Active
7User 727ShenzhenProduct Manageruser7@example.com138001380007Active
8User 828GuangzhouQA Engineeruser8@example.com138001380008Resigned
9User 929HangzhouOperationsuser9@example.com138001380009Active
10User 1030BeijingSoftware Engineeruser10@example.com138001380010Active
11User 1131ShanghaiDesigneruser11@example.com138001380011Resigned
12User 1232ShenzhenProduct Manageruser12@example.com138001380012Active
13User 1333GuangzhouQA Engineeruser13@example.com138001380013Active
14User 1434HangzhouOperationsuser14@example.com138001380014Resigned
15User 1525BeijingSoftware Engineeruser15@example.com138001380015Active
16User 1626ShanghaiDesigneruser16@example.com138001380016Active
17User 1727ShenzhenProduct Manageruser17@example.com138001380017Resigned
18User 1828GuangzhouQA Engineeruser18@example.com138001380018Active
19User 1929HangzhouOperationsuser19@example.com138001380019Active
20User 2030BeijingSoftware Engineeruser20@example.com138001380020Resigned
21User 2131ShanghaiDesigneruser21@example.com138001380021Active
22User 2232ShenzhenProduct Manageruser22@example.com138001380022Active
23User 2333GuangzhouQA Engineeruser23@example.com138001380023Resigned
24User 2434HangzhouOperationsuser24@example.com138001380024Active
vue
<template>
  <div>
    <h3>Header scroll sync test</h3>
    <p>Test header/body scroll sync and column alignment</p>

    <!-- Fixed widths + horizontal scroll -->
    <h4>Fixed column widths + horizontal scroll (container 600px, table ~1000px)</h4>
    <div style="width: 600px">
      <bp-table :data="list" border row-key="id" :scroll="{ x: 1000 }" :row-selection="{ type: 'radio' }">
        <template #columns>
          <bp-table-column title="ID" data-index="id" :width="80" />
          <bp-table-column title="Name" data-index="name" :width="120" />
          <bp-table-column title="Age" data-index="age" :width="80" />
          <bp-table-column title="City" data-index="city" :width="120" />
          <bp-table-column title="Job" data-index="job" :width="200" />
          <bp-table-column title="Email" data-index="email" :width="250" />
          <bp-table-column title="Status" data-index="status" :width="100" />
        </template>
      </bp-table>
    </div>

    <!-- Fixed columns -->
    <h4>Fixed columns (ID fixed left, Status fixed right)</h4>
    <div style="width: 600px">
      <bp-table :data="bigList" border row-key="id" :scroll="{ x: 1100, y: 220 }">
        <template #columns>
          <bp-table-column title="ID" data-index="id" :width="80" fixed="left" />
          <bp-table-column title="Name" data-index="name" :width="120" />
          <bp-table-column title="Age" data-index="age" :width="80" />
          <bp-table-column title="City" data-index="city" :width="120" />
          <bp-table-column title="Job" data-index="job" :width="220" />
          <bp-table-column title="Email" data-index="email" :width="260" />
          <bp-table-column title="Phone" data-index="phone" :width="140" />
          <bp-table-column title="Status" data-index="status" :width="100" fixed="right" />
        </template>
      </bp-table>
    </div>

    <!-- Mixed widths -->
    <h4>Mixed widths (some fixed + flexible)</h4>
    <div style="width: 500px">
      <bp-table :data="list" border row-key="id" :scroll="{ x: 800 }">
        <template #columns>
          <bp-table-column title="ID" data-index="id" :width="60" />
          <bp-table-column title="Name" data-index="name" :width="100" />
          <bp-table-column title="Age" data-index="age" />
          <bp-table-column title="City" data-index="city" />
          <bp-table-column title="Job" data-index="job" :width="180" />
          <bp-table-column title="Email" data-index="email" :width="220" />
          <bp-table-column title="Status" data-index="status" />
        </template>
      </bp-table>
    </div>

    <!-- Vertical + horizontal scroll -->
    <h4>Vertical + horizontal scroll</h4>
    <div style="width: 700px">
      <bp-table :data="bigList" border row-key="id" :scroll="{ x: 900, y: 200 }" :row-selection="{ type: 'checkbox' }">
        <template #columns>
          <bp-table-column title="ID" data-index="id" :width="60" />
          <bp-table-column title="Name" data-index="name" :width="100" />
          <bp-table-column title="Age" data-index="age" :width="80" />
          <bp-table-column title="City" data-index="city" :width="120" />
          <bp-table-column title="Job" data-index="job" :width="180" />
          <bp-table-column title="Email" data-index="email" :width="200" />
          <bp-table-column title="Phone" data-index="phone" :width="120" />
          <bp-table-column title="Status" data-index="status" :width="80" />
        </template>
      </bp-table>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref } from "vue";

const list = ref([
  {
    id: 1,
    name: "Zhang San",
    age: 28,
    city: "Beijing",
    job: "Frontend Engineer",
    email: "zhangsan@example.com",
    phone: "13800138001",
    status: "Active",
  },
  {
    id: 2,
    name: "Li Si",
    age: 32,
    city: "Shanghai",
    job: "Backend Engineer",
    email: "lisi@example.com",
    phone: "13800138002",
    status: "Active",
  },
  {
    id: 3,
    name: "Wang Wu",
    age: 26,
    city: "Shenzhen",
    job: "UI Designer",
    email: "wangwu@example.com",
    phone: "13800138003",
    status: "Resigned",
  },
  {
    id: 4,
    name: "Zhao Liu",
    age: 30,
    city: "Guangzhou",
    job: "Product Manager",
    email: "zhaoliu@example.com",
    phone: "13800138004",
    status: "Active",
  },
]);

// Extra rows for vertical scroll
const bigList = ref([
  ...list.value,
  ...Array.from({ length: 20 }, (_, i) => ({
    id: i + 5,
    name: `User ${i + 5}`,
    age: 25 + (i % 10),
    city: ["Beijing", "Shanghai", "Shenzhen", "Guangzhou", "Hangzhou"][i % 5],
    job: ["Software Engineer", "Designer", "Product Manager", "QA Engineer", "Operations"][i % 5],
    email: `user${i + 5}@example.com`,
    phone: `1380013800${(i + 5).toString().padStart(2, "0")}`,
    status: i % 3 === 0 ? "Resigned" : "Active",
  })),
]);
</script>

<style scoped>
h3,
h4 {
  margin: 20px 0 10px 0;
  color: #333;
}

p {
  margin: 10px 0;
  color: #666;
  font-size: 14px;
}

.bp-table {
  margin-bottom: 30px;
}

div[style*="border"] {
  margin-bottom: 20px;
  border-radius: 4px;
  background-color: #fafafa;
}
</style>

Horizontal scroll example

With many columns, the table enables horizontal scroll so each column keeps a proper width

Auto horizontal scroll (unlimited)

1Zhang San28BeijingFrontend Engineerzhangsan@example.com138001380011 Jianguomenwai Ave, Chaoyang, BeijingTech Co., Ltd.15000
2Li Si32ShanghaiBackend Engineerlisi@example.com13800138002100 Century Avenue, Pudong, ShanghaiInternet Company18000
3Wang Wu26ShenzhenUI Designerwangwu@example.com13800138003South Science Park, Nanshan, ShenzhenDesign Studio12000
4Zhao Liu30GuangzhouProduct Managerzhaoliu@example.com13800138004Zhujiang New Town, Tianhe, GuangzhouStartup20000

Explicit horizontal scroll width (1200px)

1Zhang San28BeijingFrontend Engineerzhangsan@example.com138001380011 Jianguomenwai Ave, Chaoyang, BeijingTech Co., Ltd.15000
2Li Si32ShanghaiBackend Engineerlisi@example.com13800138002100 Century Avenue, Pudong, ShanghaiInternet Company18000
3Wang Wu26ShenzhenUI Designerwangwu@example.com13800138003South Science Park, Nanshan, ShenzhenDesign Studio12000
4Zhao Liu30GuangzhouProduct Managerzhaoliu@example.com13800138004Zhujiang New Town, Tianhe, GuangzhouStartup20000

Horizontal + vertical scroll

1Zhang San28BeijingFrontend Engineerzhangsan@example.com138001380011 Jianguomenwai Ave, Chaoyang, Beijing
2Li Si32ShanghaiBackend Engineerlisi@example.com13800138002100 Century Avenue, Pudong, Shanghai
3Wang Wu26ShenzhenUI Designerwangwu@example.com13800138003South Science Park, Nanshan, Shenzhen
4Zhao Liu30GuangzhouProduct Managerzhaoliu@example.com13800138004Zhujiang New Town, Tianhe, Guangzhou
5User 525BeijingSoftware Engineeruser5@example.com13800138005Address 5
6User 626ShanghaiDesigneruser6@example.com13800138006Address 6
7User 727ShenzhenProduct Manageruser7@example.com13800138007Address 7
8User 828GuangzhouQA Engineeruser8@example.com13800138008Address 8
9User 929HangzhouOperationsuser9@example.com13800138009Address 9
10User 1030BeijingSoftware Engineeruser10@example.com138001380010Address 10
11User 1131ShanghaiDesigneruser11@example.com138001380011Address 11
12User 1232ShenzhenProduct Manageruser12@example.com138001380012Address 12
13User 1333GuangzhouQA Engineeruser13@example.com138001380013Address 13
14User 1434HangzhouOperationsuser14@example.com138001380014Address 14
15User 1525BeijingSoftware Engineeruser15@example.com138001380015Address 15
16User 1626ShanghaiDesigneruser16@example.com138001380016Address 16
17User 1727ShenzhenProduct Manageruser17@example.com138001380017Address 17
18User 1828GuangzhouQA Engineeruser18@example.com138001380018Address 18
19User 1929HangzhouOperationsuser19@example.com138001380019Address 19
20User 2030BeijingSoftware Engineeruser20@example.com138001380020Address 20
21User 2131ShanghaiDesigneruser21@example.com138001380021Address 21
22User 2232ShenzhenProduct Manageruser22@example.com138001380022Address 22
23User 2333GuangzhouQA Engineeruser23@example.com138001380023Address 23
24User 2434HangzhouOperationsuser24@example.com138001380024Address 24
vue
<template>
  <div>
    <h3>Horizontal scroll example</h3>
    <p>With many columns, the table enables horizontal scroll so each column keeps a proper width</p>
    
    <!-- No scroll limit - auto -->
    <h4>Auto horizontal scroll (unlimited)</h4>
    <bp-table
      :data="list"
      border
      row-key="id"
      style="width: 800px;"
    >
      <template #columns>
        <bp-table-column title="ID" data-index="id" :width="80" />
        <bp-table-column title="Name" data-index="name" :width="120" />
        <bp-table-column title="Age" data-index="age" :width="80" />
        <bp-table-column title="City" data-index="city" :width="120" />
        <bp-table-column title="Job" data-index="job" :width="150" />
        <bp-table-column title="Email" data-index="email" :width="200" />
        <bp-table-column title="Phone" data-index="phone" :width="150" />
        <bp-table-column title="Address" data-index="address" :width="250" />
        <bp-table-column title="Company" data-index="company" :width="180" />
        <bp-table-column title="Salary" data-index="salary" :width="120" />
      </template>
    </bp-table>

    <!-- Explicit horizontal scroll width -->
    <h4>Explicit horizontal scroll width (1200px)</h4>
    <bp-table
      :data="list"
      border
      row-key="id"
      :scroll="{ x: 1200 }"
      style="width: 600px;"
    >
      <template #columns>
        <bp-table-column title="ID" data-index="id" :width="80" />
        <bp-table-column title="Name" data-index="name" :width="120" />
        <bp-table-column title="Age" data-index="age" :width="80" />
        <bp-table-column title="City" data-index="city" :width="120" />
        <bp-table-column title="Job" data-index="job" :width="150" />
        <bp-table-column title="Email" data-index="email" :width="200" />
        <bp-table-column title="Phone" data-index="phone" :width="150" />
        <bp-table-column title="Address" data-index="address" :width="250" />
        <bp-table-column title="Company" data-index="company" :width="180" />
        <bp-table-column title="Salary" data-index="salary" :width="120" />
      </template>
    </bp-table>

    <!-- Horizontal and vertical scroll -->
    <h4>Horizontal + vertical scroll</h4>
    <bp-table
      :data="bigList"
      border
      row-key="id"
      :scroll="{ x: 1000, y: 300 }"
      style="width: 700px;"
    >
      <template #columns>
        <bp-table-column title="ID" data-index="id" :width="80" />
        <bp-table-column title="Name" data-index="name" :width="120" />
        <bp-table-column title="Age" data-index="age" :width="80" />
        <bp-table-column title="City" data-index="city" :width="120" />
        <bp-table-column title="Job" data-index="job" :width="150" />
        <bp-table-column title="Email" data-index="email" :width="200" />
        <bp-table-column title="Phone" data-index="phone" :width="150" />
        <bp-table-column title="Address" data-index="address" :width="250" />
      </template>
    </bp-table>
  </div>
</template>

<script setup lang="ts">
import { ref } from "vue";

const list = ref([
  {
    id: 1,
    name: "Zhang San",
    age: 28,
    city: "Beijing",
    job: "Frontend Engineer",
    email: "zhangsan@example.com",
    phone: "13800138001",
    address: "1 Jianguomenwai Ave, Chaoyang, Beijing",
    company: "Tech Co., Ltd.",
    salary: "15000"
  },
  {
    id: 2,
    name: "Li Si",
    age: 32,
    city: "Shanghai",
    job: "Backend Engineer",
    email: "lisi@example.com",
    phone: "13800138002",
    address: "100 Century Avenue, Pudong, Shanghai",
    company: "Internet Company",
    salary: "18000"
  },
  {
    id: 3,
    name: "Wang Wu",
    age: 26,
    city: "Shenzhen",
    job: "UI Designer",
    email: "wangwu@example.com",
    phone: "13800138003",
    address: "South Science Park, Nanshan, Shenzhen",
    company: "Design Studio",
    salary: "12000"
  },
  {
    id: 4,
    name: "Zhao Liu",
    age: 30,
    city: "Guangzhou",
    job: "Product Manager",
    email: "zhaoliu@example.com",
    phone: "13800138004",
    address: "Zhujiang New Town, Tianhe, Guangzhou",
    company: "Startup",
    salary: "20000"
  }
]);

// Extra rows for vertical scroll
const bigList = ref([
  ...list.value,
  ...Array.from({ length: 20 }, (_, i) => ({
    id: i + 5,
    name: `User ${i + 5}`,
    age: 25 + (i % 10),
    city: ["Beijing", "Shanghai", "Shenzhen", "Guangzhou", "Hangzhou"][i % 5],
    job: ["Software Engineer", "Designer", "Product Manager", "QA Engineer", "Operations"][i % 5],
    email: `user${i + 5}@example.com`,
    phone: `1380013800${i + 5}`,
    address: `Address ${i + 5}`,
    company: `Company ${i + 5}`,
    salary: `${10000 + i * 1000}`
  }))
]);
</script>

<style scoped>
h3, h4 {
  margin: 20px 0 10px 0;
  color: #333;
}

p {
  margin: 10px 0;
  color: #666;
  font-size: 14px;
}

.bp-table {
  margin-bottom: 30px;
}
</style>

Table Props

v-model:selected-keySelected key (radio)
StringNumber
--
v-model:selected-keysSelected keys (checkbox)
Array
--
dataData source
Array
[]-
heightFixed height
String
--
borderWhether bordered
Boolean
--
stripeWhether striped
Boolean
--
row-keyRow key
String
id-
loadingWhether loading
Boolean
--
spin-iconLoading icon
NumberComponent
1-
descriptionLoading description
String
--
empty-textEmpty data text
String
No data-
row-selectionRow selection config
TableRowSelection
null-
scrollScroll config
TableScroll
{}-

TableColumn Props

titleColumn title
String
--
data-indexField name
String
--
widthColumn width
NumberString
--
min-widthMin column width
NumberString
--
fixedFixed column
String
--
alignAlignment
String
left-
ellipsisWhether to ellipsis overflow
Boolean
--
tooltipWhether to show tooltip
Boolean
--

Table Events

select-allTriggered on select-all toggleval: boolean-
selectTriggered when selected rows changevals: CheckboxValue[], rowKey: RadioValue, record: any-
selection-changeTriggered when checkbox selection changesvals: CheckboxValue[]-

Table Slots

columnsColumn definitions--
emptyEmpty-state content--

TableColumn Slots

cellCell content{ record, rowIndex }-