Skip to content

前沿

组件思路

  1. 普通用法:就是和原来el-table一样,api基本一致,就是把本来绑定在el-table的属性绑定在此组件上,把本来绑定在el-table-column上的属性通过column属性以数组的形式传入,数组内每个对象对应着每一列的。el-table-column,如果需要使用页码参数其也内置了页码组件,可以直接传参生成。
  2. 表格内置 页码配置工具loading 相关配置请见文档。
  3. 自动请求用法:可以通过传api属性,开启自动请求功能。入口是一个方法,方法参数是请求参数,返回一个promise即可被api属性读取,配合一些其他扩展属性可以很好的实现组件自动请求,实现一个配置项完成整个表格业务功能。
  4. 其支持所有el-table属性,而且也有很强的扩展性,可以随意自定义插槽,render等,对于比较特殊的一些情况,比如插入并自定义某一整行。

例子

基础表格

基础的表格展示用法,当 el-table 元素中注入 data 对象数组后,在 column 中用 prop 属性来对应对象中的键名即可填入数据,用 label 属性来定义表格的列名。 可以使用 width 属性来定义列宽。

<template>
    <FpiElTable
        :column="column"
        :table-data="list"
        :page-params="pageParams"
    />
</template>

<script lang="ts" setup>
import { reactive, shallowRef } from 'vue'
import type { tableColumnTs } from '@ued_fpi/element-plus-expand/es/src/fpi-el-table/types'

const column = shallowRef<tableColumnTs[]>([
    {
        prop: 'date',
        label: '日期',
    },
    {
        prop: 'name',
        label: '名称',
    },
    {
        prop: 'address',
        label: '地址',
    },
])

const list = shallowRef([
    {
        date: '2016-05-03',
        name: 'Tom',
        address: 'No. 189, Grove St, Los Angeles',
    },
    {
        date: '2016-05-02',
        name: 'Tom',
        address: 'No. 189, Grove St, Los Angeles',
    },
    {
        date: '2016-05-04',
        name: 'Tom',
        address: 'No. 189, Grove St, Los Angeles',
    },
    {
        date: '2016-05-01',
        name: 'Tom',
        address: 'No. 189, Grove St, Los Angeles',
    },
])
const pageParams = reactive({
    currentPage: 1,
    total: list.value.length,
    pageSizes: 10,
})
</script>

显示代码

页码使用

is-show-page属性可以设置是否显示页码,默认为true,传入 pageParams 可以设置当前为第几页,总共多少页,以及页面size。
必须传入响应式对象,组件内部会动态监听此变量变更新;page-layout 属性设置显示的分页按钮; page-box-style 可以设置页面行的样式。 其他页面属性支持请点击查看 页码属性

<template>
    <FpiElTable
        :column="column"
        :table-data="list"
        :page-params="pageParams"
        :is-show-page="true"
        page-layout="total,sizes,prev, pager,next,jumper"
        :page-box-style="{ marginTop: '20px' }"
    />
</template>

<script lang="ts" setup>
import type { tableColumnTs } from '@ued_fpi/element-plus-expand/es/src/fpi-el-table/types'

import { reactive, shallowRef } from 'vue'

const column: tableColumnTs[] = [
    {
        prop: 'date',
        label: '日期',
    },
    {
        prop: 'name',
        label: '名称',
    },
    {
        prop: 'address',
        label: '地址',
    },
]

const list = shallowRef([
    {
        date: '2016-05-03',
        name: 'Tom',
        address: 'No. 189, Grove St, Los Angeles',
    },
    {
        date: '2016-05-02',
        name: 'Tom',
        address: 'No. 189, Grove St, Los Angeles',
    },
    {
        date: '2016-05-04',
        name: 'Tom',
        address: 'No. 189, Grove St, Los Angeles',
    },
    {
        date: '2016-05-01',
        name: 'Tom',
        address: 'No. 189, Grove St, Los Angeles',
    },
])
const pageParams = reactive({
    currentPage: 1,
    total: list.value.length,
    pageSizes: 10,
})
</script>

显示代码

带斑马纹表格

使用带斑马纹的表格,可以更容易区分出不同行的数据。

stripe 可以创建带斑马纹的表格。 如果 true, 表格将会带有斑马纹。

<template>
    <FpiElTable
        :column="column"
        :table-data="list"
        stripe
        :page-params="pageParams"
        :is-show-page="false"
        @page-change="pageChange"
    />
</template>

<script lang="ts" setup>
import { reactive, shallowRef } from 'vue'
import type { tableColumnTs } from '@ued_fpi/element-plus-expand/es/src/fpi-el-table/types'

const column = shallowRef<tableColumnTs[]>([
    {
        prop: 'date',
        label: '日期',
    },
    {
        prop: 'name',
        label: '名称',
    },
    {
        prop: 'address',
        label: '地址',
    },
])

const pageParams = reactive({
    currentPage: 1,
    total: 0,
    pageSizes: 10,
})
const list = shallowRef([
    {
        date: '2016-05-03',
        name: 'Tom',
        address: 'No. 189, Grove St, Los Angeles',
    },
    {
        date: '2016-05-02',
        name: 'Tom',
        address: 'No. 189, Grove St, Los Angeles',
    },
    {
        date: '2016-05-04',
        name: 'Tom',
        address: 'No. 189, Grove St, Los Angeles',
    },
    {
        date: '2016-05-01',
        name: 'Tom',
        address: 'No. 189, Grove St, Los Angeles',
    },
])

// 必须按照这三个变量名写
const pageChange = (pageObj: {
    currentPage: number
    total: number
    pageSizes: number
}) => {
    pageParams.pageSizes = pageObj.pageSizes
    pageParams.currentPage = pageObj.currentPage
}
</script>

显示代码

带边框表格

默认情况下,Table 组件是不具有竖直方向的边框的, 如果需要,可以使用 border 属性,把该属性设置为 true 即可启用。

<!--
 * @Author: mjh
 * @Date: 2023-03-26 22:39:25
 * @LastEditors: mjh
 * @LastEditTime: 2023-04-22 23:38:17
 * @Description:
