Skip to content
On this page

表格 Table

基础的表格组件,用于显示列表数据

基础用法

姓名
年龄
出生日期
地址
王小明
18
1990-04-22
北京市朝阳区芍药居
张小刚
25
1990-11-11
北京市海淀区西二旗
李小红
30
1985-02-05
上海市浦东新区世纪大道
周小伟
26
1993-07-11
深圳市南山区深南大道
张小发
33
1999-12-12
南京市龙眠大道
<template>
  <b-table :columns="columns" :data="data">
    <template #age="{ row }">
      <b-tag>{{ row.age }}</b-tag>
    </template>
  </b-table>
</template>

<script setup lang="ts">
import { ref } from 'vue'
const columns = [
  { title: '姓名', key: 'name' },
  { title: '年龄', slot: 'age' },
  { title: '出生日期', key: 'birthday' },
  { title: '地址', key: 'address' }
]
const data = ref([
  {
    name: '王小明',
    age: 18,
    birthday: '1990-04-22',
    address: '北京市朝阳区芍药居'
  },
  {
    name: '张小刚',
    age: 25,
    birthday: '1990-11-11',
    address: '北京市海淀区西二旗'
  },
  {
    name: '李小红',
    age: 30,
    birthday: '1985-02-05',
    address: '上海市浦东新区世纪大道'
  },
  {
    name: '周小伟',
    age: 26,
    birthday: '1993-07-11',
    address: '深圳市南山区深南大道'
  },
  {
    name: '张小发',
    age: 33,
    birthday: '1999-12-12',
    address: '南京市龙眠大道'
  }
])
</script>
<template>
  <b-table :columns="columns" :data="data">
    <template #age="{ row }">
      <b-tag>{{ row.age }}</b-tag>
    </template>
  </b-table>
</template>

<script setup lang="ts">
import { ref } from 'vue'
const columns = [
  { title: '姓名', key: 'name' },
  { title: '年龄', slot: 'age' },
  { title: '出生日期', key: 'birthday' },
  { title: '地址', key: 'address' }
]
const data = ref([
  {
    name: '王小明',
    age: 18,
    birthday: '1990-04-22',
    address: '北京市朝阳区芍药居'
  },
  {
    name: '张小刚',
    age: 25,
    birthday: '1990-11-11',
    address: '北京市海淀区西二旗'
  },
  {
    name: '李小红',
    age: 30,
    birthday: '1985-02-05',
    address: '上海市浦东新区世纪大道'
  },
  {
    name: '周小伟',
    age: 26,
    birthday: '1993-07-11',
    address: '深圳市南山区深南大道'
  },
  {
    name: '张小发',
    age: 33,
    birthday: '1999-12-12',
    address: '南京市龙眠大道'
  }
])
</script>

斑马纹

通过设置stripe来设置斑马纹显示

姓名
年龄
出生日期
地址
王小明
18
1990-04-22
北京市朝阳区芍药居
张小刚
25
1990-11-11
北京市海淀区西二旗
李小红
30
1985-02-05
上海市浦东新区世纪大道
周小伟
26
1993-07-11
深圳市南山区深南大道
张小发
33
1999-12-12
南京市龙眠大道
<template>
  <b-table :columns="columns" :data="data" stripe>
    <template #age="{ row }">
      <b-tag>{{ row.age }}</b-tag>
    </template>
  </b-table>
</template>

<script setup lang="ts">
import { ref } from 'vue'
const columns = [
  { title: '姓名', key: 'name' },
  { title: '年龄', slot: 'age' },
  { title: '出生日期', key: 'birthday' },
  { title: '地址', key: 'address' }
]
const data = ref([
  {
    name: '王小明',
    age: 18,
    birthday: '1990-04-22',
    address: '北京市朝阳区芍药居'
  },
  {
    name: '张小刚',
    age: 25,
    birthday: '1990-11-11',
    address: '北京市海淀区西二旗'
  },
  {
    name: '李小红',
    age: 30,
    birthday: '1985-02-05',
    address: '上海市浦东新区世纪大道'
  },
  {
    name: '周小伟',
    age: 26,
    birthday: '1993-07-11',
    address: '深圳市南山区深南大道'
  },
  {
    name: '张小发',
    age: 33,
    birthday: '1999-12-12',
    address: '南京市龙眠大道'
  }
])
</script>
<template>
  <b-table :columns="columns" :data="data" stripe>
    <template #age="{ row }">
      <b-tag>{{ row.age }}</b-tag>
    </template>
  </b-table>
</template>

<script setup lang="ts">
import { ref } from 'vue'
const columns = [
  { title: '姓名', key: 'name' },
  { title: '年龄', slot: 'age' },
  { title: '出生日期', key: 'birthday' },
  { title: '地址', key: 'address' }
]
const data = ref([
  {
    name: '王小明',
    age: 18,
    birthday: '1990-04-22',
    address: '北京市朝阳区芍药居'
  },
  {
    name: '张小刚',
    age: 25,
    birthday: '1990-11-11',
    address: '北京市海淀区西二旗'
  },
  {
    name: '李小红',
    age: 30,
    birthday: '1985-02-05',
    address: '上海市浦东新区世纪大道'
  },
  {
    name: '周小伟',
    age: 26,
    birthday: '1993-07-11',
    address: '深圳市南山区深南大道'
  },
  {
    name: '张小发',
    age: 33,
    birthday: '1999-12-12',
    address: '南京市龙眠大道'
  }
])
</script>

边框

通过设置border来设置斑马纹显示

姓名
年龄
出生日期
地址
王小明
18
1990-04-22
北京市朝阳区芍药居
张小刚
25
1990-11-11
北京市海淀区西二旗
李小红
30
1985-02-05
上海市浦东新区世纪大道
周小伟
26
1993-07-11
深圳市南山区深南大道
张小发
33
1999-12-12
南京市龙眠大道
<template>
  <b-table :columns="columns" :data="data" border>
    <template #age="{ row }">
      <b-tag>{{ row.age }}</b-tag>
    </template>
  </b-table>
</template>

<script setup lang="ts">
import { ref } from 'vue'
const columns = [
  { title: '姓名', key: 'name' },
  { title: '年龄', slot: 'age' },
  { title: '出生日期', key: 'birthday' },
  { title: '地址', key: 'address' }
]
const data = ref([
  {
    name: '王小明',
    age: 18,
    birthday: '1990-04-22',
    address: '北京市朝阳区芍药居'
  },
  {
    name: '张小刚',
    age: 25,
    birthday: '1990-11-11',
    address: '北京市海淀区西二旗'
  },
  {
    name: '李小红',
    age: 30,
    birthday: '1985-02-05',
    address: '上海市浦东新区世纪大道'
  },
  {
    name: '周小伟',
    age: 26,
    birthday: '1993-07-11',
    address: '深圳市南山区深南大道'
  },
  {
    name: '张小发',
    age: 33,
    birthday: '1999-12-12',
    address: '南京市龙眠大道'
  }
])
</script>
<template>
  <b-table :columns="columns" :data="data" border>
    <template #age="{ row }">
      <b-tag>{{ row.age }}</b-tag>
    </template>
  </b-table>
</template>

<script setup lang="ts">
import { ref } from 'vue'
const columns = [
  { title: '姓名', key: 'name' },
  { title: '年龄', slot: 'age' },
  { title: '出生日期', key: 'birthday' },
  { title: '地址', key: 'address' }
]
const data = ref([
  {
    name: '王小明',
    age: 18,
    birthday: '1990-04-22',
    address: '北京市朝阳区芍药居'
  },
  {
    name: '张小刚',
    age: 25,
    birthday: '1990-11-11',
    address: '北京市海淀区西二旗'
  },
  {
    name: '李小红',
    age: 30,
    birthday: '1985-02-05',
    address: '上海市浦东新区世纪大道'
  },
  {
    name: '周小伟',
    age: 26,
    birthday: '1993-07-11',
    address: '深圳市南山区深南大道'
  },
  {
    name: '张小发',
    age: 33,
    birthday: '1999-12-12',
    address: '南京市龙眠大道'
  }
])
</script>

超出隐藏

可以通过给columns设置属性tooltip来设置超出隐藏并悬停显示, 如仅有一张表格则可以设置tooltip皮肤tooltip-theme来开启优化样式 (注意:因表格单元格存在超出隐藏样式所以必须将tooltip标签插入至body元素,会成多余标签,如有多个表格缓存则会插入过多标签造成性能问题,所以是否开启需要根据需求确定)

默认原生title
姓名
年龄
出生日期
地址
备注
王小明
18
1990-04-22
北京市朝阳区芍药居
这是一段描述文字,文本长度会超出列宽,设置tooltip属性可以设置不换行显示并开启鼠标悬停显示所有文字。
张小刚
25
1990-11-11
北京市海淀区西二旗
这是一段描述文字,文本长度会超出列宽,设置tooltip属性可以设置不换行显示并开启鼠标悬停显示所有文字。
李小红
30
1985-02-05
上海市浦东新区世纪大道
这是一段描述文字,文本长度会超出列宽,设置tooltip属性可以设置不换行显示并开启鼠标悬停显示所有文字。
周小伟
26
1993-07-11
深圳市南山区深南大道
这是一段描述文字,文本长度会超出列宽,设置tooltip属性可以设置不换行显示并开启鼠标悬停显示所有文字。
张小发
33
1999-12-12
南京市龙眠大道
这是一段描述文字,文本长度会超出列宽,设置tooltip属性可以设置不换行显示并开启鼠标悬停显示所有文字。
开启tooltip
姓名
年龄
出生日期
地址
备注
王小明
18
1990-04-22
北京市朝阳区芍药居
这是一段描述文字,文本长度会超出列宽,设置tooltip属性可以设置不换行显示并开启鼠标悬停显示所有文字。
张小刚
25
1990-11-11
北京市海淀区西二旗
这是一段描述文字,文本长度会超出列宽,设置tooltip属性可以设置不换行显示并开启鼠标悬停显示所有文字。
李小红
30
1985-02-05
上海市浦东新区世纪大道
这是一段描述文字,文本长度会超出列宽,设置tooltip属性可以设置不换行显示并开启鼠标悬停显示所有文字。
周小伟
26
1993-07-11
深圳市南山区深南大道
这是一段描述文字,文本长度会超出列宽,设置tooltip属性可以设置不换行显示并开启鼠标悬停显示所有文字。
张小发
33
1999-12-12
南京市龙眠大道
这是一段描述文字,文本长度会超出列宽,设置tooltip属性可以设置不换行显示并开启鼠标悬停显示所有文字。
<template>
  <div>
    <b-divider align="left">默认原生title</b-divider>
    <b-table :columns="columns" :data="data" border></b-table>
    <b-divider align="left">开启tooltip</b-divider>
    <b-table :columns="columns" :data="data" border tooltip-theme="dark"></b-table>
  </div>
</template>

