# an-table

基于 el-table 二次封装的表格组件, 通过 column 配置,自带分页功能

# Props

Prop name Description Type Values Default
column 列配置, 每个数组元素参照 element-ui Table-column Attributes array -
data 数据源 array - []
openDefaultFormatter 是否开始空值是否默认值,空值包括null, 空字符串, undefined, boolean - false
splitSymbol 默认格式化字符 string - "-"
maxHeight Table 的最大高度。合法的值为数字或者单位为 px 的高度, 参照 el-table string|number -
pagination 是否显示分页 boolean - false
border 是否带有纵向边框 boolean - true
stripe 是否为斑马纹 table boolean - true
paginationTop 距离列表底部的 margin-top 距离 string - "15px"
paginationAlign 分页对齐方式 string right, left, center "right"
pageSize 分页大小 number - 10
currentPage 当前页 number - 1
spanMethod 合并行或列的计算方法, 同el-table func -
merge 需要合并 prop 数组,如果配置了此值,默认计算spanMethod方法 array -

# Events

Event name Description Arguments
p-current-change el-pagination 的 current-change 事件 page: number — 当前页

# Slots

Name Description slotProps
default 提供给列表头部,列配置的插槽 name : string —> 指定插槽名字(没指定的话,默认 default)
row : object —> 列配置数据
$index : - —> -
footer 列表底部操作,一般用于列表下面操作,与分页一排 -

# 示例

# 基础用法

an-table 组件示例

<template>
  <an-table align="center" :column="column" :data="tableData"></an-table>
</template>
<script>
export default {
  data() {
    return {
      column: [
        {
          type: "index",
          width: "50px",
          label: "序号",
        },
        {
          prop: "name",
          label: "名字",
        },
        {
          prop: "date",
          label: "日期",
        },
        {
          prop: "address",
          label: "地址",
        },
      ],
      tableData: [
        {
          date: "2016-05-02",
          name: "佘太君",
          address: "上海市普陀区金沙江路 1518 弄",
        },
        {
          date: "2016-05-04",
          name: "王小虎",
          address: "上海市普陀区金沙江路 1517 弄",
        },
        {
          date: "2016-05-01",
          name: "王小虎",
          address: "上海市普陀区金沙江路 1519 弄",
        },
        {
          date: "2016-05-03",
          name: "王小虎",
          address: "上海市普陀区金沙江路 1516 弄",
        },
      ],
    };
  },
};
</script>
显示 复制

# 插槽模式

支持使用插槽作为某一列 column 配置

<template>
  <an-table align="center" :column="column" :data="tableData">
    <template v-slot="{ row }">
      <div>
        <button-counter />
        <span>插槽</span>
      </div>
    </template>
  </an-table>
</template>
<script>
export default {
  components: {
    "button-counter": {
      data: function() {
        return {
          count: 0,
        };
      },
      template:
        '<button v-on:click="count++">You clicked me {{ count }} times.</button>',
    },
  },
  data() {
    return {
      column: [
        {
          type: "index",
          width: "50px",
          label: "序号",
        },
        {
          //prop: "name",
          label: "名字",
          slotName: "default",
        },
        {
          prop: "date",
          label: "日期",
        },
        {
          prop: "address",
          label: "地址",
        },
      ],
      tableData: [
        {
          date: "2016-05-02",
          name: "佘太君",
          address: "上海市普陀区金沙江路 1518 弄",
        },
        {
          date: "2016-05-04",
          name: "王小虎",
          address: "上海市普陀区金沙江路 1517 弄",
        },
        {
          date: "2016-05-01",
          name: "王小虎",
          address: "上海市普陀区金沙江路 1519 弄",
        },
        {
          date: "2016-05-03",
          name: "王小虎",
          address: "上海市普陀区金沙江路 1516 弄",
        },
      ],
    };
  },
};
</script>
显示 复制

# render 模式

column 配置支持自定义 render 模式, 但要注意一点,如果要 render 自定义的组件的话,注册在当前组件是渲染不了,可以用插槽模式,或者全局注册该组件

<template>
  <an-table align="center" :column="column" :data="tableData"> </an-table>
</template>
<script>
// const Vue = require("vue");
// Vue.component("button-counter", {
//   data: function () {
//     return {
//       count: 0,
//     };
//   },
//   template:
//     '<button v-on:click="count++">You clicked me {{ count }} times.</button>',
// });
export default {
  data() {
    return {
      column: [
        {
          type: "index",
          width: "50px",
          label: "序号",
        },
        {
          label: "名字",
          prop: "name",
          render: (h, scope) => {
            const { row, column } = scope;
            const propKey = column.property;
            return <div>render 结果 -- {row[propKey]}</div>;
          },
        },
        {
          prop: "date",
          label: "日期",
        },
        {
          prop: "address",
          label: "地址",
        },
      ],
      tableData: [
        {
          date: "2016-05-02",
          name: "佘太君",
          address: "上海市普陀区金沙江路 1518 弄",
        },
        {
          date: "2016-05-04",
          name: "王小虎",
          address: "上海市普陀区金沙江路 1517 弄",
        },
        {
          date: "2016-05-01",
          name: "王小虎",
          address: "上海市普陀区金沙江路 1519 弄",
        },
        {
          date: "2016-05-03",
          name: "王小虎",
          address: "上海市普陀区金沙江路 1516 弄",
        },
      ],
    };
  },
};
</script>
显示 复制

# 集成分页

el-pagination集成了分页功能,设置pagination 开始分页功能, el-paginationcurrent-change事件名与 table 的事件名冲突,重新命名为p-current-change, 其他属性与事件同el-pagination 一样

<template>
  <an-table
    v-loading="loading"
    :column="tableData.column"
    :data="tableData.data"
    pagination
    layout="total, sizes, prev, pager, next, jumper"
    :page-sizes="[5, 10, 20, 30]"
    :pager-count="5"
    :current-page.sync="currentPage"
    :total="100"
    :page-size="pageSize"
    @size-change="handleSizeChange"
    @p-current-change="handleCurrentChange"
  >
  </an-table>
</template>

<script>
export default {
  data() {
    return {
      tableData: {
        column: [
          {
            prop: "date",
            label: "日期",
          },
          {
            prop: "name",
            label: "姓名",
          },
          {
            prop: "address",
            label: "地址",
          },
        ],
        data: [],
      },
      loading: false,
      currentPage: 1,
      pageSize: 5,
    };
  },
  created() {
    this.createData(this.pageSize);
  },
  methods: {
    createData(length) {
      this.loading = true;
      let data = [];
      for (let i = 0; i < length; i++) {
        data.push({
          date: "2016-05-02",
          name: `王小虎-${this.currentPage}-${i + 1}`,
          address: `上海市普陀区金沙江路 -${this.currentPage}-${i + 1}`,
        });
      }
      setTimeout(() => {
        this.tableData.data = data;
        this.loading = false;
      }, 1000);
    },
    handleSizeChange(val) {
      this.currentPage = 1;
      this.pageSize = val;
      this.createData(this.pageSize);
    },
    handleCurrentChange() {
      this.createData(this.pageSize);
    },
  },
};
</script>
显示 复制

# 格式化默认值

利用formatter功能,实现空值时候显示默认值, openDefaultFormatter 开始该功能, 使用splitSymbol 修改默认值, 也可以 column 的 openDefaultFormatter 关闭该功能, 或者使用 column 的 formatter 属性覆盖默认 formatter 函数