-->
<template>
    <FpiElTable
        :column="column"
        :table-data="list"
        :is-show-page="false"
        border
    />
</template>

<script lang="ts" setup>
import { shallowRef } from 'vue'
import type { tableColumnTs } from '@ued_fpi/element-plus-expand/es/src/fpi-el-table/types'
const column: any = shallowRef<tableColumnTs[]>([

    {
        prop: 'date',
        label: '日期',
    },
    {
        prop: 'name',
        label: '名称',
    },
    {
        prop: 'address',
        label: '地址',
    },
])

const list = shallowRef([
    {
        date: '2016-05-03',
        name: 'Tom',
        address: 'No. 189, Grove St, Los Angeles',
    },
    {
        date: '2016-05-02',
        name: 'Tom',
        address: 'No. 189, Grove St, Los Angeles',
    },
    {
        date: '2016-05-04',
        name: 'Tom',
        address: 'No. 189, Grove St, Los Angeles',
    },
    {
        date: '2016-05-01',
        name: 'Tom',
        address: 'No. 189, Grove St, Los Angeles',
    },
])
</script>

显示代码

固定表头

纵向内容过多时,可选择固定表头。

只要在 el-table 元素中定义了 height 属性,即可实现固定表头的表格,而不需要额外的代码。

<!--
 * @Author: mjh
 * @Date: 2023-03-26 22:41:06
 * @LastEditors: mjh
 * @LastEditTime: 2023-04-23 10:25:24
 * @Description:
-->
<template>
    <FpiElTable
        :column="column"
        :table-data="list"
        height="300"
    />
</template>

<script lang="ts" setup>
import { reactive, shallowRef } from 'vue'
import type { tableColumnTs } from '@ued_fpi/element-plus-expand/es/src/fpi-el-table/types'

const column: any = shallowRef<tableColumnTs[]>([

    {
        prop: 'date',
        label: '日期',
    },
    {
        prop: 'name',
        label: '名称',
    },
    {
        prop: 'address',
        label: '地址',
    },
])
const list = shallowRef([
    {
        date: '2016-05-03',
        name: 'Tom',
        address: 'No. 189, Grove St, Los Angeles',
    },
    {
        date: '2016-05-02',
        name: 'Tom',
        address: 'No. 189, Grove St, Los Angeles',
    },
    {
        date: '2016-05-04',
        name: 'Tom',
        address: 'No. 189, Grove St, Los Angeles',
    },
    {
        date: '2016-05-01',
        name: 'Tom',
        address: 'No. 189, Grove St, Los Angeles',
    },
    {
        date: '2016-05-08',
        name: 'Tom',
        address: 'No. 189, Grove St, Los Angeles',
    },
    {
        date: '2016-05-06',
        name: 'Tom',
        address: 'No. 189, Grove St, Los Angeles',
    },
    {
        date: '2016-05-07',
        name: 'Tom',
        address: 'No. 189, Grove St, Los Angeles',
    },
])
</script>
显示代码

固定列

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

固定列需要在 column使用 fixed 属性,它接受 Boolean 值。 如果为 true, 列将被左侧固定. 它还接受传入字符串,leftright,表示左边固定还是右边固定。

<!--
 * @Author: mjh
 * @Date: 2023-04-11 11:08:41
 * @LastEditors: mjh
 * @LastEditTime: 2023-04-22 23:37:40
 * @Description:
-->
<template>
    <FpiElTable
        :column="column"
        :table-data="list"
        :is-show-page="false"
    />
</template>

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

import type { tableColumnTs } from '@ued_fpi/element-plus-expand/es/src/fpi-el-table/types'

const column: any = shallowRef<tableColumnTs[]>([

    {
        prop: 'date',
        label: '日期',
        fixed: true,
        width: '150'
    },
    {
        prop: 'name',
        label: '名称',
        width: '120'
    },
    {
        prop: 'name',
        label: '名称',
        width: '120'
    },
    {
        prop: 'state',
        label: '状态',
        width: '120',
        fixed: 'right'
    },
    {
        prop: 'address',
        label: 'Address',
        width: '600',
    },
    {
        prop: 'city',
        label: 'City',
        width: '120',
    },
])

const list = shallowRef([
    {
        date: '2016-05-03',
        name: 'Tom',
        state: 'California',
        city: 'Los Angeles',
        address: 'No. 189, Grove St, Los Angeles',
        zip: 'CA 90036',
        tag: 'Home',
    },
    {
        date: '2016-05-02',
        name: 'Tom',
        state: 'California',
        city: 'Los Angeles',
        address: 'No. 189, Grove St, Los Angeles',
        zip: 'CA 90036',
        tag: 'Office',
    },
    {
        date: '2016-05-04',
        name: 'Tom',
        state: 'California',
        city: 'Los Angeles',
        address: 'No. 189, Grove St, Los Angeles',
        zip: 'CA 90036',
        tag: 'Home',
    },
    {
        date: '2016-05-01',
        name: 'Tom',
        state: 'California',
        city: 'Los Angeles',
        address: 'No. 189, Grove St, Los Angeles',
        zip: 'CA 90036',
        tag: 'Office',
    },
    {
        date: '2016-05-01',
        name: 'Tom',
        state: 'California',
        city: 'Los Angeles',
        address: 'No. 189, Grove St, Los Angeles',
        zip: 'CA 90036',
        tag: 'Office',
    },
])
</script>
显示代码

固定列和表头

当您有大量数据块放入表中,您可以同时固定表头和列。

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

<template>
    <FpiElTable
        :column="column"
        :table-data="list"
        height="250"
        :is-show-page="false"
    />
</template>

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

import type { tableColumnTs } from '@ued_fpi/element-plus-expand/es/src/fpi-el-table/types'

const column: any = shallowRef<tableColumnTs[]>([

    {
        prop: 'date',
        label: '日期',
        fixed: true,
        width: '150'
    },
    {
        prop: 'name',
        label: '名称',
        width: '120'
    },
    {
        prop: 'name',
        label: '名称',
        width: '120'
    },
    {
        prop: 'state',
        label: '状态',
        width: '120',
        fixed: 'right'
    },
    {
        prop: 'address',
        label: 'Address',
        width: '600',
    },
    {
        prop: 'city',
        label: 'City',
        width: '120',
    },
])