<script setup lang="ts">
import { ref } from 'vue'
const columns = [
  { title: '姓名', key: 'name' },
  { title: '年龄', key: 'age' },
  { title: '出生日期', key: 'birthday' },
  { title: '地址', key: 'address' },
  { title: '备注', key: 'remark', tooltip: true }
]
const data = ref([
  {
    name: '王小明',
    age: 18,
    birthday: '1990-04-22',
    address: '北京市朝阳区芍药居',
    remark:
      '这是一段描述文字,文本长度会超出列宽,设置tooltip属性可以设置不换行显示并开启鼠标悬停显示所有文字。'
  },
  {
    name: '张小刚',
    age: 25,
    birthday: '1990-11-11',
    address: '北京市海淀区西二旗',
    remark:
      '这是一段描述文字,文本长度会超出列宽,设置tooltip属性可以设置不换行显示并开启鼠标悬停显示所有文字。'
  },
  {
    name: '李小红',
    age: 30,
    birthday: '1985-02-05',
    address: '上海市浦东新区世纪大道',
    remark:
      '这是一段描述文字,文本长度会超出列宽,设置tooltip属性可以设置不换行显示并开启鼠标悬停显示所有文字。'
  },
  {
    name: '周小伟',
    age: 26,
    birthday: '1993-07-11',
    address: '深圳市南山区深南大道',
    remark:
      '这是一段描述文字,文本长度会超出列宽,设置tooltip属性可以设置不换行显示并开启鼠标悬停显示所有文字。'
  },
  {
    name: '张小发',
    age: 33,
    birthday: '1999-12-12',
    address: '南京市龙眠大道',
    remark:
      '这是一段描述文字,文本长度会超出列宽,设置tooltip属性可以设置不换行显示并开启鼠标悬停显示所有文字。'
  }
])
</script>
<template>
  <div>
    <b-divider align="left">默认原生title</b-divider>
    <b-table :columns="columns" :data="data" border></b-table>
    <b-divider align="left">开启tooltip</b-divider>
    <b-table :columns="columns" :data="data" border tooltip-theme="dark"></b-table>
  </div>
</template>

<script setup lang="ts">
import { ref } from 'vue'
const columns = [
  { title: '姓名', key: 'name' },
  { title: '年龄', key: 'age' },
  { title: '出生日期', key: 'birthday' },
  { title: '地址', key: 'address' },
  { title: '备注', key: 'remark', tooltip: true }
]
const data = ref([
  {
    name: '王小明',
    age: 18,
    birthday: '1990-04-22',
    address: '北京市朝阳区芍药居',
    remark:
      '这是一段描述文字,文本长度会超出列宽,设置tooltip属性可以设置不换行显示并开启鼠标悬停显示所有文字。'
  },
  {
    name: '张小刚',
    age: 25,
    birthday: '1990-11-11',
    address: '北京市海淀区西二旗',
    remark:
      '这是一段描述文字,文本长度会超出列宽,设置tooltip属性可以设置不换行显示并开启鼠标悬停显示所有文字。'
  },
  {
    name: '李小红',
    age: 30,
    birthday: '1985-02-05',
    address: '上海市浦东新区世纪大道',
    remark:
      '这是一段描述文字,文本长度会超出列宽,设置tooltip属性可以设置不换行显示并开启鼠标悬停显示所有文字。'
  },
  {
    name: '周小伟',
    age: 26,
    birthday: '1993-07-11',
    address: '深圳市南山区深南大道',
    remark:
      '这是一段描述文字,文本长度会超出列宽,设置tooltip属性可以设置不换行显示并开启鼠标悬停显示所有文字。'
  },
  {
    name: '张小发',
    age: 33,
    birthday: '1999-12-12',
    address: '南京市龙眠大道',
    remark:
      '这是一段描述文字,文本长度会超出列宽,设置tooltip属性可以设置不换行显示并开启鼠标悬停显示所有文字。'
  }
])
</script>

固定表头

height 和 maxHeight 可以设置固定表头

姓名
年龄
出生日期
地址
王小明
18
1990-04-22
北京市朝阳区芍药居
张小刚
25
1990-11-11
北京市海淀区西二旗
李小红
30
1985-02-05
上海市浦东新区世纪大道
周小伟
26
1993-07-11
深圳市南山区深南大道
张小发
33
1999-12-12
南京市龙眠大道
<template>
  <b-table :columns="columns" :data="data" height="200" border></b-table>
</template>

<script setup lang="ts">
import { ref } from 'vue'
const columns = [
  { title: '姓名', key: 'name' },
  { title: '年龄', key: 'age' },
  { title: '出生日期', key: 'birthday' },
  { title: '地址', key: 'address' }
]
const data = ref([
  {
    name: '王小明',
    age: 18,
    birthday: '1990-04-22',
    address: '北京市朝阳区芍药居'
  },
  {
    name: '张小刚',
    age: 25,
    birthday: '1990-11-11',
    address: '北京市海淀区西二旗'
  },
  {
    name: '李小红',
    age: 30,
    birthday: '1985-02-05',
    address: '上海市浦东新区世纪大道'
  },
  {
    name: '周小伟',
    age: 26,
    birthday: '1993-07-11',
    address: '深圳市南山区深南大道'
  },
  {
    name: '张小发',
    age: 33,
    birthday: '1999-12-12',
    address: '南京市龙眠大道'
  }
])
</script>
<template>
  <b-table :columns="columns" :data="data" height="200" border></b-table>
</template>

<script setup lang="ts">
import { ref } from 'vue'
const columns = [
  { title: '姓名', key: 'name' },
  { title: '年龄', key: 'age' },
  { title: '出生日期', key: 'birthday' },
  { title: '地址', key: 'address' }
]
const data = ref([
  {
    name: '王小明',
    age: 18,
    birthday: '1990-04-22',
    address: '北京市朝阳区芍药居'
  },
  {
    name: '张小刚',
    age: 25,
    birthday: '1990-11-11',
    address: '北京市海淀区西二旗'
  },
  {
    name: '李小红',
    age: 30,
    birthday: '1985-02-05',
    address: '上海市浦东新区世纪大道'
  },
  {
    name: '周小伟',
    age: 26,
    birthday: '1993-07-11',
    address: '深圳市南山区深南大道'
  },
  {
    name: '张小发',
    age: 33,
    birthday: '1999-12-12',
    address: '南京市龙眠大道'
  }
])
</script>

固定表头和列

可以同时固定表头和列

姓名
年龄
出生日期
地址
操作
王小明
18
1990-04-22
北京市朝阳区芍药居
张小刚
25
1990-11-11
北京市海淀区西二旗
李小红
30
1985-02-05
上海市浦东新区世纪大道
周小伟
26
1993-07-11
深圳市南山区深南大道
张小发
33
1999-12-12
南京市龙眠大道
姓名
年龄
出生日期
地址
操作
王小明
18
1990-04-22
北京市朝阳区芍药居
张小刚
25
1990-11-11
北京市海淀区西二旗
李小红
30
1985-02-05
上海市浦东新区世纪大道
周小伟
26
1993-07-11
深圳市南山区深南大道
张小发
33
1999-12-12
南京市龙眠大道
操作
姓名
年龄
出生日期
地址
王小明
18
1990-04-22
北京市朝阳区芍药居
张小刚
25
1990-11-11
北京市海淀区西二旗
李小红
30
1985-02-05
上海市浦东新区世纪大道
周小伟
26
1993-07-11
深圳市南山区深南大道
张小发
33
1999-12-12
南京市龙眠大道
<template>
  <div style="width: 800px">
    <b-table :columns="columns" :data="data" height="200" border></b-table>
  </div>
</template>

<script setup lang="ts">
import { ref, h } from 'vue'

const columns = [
  {
    title: '姓名',
    fixed: 'left',
    key: 'name',
    width: 150
  },
  {
    title: '年龄',
    key: 'age',
    width: 150
  },
  {
    title: '出生日期',
    key: 'birthday',
    width: 150
  },
  {
    title: '地址',
    key: 'address',
    width: 350
  },
  {
    title: '操作',
    fixed: 'right',
    width: 100,
    render: () => {
      return h('a', { style: { cursor: 'pointer' } }, '编辑')
    }
  }
]

const data = ref([
  {
    name: '王小明',
    age: 18,
    birthday: '1990-04-22',
    address: '北京市朝阳区芍药居'
  },
  {
    name: '张小刚',
    age: 25,
    birthday: '1990-11-11',
    address: '北京市海淀区西二旗'
  },
  {
    name: '李小红',
    age: 30,
    birthday: '1985-02-05',
    address: '上海市浦东新区世纪大道'
  },
  {
    name: '周小伟',
    age: 26,
    birthday: '1993-07-11',
    address: '深圳市南山区深南大道'
  },
  {
    name: '张小发',
    age: 33,
    birthday: '1999-12-12',
    address: '南京市龙眠大道'
  }
])
</script>
<template>
  <div style="width: 800px">
    <b-table :columns="columns" :data="data" height="200" border></b-table>
  </div>
</template>

<script setup lang="ts">
import { ref, h } from 'vue'

const columns = [
  {
    title: '姓名',
    fixed: 'left',
    key: 'name',
    width: 150
  },
  {
    title: '年龄',
    key: 'age',
    width: 150
  },
  {
    title: '出生日期',
    key: 'birthday',
    width: 150
  },
  {
    title: '地址',
    key: 'address',
    width: 350
  },
  {
    title: '操作',
    fixed: 'right',
    width: 100,
    render: () => {
      return h('a', { style: { cursor: 'pointer' } }, '编辑')
    }
  }
]

const data = ref([
  {
    name: '王小明',
    age: 18,
    birthday: '1990-04-22',
    address: '北京市朝阳区芍药居'
  },
  {
    name: '张小刚',
    age: 25,
    birthday: '1990-11-11',
    address: '北京市海淀区西二旗'
  },
  {
    name: '李小红',
    age: 30,
    birthday: '1985-02-05',
    address: '上海市浦东新区世纪大道'
  },
  {
    name: '周小伟',
    age: 26,
    birthday: '1993-07-11',
    address: '深圳市南山区深南大道'
  },
  {
    name: '张小发',
    age: 33,
    birthday: '1999-12-12',
    address: '南京市龙眠大道'
  }
])
</script>

流体高度

姓名
年龄
出生日期
地址
操作
王小明
18
1990-04-22
北京市朝阳区芍药居
张小刚
25
1990-11-11
北京市海淀区西二旗

<template>
  <div style="padding: 2px">
    <b-table :columns="columns" :data="data" max-height="200" border>
      <template #ctrl="{ index }">
        <b-button type="danger" size="mini" plain @click="removeRow(index)">删除</b-button>
      </template>
    </b-table>
    <br />
    <b-button @click="add">增加一条数据</b-button>
  </div>
</template>

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