<template>
  <an-table
    :column="tableData.column"
    :data="tableData.data"
    openDefaultFormatter
  >
  </an-table>
</template>

<script>
export default {
  data() {
    return {
      tableData: {
        column: [
          {
            prop: "date",
            label: "日期",
          },
          {
            prop: "name",
            label: "姓名",
          },
          {
            prop: "address",
            label: "地址",
            openDefaultFormatter: false,
          },
          {
            prop: "age",
            label: "年龄",
            formatter() {
              return "18";
            },
          },
        ],
        data: [
          {
            date: "2016-05-02",
            name: "王小虎1",
            address: "上海市普陀区金沙江路 1518 弄",
          },
          {
            date: "2016-05-02",
            name: undefined,
            address: "上海市普陀区金沙江路 1518 弄",
          },
          {
            date: "2016-05-02",
            name: "王小虎2",
            address: "",
          },
          {
            date: "2016-05-02",
            name: "王小虎3",
            address: "上海市普陀区金沙江路 1518 弄",
          },
        ],
      },
    };
  },
};
</script>
显示 复制

# 带状态表格

可将表格内容 highlight 显示,方便区分「成功、信息、警告、危险」等内容。

可以通过指定 Table 组件的 row-class-name 属性来为 Table 中的某一行添加 class,表明该行处于某种状态。

<template>
  <an-table
    :column="tableData.column"
    :data="tableData.data"
    :stripe="false"
    :row-class-name="tableRowClassName"
  >
  </an-table>
</template>

<script>
export default {
  data() {
    return {
      tableData: {
        column: [
          {
            prop: "date",
            label: "日期",
          },
          {
            prop: "name",
            label: "姓名",
          },
          {
            prop: "address",
            label: "地址",
          },
        ],
        data: [
          {
            date: "2016-05-02",
            name: "王小虎1",
            address: "上海市普陀区金沙江路 1518 弄",
          },
          {
            date: "2016-05-02",
            name: "王小虎2",
            address: "上海市普陀区金沙江路 1518 弄",
          },
          {
            date: "2016-05-02",
            name: "王小虎3",
            address: "上海市普陀区金沙江路 1518 弄",
          },
          {
            date: "2016-05-02",
            name: "王小虎4",
            address: "上海市普陀区金沙江路 1518 弄",
          },
        ],
      },
    };
  },
  methods: {
    tableRowClassName({ row, rowIndex }) {
      if (rowIndex === 1) {
        return "warning-row";
      } else if (rowIndex === 3) {
        return "success-row";
      }
      return "";
    },
  },
};
</script>

<style>
.el-table .warning-row {
  background: oldlace;
}

.el-table .success-row {
  background: #f0f9eb;
}
</style>
显示 复制

# 固定表头

纵向内容过多时,可选择固定表头。这里用max-height, 与el-tableheight不太一样, 其实是结合流体高度特性,当数据量动态变化时,可以为 Table 设置一个最大高度。

通过设置 max-height 属性为 Table 指定最大高度与设置固定表头。此时若表格所需的高度大于最大高度,则会显示一个滚动条。

<template>
  <an-table :column="column" :data="data" border maxHeight="250"> </an-table>
</template>

<script>
export default {
  data() {
    return {
      column: [
        {
          prop: "date",
          label: "日期",
        },
        {
          prop: "name",
          label: "姓名",
        },
        {
          prop: "address",
          label: "地址",
        },
      ],
      data: [],
    };
  },
  created() {
    for (let i = 0; i < 20; i++) {
      this.data.push({
        date: `2016-05-${i + 1}`,
        name: `王小虎${i + 1}`,
        address: `上海市普陀区金沙江路 ${i + 1}`,
      });
    }
  },
};
</script>
显示 复制

# 固定列

横向内容过多时,可选择固定列。

固定列需要使用 fixed 属性,它接受 Boolean 值或者 leftright,表示左边固定还是右边固定。

<template>
  <an-table :column="tableData.column" :data="tableData.data"> </an-table>
</template>

<script>
export default {
  data() {
    return {
      tableData: {
        column: [
          {
            prop: "date",
            label: "日期",
            width: "150",
            fixed: true,
          },
          {
            prop: "name",
            label: "姓名",
            width: "120",
          },
          {
            prop: "province",
            label: "省份",
            width: "120",
          },
          {
            prop: "city",
            label: "市区",
            width: "120",
          },
          {
            prop: "address",
            label: "地址",
            width: "300",
          },
          {
            prop: "zip",
            label: "邮编",
            width: "120",
            fixed: "right",
          },
        ],
        data: [
          {
            date: "2016-05-02",
            name: "王小虎",
            province: "上海",
            city: "普陀区",
            address: "上海市普陀区金沙江路 1518 弄",
            zip: 200333,
          },
          {
            date: "2016-05-04",
            name: "王小虎",
            province: "上海",
            city: "普陀区",
            address: "上海市普陀区金沙江路 1517 弄",
            zip: 200333,
          },
          {
            date: "2016-05-01",
            name: "王小虎",
            province: "上海",
            city: "普陀区",
            address: "上海市普陀区金沙江路 1519 弄",
            zip: 200333,
          },
        ],
      },
    };
  },
};
</script>
显示 复制

# 固定列和表头

横纵内容过多时,可选择固定列和表头

固定列和表头可以同时使用,只需要将上述两个属性分别设置好即可。

<template>
  <an-table maxHeight="250" :column="tableData.column" :data="tableData.data">
  </an-table>
</template>

<script>
export default {
  data() {
    return {
      tableData: {
        column: [
          {
            prop: "date",
            label: "日期",
            width: "150",
            fixed: true,
          },
          {
            prop: "name",
            label: "姓名",
            width: "120",
          },
          {
            prop: "province",
            label: "省份",
            width: "120",
          },
          {
            prop: "city",
            label: "市区",
            width: "120",
          },
          {
            prop: "address",
            label: "地址",
            width: "300",
          },
          {
            prop: "zip",
            label: "邮编",
            width: "120",
            fixed: "right",
          },
        ],
        data: [],
      },
    };
  },
  created() {
    for (let i = 0; i < 20; i++) {
      this.tableData.data.push({
        date: `2016-05-${i + 1}`,
        province: `省份${i + 1}`,
        city: `城市${i + 1}`,
        zip: `邮编${i + 1}`,
        name: `王小虎${i + 1}`,
        address: `上海市普陀区金沙江路 ${i + 1}`,
      });
    }
  },
};
</script>
显示 复制

# 多级表头

数据结构比较复杂的时候,可使用多级表头来展现数据的层次关系。

只需要在 el-table-column 里面嵌套 el-table-column,就可以实现多级表头。

<template>
  <an-table :column="tableData.column" :data="tableData.data" height="450">
  </an-table>
</template>