const list = shallowRef([
    {
        date: '2016-05-03',
        name: 'Tom',
        state: 'California',
        city: 'Los Angeles',
        address: 'No. 189, Grove St, Los Angeles',
        zip: 'CA 90036',
        tag: 'Home',
    },
    {
        date: '2016-05-02',
        name: 'Tom',
        state: 'California',
        city: 'Los Angeles',
        address: 'No. 189, Grove St, Los Angeles',
        zip: 'CA 90036',
        tag: 'Office',
    },
    {
        date: '2016-05-02',
        name: 'Tom',
        state: 'California',
        city: 'Los Angeles',
        address: 'No. 189, Grove St, Los Angeles',
        zip: 'CA 90036',
        tag: 'Office',
    },
    {
        date: '2016-05-02',
        name: 'Tom',
        state: 'California',
        city: 'Los Angeles',
        address: 'No. 189, Grove St, Los Angeles',
        zip: 'CA 90036',
        tag: 'Office',
    },
    {
        date: '2016-05-02',
        name: 'Tom',
        state: 'California',
        city: 'Los Angeles',
        address: 'No. 189, Grove St, Los Angeles',
        zip: 'CA 90036',
        tag: 'Office',
    },
    {
        date: '2016-05-02',
        name: 'Tom',
        state: 'California',
        city: 'Los Angeles',
        address: 'No. 189, Grove St, Los Angeles',
        zip: 'CA 90036',
        tag: 'Office',
    },
    {
        date: '2016-05-02',
        name: 'Tom',
        state: 'California',
        city: 'Los Angeles',
        address: 'No. 189, Grove St, Los Angeles',
        zip: 'CA 90036',
        tag: 'Office',
    },
    {
        date: '2016-05-04',
        name: 'Tom',
        state: 'California',
        city: 'Los Angeles',
        address: 'No. 189, Grove St, Los Angeles',
        zip: 'CA 90036',
        tag: 'Home',
    },
    {
        date: '2016-05-01',
        name: 'Tom',
        state: 'California',
        city: 'Los Angeles',
        address: 'No. 189, Grove St, Los Angeles',
        zip: 'CA 90036',
        tag: 'Office',
    },
    {
        date: '2016-05-01',
        name: 'Tom',
        state: 'California',
        city: 'Los Angeles',
        address: 'No. 189, Grove St, Los Angeles',
        zip: 'CA 90036',
        tag: 'Office',
    },
])
</script>
显示代码

流体高度

当数据量动态变化时,可以为 Table 设置一个最大高度。

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

<!--
 * @Author: mjh
 * @Date: 2023-04-11 11:08:41
 * @LastEditors: mjh
 * @LastEditTime: 2023-04-22 23:38:41
 * @Description:
-->
<template>
    <FpiElTable
        :column="column"
        :table-data="tableData"
        max-height="320"
        :is-show-page="false"
    />
    <el-button class="mt-4" style="width: 100%;" @click="onAddItem">
        Add Item
    </el-button>
</template>

<script lang="ts" setup>
import { ref, shallowRef } from 'vue'
import type { tableColumnTs } from '@ued_fpi/element-plus-expand/es/src/fpi-el-table/types'

const tableData = ref([
    {
        date: '2016-05-01',
        name: 'Tom',
        state: 'California',
        city: 'Los Angeles',
        address: 'No. 189, Grove St, Los Angeles',
        zip: 'CA 90036',
    },
    {
        date: '2016-05-02',
        name: 'Tom',
        state: 'California',
        city: 'Los Angeles',
        address: 'No. 189, Grove St, Los Angeles',
        zip: 'CA 90036',
    },
    {
        date: '2016-05-03',
        name: 'Tom',
        state: 'California',
        city: 'Los Angeles',
        address: 'No. 189, Grove St, Los Angeles',
        zip: 'CA 90036',
    },
])

const column: any = shallowRef<tableColumnTs[]>([

    {
        prop: 'date',
        label: '日期',
    },
    {
        prop: 'name',
        label: '名称',
    },
    {
        prop: 'address',
        label: '地址',
    },
    {
        prop: 'name',
        label: '操作',
        align: 'center',
        type: 'tools',
        toolsStyle: () => {
            return {
                width: '30%',
                margin: '0 auto'
            }
        },
        toolsArr: [
            {
                label: '删除',
                click: (row: Record<string, any>, index: number) => {
                    tableData.value.splice(index, 1)
                }
            }
        ]
    }
])

const onAddItem = () => {
    tableData.value.push({
        date: '2020-10-10',
        name: 'Tom',
        state: 'California',
        city: 'Los Angeles',
        address: 'No. 189, Grove St, Los Angeles',
        zip: 'CA 90036',
    })
}
</script>
显示代码

多级表头

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

只需要将column 放置于column 的对象中,你可以实现组头。

<template>
    <FpiElTable
        :column="column"
        :table-data="tableData"
        :is-show-page="false"
    />
</template>

<script lang="ts" setup>
import { shallowRef } from 'vue'
import type { tableColumnTs } from '@ued_fpi/element-plus-expand/es/src/fpi-el-table/types'

const column: any = shallowRef<tableColumnTs[]>([
    {
        prop: 'date',
        label: '日期',
        width: '150'
    },
    {
        label: 'Delivery Info',
        column: [
            {
                prop: 'name',
                label: '名称',
                width: '120'
            },
            {
                label: 'Address Info',
                column: [
                    {
                        prop: 'name',
                        label: '名称',
                        width: '120'
                    },
                    {
                        prop: 'state',
                        label: '状态',
                        width: '120',
                    },
                    {
                        prop: 'city',
                        label: 'City',
                        width: '120',
                    },
                ]
            },
        ]
    }
])