const columns = [
  { title: '姓名', key: 'name' },
  { title: '年龄', key: 'age', align: 'center' },
  { title: '出生日期', key: 'birthday' },
  { title: '地址', key: 'address', width: 350 },
  { title: '操作', slot: 'ctrl', width: 100 }
]
const data = ref([
  {
    name: '王小明',
    age: 18,
    birthday: '1990-04-22',
    address: '北京市朝阳区芍药居'
  },
  {
    name: '张小刚',
    age: 25,
    birthday: '1990-11-11',
    address: '北京市海淀区西二旗'
  }
])

function add() {
  data.value.push({
    name: '张小发',
    age: 33,
    birthday: '1999-12-12',
    address: '南京市龙眠大道'
  })
}
function removeRow(index) {
  data.value.splice(index, 1)
}
</script>
<template>
  <div style="padding: 2px">
    <b-table :columns="columns" :data="data" max-height="200" border>
      <template #ctrl="{ index }">
        <b-button type="danger" size="mini" plain @click="removeRow(index)">删除</b-button>
      </template>
    </b-table>
    <br />
    <b-button @click="add">增加一条数据</b-button>
  </div>
</template>

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

const columns = [
  { title: '姓名', key: 'name' },
  { title: '年龄', key: 'age', align: 'center' },
  { title: '出生日期', key: 'birthday' },
  { title: '地址', key: 'address', width: 350 },
  { title: '操作', slot: 'ctrl', width: 100 }
]
const data = ref([
  {
    name: '王小明',
    age: 18,
    birthday: '1990-04-22',
    address: '北京市朝阳区芍药居'
  },
  {
    name: '张小刚',
    age: 25,
    birthday: '1990-11-11',
    address: '北京市海淀区西二旗'
  }
])

function add() {
  data.value.push({
    name: '张小发',
    age: 33,
    birthday: '1999-12-12',
    address: '南京市龙眠大道'
  })
}
function removeRow(index) {
  data.value.splice(index, 1)
}
</script>

单选表格

姓名
年龄
出生日期
地址
王小明
18
1990-04-22
北京市朝阳区芍药居
张小刚
25
1990-11-11
北京市海淀区西二旗
李小红
30
1985-02-05
上海市浦东新区世纪大道
周小伟
26
1993-07-11
深圳市南山区深南大道
张小发
33
1999-12-12
南京市龙眠大道


姓名
年龄
出生日期
地址
操作
王小明
18
1990-04-22
北京市朝阳区芍药居
张小刚
25
1990-11-11
北京市海淀区西二旗
李小红
30
1985-02-05
上海市浦东新区世纪大道
周小伟
26
1993-07-11
深圳市南山区深南大道
张小发
33
1999-12-12
南京市龙眠大道

<template>
  <div>
    <b-table
      ref="currentRowTable"
      :columns="columns"
      :data="data"
      highlight-row
      @current-change="currentRowChange"
    ></b-table>
    <br />
    <div>
      <b-button @click="clearSelect">清除单选</b-button>
      <b-button @click="clickRow(0)">选中第一行</b-button>
    </div>
    <br />
    <b-table
      ref="currentRowTable2"
      :columns="columns2"
      :data="data2"
      highlight-row
      @current-change="currentRowChange"
    >
      <template #ctrl="{ index }">
        <b-button type="text" text-color="danger" @click="removeRow(index)">删除</b-button>
      </template>
    </b-table>
    <br />
    <b-button @click="init">初始化表格2并默认选中第一行</b-button>
  </div>
</template>

<script setup lang="ts">
import { ref, nextTick } from 'vue'
import { Message } from 'bin-ui-design'

const columns = [
  { title: '姓名', key: 'name' },
  { title: '年龄', key: 'age' },
  { title: '出生日期', key: 'birthday' },
  { title: '地址', key: 'address' }
]
const columns2 = [
  { title: '姓名', key: 'name' },
  { title: '年龄', key: 'age' },
  { title: '出生日期', key: 'birthday' },
  { title: '地址', key: 'address' },
  { title: '操作', slot: 'ctrl' }
]
const data = ref([
  {
    name: '王小明',
    age: 18,
    birthday: '1990-04-22',
    address: '北京市朝阳区芍药居'
  },
  {
    name: '张小刚',
    age: 25,
    birthday: '1990-11-11',
    address: '北京市海淀区西二旗'
  },
  {
    name: '李小红',
    age: 30,
    birthday: '1985-02-05',
    address: '上海市浦东新区世纪大道'
  },
  {
    name: '周小伟',
    age: 26,
    birthday: '1993-07-11',
    address: '深圳市南山区深南大道'
  },
  {
    name: '张小发',
    age: 33,
    birthday: '1999-12-12',
    address: '南京市龙眠大道'
  }
])
const data2 = ref([
  {
    name: '王小明',
    age: 18,
    birthday: '1990-04-22',
    address: '北京市朝阳区芍药居'
  },
  {
    name: '张小刚',
    age: 25,
    birthday: '1990-11-11',
    address: '北京市海淀区西二旗'
  },
  {
    name: '李小红',
    age: 30,
    birthday: '1985-02-05',
    address: '上海市浦东新区世纪大道'
  },
  {
    name: '周小伟',
    age: 26,
    birthday: '1993-07-11',
    address: '深圳市南山区深南大道'
  },
  {
    name: '张小发',
    age: 33,
    birthday: '1999-12-12',
    address: '南京市龙眠大道'
  }
])
const currentRowTable = ref(null)
const currentRowTable2 = ref(null)

function currentRowChange(currentRow, oldRow, index) {
  if (index >= 0) {
    Message(`选中了第${index + 1}行`)
  }
}

function clearSelect() {
  currentRowTable.value.clearCurrentRow()
}
// 选中某一行
function clickRow(index) {
  currentRowTable.value.clickCurrentRow(index)
}
function init() {
  data2.value = JSON.parse(JSON.stringify(data.value))
  nextTick(() => {
    currentRowTable2.value.clickCurrentRow(0)
  })
}
function removeRow(index) {
  data2.value.splice(index, 1)
}
</script>
<template>
  <div>
    <b-table
      ref="currentRowTable"
      :columns="columns"
      :data="data"
      highlight-row
      @current-change="currentRowChange"
    ></b-table>
    <br />
    <div>
      <b-button @click="clearSelect">清除单选</b-button>
      <b-button @click="clickRow(0)">选中第一行</b-button>
    </div>
    <br />
    <b-table
      ref="currentRowTable2"
      :columns="columns2"
      :data="data2"
      highlight-row
      @current-change="currentRowChange"
    >
      <template #ctrl="{ index }">
        <b-button type="text" text-color="danger" @click="removeRow(index)">删除</b-button>
      </template>
    </b-table>
    <br />
    <b-button @click="init">初始化表格2并默认选中第一行</b-button>
  </div>
</template>

<script setup lang="ts">
import { ref, nextTick } from 'vue'
import { Message } from 'bin-ui-design'

const columns = [
  { title: '姓名', key: 'name' },
  { title: '年龄', key: 'age' },
  { title: '出生日期', key: 'birthday' },
  { title: '地址', key: 'address' }
]
const columns2 = [
  { title: '姓名', key: 'name' },
  { title: '年龄', key: 'age' },
  { title: '出生日期', key: 'birthday' },
  { title: '地址', key: 'address' },
  { title: '操作', slot: 'ctrl' }
]
const data = ref([
  {
    name: '王小明',
    age: 18,
    birthday: '1990-04-22',
    address: '北京市朝阳区芍药居'
  },
  {
    name: '张小刚',
    age: 25,
    birthday: '1990-11-11',
    address: '北京市海淀区西二旗'
  },
  {
    name: '李小红',
    age: 30,
    birthday: '1985-02-05',
    address: '上海市浦东新区世纪大道'
  },
  {
    name: '周小伟',
    age: 26,
    birthday: '1993-07-11',
    address: '深圳市南山区深南大道'
  },
  {
    name: '张小发',
    age: 33,
    birthday: '1999-12-12',
    address: '南京市龙眠大道'
  }
])
const data2 = ref([
  {
    name: '王小明',
    age: 18,
    birthday: '1990-04-22',
    address: '北京市朝阳区芍药居'
  },
  {
    name: '张小刚',
    age: 25,
    birthday: '1990-11-11',
    address: '北京市海淀区西二旗'
  },
  {
    name: '李小红',
    age: 30,
    birthday: '1985-02-05',
    address: '上海市浦东新区世纪大道'
  },
  {
    name: '周小伟',
    age: 26,
    birthday: '1993-07-11',
    address: '深圳市南山区深南大道'
  },
  {
    name: '张小发',
    age: 33,
    birthday: '1999-12-12',
    address: '南京市龙眠大道'
  }
])
const currentRowTable = ref(null)
const currentRowTable2 = ref(null)

function currentRowChange(currentRow, oldRow, index) {
  if (index >= 0) {
    Message(`选中了第${index + 1}行`)
  }
}

function clearSelect() {
  currentRowTable.value.clearCurrentRow()
}
// 选中某一行
function clickRow(index) {
  currentRowTable.value.clickCurrentRow(index)
}
function init() {
  data2.value = JSON.parse(JSON.stringify(data.value))
  nextTick(() => {
    currentRowTable2.value.clickCurrentRow(0)
  })
}
function removeRow(index) {
  data2.value.splice(index, 1)
}
</script>

多选表格

通过给 columns 数据设置一项,指定 type: 'selection',即可自动开启多选功能。

给 data 项设置特殊 key _checked: true 可以默认选中当前项。

给 data 项设置特殊 key _disabled: true 可以禁止选择当前项。

@select,选中某一项触发,返回值为 selection 和 row,分别为已选项和刚选择的项。@select-all,点击全选时触发,返回值为 selection,已选项。 @selection-change,只要选中项发生变化时就会触发,返回值为 selection,已选项。

姓名
年龄
出生日期
地址
王小明
18
1990-04-22
北京市朝阳区芍药居
张小刚
25
1990-11-11
北京市海淀区西二旗
李小红
30
1985-02-05
上海市浦东新区世纪大道
周小伟
26
1993-07-11
深圳市南山区深南大道
张小发
33
1999-12-12
南京市龙眠大道

<template>
  <div>
    <b-table ref="tableRef" :columns="columns" :data="data" highlight-row></b-table>
    <br />
    <b-button @click="$refs.tableRef.selectAll(true)">设置全选</b-button>
    <b-button @click="$refs.tableRef.selectAll(false)">取消全选</b-button>
    <b-button @click="getAllSelected">获取选中</b-button>
  </div>
</template>

