Skip to content

表格组件多级表头固定列

一、el-table(不推荐)

  • el-table的多级表头:启用固定列时,需要在一级表头启用(添加fixed属性),其他子级表头无需添加,添加了不起任何作用
  • el-table固定列的判定:根据一级表头设定的列宽控制(固定列的范围是宽度范围,跟第几列没关系),比如下方代码,“测试列1”设定宽度350,子级设定每列宽度为100,则可以看到固定的列有3列,然后第4列有半列被固定(固定了3.5列)。
  • 由于以上特性,el-table想要固定列,需要手动计算一级表头的宽度,但宽度很多都是min-width,实际的宽度需要单独去获取,所以不推荐使用el-table。
vue
<template>
  <el-table :data="tableData" style="width: 100%">
    <el-table-column prop="date" label="日期" width="150"></el-table-column>
    <el-table-column label="测试列1" fixed="left" width="350">
      <el-table-column prop="name" label="姓名" width="100"></el-table-column>
      <el-table-column prop="province" label="省份" width="100"></el-table-column>
      <el-table-column prop="city" label="市区" width="100"></el-table-column>
      <el-table-column prop="address" label="地址" width="100"></el-table-column>
      <el-table-column prop="zip" label="邮编" width="100"></el-table-column>
      <el-table-column prop="name" label="姓名" width="100"></el-table-column>
      <el-table-column prop="province" label="省份" width="100"></el-table-column>
      <el-table-column prop="city" label="市区" width="100"></el-table-column>
      <el-table-column prop="address" label="地址" width="100"></el-table-column>
      <el-table-column prop="zip" label="邮编" width="100"></el-table-column>
      <el-table-column prop="name" label="姓名" width="100"></el-table-column>
      <el-table-column prop="province" label="省份" width="100"></el-table-column>
      <el-table-column prop="city" label="市区" width="100"></el-table-column>
      <el-table-column prop="address" label="地址" width="100"></el-table-column>
      <el-table-column prop="zip" label="邮编" width="100"></el-table-column>
    </el-table-column>
    <el-table-column label="测试列2">
      <el-table-column prop="name" label="姓名" width="100"></el-table-column>
      <el-table-column prop="province" label="省份" width="100"></el-table-column>
      <el-table-column prop="city" label="市区" width="100"></el-table-column>
      <el-table-column prop="address" label="地址" width="100"></el-table-column>
      <el-table-column prop="zip" label="邮编" width="100"></el-table-column>
      <el-table-column prop="name" label="姓名" width="100"></el-table-column>
      <el-table-column prop="province" label="省份" width="100"></el-table-column>
      <el-table-column prop="city" label="市区" width="100"></el-table-column>
      <el-table-column prop="address" label="地址" width="100"></el-table-column>
      <el-table-column prop="zip" label="邮编" width="100"></el-table-column>
      <el-table-column prop="name" label="姓名" width="100"></el-table-column>
      <el-table-column prop="province" label="省份" width="100"></el-table-column>
      <el-table-column prop="city" label="市区" width="100"></el-table-column>
      <el-table-column prop="address" label="地址" width="100"></el-table-column>
      <el-table-column prop="zip" label="邮编" width="100"></el-table-column>
    </el-table-column>
  </el-table>
</template>