const tableData = [
    {
        date: '2016-05-04',
        name: 'Tom',
        state: 'California',
        city: 'Los Angeles',
        address: 'No. 189, Grove St, Los Angeles',
        zip: 'CA 90036',
    },
    {
        date: '2016-05-01',
        name: 'Tom',
        state: 'California',
        city: 'Los Angeles',
        address: 'No. 189, Grove St, Los Angeles',
        zip: 'CA 90036',
    },
    {
        date: '2016-05-08',
        name: 'Tom',
        state: 'California',
        city: 'Los Angeles',
        address: 'No. 189, Grove St, Los Angeles',
        zip: 'CA 90036',
    },
    {
        date: '2016-05-06',
        name: 'Tom',
        state: 'California',
        city: 'Los Angeles',
        address: 'No. 189, Grove St, Los Angeles',
        zip: 'CA 90036',
    },
    {
        date: '2016-05-07',
        name: 'Tom',
        state: 'California',
        city: 'Los Angeles',
        address: 'No. 189, Grove St, Los Angeles',
        zip: 'CA 90036',
    },
]
</script>
显示代码

单选,多选

你也可以选择多行。

单选:设置 highlight-current-row 属性就可以实现单选高亮;
实现多选非常简单: 手动添加一个 column 内的对象,设 type 属性为 selection 即可;
除了多选,这里还使用到了 show-overflow-tooltip属性。 默认情况下,如果单元格内容过长,会占用多行显示。 若需要单行显示可以使用 show-overflow-tooltip 属性,它接受一个 Boolean,true 时多余的内容会在 hover 时以 tooltip 的形式显示出来。

<!--
 * @Author: mjh
 * @Date: 2023-04-03 22:05:09
 * @LastEditors: mjh
 * @LastEditTime: 2023-04-03 22:22:29
 * @Description:
-->
<template>
    <FpiElTable
        :ref="(el:any) => fpiElTableDom = el"
        :column="column"
        :table-data="tableData"
        :is-show-page="false"
        highlight-current-row
        @current-change="handleCurrentChange"
        @selection-change="handleSelectionChange"
    />
    <div style="margin-top: 20px;">
        <el-button size="small" @click="setCurrent(1)">
            单选选中第二行
        </el-button>
        <el-button size="small" @click="setCurrent()">
            清除单选
        </el-button>
        <el-button size="small" @click="toggleSelection([1, 2])">
            复选选中第二三行
        </el-button>
        <el-button size="small" @click="toggleSelection()">
            清除复选
        </el-button>
        <el-button size="small" @click="toggleSelection('all')">
            复选全选或全不选
        </el-button>
    </div>
</template>

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

import type { tableColumnTs } from '@ued_fpi/element-plus-expand/es/src/fpi-el-table/types'

const column: any = shallowRef<tableColumnTs[]>([

    {
        type: 'selection',
        width: '55',
    },
    {
        prop: 'date',
        width: '120',
        label: 'Date',
    },
    {
        prop: 'date',
        width: '120',
        label: 'Date',
    },
    {
        prop: 'name',
        label: 'Name',
        width: '120'
    },
    {
        prop: 'address',
        label: 'Address',
        showOverflowTooltip: true
    },

])

interface User {
  date: string
  name: string
  address: string
}

const fpiElTableDom = ref<any>()

// 单选设置点击选中
// 静态数据模式时只支持number
const setCurrent = (row?: any | number) => {
    fpiElTableDom.value && fpiElTableDom.value.setCurrentRow(row)
}

/**
 * @desc 复选框手动调用方法
 * @param rows  undefined 清除选中  'all' 全选获不全选会自动取反
 * rows传数组 可以是对应的对象(静态模式不可用对象)也可以是对应的index(0开始)选中对应列
 */
const toggleSelection = (rows?: any[] | 'all') => {
    fpiElTableDom.value && fpiElTableDom.value.toggleSelection(rows)
}

// 单选点击回调
const handleCurrentChange = (val: any | undefined, old: any) => {
    console.log('此次单选选中:', val, '上次单选选中:', old, '单选')
}
// 多选点击回调
const handleSelectionChange = (val: any[]) => {
    console.log(val, '复选')
}

const tableData: User[] = [
    {
        date: '2016-05-03',
        name: 'Tom',
        address: 'No. 189, Grove St, Los Angeles',
    },
    {
        date: '2016-05-02',
        name: 'Tom',
        address: 'No. 189, Grove St, Los Angeles',
    },
    {
        date: '2016-05-04',
        name: 'Tom',
        address: 'No. 189, Grove St, Los Angeles',
    },
    {
        date: '2016-05-01',
        name: 'Tom',
        address: 'No. 189, Grove St, Los Angeles',
    },
    {
        date: '2016-05-08',
        name: 'Tom',
        address: 'No. 189, Grove St, Los Angeles',
    },
    {
        date: '2016-05-06',
        name: 'Tom',
        address: 'No. 189, Grove St, Los Angeles',
    },
    {
        date: '2016-05-07',
        name: 'Tom',
        address: 'No. 189, Grove St, Los Angeles',
    },
]
</script>
显示代码

排序

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

在列中设置 sortable 属性即可实现以该列为基准的排序, 接受一个 Boolean,默认为 false。 可以通过 Table 的 defaultSort 属性设置默认的排序列和排序顺序。 可以使用 sortMethod 或者 sort-by 使用自定义的排序规则。 如果需要后端排序,需将 sortable 设置为 custom,同时在 Table 上监听 sort-change 事件, 在事件回调中可以获取当前排序的字段名和排序顺序,从而向接口请求排序后的表格数据。 在本例中,我们还使用了 formatter 属性,它用于格式化指定列的值, 接受一个 Function,会传入两个参数:rowcolumn, 可以根据自己的需求进行处理。
插槽: 设置isSlottrue 就可以开启此列的插槽模式,插槽的名称就是 prop 属性的值