<script setup lang="ts">
import { ref } from 'vue'
const columns = [
  { type: 'selection', width: 60, align: 'center' },
  { title: '姓名', key: 'name' },
  { title: '年龄', key: 'age' },
  { title: '出生日期', key: 'birthday' },
  { title: '地址', key: 'address' }
]
const data = ref([
  {
    name: '王小明',
    age: 18,
    birthday: '1990-04-22',
    address: '北京市朝阳区芍药居'
  },
  {
    name: '张小刚',
    age: 25,
    birthday: '1990-11-11',
    address: '北京市海淀区西二旗'
  },
  {
    name: '李小红',
    age: 30,
    birthday: '1985-02-05',
    address: '上海市浦东新区世纪大道'
  },
  {
    name: '周小伟',
    age: 26,
    birthday: '1993-07-11',
    address: '深圳市南山区深南大道'
  },
  {
    name: '张小发',
    age: 33,
    birthday: '1999-12-12',
    address: '南京市龙眠大道'
  }
])
const tableRef = ref(null)
function getAllSelected() {
  const selected = tableRef.value.getSelection()
  console.log(selected)
}
</script>
<template>
  <div>
    <b-table ref="tableRef" :columns="columns" :data="data" highlight-row></b-table>
    <br />
    <b-button @click="$refs.tableRef.selectAll(true)">设置全选</b-button>
    <b-button @click="$refs.tableRef.selectAll(false)">取消全选</b-button>
    <b-button @click="getAllSelected">获取选中</b-button>
  </div>
</template>

<script setup lang="ts">
import { ref } from 'vue'
const columns = [
  { type: 'selection', width: 60, align: 'center' },
  { title: '姓名', key: 'name' },
  { title: '年龄', key: 'age' },
  { title: '出生日期', key: 'birthday' },
  { title: '地址', key: 'address' }
]
const data = ref([
  {
    name: '王小明',
    age: 18,
    birthday: '1990-04-22',
    address: '北京市朝阳区芍药居'
  },
  {
    name: '张小刚',
    age: 25,
    birthday: '1990-11-11',
    address: '北京市海淀区西二旗'
  },
  {
    name: '李小红',
    age: 30,
    birthday: '1985-02-05',
    address: '上海市浦东新区世纪大道'
  },
  {
    name: '周小伟',
    age: 26,
    birthday: '1993-07-11',
    address: '深圳市南山区深南大道'
  },
  {
    name: '张小发',
    age: 33,
    birthday: '1999-12-12',
    address: '南京市龙眠大道'
  }
])
const tableRef = ref(null)
function getAllSelected() {
  const selected = tableRef.value.getSelection()
  console.log(selected)
}
</script>

可展开

通过给columns 数据设置一项,指定 type: 'expand',即可开启扩展功能。

姓名
年龄
出生日期
详细地址
王小明
18
1990-04-22
北京市朝阳区芍药居
张小刚
25
1990-11-11
北京市海淀区西二旗
李小红
30
1985-02-05
上海市浦东新区世纪大道
周小伟
26
1993-07-11
深圳市南山区深南大道
张小发
33
1999-12-12
南京市龙眠大道
<template>
  <b-table :columns="columns" :data="data"></b-table>
</template>

<script setup lang="ts">
import { ref, h } from 'vue'
const columns = [
  {
    type: 'expand',
    width: 50,
    render: params => {
      return h('div', '详细地址:' + params.row.address)
    }
  },
  { title: '姓名', key: 'name' },
  { title: '年龄', key: 'age' },
  { title: '出生日期', key: 'birthday' },
  { title: '详细地址', key: 'address' }
]

const data = ref([
  {
    name: '王小明',
    age: 18,
    birthday: '1990-04-22',
    address: '北京市朝阳区芍药居'
  },
  {
    name: '张小刚',
    age: 25,
    birthday: '1990-11-11',
    address: '北京市海淀区西二旗'
  },
  {
    name: '李小红',
    age: 30,
    birthday: '1985-02-05',
    address: '上海市浦东新区世纪大道'
  },
  {
    name: '周小伟',
    age: 26,
    birthday: '1993-07-11',
    address: '深圳市南山区深南大道'
  },
  {
    name: '张小发',
    age: 33,
    birthday: '1999-12-12',
    address: '南京市龙眠大道'
  }
])
</script>
<template>
  <b-table :columns="columns" :data="data"></b-table>
</template>

<script setup lang="ts">
import { ref, h } from 'vue'
const columns = [
  {
    type: 'expand',
    width: 50,
    render: params => {
      return h('div', '详细地址:' + params.row.address)
    }
  },
  { title: '姓名', key: 'name' },
  { title: '年龄', key: 'age' },
  { title: '出生日期', key: 'birthday' },
  { title: '详细地址', key: 'address' }
]

const data = ref([
  {
    name: '王小明',
    age: 18,
    birthday: '1990-04-22',
    address: '北京市朝阳区芍药居'
  },
  {
    name: '张小刚',
    age: 25,
    birthday: '1990-11-11',
    address: '北京市海淀区西二旗'
  },
  {
    name: '李小红',
    age: 30,
    birthday: '1985-02-05',
    address: '上海市浦东新区世纪大道'
  },
  {
    name: '周小伟',
    age: 26,
    birthday: '1993-07-11',
    address: '深圳市南山区深南大道'
  },
  {
    name: '张小发',
    age: 33,
    birthday: '1999-12-12',
    address: '南京市龙眠大道'
  }
])
</script>

表头分组

columns内容可以设置children来分组渲染表头,合并表头和行列时推荐使用border模式

姓名
基本信息
学历信息
年龄
出生日期
详细地址
毕业院校
毕业日期
王小明
18
1990-04-22
北京市朝阳区芍药居
南京河海大学
2012-04-22
张小刚
25
1990-11-11
北京市海淀区西二旗
北京大学
2012-04-22
李小红
30
1985-02-05
上海市浦东新区世纪大道
上海复旦
2012-04-22
周小伟
26
1993-07-11
深圳市南山区深南大道
广东大学
2012-04-22
张小发
33
1999-12-12
南京市龙眠大道
南京交通学院
2012-04-22
李晓红
23
1999-12-12
南京市龙眠大道
南京交通学院
2012-04-22
郭小宁
23
1999-12-12
南京市龙眠大道
南京交通学院
2012-04-22
<template>
  <b-table :columns="columns" height="300" :data="data" border></b-table>
</template>

<script setup lang="ts">
import { ref } from 'vue'
const columns = [
  { title: '姓名', key: 'name' },
  {
    title: '基本信息',
    align: 'center',
    children: [
      { title: '年龄', key: 'age' },
      { title: '出生日期', key: 'birthday' },
      { title: '详细地址', key: 'address' }
    ]
  },
  {
    title: '学历信息',
    align: 'center',
    children: [
      { title: '毕业院校', key: 'school' },
      { title: '毕业日期', key: 'eduDate' }
    ]
  }
]
const data = ref([
  {
    name: '王小明',
    age: 18,
    birthday: '1990-04-22',
    address: '北京市朝阳区芍药居',
    school: '南京河海大学',
    eduDate: '2012-04-22'
  },
  {
    name: '张小刚',
    age: 25,
    birthday: '1990-11-11',
    address: '北京市海淀区西二旗',
    school: '北京大学',
    eduDate: '2012-04-22'
  },
  {
    name: '李小红',
    age: 30,
    birthday: '1985-02-05',
    address: '上海市浦东新区世纪大道',
    school: '上海复旦',
    eduDate: '2012-04-22'
  },
  {
    name: '周小伟',
    age: 26,
    birthday: '1993-07-11',
    address: '深圳市南山区深南大道',
    school: '广东大学',
    eduDate: '2012-04-22'
  },
  {
    name: '张小发',
    age: 33,
    birthday: '1999-12-12',
    address: '南京市龙眠大道',
    school: '南京交通学院',
    eduDate: '2012-04-22'
  },
  {
    name: '李晓红',
    age: 23,
    birthday: '1999-12-12',
    address: '南京市龙眠大道',
    school: '南京交通学院',
    eduDate: '2012-04-22'
  },
  {
    name: '郭小宁',
    age: 23,
    birthday: '1999-12-12',
    address: '南京市龙眠大道',
    school: '南京交通学院',
    eduDate: '2012-04-22'
  }
])
</script>
<template>
  <b-table :columns="columns" height="300" :data="data" border></b-table>
</template>

<script setup lang="ts">
import { ref } from 'vue'
const columns = [
  { title: '姓名', key: 'name' },
  {
    title: '基本信息',
    align: 'center',
    children: [
      { title: '年龄', key: 'age' },
      { title: '出生日期', key: 'birthday' },
      { title: '详细地址', key: 'address' }
    ]
  },
  {
    title: '学历信息',
    align: 'center',
    children: [
      { title: '毕业院校', key: 'school' },
      { title: '毕业日期', key: 'eduDate' }
    ]
  }
]
const data = ref([
  {
    name: '王小明',
    age: 18,
    birthday: '1990-04-22',
    address: '北京市朝阳区芍药居',
    school: '南京河海大学',
    eduDate: '2012-04-22'
  },
  {
    name: '张小刚',
    age: 25,
    birthday: '1990-11-11',
    address: '北京市海淀区西二旗',
    school: '北京大学',
    eduDate: '2012-04-22'
  },
  {
    name: '李小红',
    age: 30,
    birthday: '1985-02-05',
    address: '上海市浦东新区世纪大道',
    school: '上海复旦',
    eduDate: '2012-04-22'
  },
  {
    name: '周小伟',
    age: 26,
    birthday: '1993-07-11',
    address: '深圳市南山区深南大道',
    school: '广东大学',
    eduDate: '2012-04-22'
  },
  {
    name: '张小发',
    age: 33,
    birthday: '1999-12-12',
    address: '南京市龙眠大道',
    school: '南京交通学院',
    eduDate: '2012-04-22'
  },
  {
    name: '李晓红',
    age: 23,
    birthday: '1999-12-12',
    address: '南京市龙眠大道',
    school: '南京交通学院',
    eduDate: '2012-04-22'
  },
  {
    name: '郭小宁',
    age: 23,
    birthday: '1999-12-12',
    address: '南京市龙眠大道',
    school: '南京交通学院',
    eduDate: '2012-04-22'
  }
])
</script>

行列合并

可以设置属性mergeMethod制定合并行或者列的算法,方法参数为四个对象rowcolumnrowIndexcolumnIndex, 该方法返回一个包含两个元素的数组,第一个表示rowspan,第二个为colspan,用于合并单元格 合并表格最好是使用border模式

姓名
年龄
出生日期
地址
王小明
18
1990-04-22
北京市朝阳区芍药居
25
1990-11-11
北京市海淀区西二旗
李小红
30
1985-02-05
上海市浦东新区世纪大道
周小伟
26
1993-07-11
张小发
33
1999-12-12
南京市龙眠大道
<template>
  <b-table :columns="columns" :data="data" border :merge-method="handleSpan"></b-table>
</template>