<script>
export default {
  data() {
    return {
      tableData: {
        column: [
          {
            prop: "date",
            label: "日期",
            fixed: true,
            width: "120",
            renderHeader: (h, scope) => {
              return (
                <span>
                  <i class="el-icon-time"></i>
                  {scope.column.label}
                </span>
              );
            },
          },
          {
            label: "配送信息",
            children: [
              {
                prop: "name",
                label: "姓名",
                width: "120",
                render: (h, scope) => {
                  return <el-tag>{scope.row[scope.column.property]}</el-tag>;
                },
              },
              {
                label: "地址",
                children: [
                  {
                    prop: "province",
                    label: "省份",
                    width: "120",
                  },
                  {
                    prop: "city",
                    label: "市区",
                    width: "120",
                  },
                  {
                    prop: "address",
                    label: "地址",
                    width: "300px",
                    renderHeader: (h, scope) => {
                      return (
                        <span>
                          <i class="el-icon-location-outline"></i>
                          {scope.column.label}
                        </span>
                      );
                    },
                  },
                ],
              },
            ],
          },
        ],
        data: [],
      },
    };
  },
  created() {
    for (let i = 0; i < 10; i++) {
      this.tableData.data.push({
        date: `2016-05-${i + 1}`,
        name: `王小虎${i + 1}`,
        province: "上海",
        city: "普陀区",
        address: `上海市普陀区金沙江路 ${i + 1}`,
        zip: 200333,
      });
    }
  },
};
</script>
显示 复制

# 单选

选择单行数据时使用色块表示。

选中第二行 取消选择

El-Table 组件,只需要配置highlight-current-row属性即可实现单选。之后由 current-change 事件来管理选中时触发的事件,它会传入currentRowoldCurrentRow。如果需要显示索引,可设置索引列type属性为index即可显示从 1 开始的索引号。

<template>
  <div>
    <an-table
      ref="anTable"
      highlight-current-row
      :column="tableData.column"
      :data="tableData.data"
      @current-change="handleCurrentChange"
    >
    </an-table>
    <div style="margin-top: 20px">
      <el-button @click="setCurrent(tableData.data[1])">选中第二行</el-button>
      <el-button @click="setCurrent()">取消选择</el-button>
    </div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      tableData: {
        column: [
          {
            type: "index",
            align: "center",
          },
          {
            prop: "date",
            label: "日期",
          },
          {
            prop: "name",
            label: "姓名",
          },
          {
            prop: "address",
            label: "地址",
          },
        ],
        data: [
          {
            date: "2016-05-02",
            name: "王小虎1",
            address: "上海市普陀区金沙江路 1518 弄",
          },
          {
            date: "2016-05-02",
            name: "王小虎2",
            address: "上海市普陀区金沙江路 1518 弄",
          },
          {
            date: "2016-05-02",
            name: "王小虎3",
            address: "上海市普陀区金沙江路 1518 弄",
          },
        ],
      },
      currentRow: null,
    };
  },
  methods: {
    setCurrent(row) {
      this.$refs.anTable.setCurrentRow(row);
    },
    handleCurrentChange(val) {
      this.currentRow = val;
    },
  },
};
</script>
显示 复制

# 多选

选择多行数据时使用 Checkbox。

切换第二、第三行的选中状态 取消选择

设置typeselection即可。

<template>
  <div>
    <an-table
      ref="multipleTable"
      :column="tableData.column"
      :data="tableData.data"
      @selection-change="handleSelectionChange"
    >
    </an-table>
    <div style="margin-top: 20px">
      <el-button
        @click="toggleSelection([tableData.data[1], tableData.data[2]])"
        >切换第二、第三行的选中状态</el-button
      >
      <el-button @click="toggleSelection()">取消选择</el-button>
    </div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      tableData: {
        column: [
          {
            type: "selection",
            width: "50px",
          },
          {
            prop: "date",
            label: "日期",
          },
          {
            prop: "name",
            label: "姓名",
          },
          {
            prop: "address",
            label: "地址",
          },
        ],
        data: [
          {
            date: "2016-05-02",
            name: "王小虎1",
            address: "上海市普陀区金沙江路 1518 弄",
          },
          {
            date: "2016-05-02",
            name: "王小虎2",
            address: "上海市普陀区金沙江路 1518 弄",
          },
          {
            date: "2016-05-02",
            name: "王小虎3",
            address: "上海市普陀区金沙江路 1518 弄",
          },
        ],
      },
      multipleSelection: [],
    };
  },
  methods: {
    toggleSelection(rows) {
      if (rows) {
        rows.forEach((row) => {
          this.$refs.multipleTable.toggleRowSelection(row);
        });
      } else {
        this.$refs.multipleTable.clearSelection();
      }
    },
    handleSelectionChange(val) {
      console.log(
        `🚀 ~ file: multiple-table.vue ~ line 75 ~ handleSelectionChange ~ val`,
        val
      );
      this.multipleSelection = val;
    },
  },
};
</script>
显示 复制

# 排序

对表格进行排序,可快速查找或对比数据

在列中设置 sortable 属性即可实现以该列为基准的排序,接受一个 Boolean,默认为 false。可以通过 Table 的 default-sort 属性设置默认的排序列和排序顺序。

<template>
  <div>
    <an-table
      ref="multipleTable"
      :column="tableData.column"
      :data="tableData.data"
      :default-sort="{ prop: 'date', order: 'descending' }"
    >
    </an-table>
  </div>
</template>

<script>
export default {
  data() {
    return {
      tableData: {
        column: [
          {
            prop: "date",
            label: "日期",
            sortable: true,
          },
          {
            prop: "name",
            label: "姓名",
          },
          {
            prop: "address",
            label: "地址",
            formatter: this.formatter,
          },
        ],
        data: [
          {
            date: "2016-05-01",
            name: "王小虎1",
            address: "上海市普陀区金沙江路 1511 弄",
          },
          {
            date: "2016-05-02",
            name: "王小虎2",
            address: "上海市普陀区金沙江路 1512 弄",
          },
          {
            date: "2016-05-03",
            name: "王小虎3",
            address: "上海市普陀区金沙江路 1513 弄",
          },
        ],
      },
      multipleSelection: [],
    };
  },
  methods: {
    formatter(row) {
      return row.address + "-formatter";
    },
  },
};
</script>
显示 复制

自定义排序

可以使用 sort-method 或者 sort-by 使用自定义的排序规则。如果需要后端排序,需将 sortable 设置为 custom,同时在 Table 上监听 sort-change 事件,在事件回调中可以获取当前排序的字段名和排序顺序,从而向接口请求排序后的表格数据。在本例中,我们还使用了 formatter 属性,它用于格式化指定列的值,接受一个 Function,会传入两个参数:row 和 column,可以根据自己的需求进行处理。

<template>
  <div>
    <an-table
      v-loading="loading"
      ref="multipleTable"
      :column="tableData.column"
      :data="tableData.data"
      @sort-change="handleSortChange"
    >
    </an-table>
  </div>
</template>

<script>
const mockData = [
  {
    date: "2016-05-01",
    name: "王小虎1",
    address: "上海市普陀区金沙江路 1511 弄",
  },
  {
    date: "2016-05-05",
    name: "王小虎2",
    address: "上海市普陀区金沙江路 1512 弄",
  },
  {
    date: "2016-05-02",
    name: "王小虎2",
    address: "上海市普陀区金沙江路 1512 弄",
  },
  {
    date: "2016-05-03",
    name: "王小虎3",
    address: "上海市普陀区金沙江路 1513 弄",
  },
];
export default {
  data() {
    return {
      loading: false,
      tableData: {
        column: [
          {
            prop: "date",
            label: "日期",
            sortable: "custom",
          },
          {
            prop: "name",
            label: "姓名",
          },
          {
            prop: "address",
            label: "地址",
            formatter: this.formatter,
          },
        ],
        data: mockData,
      },
      multipleSelection: [],
    };
  },
  methods: {
    handleSortChange({ column, prop, order }) {
      this.loading = true;
      setTimeout(() => {
        this.tableData.data = mockData.sort((a, b) =>
          order === "ascending"
            ? new Date(a.date) - new Date(b.date)
            : new Date(b.date) - new Date(a.date)
        );
        this.loading = false;
      }, 1000);
    },
    formatter(row) {
      return row.address + "-formatter";
    },
  },
};
</script>
显示 复制