<template>
    <el-button @click="resetDateFilter">
        reset date filter
    </el-button>
    <el-button @click="clearFilter">
        reset all filters
    </el-button>
    <FpiElTable
        :ref="(el:any) => fpiElTableDom = el"
        :column="column"
        row-key="date"
        style="margin-top: 10px;"
        :table-data="tableData"
        :is-show-page="false"
    >
        <template #tag="{ scope }">
            <el-tag
                :type="scope.row.tag === 'Home' ? '' : 'success'"
                disable-transitions
            >
                {{ scope.row.tag }}
            </el-tag>
        </template>
    </FpiElTable>
</template>

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

import type { tableColumnTs } from '@ued_fpi/element-plus-expand/es/src/fpi-el-table/types'

interface User {
  date: string
  name: string
  address: string
  tag: string
}

const filterHandler = (
    value: string,
    row: User,
    column: any
) => {
    const property: keyof User = column.property
    return row[property] === value
}

const formatter = (row: User, column: any) => {
    return row.address
}

const filterTag = (value: string, row: User) => {
    return row.tag === value
}

const column: any = shallowRef<tableColumnTs[]>([

    {
        prop: 'date',
        width: '180',
        label: 'Date',
        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: filterHandler
    },

    {
        prop: 'name',
        label: 'Name',
        width: '180'
    },
    {
        prop: 'address',
        label: 'Address',
        formatter
    },
    {
        prop: 'tag',
        label: 'Tag',
        width: '100',
        filters: [
            { text: 'Home', value: 'Home' },
            { text: 'Office', value: 'Office' },
        ],
        filterMethod: filterTag,
        filterPlacement: 'bottom-end',
        isSlot: true
    },

])

const fpiElTableDom = ref<any>()

const resetDateFilter = () => {
  fpiElTableDom.value!.clearFilter(['date'])
}
// TODO: improvement typing when refactor table
const clearFilter = () => {
  fpiElTableDom.value!.clearFilter()
}

const tableData: User[] = [
    {
        date: '2016-05-03',
        name: 'Tom',
        address: 'No. 189, Grove St, Los Angeles',
        tag: 'Home',
    },
    {
        date: '2016-05-02',
        name: 'Tom',
        address: 'No. 189, Grove St, Los Angeles',
        tag: 'Office',
    },
    {
        date: '2016-05-04',
        name: 'Tom',
        address: 'No. 189, Grove St, Los Angeles',
        tag: 'Home',
    },
    {
        date: '2016-05-01',
        name: 'Tom',
        address: 'No. 189, Grove St, Los Angeles',
        tag: 'Office',
    },
]
</script>
显示代码

树形数据与懒加载

支持树类型的数据的显示。 当 row 中包含 children 字段时,被视为树形数据。 渲染嵌套数据需要 proprow-key。 此外,子行数据可以异步加载。 设置 Tablelazy属性为 true 与加载函数 load 。 通过指定 row 中的hasChildren字段来指定哪些行是包含子节点。 childrenhasChildren都可以通过 tree-props 配置。

<template>
    <FpiElTable
        :ref="(el:any) => data.fpiElTableDom = el"
        :column="column"
        style="width: 100%;
        margin-bottom: 20px;"
        :table-data="tableData"
        :page-params="pageParams"
        row-key="id"
        :is-show-page="false"
        max-height="250"
        @page-change="pageChange"
    />
    <FpiElTable
        :column="column"
        style="width: 100%;"
        :table-data="tableData1"
        :page-params="pageParams"
        row-key="id"
        max-height="250"
        :is-show-page="false"
        lazy
        :load="load"
        :tree-props="{ children: 'children', hasChildren: 'hasChildren' }"
        @page-change="pageChange"
    />
</template>

<script lang="ts" setup>
import { onMounted, reactive, ref, toRefs } from 'vue'
import type { tableColumnTs } from '@ued_fpi/element-plus-expand/es/src/fpi-el-table/types'

interface User {
    id: number
    date: string
    name: string
    hasChildren?: boolean
    children?: User[]
}

const data = reactive({
    column: [
        {
            type: 'index',
            label: '序号',
            width: '60',
        },
        {
            prop: 'date',
            label: 'date',
        },
        {
            prop: 'name',
            label: 'Name',
        }
    ] as tableColumnTs[],
    pageParams: {
        currentPage: 1,
        total: 0,
        pageSizes: 10,
    },
    // dom 节点
    fpiElTableDom: ref(),
    tableData: [
        {
            id: 1,
            date: '2016-05-02',
            name: 'wangxiaohu',
        },
        {
            id: 2,
            date: '2016-05-04',
            name: 'wangxiaohu',
        },
        {
            id: 3,
            date: '2016-05-01',
            name: 'wangxiaohu',
            children: [
                {
                    id: 31,
                    date: '2016-05-01',
                    name: 'wangxiaohu',
                },
                {
                    id: 32,
                    date: '2016-05-01',
                    name: 'wangxiaohu',
                },
            ],
        },
        {
            id: 4,
            date: '2016-05-03',
            name: 'wangxiaohu',
        }
    ],
    tableData1: [
        {
            id: 1,
            date: '2016-05-02',
            name: 'wangxiaohu',
        },
        {
            id: 2,
            date: '2016-05-04',
            name: 'wangxiaohu',
        },
        {
            id: 3,
            date: '2016-05-01',
            name: 'wangxiaohu',
            hasChildren: true,
        },
        {
            id: 4,
            date: '2016-05-03',
            name: 'wangxiaohu',
        },
    ]
})
onMounted(() => {
    // 还可以使用此方法设置展开行
    data.fpiElTableDom.toggleRowExpansion(data.tableData[2], true)
})
const load = (
    row: any,
    treeNode: unknown,
    resolve: (date: User[]) => void
) => {
    setTimeout(() => {
        resolve([
            {
                id: 31,
                date: '2016-05-01',
                name: 'wangxiaohu',
            },
            {
                id: 32,
                date: '2016-05-01',
                name: 'wangxiaohu',
            },
        ])
    }, 1000)
}
// 必须按照这三个变量名写
const pageChange = (pageObj: {
    currentPage: number
    total: number
    pageSizes: number
}) => {
    data.pageParams.pageSizes = pageObj.pageSizes
    data.pageParams.currentPage = pageObj.currentPage
    // getData()
}
const { column, pageParams, tableData, tableData1 } = toRefs(data)
</script>