<script>
export default {
  data() {
    return {
      tableData: [
        {
          date: '2016-05-03',
          name: '王小虎',
          province: '上海',
          city: '普陀区',
          address: '上海市普陀区金沙江路 1518 弄',
          zip: 200333,
        },
        {
          date: '2016-05-02',
          name: '王小虎',
          province: '上海',
          city: '普陀区',
          address: '上海市普陀区金沙江路 1518 弄',
          zip: 200333,
        },
        {
          date: '2016-05-04',
          name: '王小虎',
          province: '上海',
          city: '普陀区',
          address: '上海市普陀区金沙江路 1518 弄',
          zip: 200333,
        },
        {
          date: '2016-05-01',
          name: '王小虎',
          province: '上海',
          city: '普陀区',
          address: '上海市普陀区金沙江路 1518 弄',
          zip: 200333,
        },
        {
          date: '2016-05-08',
          name: '王小虎',
          province: '上海',
          city: '普陀区',
          address: '上海市普陀区金沙江路 1518 弄',
          zip: 200333,
        },
        {
          date: '2016-05-06',
          name: '王小虎',
          province: '上海',
          city: '普陀区',
          address: '上海市普陀区金沙江路 1518 弄',
          zip: 200333,
        },
        {
          date: '2016-05-07',
          name: '王小虎',
          province: '上海',
          city: '普陀区',
          address: '上海市普陀区金沙江路 1518 弄',
          zip: 200333,
        },
      ],
    };
  },
};
</script>

二、vxe-table(推荐使用)

  • vxe-table的多级表头:启用固定列时,需要在一级表头启用(添加fixed属性),其他子级表头启用不起作用,启用后整个一级表头连带着下方的子列都会固定。
  • vxe-table的固定列不用考虑宽度,只要设定了固定列则直接生效,比如下方代码,“基本信息”列设置了固定列,如图所示,可以看到整个列都固定到左侧了
vue
<template>
  <vxe-table border ref="xTable" height="400" :data="tableData">
    <vxe-table-colgroup field="group0" title="基本信息" fixed="left">
      <vxe-table-column type="seq" width="60"></vxe-table-column>
      <vxe-table-column field="name" title="Name" width="180"></vxe-table-column>
      <vxe-table-column type="seq" width="60"></vxe-table-column>
      <vxe-table-column field="name" title="Name" width="180"></vxe-table-column>
      <vxe-table-column type="seq" width="60"></vxe-table-column>
      <vxe-table-column field="name" title="Name" width="180"></vxe-table-column>
      <vxe-table-column type="seq" width="60"></vxe-table-column>
      <vxe-table-column field="name" title="Name" width="180"></vxe-table-column>
      <vxe-table-column type="seq" width="60"></vxe-table-column>
      <vxe-table-column field="name" title="Name" width="180"></vxe-table-column>
    </vxe-table-colgroup>
    <vxe-table-colgroup field="group1" title="分类信息1">
      <vxe-table-column field="age" title="Age1" width="120"></vxe-table-column>
      <vxe-table-column type="seq" width="60"></vxe-table-column>
      <vxe-table-column field="name" title="Name" width="180"></vxe-table-column>
      <vxe-table-column type="seq" width="60"></vxe-table-column>
      <vxe-table-column field="name" title="Name" width="180"></vxe-table-column>
      <vxe-table-column type="seq" width="60"></vxe-table-column>
      <vxe-table-column field="name" title="Name" width="180"></vxe-table-column>
    </vxe-table-colgroup>
    <vxe-table-colgroup field="group2" title="更多信息">
      <vxe-table-column field="role" title="Role" width="300"></vxe-table-column>
      <vxe-table-column field="attr1" title="Attr1" width="200"></vxe-table-column>
      <vxe-table-column type="seq" width="60"></vxe-table-column>
      <vxe-table-column field="name" title="Name" width="180"></vxe-table-column>
      <vxe-table-column type="seq" width="60"></vxe-table-column>
      <vxe-table-column field="name" title="Name" width="180"></vxe-table-column>
      <vxe-table-column type="seq" width="60"></vxe-table-column>
      <vxe-table-column field="name" title="Name" width="180"></vxe-table-column>
      <vxe-table-colgroup title="详细信息">
        <vxe-table-column field="sex" title="Sex" width="200"></vxe-table-column>
        <vxe-table-column field="num" title="Num" width="200"></vxe-table-column>
      <vxe-table-column type="seq" width="60"></vxe-table-column>
      <vxe-table-column field="name" title="Name" width="180"></vxe-table-column>
      <vxe-table-column type="seq" width="60"></vxe-table-column>
      <vxe-table-column field="name" title="Name" width="180"></vxe-table-column>
      <vxe-table-column type="seq" width="60"></vxe-table-column>
      <vxe-table-column field="name" title="Name" width="180"></vxe-table-column>
      </vxe-table-colgroup>
    </vxe-table-colgroup>
    <vxe-table-colgroup field="group3" title="分类信息2">
      <vxe-table-column field="attr6" title="Attr6" width="120"></vxe-table-column>
      <vxe-table-column type="seq" width="60"></vxe-table-column>
      <vxe-table-column field="name" title="Name" width="180"></vxe-table-column>
      <vxe-table-column type="seq" width="60"></vxe-table-column>
      <vxe-table-column field="name" title="Name" width="180"></vxe-table-column>
      <vxe-table-column type="seq" width="60"></vxe-table-column>
      <vxe-table-column field="name" title="Name" width="180"></vxe-table-column>
    </vxe-table-colgroup>
    <vxe-table-colgroup field="group4" title="额外信息">
      <vxe-table-column field="date3" title="Date" width="140"></vxe-table-column>
      <vxe-table-column field="address" title="Address" width="200" show-overflow></vxe-table-column>
      <vxe-table-column type="seq" width="60"></vxe-table-column>
      <vxe-table-column field="name" title="Name" width="180"></vxe-table-column>
      <vxe-table-column type="seq" width="60"></vxe-table-column>
      <vxe-table-column field="name" title="Name" width="180"></vxe-table-column>
      <vxe-table-column type="seq" width="60"></vxe-table-column>
      <vxe-table-column field="name" title="Name" width="180"></vxe-table-column>
    </vxe-table-colgroup>
  </vxe-table>