# 筛选

对表格进行筛选,可快速查找到自己想看的数据。

清除日期过滤器 清除所有过滤器

在列中设置 filters filter-method属性即可开启该列的筛选,filters 是一个数组,filter-method 是一个方法,它用于决定某些数据是否显示,会传入三个参数:value, rowcolumn

<template>
  <div>
    <el-button @click="resetDateFilter">清除日期过滤器</el-button>
    <el-button @click="clearFilter">清除所有过滤器</el-button>
    <an-table
      style="margin-top: 16px"
      ref="filterTable"
      :column="tableData.column"
      :data="tableData.data"
    >
    </an-table>
  </div>
</template>

<script>
export default {
  data() {
    return {
      tableData: {
        column: [
          {
            prop: "date",
            label: "日期",
            sortable: true,
            columnKey: "date",
            filters: [
              { text: "2016-05-01", value: "2016-05-01" },
              { text: "2016-05-02", value: "2016-05-02" },
              { text: "2016-05-03", value: "2016-05-03" },
              { text: "2016-05-04", value: "2016-05-04" },
            ],
            filterMethod: this.filterHandler,
          },
          {
            prop: "name",
            label: "姓名",
          },
          {
            prop: "address",
            label: "地址",
          },
          {
            prop: "tag",
            label: "标签",
            filters: [
              { text: "家", value: "家" },
              { text: "公司", value: "公司" },
            ],
            filterMethod: this.filterTag,
            filterPlacement: "bottom-end",
            render: (h, scope) => {
              return (
                <el-tag type={scope.row.tag === "家" ? "primary" : "success"}>
                  {scope.row.tag}
                </el-tag>
              );
            },
          },
        ],
        data: [
          {
            date: "2016-05-02",
            name: "王小虎",
            address: "上海市普陀区金沙江路 1518 弄",
            tag: "家",
          },
          {
            date: "2016-05-04",
            name: "王小虎",
            address: "上海市普陀区金沙江路 1517 弄",
            tag: "公司",
          },
          {
            date: "2016-05-01",
            name: "王小虎",
            address: "上海市普陀区金沙江路 1519 弄",
            tag: "家",
          },
          {
            date: "2016-05-03",
            name: "王小虎",
            address: "上海市普陀区金沙江路 1516 弄",
            tag: "公司",
          },
        ],
      },
    };
  },
  methods: {
    resetDateFilter() {
      this.$refs.filterTable.clearFilter("date");
    },
    clearFilter() {
      this.$refs.filterTable.clearFilter();
    },
    formatter(row, column) {
      return row.address;
    },
    filterTag(value, row) {
      return row.tag === value;
    },
    filterHandler(value, row, column) {
      const property = column["property"];
      return row[property] === value;
    },
  },
};
</script>
显示 复制

# 自定义列模板

使用 render 函数, 自定义列的显示内容,可组合其他组件使用。

通过 column render 函数自定义 render 模板。

<template>
  <an-table border :column="tableData.column" :data="tableData.data">
  </an-table>
</template>

<script>
export default {
  data() {
    return {
      tableData: {
        column: [
          {
            prop: "date",
            label: "日期",
            render: (h, scope) => {
              return (
                <div>
                  <i class="el-icon-time"></i>
                  <span style="margin-left: 10px">{scope.row.date}</span>
                </div>
              );
            },
          },
          {
            prop: "name",
            label: "姓名",
            render: (h, scope) => {
              return (
                <el-popover trigger="hover" placement="top">
                  <p>姓名: {scope.row.name}</p>
                  <p>住址: {scope.row.address}</p>
                  <div slot="reference" style="display: inline-block">
                    <el-tag size="medium">{scope.row.name}</el-tag>
                  </div>
                </el-popover>
              );
            },
          },
          {
            label: "操作",
            render: (h, scope) => {
              return (
                <div>
                  <el-button
                    size="mini"
                    onClick={() => {
                      this.handleEdit(scope.$index, scope.row);
                    }}
                  >
                    编辑
                  </el-button>
                  <el-button
                    size="mini"
                    type="danger"
                    onClick={() => {
                      this.handleDelete(scope.$index, scope.row);
                    }}
                  >
                    删除
                  </el-button>
                </div>
              );
            },
          },
        ],
        data: [
          {
            date: "2016-05-02",
            name: "王小虎1",
            address: "上海市普陀区金沙江路 1518 弄",
          },
          {
            date: "2016-05-02",
            name: "王小虎2",
            address: "上海市普陀区金沙江路 1519 弄",
          },
          {
            date: "2016-05-02",
            name: "王小虎3",
            address: "上海市普陀区金沙江路 1520 弄",
          },
        ],
      },
    };
  },
  methods: {
    handleEdit(index, row) {
      console.log(index, row);
      this.$message(`点击的了编辑,索引:${index}`);
    },
    handleDelete(index, row) {
      console.log(index, row);
      this.$message(`点击的了删除,索引:${index}`);
    },
  },
};
</script>
显示 复制

使用slotName插槽, 自定义列的显示内容,可组合其他组件使用。

通过 column render 函数自定义 render 模板。

<template>
  <an-table :column="tableData.column" :data="tableData.data">
    <template v-slot:columnSlotName="scope">
      <el-popover trigger="hover" placement="top">
        <p>姓名: {{ scope.row.name }}</p>
        <p>住址: {{ scope.row.address }}</p>
        <div slot="reference" style="display: inline-block">
          <el-tag size="medium">{{ scope.row.name }}</el-tag>
        </div>
      </el-popover>
    </template>
  </an-table>
</template>

<script>
export default {
  data() {
    return {
      tableData: {
        column: [
          {
            prop: "date",
            label: "日期",
            render: (h, scope) => {
              return (
                <div>
                  <i class="el-icon-time"></i>
                  <span style="margin-left: 10px">{scope.row.date}</span>
                </div>
              );
            },
          },
          {
            prop: "name",
            label: "姓名",
            slotName: "columnSlotName",
            // render: (h, scope) => {
            //   return (
            //     <el-popover trigger="hover" placement="top">
            //       <p>姓名: {scope.row.name}</p>
            //       <p>住址: {scope.row.address}</p>
            //       <div slot="reference" style="display: inline-block">
            //         <el-tag size="medium">{scope.row.name}</el-tag>
            //       </div>
            //     </el-popover>
            //   );
            // },
          },
          {
            label: "操作",
            render: (h, scope) => {
              return (
                <div>
                  <el-button
                    size="mini"
                    onClick={() => {
                      this.handleEdit(scope.$index, scope.row);
                    }}
                  >
                    编辑
                  </el-button>
                  <el-button
                    size="mini"
                    type="danger"
                    onClick={() => {
                      this.handleDelete(scope.$index, scope.row);
                    }}
                  >
                    删除
                  </el-button>
                </div>
              );
            },
          },
        ],
        data: [
          {
            date: "2016-05-02",
            name: "王小虎1",
            address: "上海市普陀区金沙江路 1518 弄",
          },
          {
            date: "2016-05-02",
            name: "王小虎2",
            address: "上海市普陀区金沙江路 1519 弄",
          },
          {
            date: "2016-05-02",
            name: "王小虎3",
            address: "上海市普陀区金沙江路 1520 弄",
          },
        ],
      },
    };
  },
  methods: {
    handleEdit(index, row) {
      console.log(index, row);
      this.$message(`点击的了编辑,索引:${index}`);
    },
    handleDelete(index, row) {
      console.log(index, row);
      this.$message(`点击的了删除,索引:${index}`);
    },
  },
};
</script>
显示 复制