<script setup lang="ts">
import { ref } from 'vue'
const columns = [
  { title: '姓名', key: 'name' },
  { title: '年龄', key: 'age' },
  { title: '出生日期', key: 'birthday' },
  { title: '地址', key: 'address' }
]
const data = ref([
  {
    name: '王小明',
    age: 18,
    birthday: '1990-04-22',
    address: '北京市朝阳区芍药居'
  },
  {
    name: '张小刚',
    age: 25,
    birthday: '1990-11-11',
    address: '北京市海淀区西二旗'
  },
  {
    name: '李小红',
    age: 30,
    birthday: '1985-02-05',
    address: '上海市浦东新区世纪大道'
  },
  {
    name: '周小伟',
    age: 26,
    birthday: '1993-07-11',
    address: '深圳市南山区深南大道'
  },
  {
    name: '张小发',
    age: 33,
    birthday: '1999-12-12',
    address: '南京市龙眠大道'
  }
])

function handleSpan({ row, column, rowIndex, columnIndex }) {
  // 获取相同姓名的行是,0,1
  if (rowIndex === 0 && columnIndex === 0) {
    return {
      rowspan: 2,
      colspan: 1
    }
  } else if (rowIndex === 1 && columnIndex === 0) {
    return {
      rowspan: 0,
      colspan: 1
    }
  }
  // 合并列,这里将第三行,周小伟的日期和地址合并
  if (rowIndex === 3 && columnIndex === 2) {
    return [1, 2]
  } else if (rowIndex === 3 && columnIndex === 3) {
    return [0, 0]
  }
}
</script>
<template>
  <b-table :columns="columns" :data="data" border :merge-method="handleSpan"></b-table>
</template>

<script setup lang="ts">
import { ref } from 'vue'
const columns = [
  { title: '姓名', key: 'name' },
  { title: '年龄', key: 'age' },
  { title: '出生日期', key: 'birthday' },
  { title: '地址', key: 'address' }
]
const data = ref([
  {
    name: '王小明',
    age: 18,
    birthday: '1990-04-22',
    address: '北京市朝阳区芍药居'
  },
  {
    name: '张小刚',
    age: 25,
    birthday: '1990-11-11',
    address: '北京市海淀区西二旗'
  },
  {
    name: '李小红',
    age: 30,
    birthday: '1985-02-05',
    address: '上海市浦东新区世纪大道'
  },
  {
    name: '周小伟',
    age: 26,
    birthday: '1993-07-11',
    address: '深圳市南山区深南大道'
  },
  {
    name: '张小发',
    age: 33,
    birthday: '1999-12-12',
    address: '南京市龙眠大道'
  }
])

function handleSpan({ row, column, rowIndex, columnIndex }) {
  // 获取相同姓名的行是,0,1
  if (rowIndex === 0 && columnIndex === 0) {
    return {
      rowspan: 2,
      colspan: 1
    }
  } else if (rowIndex === 1 && columnIndex === 0) {
    return {
      rowspan: 0,
      colspan: 1
    }
  }
  // 合并列,这里将第三行,周小伟的日期和地址合并
  if (rowIndex === 3 && columnIndex === 2) {
    return [1, 2]
  } else if (rowIndex === 3 && columnIndex === 3) {
    return [0, 0]
  }
}
</script>

排序表格

姓名
年龄
出生日期
地址
王小明
18
1990-04-22
北京市朝阳区芍药居
张小刚
25
1990-11-11
北京市海淀区西二旗
李小红
30
1985-02-05
上海市浦东新区世纪大道
周小伟
26
1993-07-11
深圳市南山区深南大道
张小发
33
1999-12-12
南京市龙眠大道
<template>
  <b-table :columns="columns" :data="data"></b-table>
</template>

<script setup lang="ts">
import { ref } from 'vue'
const columns = [
  { title: '姓名', key: 'name' },
  { title: '年龄', key: 'age', sortable: true },
  { title: '出生日期', key: 'birthday' },
  { title: '地址', key: 'address' }
]
const data = ref([
  {
    name: '王小明',
    age: 18,
    birthday: '1990-04-22',
    address: '北京市朝阳区芍药居'
  },
  {
    name: '张小刚',
    age: 25,
    birthday: '1990-11-11',
    address: '北京市海淀区西二旗'
  },
  {
    name: '李小红',
    age: 30,
    birthday: '1985-02-05',
    address: '上海市浦东新区世纪大道'
  },
  {
    name: '周小伟',
    age: 26,
    birthday: '1993-07-11',
    address: '深圳市南山区深南大道'
  },
  {
    name: '张小发',
    age: 33,
    birthday: '1999-12-12',
    address: '南京市龙眠大道'
  }
])
</script>
<template>
  <b-table :columns="columns" :data="data"></b-table>
</template>

<script setup lang="ts">
import { ref } from 'vue'
const columns = [
  { title: '姓名', key: 'name' },
  { title: '年龄', key: 'age', sortable: true },
  { title: '出生日期', key: 'birthday' },
  { title: '地址', key: 'address' }
]
const data = ref([
  {
    name: '王小明',
    age: 18,
    birthday: '1990-04-22',
    address: '北京市朝阳区芍药居'
  },
  {
    name: '张小刚',
    age: 25,
    birthday: '1990-11-11',
    address: '北京市海淀区西二旗'
  },
  {
    name: '李小红',
    age: 30,
    birthday: '1985-02-05',
    address: '上海市浦东新区世纪大道'
  },
  {
    name: '周小伟',
    age: 26,
    birthday: '1993-07-11',
    address: '深圳市南山区深南大道'
  },
  {
    name: '张小发',
    age: 33,
    birthday: '1999-12-12',
    address: '南京市龙眠大道'
  }
])
</script>

行内编辑

姓名
年龄
出生日期
爱好
地址
操作
王小明
18
1990-04-22
吃饭
北京市朝阳区芍药居
张小刚
25
1990-11-11
吃饭
北京市海淀区西二旗
李小红
30
1985-02-05
打豆豆
上海市浦东新区世纪大道
周小伟
26
1993-07-11
吃饭
深圳市南山区深南大道
张小发
33
1999-12-12
睡觉
南京市龙眠大道
<template>
  <b-table :columns="columns" :data="data">
    <template #name="{ index, row }">
      <b-input
        v-if="obj.editIndex === index"
        v-model="obj.editName"
        type="text"
        size="small"
        clearable
      ></b-input>
      <span v-else>{{ row.name }}</span>
    </template>
    <template #age="{ index, row }">
      <b-input-number
        v-if="obj.editIndex === index"
        v-model="obj.editAge"
        type="text"
        size="small"
      ></b-input-number>
      <span v-else>{{ row.age }}</span>
    </template>
    <template #birthday="{ index, row }">
      <b-date-picker
        v-if="obj.editIndex === index"
        v-model="obj.editBirthday"
        size="small"
        type="date"
        placeholder="选择日期"
      ></b-date-picker>
      <span v-else>{{ row.birthday }}</span>
    </template>
    <template #hobby="{ index, row }">
      <b-select v-if="obj.editIndex === index" v-model="obj.editHobby" clearable size="small">
        <b-option v-for="(val, key) in hobbyMap" :key="key" :value="key" :label="val">
          {{ val }}
        </b-option>
      </b-select>
      <span v-else>{{ hobbyMap[row.hobby] }}</span>
    </template>
    <template #address="{ index, row }">
      <b-input
        v-if="obj.editIndex === index"
        v-model="obj.editAddress"
        type="text"
        size="small"
      ></b-input>
      <span v-else>{{ row.address }}</span>
    </template>
    <template #action="{ index, row }">
      <div v-if="obj.editIndex === index">
        <b-button size="small" type="success" plain @click="handleSave(index)">保存</b-button>
        <b-button size="small" @click="obj.editIndex = -1">取消</b-button>
      </div>
      <div v-else>
        <b-button size="small" @click="handleEdit(row, index)">操作</b-button>
      </div>
    </template>
  </b-table>
</template>

<script setup lang="ts">
import { reactive, ref } from 'vue'
import dayjs from 'dayjs'

const columns = [
  { title: '姓名', slot: 'name' },
  { title: '年龄', slot: 'age' },
  { title: '出生日期', slot: 'birthday' },
  { title: '爱好', slot: 'hobby' },
  { title: '地址', slot: 'address' },
  { title: '操作', slot: 'action' }
]
const hobbyMap = { '1': '吃饭', '2': '睡觉', '3': '打豆豆' }
const data = ref([
  {
    name: '王小明',
    age: 18,
    birthday: '1990-04-22',
    hobby: '1',
    address: '北京市朝阳区芍药居'
  },
  {
    name: '张小刚',
    age: 25,
    birthday: '1990-11-11',
    hobby: '1',
    address: '北京市海淀区西二旗'
  },
  {
    name: '李小红',
    age: 30,
    birthday: '1985-02-05',
    hobby: '3',
    address: '上海市浦东新区世纪大道'
  },
  {
    name: '周小伟',
    age: 26,
    birthday: '1993-07-11',
    hobby: '1',
    address: '深圳市南山区深南大道'
  },
  {
    name: '张小发',
    age: 33,
    birthday: '1999-12-12',
    hobby: '2',
    address: '南京市龙眠大道'
  }
])

const obj = reactive({
  editName: '',
  editAge: '',
  editBirthday: '',
  editHobby: '',
  editAddress: '',
  editIndex: -1
})

function handleEdit(row, index) {
  obj.editName = row.name
  obj.editAge = row.age
  obj.editHobby = row.hobby
  obj.editAddress = row.address
  obj.editBirthday = new Date(row.birthday)
  obj.editIndex = index
}
function handleSave(index) {
  data.value[index].name = obj.editName
  data.value[index].age = obj.editAge
  data.value[index].birthday = dayjs(obj.editBirthday).format('YYYY-MM-DD')
  data.value[index].hobby = obj.editHobby
  data.value[index].address = obj.editAddress
  obj.editIndex = -1
}
</script>
<template>
  <b-table :columns="columns" :data="data">
    <template #name="{ index, row }">
      <b-input
        v-if="obj.editIndex === index"
        v-model="obj.editName"
        type="text"
        size="small"
        clearable
      ></b-input>
      <span v-else>{{ row.name }}</span>
    </template>
    <template #age="{ index, row }">
      <b-input-number
        v-if="obj.editIndex === index"
        v-model="obj.editAge"
        type="text"
        size="small"
      ></b-input-number>
      <span v-else>{{ row.age }}</span>
    </template>
    <template #birthday="{ index, row }">
      <b-date-picker
        v-if="obj.editIndex === index"
        v-model="obj.editBirthday"
        size="small"
        type="date"
        placeholder="选择日期"
      ></b-date-picker>
      <span v-else>{{ row.birthday }}</span>
    </template>
    <template #hobby="{ index, row }">
      <b-select v-if="obj.editIndex === index" v-model="obj.editHobby" clearable size="small">
        <b-option v-for="(val, key) in hobbyMap" :key="key" :value="key" :label="val">
          {{ val }}
        </b-option>
      </b-select>
      <span v-else>{{ hobbyMap[row.hobby] }}</span>
    </template>
    <template #address="{ index, row }">
      <b-input
        v-if="obj.editIndex === index"
        v-model="obj.editAddress"
        type="text"
        size="small"
      ></b-input>
      <span v-else>{{ row.address }}</span>
    </template>
    <template #action="{ index, row }">
      <div v-if="obj.editIndex === index">
        <b-button size="small" type="success" plain @click="handleSave(index)">保存</b-button>
        <b-button size="small" @click="obj.editIndex = -1">取消</b-button>
      </div>
      <div v-else>
        <b-button size="small" @click="handleEdit(row, index)">操作</b-button>
      </div>
    </template>
  </b-table>