显示代码

表尾合计行

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

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

<template>
    <FpiElTable
        border
        :column="column1"
        :table-data="tableData"
        show-summary
        :is-show-page="false"
        style="width: 100%;"
    />

    <FpiElTable
        border
        :column="column2"
        :is-show-page="false"
        :table-data="tableData"
        height="200"
        :summary-method="getSummaries"
        show-summary
        style="width: 100%; margin-top: 20px;"
    />
</template>

<script lang="ts" setup>
import { shallowRef } from 'vue'
import type { tableColumnTs } from '@ued_fpi/element-plus-expand/es/src/fpi-el-table/types'

interface Product {
  id: string
  name: string
  amount1: string
  amount2: string
  amount3: number
}

interface SummaryMethodProps<T = Product> {
  columns: any[]
  data: T[]
}
const column1: any = shallowRef<tableColumnTs[]>([
    {
        prop: 'id',
        width: '150',
        label: 'ID',
        columnKey: 'date',
    },

    {
        prop: 'name',
        label: 'Name',
    },
    {
        prop: 'amount1',
        label: 'Amount 1',
        sortable: true
    },
    {
        prop: 'amount2',
        label: 'Amount 2',
        sortable: true
    },
    {
        prop: 'amount3',
        label: 'Amount 3',
        sortable: true
    },
])

const column2: any = shallowRef([
    {
        prop: 'id',
        width: '150',
        label: 'ID',
        columnKey: 'date',
    },

    {
        prop: 'name',
        label: 'Name',
    },
    {
        prop: 'amount1',
        label: 'Cost 1 ($)',
    },
    {
        prop: 'amount2',
        label: 'Cost 2 ($)',
    },
    {
        prop: 'amount3',
        label: 'Cost 3 ($)',
    },
])

const getSummaries = (param: SummaryMethodProps) => {
    const { columns, data } = param
    const sums: string[] = []
    columns.forEach((column, index) => {
        if (index === 0) {
            sums[index] = 'Total Cost'
            return
        }
        const values = data.map((item: any) => Number(item[column.property]))
        if (!values.every(value => Number.isNaN(value))) {
            sums[index] = `$ ${values.reduce((prev, curr) => {
                const value = Number(curr)
                if (!Number.isNaN(value))
                    return prev + curr

                else
                    return prev
            }, 0)}`
        }
        else {
            sums[index] = 'N/A'
        }
    })

    return sums
}

const tableData: Product[] = [
    {
        id: '12987122',
        name: 'Tom',
        amount1: '234',
        amount2: '3.2',
        amount3: 10,
    },
    {
        id: '12987123',
        name: 'Tom',
        amount1: '165',
        amount2: '4.43',
        amount3: 12,
    },
    {
        id: '12987124',
        name: 'Tom',
        amount1: '324',
        amount2: '1.9',
        amount3: 9,
    },
    {
        id: '12987125',
        name: 'Tom',
        amount1: '621',
        amount2: '2.2',
        amount3: 17,
    },
    {
        id: '12987126',
        name: 'Tom',
        amount1: '539',
        amount2: '4.1',
        amount3: 15,
    },
]
</script>
显示代码

合并行或列

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

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

<template>
    <div>
        <FpiElTable
            :column="column"
            :table-data="tableData"
            :is-show-page="false"
            :span-method="arraySpanMethod"
            style="width: 100%;"
        />

        <FpiElTable
            :column="column"
            :is-show-page="false"
            :table-data="tableData"
            height="200"
            :span-method="objectSpanMethod"
            style="width: 100%; margin-top: 20px;"
        />
    </div>
</template>

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

import type { tableColumnTs } from '@ued_fpi/element-plus-expand/es/src/fpi-el-table/types'

interface User {
  id: string
  name: string
  amount1: string
  amount2: string
  amount3: number
}

interface SpanMethodProps {
  row: User
  column: any
  rowIndex: number
  columnIndex: number
}

const column: any = shallowRef<tableColumnTs[]>([

    {
        prop: 'id',
        width: '150',
        label: 'ID',
        columnKey: 'date',
    },

    {
        prop: 'name',
        label: 'Name',
    },
    {
        prop: 'amount1',
        label: 'Amount 1',
        sortable: true
    },
    {
        prop: 'amount2',
        label: 'Amount 2',
        sortable: true
    },
    {
        prop: 'amount3',
        label: 'Amount 3',
        sortable: true
    },
])

const arraySpanMethod = ({
    row,
    column,
    rowIndex,
    columnIndex,
}: SpanMethodProps) => {
    if (rowIndex % 2 === 0) {
        if (columnIndex === 0)
            return [1, 2]

        else if (columnIndex === 1)
            return [0, 0]
    }
}

const objectSpanMethod = ({
    row,
    column,
    rowIndex,
    columnIndex,
}: SpanMethodProps) => {
    if (columnIndex === 0) {
        if (rowIndex % 2 === 0) {
            return {
                rowspan: 2,
                colspan: 1,
            }
        }
        else {
            return {
                rowspan: 0,
                colspan: 0,
            }
        }
    }
}

const tableData: User[] = [
    {
        id: '12987122',
        name: 'Tom',
        amount1: '234',
        amount2: '3.2',
        amount3: 10,
    },
    {
        id: '12987123',
        name: 'Tom',
        amount1: '165',
        amount2: '4.43',
        amount3: 12,
    },
    {
        id: '12987124',
        name: 'Tom',
        amount1: '324',
        amount2: '1.9',
        amount3: 9,
    },
    {
        id: '12987125',
        name: 'Tom',
        amount1: '621',
        amount2: '2.2',
        amount3: 17,
    },
    {
        id: '12987126',
        name: 'Tom',
        amount1: '539',
        amount2: '4.1',
        amount3: 15,
    },
]
</script>
显示代码

自定义索引

自定义 type=index 列的行号。

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

<!--
 * @Author: mjh
 * @Date: 2023-04-11 11:08:41
 * @LastEditors: mjh
 * @LastEditTime: 2023-04-22 23:48:43
 * @Description:
-->
<template>
    <FpiElTable
        :column="column"
        :table-data="tableData"
        :is-show-page="false"
        style="width: 100%;"
    />
</template>

<script lang="ts" setup>
import type { tableColumnTs } from '@ued_fpi/element-plus-expand/es/src/fpi-el-table/types'
const indexMethod = (index: number) => {
    return index * 2
}

const column: tableColumnTs[] = [
    {
        type: 'index',
        label: '序号',
        width: '60',
        index: indexMethod
    },
    {
        prop: 'date',
        label: 'Date',
        width: '180'
    },
    {
        prop: 'name',
        label: 'Name',
        width: '180'
    },
    {
        prop: 'address',
        label: 'Address',
    },
]

const tableData = [
    {
        date: '2016-05-03',
        name: 'Tom',
        state: 'California',
        city: 'Los Angeles',
        address: 'No. 189, Grove St, Los Angeles',
        zip: 'CA 90036',
        tag: 'Home',
    },
    {
        date: '2016-05-02',
        name: 'Tom',
        state: 'California',
        city: 'Los Angeles',
        address: 'No. 189, Grove St, Los Angeles',
        zip: 'CA 90036',
        tag: 'Office',
    },
    {
        date: '2016-05-04',
        name: 'Tom',
        state: 'California',
        city: 'Los Angeles',
        address: 'No. 189, Grove St, Los Angeles',
        zip: 'CA 90036',
        tag: 'Home',
    },
    {
        date: '2016-05-01',
        name: 'Tom',
        state: 'California',
        city: 'Los Angeles',
        address: 'No. 189, Grove St, Los Angeles',
        zip: 'CA 90036',
        tag: 'Office',
    },
]
</script>
显示代码

配置工具

column内定义 typetools 可以自定义工具列。

toolsArr 数组内每一个对象代表工具列内部的按钮,对象内 label 代表文字,click 点击事件 toolsStyle 可以定义整个工具类的样式

<template>
    <FpiElTable
        :column="column"
        :table-data="tableData"
        :is-show-page="false"
        style="width: 100%;"
    />
</template>

<script lang="ts" setup>
import type { tableColumnTs } from '@ued_fpi/element-plus-expand/es/src/fpi-el-table/types'

const column: tableColumnTs[] = [
    {
        type: 'index',
        label: '序号',
        width: '60',
    },
    {
        prop: 'date',
        label: 'Date',
        width: '180'
    },
    {
        prop: 'name',
        label: 'Name',
        width: '180'
    },
    {
        label: '操作',
        align: 'center',
        type: 'tools',
        toolsStyle: () => {
            return {
                width: '70%',
                margin: '0 auto'
            }
        },
        toolsArr: [
            {
                label: '查看',
                click: (row: Record<string, any>, index: number) => {
                    console.log(row, index, '查看')
                }
            },
            {
                label: '编辑',
                click: (row: Record<string, any>, index: number) => {
                    console.log(row, index, '编辑')
                }
            },
            {
                label: '删除',
                style: () => {
                    return {
                        color: '#FF0200'
                    }
                },
                click: (row: Record<string, any>, index: number) => {
                    console.log(row, index, '删除')
                }
            }
        ]
    },
]

const tableData = [
    {
        date: '2016-05-03',
        name: 'Tom',
        state: 'California',
        city: 'Los Angeles',
        address: 'No. 189, Grove St, Los Angeles',
        zip: 'CA 90036',
        tag: 'Home',
    },
    {
        date: '2016-05-02',
        name: 'Tom',
        state: 'California',
        city: 'Los Angeles',
        address: 'No. 189, Grove St, Los Angeles',
        zip: 'CA 90036',
        tag: 'Office',
    },
    {
        date: '2016-05-04',
        name: 'Tom',
        state: 'California',
        city: 'Los Angeles',
        address: 'No. 189, Grove St, Los Angeles',
        zip: 'CA 90036',
        tag: 'Home',
    },
    {
        date: '2016-05-01',
        name: 'Tom',
        state: 'California',
        city: 'Los Angeles',
        address: 'No. 189, Grove St, Los Angeles',
        zip: 'CA 90036',
        tag: 'Office',
    },
]
</script>
显示代码

自定义整列

arraySpanMethod 方法可以自由自定义整列。

<template>
    <FpiElTable
        :column="columns"
        :table-data="tableData"
        :is-show-page="false"
        :span-method="arraySpanMethod"
        style="width: 100%;"
    >
        <template #state="props">
            <div>
                <span v-if="props.scope.row.isLineDiy">这是一个自定义的列----------------------</span>
                <span v-else>{{ props.scope.row.state }}</span>
            </div>
        </template>
    </FpiElTable>
</template>

<script lang="ts" setup>
import type { SpanMethodProps, tableColumnTs } from '@ued_fpi/element-plus-expand/es/src/fpi-el-table/types'

const columns: Array<tableColumnTs> = [
    {
        prop: 'state',
        label: '状态',
        width: '100',
        isSlot: true,
    },
    {
        prop: 'date',
        label: 'Date',
        width: '180'
    },
    {
        prop: 'name',
        label: 'Name',
        width: '180'
    },
    {
        prop: 'address',
        label: 'Address',
    },
]

const tableData = [
    {
        date: '2016-05-03',
        name: 'Tom',
        state: 'California',
        city: 'Los Angeles',
        address: 'No. 189, Grove St, Los Angeles',
        zip: 'CA 90036',
        tag: 'Home',
    },
    {
        date: '2016-05-02',
        name: 'Tom',
        state: 'California',
        city: 'Los Angeles',
        address: 'No. 189, Grove St, Los Angeles',
        zip: 'CA 90036',
        tag: 'Office',
        isLineDiy: true
    },
    {
        date: '2016-05-04',
        name: 'Tom',
        state: 'California',
        city: 'Los Angeles',
        address: 'No. 189, Grove St, Los Angeles',
        zip: 'CA 90036',
        tag: 'Home',
    },
    {
        date: '2016-05-01',
        name: 'Tom',
        state: 'California',
        city: 'Los Angeles',
        address: 'No. 189, Grove St, Los Angeles',
        zip: 'CA 90036',
        tag: 'Office',
        isLineDiy: true
    },
]