# 展开行

当行内容过多并且不想显示横向滚动条时,可以使用 Table 展开行功能。

通过设置 type="expand"可以开启展开行功能,展开行的内容可以通过render自定义

<template>
  <an-table :border="false" :column="tableData.column" :data="tableData.data">
  </an-table>
</template>

<script>
export default {
  data() {
    return {
      tableData: {
        column: [
          {
            type: "expand",
            render: (h, props) => {
              return (
                <el-form label-position="left" inline class="demo-table-expand">
                  <el-form-item label="商品名称">
                    <span>{props.row.name}</span>
                  </el-form-item>
                  <el-form-item label="所属店铺">
                    <span>{props.row.shop}</span>
                  </el-form-item>
                  <el-form-item label="商品 ID">
                    <span>{props.row.id}</span>
                  </el-form-item>
                  <el-form-item label="店铺 ID">
                    <span>{props.row.shopId}</span>
                  </el-form-item>
                  <el-form-item label="商品分类">
                    <span>{props.row.category}</span>
                  </el-form-item>
                  <el-form-item label="店铺地址">
                    <span>{props.row.address}</span>
                  </el-form-item>
                  <el-form-item label="商品描述">
                    <span>{props.row.desc}</span>
                  </el-form-item>
                </el-form>
              );
            },
          },
          {
            prop: "id",
            label: "ID",
          },
          {
            prop: "name",
            label: "商品名称",
          },
          {
            prop: "desc",
            label: "描述",
          },
        ],
        data: [
          {
            id: "12987122",
            name: "好滋好味鸡蛋仔",
            category: "江浙小吃、小吃零食",
            desc: "荷兰优质淡奶,奶香浓而不腻",
            address: "上海市普陀区真北路",
            shop: "王小虎夫妻店",
            shopId: "10333",
          },
          {
            id: "12987123",
            name: "好滋好味鸡蛋仔",
            category: "江浙小吃、小吃零食",
            desc: "荷兰优质淡奶,奶香浓而不腻",
            address: "上海市普陀区真北路",
            shop: "王小虎夫妻店",
            shopId: "10333",
          },
          {
            id: "12987125",
            name: "好滋好味鸡蛋仔",
            category: "江浙小吃、小吃零食",
            desc: "荷兰优质淡奶,奶香浓而不腻",
            address: "上海市普陀区真北路",
            shop: "王小虎夫妻店",
            shopId: "10333",
          },
          {
            id: "12987126",
            name: "好滋好味鸡蛋仔",
            category: "江浙小吃、小吃零食",
            desc: "荷兰优质淡奶,奶香浓而不腻",
            address: "上海市普陀区真北路",
            shop: "王小虎夫妻店",
            shopId: "10333",
          },
        ],
      },
    };
  },
};
</script>

<style>
.demo-table-expand {
  font-size: 0;
}
.demo-table-expand label {
  width: 90px;
  color: #99a9bf;
}
.demo-table-expand .el-form-item {
  margin-right: 0;
  margin-bottom: 0;
  width: 50%;
}
</style>
显示 复制

# 树形数据与懒加载


通过设置 type="expand"可以开启展开行功能,展开行的内容可以通过render自定义

<template>
  <div>
    <an-table
      :column="tableData1.column"
      :data="tableData1.data"
      row-key="id"
      default-expand-all
      :tree-props="{ children: 'children', hasChildren: 'hasChildren' }"
    >
    </an-table>
    <br />
    <an-table
      :column="tableData1.column"
      :data="tableData2.data"
      row-key="id"
      lazy
      :load="load"
      :tree-props="{ children: 'children', hasChildren: 'hasChildren' }"
    >
    </an-table>
  </div>
</template>

<script>
export default {
  data() {
    return {
      tableData1: {
        column: [
          {
            prop: "date",
            label: "日期",
          },
          {
            prop: "name",
            label: "姓名",
          },
          {
            prop: "address",
            label: "地址",
          },
        ],
        data: [
          {
            id: 1,
            date: "2016-05-02",
            name: "王小虎",
            address: "上海市普陀区金沙江路 1518 弄",
          },
          {
            id: 2,
            date: "2016-05-04",
            name: "王小虎",
            address: "上海市普陀区金沙江路 1517 弄",
          },
          {
            id: 3,
            date: "2016-05-01",
            name: "王小虎",
            address: "上海市普陀区金沙江路 1519 弄",
            children: [
              {
                id: 31,
                date: "2016-05-01",
                name: "王小虎",
                address: "上海市普陀区金沙江路 1519 弄",
              },
              {
                id: 32,
                date: "2016-05-01",
                name: "王小虎",
                address: "上海市普陀区金沙江路 1519 弄",
              },
            ],
          },
          {
            id: 4,
            date: "2016-05-03",
            name: "王小虎",
            address: "上海市普陀区金沙江路 1516 弄",
          },
        ],
      },
      tableData2: {
        data: [
          {
            id: 1,
            date: "2016-05-02",
            name: "王小虎",
            address: "上海市普陀区金沙江路 1518 弄",
          },
          {
            id: 2,
            date: "2016-05-04",
            name: "王小虎",
            address: "上海市普陀区金沙江路 1517 弄",
          },
          {
            id: 3,
            date: "2016-05-01",
            name: "王小虎",
            address: "上海市普陀区金沙江路 1519 弄",
            hasChildren: true,
          },
          {
            id: 4,
            date: "2016-05-03",
            name: "王小虎",
            address: "上海市普陀区金沙江路 1516 弄",
          },
        ],
      },
    };
  },
  methods: {
    load(tree, treeNode, resolve) {
      setTimeout(() => {
        resolve([
          {
            id: 31,
            date: "2016-05-01",
            name: "王小虎",
            address: "上海市普陀区金沙江路 1519 弄",
          },
          {
            id: 32,
            date: "2016-05-01",
            name: "王小虎",
            address: "上海市普陀区金沙江路 1519 弄",
          },
        ]);
      }, 1000);
    },
  },
};
</script>
显示 复制

# 自定义表头

表头支持自定义--renderHeader。

通过设置renderHeader来自定义表头,写法同自定义列模板

<template>
  <an-table :column="tableData.column" :data="tableData.data"> </an-table>
</template>