</template>

<script>
export default {
  data() {
    return {
      tableData: [
        {
          id: 10001,
          name: 'Test1',
          role: 'Develop',
          sex: 'Man',
          age: 28,
          address: 'test abc',
        },
        {
          id: 10002,
          name: 'Test2',
          role: 'Test',
          sex: 'Women',
          age: 22,
          address: 'Guangzhou',
        },
        {
          id: 10003,
          name: 'Test3',
          role: 'PM',
          sex: 'Man',
          age: 32,
          address: 'Shanghai',
        },
        {
          id: 10004,
          name: 'Test4',
          role: 'Designer',
          sex: 'Women ',
          age: 23,
          address: 'test abc',
        },
        {
          id: 10005,
          name: 'Test5',
          role: 'Develop',
          sex: 'Women ',
          age: 30,
          address: 'Shanghai',
        },
        {
          id: 10006,
          name: 'Test6',
          role: 'Designer',
          sex: 'Women ',
          age: 21,
          address: 'test abc',
        },
        {
          id: 10007,
          name: 'Test7',
          role: 'Test',
          sex: 'Man ',
          age: 29,
          address: 'test abc',
        },
        {
          id: 10008,
          name: 'Test8',
          role: 'Develop',
          sex: 'Man ',
          age: 35,
          address: 'test abc',
        },
      ],
    };
  },
};
</script>

  • 动态列推荐下面写法,使用计算属性判断是否有固定列,当子列有一个配置了固定列,则直接把整个一级列都固定,子列不用再单独添加fixed属性