</template>

<script setup lang="ts">
import { reactive, ref } from 'vue'
import dayjs from 'dayjs'

const columns = [
  { title: '姓名', slot: 'name' },
  { title: '年龄', slot: 'age' },
  { title: '出生日期', slot: 'birthday' },
  { title: '爱好', slot: 'hobby' },
  { title: '地址', slot: 'address' },
  { title: '操作', slot: 'action' }
]
const hobbyMap = { '1': '吃饭', '2': '睡觉', '3': '打豆豆' }
const data = ref([
  {
    name: '王小明',
    age: 18,
    birthday: '1990-04-22',
    hobby: '1',
    address: '北京市朝阳区芍药居'
  },
  {
    name: '张小刚',
    age: 25,
    birthday: '1990-11-11',
    hobby: '1',
    address: '北京市海淀区西二旗'
  },
  {
    name: '李小红',
    age: 30,
    birthday: '1985-02-05',
    hobby: '3',
    address: '上海市浦东新区世纪大道'
  },
  {
    name: '周小伟',
    age: 26,
    birthday: '1993-07-11',
    hobby: '1',
    address: '深圳市南山区深南大道'
  },
  {
    name: '张小发',
    age: 33,
    birthday: '1999-12-12',
    hobby: '2',
    address: '南京市龙眠大道'
  }
])

const obj = reactive({
  editName: '',
  editAge: '',
  editBirthday: '',
  editHobby: '',
  editAddress: '',
  editIndex: -1
})

function handleEdit(row, index) {
  obj.editName = row.name
  obj.editAge = row.age
  obj.editHobby = row.hobby
  obj.editAddress = row.address
  obj.editBirthday = new Date(row.birthday)
  obj.editIndex = index
}
function handleSave(index) {
  data.value[index].name = obj.editName
  data.value[index].age = obj.editAge
  data.value[index].birthday = dayjs(obj.editBirthday).format('YYYY-MM-DD')
  data.value[index].hobby = obj.editHobby
  data.value[index].address = obj.editAddress
  obj.editIndex = -1
}
</script>

编辑表格

编辑表格,只需要开启编辑表格样式,即可开启一中隐藏输入边框的样式,方便进行表格编辑

编辑表格
姓名
年龄
出生日期
爱好
地址
只读
姓名
年龄
出生日期
爱好
地址
王小明
18
1990-04-22
吃饭
北京市朝阳区芍药居
张小刚
25
1990-11-11
吃饭
北京市海淀区西二旗
李小红
30
1985-02-05
打豆豆
上海市浦东新区世纪大道
周小伟
26
1993-07-11
吃饭
深圳市南山区深南大道
张小发
33
1999-12-12
睡觉
南京市龙眠大道
<template>
  <b-form ref="formRef" :model="list" label-width="85px" label-position="top">
    <b-collapse-wrap title="编辑表格" shadow="none">
      <div style="padding: 10px 24px">
        <b-table
          edit-table
          :columns="columns"
          :data="list"
          no-data-text="暂无参数"
          draggable
          drag-handle=".handle"
          max-height="420"
          @drag-drop="handleDragDrop"
        >
          <template #handle>
            <b-icon name="drag" class="handle" />
          </template>
          <template #name="{ index }">
            <b-form-item :rules="validateRules.name" :prop="index + '.name'">
              <b-input v-model="list[index].name" type="text" clearable></b-input>
            </b-form-item>
          </template>
          <template #age="{ index }">
            <b-form-item :rules="validateRules.age" :prop="index + '.age'">
              <b-input-number
                v-model="list[index].age"
                type="text"
                arrow-up-icon="plus"
                arrow-down-icon="minus"
              ></b-input-number>
            </b-form-item>
          </template>
          <template #birthday="{ index }">
            <b-form-item :rules="validateRules.birthday" :prop="index + '.birthday'">
              <b-date-picker
                v-model="list[index].birthday"
                type="date"
                placeholder="选择日期"
              ></b-date-picker>
            </b-form-item>
          </template>
          <template #hobby="{ index }">
            <b-form-item :rules="validateRules.hobby" :prop="index + '.hobby'">
              <b-select v-model="list[index].hobby" clearable>
                <b-option v-for="(val, key) in hobbyMap" :key="key" :value="key" :label="val">
                  {{ val }}
                </b-option>
              </b-select>
            </b-form-item>
          </template>
          <template #address="{ index }">
            <b-form-item :rules="validateRules.address" :prop="index + '.address'">
              <b-input v-model="list[index].address" type="text"></b-input>
            </b-form-item>
          </template>
          <template #action="{ index }">
            <b-button type="text" text-color="danger" @click="handleRemove(index)">
              <b-icon name="minus-circle" />
            </b-button>
          </template>
        </b-table>
        <div class="mt-8">
          <b-button icon="plus" dashed style="width: 100%" @click="handleAdd">新增</b-button>
        </div>
      </div>
    </b-collapse-wrap>

    <b-collapse-wrap title="只读" shadow="none">
      <div style="padding: 10px 24px">
        <b-table :columns="columns2" :data="list" edit-table edit-table-detail>
          <template #hobby="{ row }">
            {{ hobbyMap[row.hobby] }}
          </template>
        </b-table>
      </div>
    </b-collapse-wrap>
  </b-form>
</template>

<script setup lang="ts">
import { reactive, ref, nextTick } from 'vue'

const formRef = ref(null)
const tableRef = ref(null)

const hobbyMap = { 1: '吃饭', 2: '睡觉', 3: '打豆豆' }
const columns = [
  { title: ' ', slot: 'handle', width: 24, align: 'center' },
  { title: '姓名', slot: 'name' },
  { title: '年龄', slot: 'age' },
  { title: '出生日期', slot: 'birthday' },
  { title: '爱好', slot: 'hobby' },
  { title: '地址', slot: 'address' },
  { title: ' ', slot: 'action', width: 50, align: 'center' }
]
const columns2 = [
  { title: '姓名', key: 'name' },
  { title: '年龄', key: 'age' },
  { title: '出生日期', key: 'birthday' },
  { title: '爱好', slot: 'hobby' },
  { title: '地址', key: 'address' }
]

const validateRules = reactive({
  name: [{ required: true, message: '必填项', trigger: 'blur' }],
  age: [{ required: true, message: '必填项', trigger: 'change' }],
  birthday: [{ required: true, message: '必填项', trigger: 'change' }],
  hobby: [{ required: true, message: '必填项', trigger: 'change' }],
  address: [{ required: true, message: '必填项', trigger: 'blur' }]
})

const list = ref([
  {
    name: '王小明',
    age: 18,
    birthday: '1990-04-22',
    hobby: '1',
    address: '北京市朝阳区芍药居'
  },
  {
    name: '张小刚',
    age: 25,
    birthday: '1990-11-11',
    hobby: '1',
    address: '北京市海淀区西二旗'
  },
  {
    name: '李小红',
    age: 30,
    birthday: '1985-02-05',
    hobby: '3',
    address: '上海市浦东新区世纪大道'
  },
  {
    name: '周小伟',
    age: 26,
    birthday: '1993-07-11',
    hobby: '1',
    address: '深圳市南山区深南大道'
  },
  {
    name: '张小发',
    age: 33,
    birthday: '1999-12-12',
    hobby: '2',
    address: '南京市龙眠大道'
  }
])

function handleAdd() {
  const row = {
    name: '',
    age: null,
    birthday: '',
    hobby: '',
    address: ''
  }
  list.value.push(row)
}

function handleRemove(index) {
  list.value.splice(index, 1)
}

function handleDragDrop(newList, newIndex) {
  list.value = [...newList]
  nextTick(() => tableRef.value && tableRef.value.clickCurrentRow(newIndex))
}
</script>
<template>
  <b-form ref="formRef" :model="list" label-width="85px" label-position="top">
    <b-collapse-wrap title="编辑表格" shadow="none">
      <div style="padding: 10px 24px">
        <b-table
          edit-table
          :columns="columns"
          :data="list"
          no-data-text="暂无参数"
          draggable
          drag-handle=".handle"
          max-height="420"
          @drag-drop="handleDragDrop"
        >
          <template #handle>
            <b-icon name="drag" class="handle" />
          </template>
          <template #name="{ index }">
            <b-form-item :rules="validateRules.name" :prop="index + '.name'">
              <b-input v-model="list[index].name" type="text" clearable></b-input>
            </b-form-item>
          </template>
          <template #age="{ index }">
            <b-form-item :rules="validateRules.age" :prop="index + '.age'">
              <b-input-number
                v-model="list[index].age"
                type="text"
                arrow-up-icon="plus"
                arrow-down-icon="minus"
              ></b-input-number>
            </b-form-item>
          </template>
          <template #birthday="{ index }">
            <b-form-item :rules="validateRules.birthday" :prop="index + '.birthday'">
              <b-date-picker
                v-model="list[index].birthday"
                type="date"
                placeholder="选择日期"
              ></b-date-picker>
            </b-form-item>
          </template>
          <template #hobby="{ index }">
            <b-form-item :rules="validateRules.hobby" :prop="index + '.hobby'">
              <b-select v-model="list[index].hobby" clearable>
                <b-option v-for="(val, key) in hobbyMap" :key="key" :value="key" :label="val">
                  {{ val }}
                </b-option>
              </b-select>
            </b-form-item>
          </template>
          <template #address="{ index }">
            <b-form-item :rules="validateRules.address" :prop="index + '.address'">
              <b-input v-model="list[index].address" type="text"></b-input>
            </b-form-item>
          </template>
          <template #action="{ index }">
            <b-button type="text" text-color="danger" @click="handleRemove(index)">
              <b-icon name="minus-circle" />
            </b-button>
          </template>
        </b-table>
        <div class="mt-8">
          <b-button icon="plus" dashed style="width: 100%" @click="handleAdd">新增</b-button>
        </div>
      </div>
    </b-collapse-wrap>

    <b-collapse-wrap title="只读" shadow="none">
      <div style="padding: 10px 24px">
        <b-table :columns="columns2" :data="list" edit-table edit-table-detail>
          <template #hobby="{ row }">
            {{ hobbyMap[row.hobby] }}
          </template>
        </b-table>
      </div>
    </b-collapse-wrap>
  </b-form>
</template>

<script setup lang="ts">
import { reactive, ref, nextTick } from 'vue'