<script>
export default {
  data() {
    return {
      tableData: {
        column: [
          {
            prop: "date",
            label: "日期",
            renderHeader: (h, scope) => {
              return (
                <span>
                  <i class="el-icon-time">{scope.column.label}</i>
                </span>
              );
            },
          },
          {
            prop: "name",
            label: "姓名",
          },
          {
            label: "操作",
            renderHeader: (h, scope) => {
              return (
                <el-input
                  value={this.search}
                  size="mini"
                  placeholder="输入关键字搜索"
                  onInput={(val) => {
                    this.search = val;
                  }}
                />
              );
            },
            render: (h, scope) => {
              return (
                <div>
                  <el-button
                    size="mini"
                    onClick={() => {
                      this.handleEdit(scope.$index, scope.row);
                    }}
                  >
                    编辑
                  </el-button>
                  <el-button
                    size="mini"
                    type="danger"
                    onClick={() => {
                      this.handleDelete(scope.$index, scope.row);
                    }}
                  >
                    删除
                  </el-button>
                </div>
              );
            },
          },
        ],
        data: [
          {
            date: "2016-05-02",
            name: "王小虎1",
            address: "上海市普陀区金沙江路 1518 弄",
          },
          {
            date: "2016-05-02",
            name: "王小虎2",
            address: "上海市普陀区金沙江路 1518 弄",
          },
          {
            date: "2016-05-02",
            name: "王小虎3",
            address: "上海市普陀区金沙江路 1518 弄",
          },
        ],
      },
      search: "",
    };
  },
  watch: {
    search(newVal, oldVal) {
      console.log(
        `🚀 ~ file: render-header-table.vue ~ line 88 ~ search ~ newVal, oldVal`,
        newVal,
        oldVal
      );
    },
  },
  methods: {
    handleEdit(index, row) {
      console.log(index, row);
      this.$message(`点击的了编辑,索引:${index}`);
    },
    handleDelete(index, row) {
      console.log(index, row);
      this.$message(`点击的了删除,索引:${index}`);
    },
  },
};
</script>
显示 复制

表头支持自定义--插槽模式

通过设置slotHeaderName来自定义表头,写法同自定义列模板

<template>
  <an-table :column="tableData.column" :data="tableData.data">
    <template v-slot:headerSlotName="{ column }">
      <el-input
        v-model="search"
        size="mini"
        placeholder="输入关键字搜索"
        @input="handleInput($event, column)"
      />
    </template>
  </an-table>
</template>

<script>
export default {
  data() {
    return {
      tableData: {
        column: [
          {
            prop: "date",
            label: "日期",
            renderHeader: (h, scope) => {
              return (
                <span>
                  <i class="el-icon-time">{scope.column.label}</i>
                </span>
              );
            },
          },
          {
            prop: "name",
            label: "姓名",
          },
          {
            label: "操作",
            slotHeaderName: "headerSlotName",
            render: (h, scope) => {
              return (
                <div>
                  <el-button
                    size="mini"
                    onClick={() => {
                      this.handleEdit(scope.$index, scope.row);
                    }}
                  >
                    编辑
                  </el-button>
                  <el-button
                    size="mini"
                    type="danger"
                    onClick={() => {
                      this.handleDelete(scope.$index, scope.row);
                    }}
                  >
                    删除
                  </el-button>
                </div>
              );
            },
          },
        ],
        data: [
          {
            date: "2016-05-02",
            name: "王小虎1",
            address: "上海市普陀区金沙江路 1518 弄",
          },
          {
            date: "2016-05-02",
            name: "王小虎2",
            address: "上海市普陀区金沙江路 1518 弄",
          },
          {
            date: "2016-05-02",
            name: "王小虎3",
            address: "上海市普陀区金沙江路 1518 弄",
          },
        ],
      },
      search: "",
    };
  },
  watch: {
    search(newVal, oldVal) {
      console.log(
        `🚀 ~ file: render-header-table.vue ~ line 88 ~ search ~ newVal, oldVal`,
        newVal,
        oldVal
      );
    },
  },
  methods: {
    handleInput(val, row) {
      console.log(
        row,
        `🚀 ~ file: slot-header-table.vue ~ line 93 ~ handleInput ~ val`,
        val
      );
      // this.search = val;
    },
    handleEdit(index, row) {
      console.log(index, row);
      this.$message(`点击的了编辑,索引:${index}`);
    },
    handleDelete(index, row) {
      console.log(index, row);
      this.$message(`点击的了删除,索引:${index}`);
    },
  },
};
</script>
显示 复制

# 表尾合计行

若表格展示的是各类数字,可以在表尾显示各列的合计。

show-summary设置为true就会在表格尾部展示合计行。默认情况下,对于合计行,第一列不进行数据求合操作,而是显示「合计」二字(可通过sum-text配置),其余列会将本列所有数值进行求合操作,并显示出来。当然,你也可以定义自己的合计逻辑。使用summary-method并传入一个方法,返回一个数组,这个数组中的各项就会显示在合计行的各列中,具体可以参考本例中的第二个表格。

<template>
  <div>
    <an-table
      :column="tableData.column"
      :data="tableData.data"
      border
      show-summary
    >
    </an-table>

    <an-table
      :column="tableData.column"
      :data="tableData.data"
      :summary-method="getSummaries"
      style="margin-top: 20px"
      height="250"
      border
      show-summary
    >
    </an-table>
  </div>
</template>

<script>
export default {
  data() {
    return {
      tableData: {
        column: [
          {
            prop: "id",
            label: "ID",
          },
          {
            prop: "name",
            label: "姓名",
          },
          {
            prop: "amount1",
            label: "数值1",
            sortable: true,
          },
          {
            prop: "amount2",
            label: "数值2",
            sortable: true,
          },
          {
            prop: "amount3",
            label: "数值3",
            sortable: true,
          },
        ],
        data: [
          {
            id: "12987122",
            name: "王小虎",
            amount1: "234",
            amount2: "3",
            amount3: 10,
          },
          {
            id: "12987123",
            name: "王小虎",
            amount1: "165",
            amount2: "4",
            amount3: 12,
          },
          {
            id: "12987124",
            name: "王小虎",
            amount1: "324",
            amount2: "1",
            amount3: 9,
          },
          {
            id: "12987125",
            name: "王小虎",
            amount1: "621",
            amount2: "2",
            amount3: 17,
          },
          {
            id: "12987126",
            name: "王小虎",
            amount1: "539",
            amount2: "4",
            amount3: 15,
          },
        ],
      },
    };
  },
  methods: {
    getSummaries(param) {
      const { columns, data } = param;
      const sums = [];
      columns.forEach((column, index) => {
        if (index === 0) {
          sums[index] = "总价";
          return;
        }
        const values = data.map((item) => Number(item[column.property]));
        if (!values.every((value) => isNaN(value))) {
          sums[index] = values.reduce((prev, curr) => {
            const value = Number(curr);
            if (!isNaN(value)) {
              return prev + curr;
            } else {
              return prev;
            }
          }, 0);
          sums[index] += " 元";
        } else {
          sums[index] = "N/A";
        }
      });

      return sums;
    },
  },
};
</script>
显示 复制

# 合并行或列

多行或多列共用一个数据时,可以合并行或列。

通过给an-table传入span-method方法可以实现合并行或列,方法的参数是一个对象,里面包含当前行row、当前列column、当前行号rowIndex、当前列号columnIndex四个属性。该函数可以返回一个包含两个元素的数组,第一个元素代表rowspan,第二个元素代表colspan。 也可以返回一个键名为rowspancolspan的对象。