vue
<template>
  <vxe-table border ref="xTable" height="400" :data="tableData">
    <vxe-table-colgroup field="group0" title="基本信息" :fixed="isFirstColumnFixed ? 'left' : ''">
      <vxe-table-column type="seq" width="60"></vxe-table-column>
      <vxe-table-column :key="`${e.code}${i}`" :field="e.code" :title="e.name" width="180" v-for="(e, i) in firstTableColumns"></vxe-table-column>
    </vxe-table-colgroup>
    <vxe-table-colgroup field="group1" title="分类信息1">
      <vxe-table-column field="age" title="Age1" width="120"></vxe-table-column>
      <vxe-table-column type="seq" width="60"></vxe-table-column>
      <vxe-table-column field="name" title="Name" width="180"></vxe-table-column>
      <vxe-table-column type="seq" width="60"></vxe-table-column>
      <vxe-table-column field="name" title="Name" width="180"></vxe-table-column>
      <vxe-table-column type="seq" width="60"></vxe-table-column>
      <vxe-table-column field="name" title="Name" width="180"></vxe-table-column>
    </vxe-table-colgroup>
    <vxe-table-colgroup field="group2" title="更多信息">
      <vxe-table-column field="role" title="Role" width="300"></vxe-table-column>
      <vxe-table-column field="attr1" title="Attr1" width="200"></vxe-table-column>
      <vxe-table-column type="seq" width="60"></vxe-table-column>
      <vxe-table-column field="name" title="Name" width="180"></vxe-table-column>
      <vxe-table-column type="seq" width="60"></vxe-table-column>
      <vxe-table-column field="name" title="Name" width="180"></vxe-table-column>
      <vxe-table-column type="seq" width="60"></vxe-table-column>
      <vxe-table-column field="name" title="Name" width="180"></vxe-table-column>
      <vxe-table-colgroup title="详细信息">
        <vxe-table-column field="sex" title="Sex" width="200"></vxe-table-column>
        <vxe-table-column field="num" title="Num" width="200"></vxe-table-column>
        <vxe-table-column type="seq" width="60"></vxe-table-column>
        <vxe-table-column field="name" title="Name" width="180"></vxe-table-column>
        <vxe-table-column type="seq" width="60"></vxe-table-column>
        <vxe-table-column field="name" title="Name" width="180"></vxe-table-column>
        <vxe-table-column type="seq" width="60"></vxe-table-column>
        <vxe-table-column field="name" title="Name" width="180"></vxe-table-column>
      </vxe-table-colgroup>
    </vxe-table-colgroup>
  </vxe-table>
</template>

<script>
export default {
  data() {
    return {
      // 列配置
      firstTableColumns: [
        {
          code: 'name',
          name: 'Name',
          isFixed: '1',
        },
        {
          code: 'name',
          name: 'Name',
          isFixed: '1',
        },
        {
          code: 'name',
          name: 'Name',
          isFixed: '1',
        },
        {
          code: 'name',
          name: 'Name',
          isFixed: '1',
        },
        {
          code: 'name',
          name: 'Name',
          isFixed: '1',
        }
      ],
      // 表格数据
      tableData: [
        {
          id: 10001,
          name: 'Test1',
          role: 'Develop',
          sex: 'Man',
          age: 28,
          address: 'test abc',
        },
        {
          id: 10002,
          name: 'Test2',
          role: 'Test',
          sex: 'Women',
          age: 22,
          address: 'Guangzhou',
        },
        {
          id: 10003,
          name: 'Test3',
          role: 'PM',
          sex: 'Man',
          age: 32,
          address: 'Shanghai',
        },
        {
          id: 10004,
          name: 'Test4',
          role: 'Designer',
          sex: 'Women ',
          age: 23,
          address: 'test abc',
        },
        {
          id: 10005,
          name: 'Test5',
          role: 'Develop',
          sex: 'Women ',
          age: 30,
          address: 'Shanghai',
        },
        {
          id: 10006,
          name: 'Test6',
          role: 'Designer',
          sex: 'Women ',
          age: 21,
          address: 'test abc',
        },
        {
          id: 10007,
          name: 'Test7',
          role: 'Test',
          sex: 'Man ',
          age: 29,
          address: 'test abc',
        },
        {
          id: 10008,
          name: 'Test8',
          role: 'Develop',
          sex: 'Man ',
          age: 35,
          address: 'test abc',
        },
      ],
    };
  },
  computed: {
    /**
     * 判断是否有列启用了固定列
     */
    isFirstColumnFixed() {
      return this.firstTableColumns.some((e) => e.isFixed === '1');
    },
  },
};
</script>