const formRef = ref(null)
const tableRef = ref(null)

const hobbyMap = { 1: '吃饭', 2: '睡觉', 3: '打豆豆' }
const columns = [
  { title: ' ', slot: 'handle', width: 24, align: 'center' },
  { title: '姓名', slot: 'name' },
  { title: '年龄', slot: 'age' },
  { title: '出生日期', slot: 'birthday' },
  { title: '爱好', slot: 'hobby' },
  { title: '地址', slot: 'address' },
  { title: ' ', slot: 'action', width: 50, align: 'center' }
]
const columns2 = [
  { title: '姓名', key: 'name' },
  { title: '年龄', key: 'age' },
  { title: '出生日期', key: 'birthday' },
  { title: '爱好', slot: 'hobby' },
  { title: '地址', key: 'address' }
]

const validateRules = reactive({
  name: [{ required: true, message: '必填项', trigger: 'blur' }],
  age: [{ required: true, message: '必填项', trigger: 'change' }],
  birthday: [{ required: true, message: '必填项', trigger: 'change' }],
  hobby: [{ required: true, message: '必填项', trigger: 'change' }],
  address: [{ required: true, message: '必填项', trigger: 'blur' }]
})

const list = ref([
  {
    name: '王小明',
    age: 18,
    birthday: '1990-04-22',
    hobby: '1',
    address: '北京市朝阳区芍药居'
  },
  {
    name: '张小刚',
    age: 25,
    birthday: '1990-11-11',
    hobby: '1',
    address: '北京市海淀区西二旗'
  },
  {
    name: '李小红',
    age: 30,
    birthday: '1985-02-05',
    hobby: '3',
    address: '上海市浦东新区世纪大道'
  },
  {
    name: '周小伟',
    age: 26,
    birthday: '1993-07-11',
    hobby: '1',
    address: '深圳市南山区深南大道'
  },
  {
    name: '张小发',
    age: 33,
    birthday: '1999-12-12',
    hobby: '2',
    address: '南京市龙眠大道'
  }
])

function handleAdd() {
  const row = {
    name: '',
    age: null,
    birthday: '',
    hobby: '',
    address: ''
  }
  list.value.push(row)
}

function handleRemove(index) {
  list.value.splice(index, 1)
}

function handleDragDrop(newList, newIndex) {
  list.value = [...newList]
  nextTick(() => tableRef.value && tableRef.value.clickCurrentRow(newIndex))
}
</script>

拖拽调整顺序

可以设置draggable开启拖拽排序

注意,设置拖拽排序后,且鼠标拖拽也覆盖了鼠标选中文字,此时可以额外设置也可以设置handle来指定拖拽某一个元素实现

如需要更新数据,则需使用v-model:data来更新,或配合@drag-drop函数来处理更新数据都可以

默认拖拽

ID
姓名
年龄
出生日期
地址
1
王小明
18
1990-04-22
北京市朝阳区芍药居
2
张小刚
25
1990-11-11
北京市海淀区西二旗
3
李小红
30
1985-02-05
上海市浦东新区世纪大道
4
周小伟
26
1993-07-11
深圳市南山区深南大道
5
张小发
33
1999-12-12
南京市龙眠大道

实际数据:[ "1-王小明", "2-张小刚", "3-李小红", "4-周小伟", "5-张小发" ]

如需和单选结合使用,推荐使用drag-drop函数来自定义控制,这样可以更好的实现自定义选中效果

drag-handle

#
ID
姓名
年龄
出生日期
地址
操作
1
王小明
18
1990-04-22
北京市朝阳区芍药居
2
张小刚
25
1990-11-11
北京市海淀区西二旗
3
李小红
30
1985-02-05
上海市浦东新区世纪大道
4
周小伟
26
1993-07-11
深圳市南山区深南大道
5
张小发
33
1999-12-12
南京市龙眠大道

实际数据:[ "1-王小明", "2-张小刚", "3-李小红", "4-周小伟", "5-张小发" ]

选中行:{}

<template>
  <div>
    <div>
      <p>默认拖拽</p>
      <b-table v-model:data="data1" :columns="columns1" draggable></b-table>
      <p>实际数据:{{ data1.map(v => v.id + '-' + v.name) }}</p>
    </div>
    <b-divider></b-divider>
    <div>
      <p>如需和单选结合使用,推荐使用drag-drop函数来自定义控制,这样可以更好的实现自定义选中效果</p>
      <p>drag-handle</p>
      <b-table
        ref="currentRowTable"
        :columns="columns2"
        :data="data2"
        draggable
        drag-handle=".drag-handle"
        highlight-row
        @drag-drop="handleDragDrop"
        @current-change="currentRowChange"
      >
        <template #handle="{ row }">
          <span class="drag-handle" style="cursor: grab"><b-icon name="drag" size="20" /></span>
        </template>
        <template #ctrl="{ row, index }">
          <b-button type="text" @click.stop="handleEdit(row, index)">编辑</b-button>
          <b-button type="text" text-color="danger" @click.stop="removeRow(index)">删除</b-button>
        </template>
      </b-table>
      <p>实际数据:{{ data2.map(v => v.id + '-' + v.name) }}</p>
      <p>选中行:{{ currentRow }}</p>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, nextTick } from 'vue'
const columns1 = [
  { title: 'ID', key: 'id', width: 70 },
  { title: '姓名', key: 'name' },
  { title: '年龄', key: 'age' },
  { title: '出生日期', key: 'birthday' },
  { title: '地址', key: 'address' }
]
const columns2 = [
  { slot: 'handle', width: 70 },
  { title: 'ID', key: 'id', width: 70 },
  { title: '姓名', key: 'name' },
  { title: '年龄', key: 'age' },
  { title: '出生日期', key: 'birthday' },
  { title: '地址', key: 'address' },
  { title: '操作', slot: 'ctrl', width: 120 }
]
const data1 = ref([
  {
    id: 1,
    name: '王小明',
    age: 18,
    birthday: '1990-04-22',
    address: '北京市朝阳区芍药居'
  },
  {
    id: 2,
    name: '张小刚',
    age: 25,
    birthday: '1990-11-11',
    address: '北京市海淀区西二旗'
  },
  {
    id: 3,
    name: '李小红',
    age: 30,
    birthday: '1985-02-05',
    address: '上海市浦东新区世纪大道'
  },
  {
    id: 4,
    name: '周小伟',
    age: 26,
    birthday: '1993-07-11',
    address: '深圳市南山区深南大道'
  },
  {
    id: 5,
    name: '张小发',
    age: 33,
    birthday: '1999-12-12',
    address: '南京市龙眠大道'
  }
])
const data2 = ref([
  {
    id: 1,
    name: '王小明',
    age: 18,
    birthday: '1990-04-22',
    address: '北京市朝阳区芍药居'
  },
  {
    id: 2,
    name: '张小刚',
    age: 25,
    birthday: '1990-11-11',
    address: '北京市海淀区西二旗'
  },
  {
    id: 3,
    name: '李小红',
    age: 30,
    birthday: '1985-02-05',
    address: '上海市浦东新区世纪大道'
  },
  {
    id: 4,
    name: '周小伟',
    age: 26,
    birthday: '1993-07-11',
    address: '深圳市南山区深南大道'
  },
  {
    id: 5,
    name: '张小发',
    age: 33,
    birthday: '1999-12-12',
    address: '南京市龙眠大道'
  }
])
const currentRow = ref({})
const currentRowTable = ref(null)

function currentRowChange(row, oldRow, index) {
  currentRow.value = row
}
function handleDragDrop(newList, newIndex, oldIndex) {
  data2.value = [...newList]
  nextTick(() => {
    currentRowTable.value.clickCurrentRow(newIndex)
  })
}
function handleEdit(row, index) {
  console.log(row, index)
}
function removeRow(index) {
  data2.value.splice(index, 1)
  nextTick(() => {
    currentRowTable.value.clearCurrentRow()
  })
}
</script>
<template>
  <div>
    <div>
      <p>默认拖拽</p>
      <b-table v-model:data="data1" :columns="columns1" draggable></b-table>
      <p>实际数据:{{ data1.map(v => v.id + '-' + v.name) }}</p>
    </div>
    <b-divider></b-divider>
    <div>
      <p>如需和单选结合使用,推荐使用drag-drop函数来自定义控制,这样可以更好的实现自定义选中效果</p>
      <p>drag-handle</p>
      <b-table
        ref="currentRowTable"
        :columns="columns2"
        :data="data2"
        draggable
        drag-handle=".drag-handle"
        highlight-row
        @drag-drop="handleDragDrop"
        @current-change="currentRowChange"
      >
        <template #handle="{ row }">
          <span class="drag-handle" style="cursor: grab"><b-icon name="drag" size="20" /></span>
        </template>
        <template #ctrl="{ row, index }">
          <b-button type="text" @click.stop="handleEdit(row, index)">编辑</b-button>
          <b-button type="text" text-color="danger" @click.stop="removeRow(index)">删除</b-button>
        </template>
      </b-table>
      <p>实际数据:{{ data2.map(v => v.id + '-' + v.name) }}</p>
      <p>选中行:{{ currentRow }}</p>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, nextTick } from 'vue'
const columns1 = [
  { title: 'ID', key: 'id', width: 70 },
  { title: '姓名', key: 'name' },
  { title: '年龄', key: 'age' },
  { title: '出生日期', key: 'birthday' },
  { title: '地址', key: 'address' }
]
const columns2 = [
  { slot: 'handle', width: 70 },
  { title: 'ID', key: 'id', width: 70 },
  { title: '姓名', key: 'name' },
  { title: '年龄', key: 'age' },
  { title: '出生日期', key: 'birthday' },
  { title: '地址', key: 'address' },
  { title: '操作', slot: 'ctrl', width: 120 }
]
const data1 = ref([
  {
    id: 1,
    name: '王小明',
    age: 18,
    birthday: '1990-04-22',
    address: '北京市朝阳区芍药居'
  },
  {
    id: 2,
    name: '张小刚',
    age: 25,
    birthday: '1990-11-11',
    address: '北京市海淀区西二旗'
  },
  {
    id: 3,
    name: '李小红',
    age: 30,
    birthday: '1985-02-05',
    address: '上海市浦东新区世纪大道'
  },
  {
    id: 4,
    name: '周小伟',
    age: 26,
    birthday: '1993-07-11',
    address: '深圳市南山区深南大道'
  },
  {
    id: 5,
    name: '张小发',
    age: 33,
    birthday: '1999-12-12',
    address: '南京市龙眠大道'
  }
])
const data2 = ref([
  {
    id: 1,
    name: '王小明',
    age: 18,
    birthday: '1990-04-22',
    address: '北京市朝阳区芍药居'
  },
  {
    id: 2,
    name: '张小刚',
    age: 25,
    birthday: '1990-11-11',
    address: '北京市海淀区西二旗'
  },
  {
    id: 3,
    name: '李小红',
    age: 30,
    birthday: '1985-02-05',
    address: '上海市浦东新区世纪大道'
  },
  {
    id: 4,
    name: '周小伟',
    age: 26,
    birthday: '1993-07-11',
    address: '深圳市南山区深南大道'
  },
  {
    id: 5,
    name: '张小发',
    age: 33,
    birthday: '1999-12-12',
    address: '南京市龙眠大道'
  }
])
const currentRow = ref({})
const currentRowTable = ref(null)