// 合并行方法
const arraySpanMethod = ({
    row,
    column,
    rowIndex,
    columnIndex,
}: SpanMethodProps) => {
    if (row.isLineDiy) {
        if (columnIndex === 0) return [1, columns.length]
        else return [0, 0]
    }
    return [1, 1]
}
</script>
显示代码

loading的使用

标题1 通过 ref 获取到 table 的节点后,可以调用 changeLoading 方法 通过传入 true/false 显示/隐藏 loading效果, 其他效果请见 文档loading

<!--
 * @Author: mjh
 * @Date: 2023-04-11 11:08:41
 * @LastEditors: mjh
 * @LastEditTime: 2023-04-22 23:49:01
 * @Description:
-->
<template>
    <FpiElTable
        :ref="(el:any) => fpiElTableDom = el"
        :column="column"
        :table-data="tableData"
        :is-show-page="false"
        element-loading-text="加载中"
        :element-loading-svg="svg"
        element-loading-svg-view-box="-10, -10, 50, 50"
        element-loading-background="rgba(122, 122, 122, 0.8)"
    />
</template>

<script lang="ts" setup>
import type { tableColumnTs } from '@ued_fpi/element-plus-expand/es/src/fpi-el-table/types'
import { onMounted, ref } from 'vue'

const svg = `
        <path class="path" d="
          M 30 15
          L 28 17
          M 25.61 25.61
          A 15 15, 0, 0, 1, 15 30
          A 15 15, 0, 1, 1, 27.99 7.5
          L 15 15
        " style="stroke-width: 4px; fill: rgba(0, 0, 0, 0)"/>
      `

const column: tableColumnTs[] = [
    {
        type: 'index',
        label: '序号',
        width: '60',
    },
    {
        prop: 'date',
        label: 'Date',
        width: '180'
    },
    {
        prop: 'name',
        label: 'Name',
        width: '180'
    },
    {
        prop: 'address',
        label: 'Address',
    },
]

const tableData = [
    {
        date: '2016-05-03',
        name: 'Tom',
        state: 'California',
        city: 'Los Angeles',
        address: 'No. 189, Grove St, Los Angeles',
        zip: 'CA 90036',
        tag: 'Home',
    },
    {
        date: '2016-05-02',
        name: 'Tom',
        state: 'California',
        city: 'Los Angeles',
        address: 'No. 189, Grove St, Los Angeles',
        zip: 'CA 90036',
        tag: 'Office',
    },
    {
        date: '2016-05-04',
        name: 'Tom',
        state: 'California',
        city: 'Los Angeles',
        address: 'No. 189, Grove St, Los Angeles',
        zip: 'CA 90036',
        tag: 'Home',
    },
    {
        date: '2016-05-01',
        name: 'Tom',
        state: 'California',
        city: 'Los Angeles',
        address: 'No. 189, Grove St, Los Angeles',
        zip: 'CA 90036',
        tag: 'Office',
    },
]
const fpiElTableDom = ref()
onMounted(() => {
    fpiElTableDom.value.changeLoading(true)
})
</script>
显示代码

插槽和render的使用

isSlot: 设置tableColumn对象内的属性 isSlot: true 开启插槽表格内容自定义插槽,其插槽名称是对象内prop属性的值。
isSlotHeader: 设置tableColumn对象内的属性 isSlotHeader: true 开启表头插槽自定义插槽,其插槽名称是对象内prop属性的值加上 -header也就是 ${prop}-header
0.8.16 render : 当然也可以直接在表格内定义 render 函数使用 vue 提供的 h 进行返回 VNode 节点即可。

<!--
 * @Author: mjh
 * @Date: 2023-04-11 11:08:41
 * @LastEditors: mjh
 * @LastEditTime: 2023-09-19 11:32:22
 * @Description:
-->
<template>
    <FpiElTable
        :column="column"
        :table-data="tableData"
        :is-show-page="false"
    >
        <template #date="{ scope }">
            {{ `${scope.row.date}##isSlot` }}
        </template>
        <template #date-header>
            日期isSlotHeader
        </template>
    </FpiElTable>
</template>

<script lang="ts" setup>
import type { tableColumnTs } from '@ued_fpi/element-plus-expand/es/src/fpi-el-table/types'
import { h } from 'vue'

const column: tableColumnTs[] = [
    {
        type: 'index',
        label: '序号',
        width: '60',
    },
    {
        prop: 'date',
        label: 'Date',
        width: '180',
        isSlot: true,
        isSlotHeader: true
    },
    {
        prop: 'name',
        label: 'Name',
        width: '180',
        render: (scope, tableColumn) => {
            return h(
                'div',
                { color: 'red' },
                `${scope.row.name}-${tableColumn.label}`
            )
        }
    },
    {
        prop: 'address',
        label: 'Address',
    },
]

const tableData = [
    {
        date: '2016-05-03',
        name: 'Tom',
        state: 'California',
        city: 'Los Angeles',
        address: 'No. 189, Grove St, Los Angeles',
        zip: 'CA 90036',
        tag: 'Home',
    },
    {
        date: '2016-05-02',
        name: 'Tom',
        state: 'California',
        city: 'Los Angeles',
        address: 'No. 189, Grove St, Los Angeles',
        zip: 'CA 90036',
        tag: 'Office',
    },
    {
        date: '2016-05-04',
        name: 'Tom',
        state: 'California',
        city: 'Los Angeles',
        address: 'No. 189, Grove St, Los Angeles',
        zip: 'CA 90036',
        tag: 'Home',
    },
    {
        date: '2016-05-01',
        name: 'Tom',
        state: 'California',
        city: 'Los Angeles',
        address: 'No. 189, Grove St, Los Angeles',
        zip: 'CA 90036',
        tag: 'Office',
    },
]
</script>
显示代码

贡献者:

水产品-马佳辉

fpi-component