<template>
  <div>
    <an-table
      :column="tableData.column"
      :data="tableData.data"
      :span-method="arraySpanMethod"
      border
    >
    </an-table>

    <an-table
      :column="tableData.column"
      :data="tableData.data"
      :span-method="objectSpanMethod"
      style="margin-top: 20px"
      border
    >
    </an-table>
  </div>
</template>

<script>
export default {
  data() {
    return {
      tableData: {
        column: [
          {
            prop: "id",
            label: "ID",
          },
          {
            prop: "name",
            label: "姓名",
          },
          {
            prop: "amount1",
            label: "数值1",
            sortable: true,
          },
          {
            prop: "amount2",
            label: "数值2",
            sortable: true,
          },
          {
            prop: "amount3",
            label: "数值3",
            sortable: true,
          },
        ],
        data: [
          {
            id: "12987122",
            name: "王小虎",
            amount1: "234",
            amount2: "3",
            amount3: 10,
          },
          {
            id: "12987123",
            name: "王小虎",
            amount1: "165",
            amount2: "4",
            amount3: 12,
          },
          {
            id: "12987124",
            name: "王小虎",
            amount1: "324",
            amount2: "1",
            amount3: 9,
          },
          {
            id: "12987125",
            name: "王小虎",
            amount1: "621",
            amount2: "2",
            amount3: 17,
          },
          {
            id: "12987126",
            name: "王小虎",
            amount1: "539",
            amount2: "4",
            amount3: 15,
          },
        ],
      },
    };
  },
  methods: {
    arraySpanMethod({ row, column, rowIndex, columnIndex }) {
      if (rowIndex % 2 === 0) {
        if (columnIndex === 0) {
          return [1, 2];
        } else if (columnIndex === 1) {
          return [0, 0];
        }
      }
    },
    objectSpanMethod({ row, column, rowIndex, columnIndex }) {
      if (columnIndex === 0) {
        if (rowIndex % 2 === 0) {
          return {
            rowspan: 2,
            colspan: 1,
          };
        } else {
          return {
            rowspan: 0,
            colspan: 0,
          };
        }
      }
    },
  },
};
</script>
显示 复制

# 自定义索引

自定义 type=index 列的行号。

通过给 type=index 的列传入 index 属性,可以自定义索引。该属性传入数字时,将作为索引的起始值。也可以传入一个方法,它提供当前行的行号(从 0 开始)作为参数,返回值将作为索引展示。

<template>
  <an-table :column="tableData.column" :data="tableData.data"> </an-table>
</template>

<script>
export default {
  data() {
    return {
      tableData: {
        column: [
          {
            type: "index",
            label: "#",
            index: this.indexMethod,
          },
          {
            prop: "date",
            label: "日期",
          },
          {
            prop: "name",
            label: "姓名",
          },
          {
            prop: "address",
            label: "地址",
          },
        ],
        data: [
          {
            date: "2016-05-02",
            name: "王小虎1",
            address: "上海市普陀区金沙江路 1518 弄",
          },
          {
            date: "2016-05-02",
            name: "王小虎2",
            address: "上海市普陀区金沙江路 1518 弄",
          },
          {
            date: "2016-05-02",
            name: "王小虎3",
            address: "上海市普陀区金沙江路 1518 弄",
          },
        ],
      },
    };
  },
  methods: {
    indexMethod(index) {
      return index * 2;
    },
  },
};
</script>
显示 复制

# 拓展使用

# 普通形式表格编辑

数据简单的情况下,可以通过点击编辑按钮直接进行表格的编辑、保存、取消操作

由于编辑模式下数据格式不统一,如日期数据通过DatePicker选择,普通的文本通过Input,下拉选择的通过ElSelect等,所以就不进行整合了,大家可以通过render自定义出任意效果的编辑模式,原理就是根据是否是编辑模式的字段,渲染不同的内容,如本例中的_edit,为true的情况下渲染相应的编辑模式下的组件,否则就是普通的文本。由于编辑模式中有取消,所以取消的时候得还原原数据,可以通过定义一个defaultData,该值为JSON.parse(JSON.stringify(this.tableData.data)),加JSON.parseJSON.stringify防止defaultData数据随着this.tableData.data的改变而改变,取消的时候通过$index索引从defaultData中拿到原数据,然后根据$index索引修改this.tableData.data的数据

<template>
  <an-table :column="tableData.column" :data="tableData.data"> </an-table>
</template>

<script>
export default {
  data() {
    return {
      tableData: {
        column: [
          {
            prop: "date",
            label: "日期",
            width: "150",
            render: (h, scope) => {
              return (
                <div>
                  {scope.row._edit ? (
                    <el-date-picker
                      value={scope.row[scope.column.property]}
                      type="date"
                      value-format="yyyy-MM-dd"
                      placeholder="选择日期"
                      style="width: 140px"
                      onInput={(val) => {
                        scope.row[scope.column.property] = val;
                      }}
                    ></el-date-picker>
                  ) : (
                    <span>{scope.row[scope.column.property]}</span>
                  )}
                </div>
              );
            },
          },
          {
            prop: "name",
            label: "姓名",
            render: (h, scope) => {
              return (
                <div>
                  {scope.row._edit ? (
                    <el-input
                      value={scope.row[scope.column.property]}
                      onInput={(val) => {
                        scope.row[scope.column.property] = val;
                      }}
                    ></el-input>
                  ) : (
                    <span>{scope.row[scope.column.property]}</span>
                  )}
                </div>
              );
            },
          },
          {
            prop: "tag",
            label: "标签",
            render: (h, scope) => {
              return (
                <div>
                  {scope.row._edit ? (
                    <el-select
                      value={scope.row[scope.column.property]}
                      style="width: 80px"
                      onChange={(val) => {
                        scope.row[scope.column.property] = val;
                      }}
                    >
                      {this.tagOptions.map((option) => {
                        return (
                          <el-option
                            label={option.label}
                            value={option.value}
                          ></el-option>
                        );
                      })}
                    </el-select>
                  ) : (
                    <el-tag
                      type={scope.row.tag === "家" ? "primary" : "success"}
                    >
                      {scope.row[scope.column.property]}
                    </el-tag>
                  )}
                </div>
              );
            },
          },
          {
            label: "操作",
            render: (h, scope) => {
              return (
                <div>
                  {scope.row._edit ? (
                    <div>
                      <el-button
                        type="primary"
                        onClick={() => {
                          this.handleSave(scope);
                        }}
                      >
                        保存
                      </el-button>
                      <el-button
                        onClick={() => {
                          this.handleCancle(scope);
                        }}
                      >
                        取消
                      </el-button>
                    </div>
                  ) : (
                    <el-button
                      type="primary"
                      onClick={() => {
                        this.handleEdit(scope);
                      }}
                    >
                      编辑
                    </el-button>
                  )}
                </div>
              );
            },
          },
        ],
        data: [
          {
            date: "2016-05-02",
            name: "王小虎1",
            tag: "家",
          },
          {
            date: "2016-05-02",
            name: "王小虎2",
            tag: "公司",
          },
          {
            date: "2016-05-02",
            name: "王小虎3",
            tag: "公司",
          },
        ],
        defaultData: [],
      },
      tagOptions: [
        {
          label: "家",
          value: "家",
        },
        {
          label: "公司",
          value: "公司",
        },
      ],
    };
  },
  created() {
    this.tableData.defaultData = JSON.parse(
      JSON.stringify(this.tableData.data)
    );
  },
  methods: {
    handleEdit(scope) {
      this.$set(scope.row, "_edit", true);
    },
    handleSave(scope) {
      this.$set(scope.row, "_edit", false);
      this.$set(
        this.tableData.defaultData,
        scope.$index,
        JSON.parse(JSON.stringify(scope.row))
      );
    },
    handleCancle(scope) {
      this.$set(
        this.tableData.data,
        scope.$index,
        JSON.parse(JSON.stringify(this.tableData.defaultData[scope.$index]))
      );
    },
  },
};
</script>
显示 复制