function currentRowChange(row, oldRow, index) {
  currentRow.value = row
}
function handleDragDrop(newList, newIndex, oldIndex) {
  data2.value = [...newList]
  nextTick(() => {
    currentRowTable.value.clickCurrentRow(newIndex)
  })
}
function handleEdit(row, index) {
  console.log(row, index)
}
function removeRow(index) {
  data2.value.splice(index, 1)
  nextTick(() => {
    currentRowTable.value.clearCurrentRow()
  })
}
</script>

loading状态

姓名
年龄
出生日期
地址
王小明
18
1990-04-22
北京市朝阳区芍药居
张小刚
25
1990-11-11
北京市海淀区西二旗
李小红
30
1985-02-05
上海市浦东新区世纪大道
周小伟
26
1993-07-11
深圳市南山区深南大道
张小发
33
1999-12-12
南京市龙眠大道

<template>
  <div>
    <b-table :columns="columns" :data="data" :loading="loading"></b-table>
    <br />
    <b-switch v-model="loading"></b-switch>
  </div>
</template>

<script setup lang="ts">
import { ref } from 'vue'
const columns = [
  { title: '姓名', key: 'name' },
  { title: '年龄', key: 'age' },
  { title: '出生日期', key: 'birthday' },
  { title: '地址', key: 'address' }
]
const data = ref([
  {
    name: '王小明',
    age: 18,
    birthday: '1990-04-22',
    address: '北京市朝阳区芍药居'
  },
  {
    name: '张小刚',
    age: 25,
    birthday: '1990-11-11',
    address: '北京市海淀区西二旗'
  },
  {
    name: '李小红',
    age: 30,
    birthday: '1985-02-05',
    address: '上海市浦东新区世纪大道'
  },
  {
    name: '周小伟',
    age: 26,
    birthday: '1993-07-11',
    address: '深圳市南山区深南大道'
  },
  {
    name: '张小发',
    age: 33,
    birthday: '1999-12-12',
    address: '南京市龙眠大道'
  }
])
const loading = ref(false)
</script>
<template>
  <div>
    <b-table :columns="columns" :data="data" :loading="loading"></b-table>
    <br />
    <b-switch v-model="loading"></b-switch>
  </div>
</template>

<script setup lang="ts">
import { ref } from 'vue'
const columns = [
  { title: '姓名', key: 'name' },
  { title: '年龄', key: 'age' },
  { title: '出生日期', key: 'birthday' },
  { title: '地址', key: 'address' }
]
const data = ref([
  {
    name: '王小明',
    age: 18,
    birthday: '1990-04-22',
    address: '北京市朝阳区芍药居'
  },
  {
    name: '张小刚',
    age: 25,
    birthday: '1990-11-11',
    address: '北京市海淀区西二旗'
  },
  {
    name: '李小红',
    age: 30,
    birthday: '1985-02-05',
    address: '上海市浦东新区世纪大道'
  },
  {
    name: '周小伟',
    age: 26,
    birthday: '1993-07-11',
    address: '深圳市南山区深南大道'
  },
  {
    name: '张小发',
    age: 33,
    birthday: '1999-12-12',
    address: '南京市龙眠大道'
  }
])
const loading = ref(false)
</script>

大小状态

通过设置属性 sizelargesmall 可以调整表格尺寸为大或小,默认不填或填写 default 。

姓名
年龄
出生日期
地址
王小明
18
1990-04-22
北京市朝阳区芍药居
张小刚
25
1990-11-11
北京市海淀区西二旗
李小红
30
1985-02-05
上海市浦东新区世纪大道
周小伟
26
1993-07-11
深圳市南山区深南大道
张小发
33
1999-12-12
南京市龙眠大道
<template>
  <div>
    <div class="mb-16">
      <b-radio-group v-model="tableSize" type="button">
        <b-radio label="large">松散</b-radio>
        <b-radio label="default">默认</b-radio>
        <b-radio label="small">紧凑</b-radio>
      </b-radio-group>
    </div>
    <b-table :columns="columns" :data="data" :size="tableSize"></b-table>
  </div>
</template>

<script setup lang="ts">
import { ref } from 'vue'
const columns = [
  { title: '姓名', key: 'name' },
  { title: '年龄', key: 'age' },
  { title: '出生日期', key: 'birthday' },
  { title: '地址', key: 'address' }
]
const data = ref([
  {
    name: '王小明',
    age: 18,
    birthday: '1990-04-22',
    address: '北京市朝阳区芍药居'
  },
  {
    name: '张小刚',
    age: 25,
    birthday: '1990-11-11',
    address: '北京市海淀区西二旗'
  },
  {
    name: '李小红',
    age: 30,
    birthday: '1985-02-05',
    address: '上海市浦东新区世纪大道'
  },
  {
    name: '周小伟',
    age: 26,
    birthday: '1993-07-11',
    address: '深圳市南山区深南大道'
  },
  {
    name: '张小发',
    age: 33,
    birthday: '1999-12-12',
    address: '南京市龙眠大道'
  }
])
const tableSize = ref('default')
</script>
<template>
  <div>
    <div class="mb-16">
      <b-radio-group v-model="tableSize" type="button">
        <b-radio label="large">松散</b-radio>
        <b-radio label="default">默认</b-radio>
        <b-radio label="small">紧凑</b-radio>
      </b-radio-group>
    </div>
    <b-table :columns="columns" :data="data" :size="tableSize"></b-table>
  </div>
</template>

<script setup lang="ts">
import { ref } from 'vue'
const columns = [
  { title: '姓名', key: 'name' },
  { title: '年龄', key: 'age' },
  { title: '出生日期', key: 'birthday' },
  { title: '地址', key: 'address' }
]
const data = ref([
  {
    name: '王小明',
    age: 18,
    birthday: '1990-04-22',
    address: '北京市朝阳区芍药居'
  },
  {
    name: '张小刚',
    age: 25,
    birthday: '1990-11-11',
    address: '北京市海淀区西二旗'
  },
  {
    name: '李小红',
    age: 30,
    birthday: '1985-02-05',
    address: '上海市浦东新区世纪大道'
  },
  {
    name: '周小伟',
    age: 26,
    birthday: '1993-07-11',
    address: '深圳市南山区深南大道'
  },
  {
    name: '张小发',
    age: 33,
    birthday: '1999-12-12',
    address: '南京市龙眠大道'
  }
])
const tableSize = ref('default')
</script>

无数据

noDataText可以设置无数据状态

姓名
年龄
出生日期
地址

No Data

<template>
  <b-table :columns="columns" :data="data" no-data-text="No Data"></b-table>
</template>

<script setup lang="ts">
import { ref } from 'vue'
const columns = [
  { title: '姓名', key: 'name' },
  { title: '年龄', key: 'age' },
  { title: '出生日期', key: 'birthday' },
  { title: '地址', key: 'address' }
]
const data = ref([])
</script>
<template>
  <b-table :columns="columns" :data="data" no-data-text="No Data"></b-table>
</template>

<script setup lang="ts">
import { ref } from 'vue'
const columns = [
  { title: '姓名', key: 'name' },
  { title: '年龄', key: 'age' },
  { title: '出生日期', key: 'birthday' },
  { title: '地址', key: 'address' }
]
const data = ref([])
</script>

Table props

参数说明类型可选值默认值
data显示的结构化数据,字段 cellClassName 用于设置任意单元格的样式名称,因此数据不能使用该字段,详见示例特定样式。Array[]
columns表格列的配置描述,具体项见后文Array[]
stripe间隔斑马纹Booleanfalse/truefalse
border纵向边框Booleanfalse/truefalse
show-header是否显示表头Booleanfalse/truefalse
width表格宽度,单位 pxNumber/Stringauto
height表格高度,单位 px,设置后,如果表格内容大于此值,会固定表头Number/String
max-height最大表格高度Number/String
loading表格加载状态Booleanfalse
disabled-hover禁用悬停高亮Booleanfalse
highlight-row是否支持高亮选中的行,即单选Booleanfalse
size表格尺寸stringlarge / smalldefault
no-data-text空数据内容string暂无数据
loading-text加载数据文字string正在加载
draggable开启拖拽调整行顺序,同步元数据需要使用v-model:data使用或需配合 @drag-drop 事件更新data都可以Booleanfalse
drag-handle拖拽的handle图标String
row-key是否强制使用内置row-key刷新Booleanfalse
merge-method表格合并行列的方法函数Functionfalse

Table events

事件名说明返回值
current-change开启 highlight-row 后有效,当表格的当前行发生变化的时候会触currentRow, oldCurrentRow,index
select在多选模式下有效,选中某一项时触发已选项, 刚选择
select-cancel在多选模式下有效,取消选中某一项时触发已选项, 取消选择
select-all全选时触发已选项
select-all-cancel取消全选时触发已选项
selection-change选中项发生变化时就会触发已选项
sort-change排序时有效,当点击排序时触发column:当前列数据 key:排序依据的指标 order(值为 asc 或 desc)
row-click单击某一行时触发当前行的数据,index
row-dblclick双击某一行时触发当前行的数据,index
expand展开或收起某一行时触row:当前行的数据,status:当前的状态
drag-drop拖拽排序松开时触发置换的两行数据索引和更新后的数据 newData, newIndex, oldIndex

Table slot

名称说明
header表头
footer页脚
loading警告提加载中示内容

Table methods

方法名说明参数
clickCurrentRow选中某一项index
clearCurrentRow清除高亮项,仅在开启
handleResize刷新表格的宽高
getSelection获取已经选中的行

column

参数说明类型可选值默认值
type列类型Stringindex、selection、expand、html String-
title列头显示文字String-#
key对应列内容的字段名String--
width列宽Number--
minWidth最小列宽Number--
maxWidth最大列宽Number--
align对齐方式Stringright,centerleft
className列的样式名称String--
fixed列是否固定在左侧或者右侧Stringleft,right-
ellipsis开启后,文本将不换行Boolean-false
tooltip开启后,文本将不换行,并用 Tooltip 组件显示完整内容Boolean-false
render自定义渲染列 ,第一个是 h,第二个为对象,包含 row、column 和 indexFunction--
indexMethodtype 为 index 时可用,自定义序号 ,参数 row 为当前行内容Function--
sortable对应列是否可以排序Boolean ,'custom'-false
sortMethod自定义排序使用的方法,三个参数 a 、 b 和 typeFunction--
sortType设置初始化排序。值为 asc 和 descString--