# 弹窗形式表格编辑

数据复杂的情况,建议通过弹窗形式进行数据编辑的操作

结合an-dialog弹窗修改数据

<template>
  <div>
    <an-table :column="tableData.column" :data="tableData.data"> </an-table>

    <an-dialog :visible.sync="dialogVisible" title="编辑" @confirm="confirm">
      <div class="dialog-content">
        <el-form v-if="currentEdit" label-width="100px">
          <el-form-item label="日期">
            <el-date-picker
              v-model="currentEdit.date"
              type="date"
              value-format="yyyy-MM-dd"
              placeholder="选择日期"
            >
            </el-date-picker>
          </el-form-item>

          <el-form-item label="姓名">
            <el-input v-model="currentEdit.name" placeholder="请输入姓名">
            </el-input>
          </el-form-item>

          <el-form-item label="地址">
            <el-input
              v-model="currentEdit.address"
              type="textarea"
              placeholder="请输入地址"
            >
            </el-input>
          </el-form-item>
        </el-form>
      </div>
      <!-- <div slot="footer" class="dialog-footer">
        <el-button @click="dialogVisible = false">取 消</el-button>
        <el-button type="primary" @click="confirm">确 定</el-button>
      </div> -->
    </an-dialog>
  </div>
</template>

<script>
export default {
  data() {
    return {
      tableData: {
        column: [
          {
            prop: "date",
            label: "日期",
          },
          {
            prop: "name",
            label: "姓名",
          },
          {
            prop: "address",
            label: "地址",
          },
          {
            label: "操作",
            render: (h, scope) => {
              return (
                <el-button
                  type="primary"
                  onClick={() => {
                    this.openDialog(scope);
                  }}
                >
                  编辑
                </el-button>
              );
            },
          },
        ],
        data: [
          {
            date: "2016-05-02",
            name: "王小虎1",
            address: "上海市普陀区金沙江路 1518 弄",
          },
          {
            date: "2016-05-02",
            name: "王小虎2",
            address: "上海市普陀区金沙江路 1518 弄",
          },
          {
            date: "2016-05-02",
            name: "王小虎3",
            address: "上海市普陀区金沙江路 1518 弄",
          },
        ],
      },
      currentEdit: null,
      currentIndex: null,
      dialogVisible: false,
    };
  },
  methods: {
    openDialog(scope) {
      this.currentEdit = JSON.parse(JSON.stringify(scope.row));
      this.currentIndex = scope.$index;
      this.dialogVisible = true;
    },
    confirm() {
      this.dialogVisible = false;
      this.$set(this.tableData.data, this.currentIndex, this.currentEdit);
    },
  },
};
</script>
显示 复制

# 表格动态合并

支持表格动态合并

an-table上配置merge,merge为一个包含需要合并的columnprop的数组,配置后会自动将值相同的项自动合并。

<template>
  <div>
    <an-table
      :column="tableData.column"
      :data="tableData.data"
      :merge="['name', 'proportion', 'material', 'value3']"
      border
    >
    </an-table>

    <an-table
      :column="tableData2.column"
      :data="tableData2.data"
      :merge="['name', 'proportion']"
      border
      style="margin-top: 20px"
    >
    </an-table>
  </div>
</template>

<script>
export default {
  data() {
    return {
      tableData: {
        column: [
          {
            prop: "name",
            label: "行业",
          },
          {
            prop: "proportion",
            label: "市场规模占比",
          },
          {
            prop: "material",
            label: "主原材料",
          },
          {
            prop: "value1",
            label: "最新价格",
          },
          {
            prop: "value2",
            label: "比年初",
          },
          {
            prop: "value3",
            label: "比上年同期",
          },
        ],
        data: [
          {
            name: " 氮肥、复合肥",
            proportion: "15.23%",
            material: "尿素",
            value1: "2.04",
            value2: "2.00%",
            value3: "	13.97%",
          },
          {
            name: " 氮肥、复合肥",
            proportion: "15.23%",
            material: "三元复合肥",
            value1: "2.74",
            value2: "0.37%",
            value3: "	2.24%",
          },
          {
            name: " 氮肥、复合肥",
            proportion: "15.23%",
            material: "三元复合肥",
            value1: "3.05",
            value2: "0.33%",
            value3: "	2.35%",
          },
          {
            name: " 种子生产",
            proportion: "6.83%",
            material: "玉米种子",
            value1: "24.3",
            value2: "-16.06%",
            value3: "	-5.70%",
          },
          {
            name: " 种子生产",
            proportion: "6.83%",
            material: "水稻种子",
            value1: "24.3",
            value2: "-16.06%",
            value3: "	-5.70%",
          },
        ],
      },
      tableData2: {
        column: [
          {
            prop: "name",
            label: "主要行业",
            width: "150",
          },
          {
            prop: "proportion",
            label: "市场规模占比",
            width: "150",
          },
          {
            prop: "indexName",
            label: "指标",
            width: "300",
          },
          {
            prop: "value1",
            label: "2018年",
          },
          {
            prop: "value2",
            label: "2017年",
          },
          {
            prop: "value3",
            label: "2016年",
          },
        ],
        data: [
          {
            name: "房地产(商业住宅)",
            proportion: "60%",
            indexName: "住宅房地产开发投资累计同比增速",
            value1: "13.6%",
            value2: "9.4%",
            value3: "6.4%",
          },
          {
            name: "房地产(商业住宅)",
            proportion: "60%",
            indexName: "商品房销售面积累计累计同比增速",
            value1: "2.9%",
            value2: "7.7%",
            value3: "22.5%",
          },
          {
            name: "建筑业(商业住宅)",
            proportion: "60%",
            indexName: "住宅房屋建筑竣工面积累计同比增长率",
            value1: "0.05%",
            value2: "0.93%",
            value3: "0.24%",
          },
          {
            name: "房地产(公共建筑)",
            proportion: "40%",
            indexName: "办公楼房地产开发投资完成额累计同比增速",
            value1: "-12%",
            value2: "3.5%",
            value3: "5.2%",
          },
          {
            name: "房地产(公共建筑)",
            proportion: "40%",
            indexName: "商业营业用房房地产开发投资累计同比增速",
            value1: "-9.4%",
            value2: "-1.2%",
            value3: "8.4%",
          },
          {
            name: "建筑业(公共建筑)",
            proportion: "40%",
            indexName: "办公用房竣工面积累计值(万平方米)",
            value1: "-8.06%",
            value2: "0.82%",
            value3: "6.46%",
          },
        ],
      },
    };
  },
};
</script>
显示 复制

# 其他

其他属性,事件与el-table (opens new window) 一致