Skip to content
此页目录
本文总阅读量

vue3 组件-表格分页

该组件依赖element-plus

进度

  • typescript 类型提示(属性、方法、el-table 与 el-pagination 自带 ts 类型)
  • json 配置 el-table
  • 控制栏自定义
  • 单元格编辑
  • 编辑行
  • 自动请求接口
  • 接口请求参数与响应数据路径自定义
  • 接口请求参数序列化
  • v-loading 显示及超时提示文字
  • 空状态提示文字及超时提示文字
  • 导出为xlsx

按需引入

ts
import { KTable } from "@tomiaa/vue3-components"

基础用法

查看代码
vue
<template>
  <KTable
    :data="tableData"
    :options="options"
  />
</template>

<script setup lang="ts">
import { ref } from "vue"
import type { TableProps } from "@tomiaa/vue3-components"
import { KTable } from "@tomiaa/vue3-components"

const tableData = ref<any>([
  {
    date: "2016-05-03",
    name: "Tom",
    address: "No. 189, Grove St, Los Angeles",
  },
  {
    date: "2016-05-01",
    name: "Tom",
    address: "No. 189, Grove St, Los Angeles",
  },
])
const options: TableProps["options"] = [
  {
    label: "名称",
    prop: "name",
  },
  {
    label: "时间",
    prop: "date",
  },
  {
    label: "地址",
    prop: "address",
  },
]
</script>

控制栏

查看代码
vue
<template>
  <KTable
    :data="tableData"
    :options="options"
    @edit="edit"
    @delete="delRow"
  />
</template>

<script setup lang="ts">
import { ref } from "vue"
import type { TableProps } from "@tomiaa/vue3-components"
import { KTable } from "@tomiaa/vue3-components"

const tableData = ref<any>([
  {
    date: "2016-05-03",
    name: "Tom",
    address: "No. 189, Grove St, Los Angeles",
  },
  {
    date: "2016-05-01",
    name: "Tom",
    address: "No. 189, Grove St, Los Angeles",
  },
])
const options: TableProps["options"] = [
  {
    label: "名称",
    prop: "name",
  },
  {
    label: "时间",
    prop: "date",
  },
  {
    label: "控制",
    action: true,
  },
]
// 点击编辑按钮
const edit = (scope: any) => {
  console.log(scope)
}
// 点击删除按钮
const delRow = (scope: any) => {
  console.log(scope)
}
</script>

函数自定义控制栏

查看代码
vue
<template>
  <KTable
    :data="tableData"
    :options="options"
    @edit="edit"
    @delete="delRow"
  />
</template>

<script setup lang="ts">
import { ref } from "vue"
import type { TableProps } from "@tomiaa/vue3-components"
import { KTable } from "@tomiaa/vue3-components"
const tableData = ref<any>([
  {
    date: "2016-05-03",
    name: "Tom",
    address: "No. 189, Grove St, Los Angeles",
  },
  {
    date: "2016-05-01",
    name: "Tom",
    address: "No. 189, Grove St, Los Angeles",
  },
])
const options: TableProps["options"] = [
  {
    label: "名称",
    prop: "name",
  },
  {
    label: "时间",
    prop: "date",
  },
  {
    label: "控制",
    width: 300,
    action: true, // 表示为控制列
    actionConfig: {
      // 控制列的配置
      showEdit: true, // 显示编辑按钮
      showDelete: true, // 显示删除按钮
      editText: "详情",
      deleteText: "撤回",
      custom(list, scope) {
        // 自定义方法
        list[0].icon = "ElIconInfoFilled"
        list.push({
          el: "el-button",
          size: "small",
          children: "自定义按钮",
          icon: "ElIconEdit",
          onClick() {
            console.log(scope)
          },
        })
        return list
      },
    },
  },
]
// 点击编辑按钮
const edit = (scope: any) => {
  console.log(scope)
}
// 点击删除按钮
const delRow = (scope: any) => {
  console.log(scope)
}
</script>

插槽

查看代码
vue
<template>
  <KTable
    :data="tableData"
    :options="options"
  >
    <template #control>
      <el-button>插槽按钮</el-button>
    </template>
  </KTable>
</template>

<script setup lang="ts">
import { ref } from "vue"
import type { TableProps } from "@tomiaa/vue3-components"
import { KTable } from "@tomiaa/vue3-components"
const tableData = ref<any>([
  {
    date: "2016-05-03",
    name: "Tom",
    address: "No. 189, Grove St, Los Angeles",
  },
  {
    date: "2016-05-01",
    name: "Tom",
    address: "No. 189, Grove St, Los Angeles",
  },
])
const options: TableProps["options"] = [
  {
    label: "名称",
    prop: "name",
  },
  {
    label: "时间",
    prop: "date",
  },
  {
    label: "控制",
    slot: "control", // 插槽名称
  },
]
</script>

单元格内编辑

查看代码
vue
<template>
  <KTable
    :data="tableData"
    :options="options"
  >
  </KTable>
</template>

<script setup lang="ts">
import { ref } from "vue"
import type { TableProps } from "@tomiaa/vue3-components"
import { KTable } from "@tomiaa/vue3-components"
const tableData = ref<any>([
  {
    date: "2016-05-03",
    name: "Tom",
    address: "No. 189, Grove St, Los Angeles",
  },
  {
    date: "2016-05-01",
    name: "Tom",
    address: "No. 189, Grove St, Los Angeles",
  },
])
const options: TableProps["options"] = [
  {
    label: "名称",
    prop: "name",
  },
  {
    label: "时间",
    prop: "date",
  },
  {
    label: "可编辑",
    prop: "address",
    editable: true, // 可编辑
  },
]
</script>

函数自定义单元格编辑按钮

查看代码
vue
<template>
  <KTable
    :data="tableData"
    :options="options"
    @confirm-edit-cell="confirmEditCell"
    @cancel-edit-cell="cancelEditCell"
  >
  </KTable>
</template>

<script setup lang="ts">
import { ref } from "vue"
import type { TableProps } from "@tomiaa/vue3-components"
import { KTable } from "@tomiaa/vue3-components"
const tableData = ref<any>([
  {
    date: "2016-05-03",
    name: "Tom",
    address: "No. 189, Grove St, Los Angeles",
  },
  {
    date: "2016-05-01",
    name: "Tom",
    address: "No. 189, Grove St, Los Angeles",
  },
])
const options: TableProps["options"] = [
  {
    label: "名称",
    prop: "name",
  },
  {
    label: "时间",
    prop: "date",
  },
  {
    label: "可编辑",
    prop: "address",
    editable: true, // 可编辑
    editableConfig: {
      // 单元格内编辑配置
      showClose: true, // 显示编辑时取消按钮
      showEnter: true, // 显示编辑时确认按钮
      custom(list, scope, isEdit) {
        list.push({
          el: "el-button",
          size: "small",
          icon: "ElIconCheck",
          onClick() {
            console.log(scope)
            isEdit.value = false // 关闭编辑状态
          },
        })
        return list
      },
    },
  },
]

// 确定编辑
const confirmEditCell = (scope: any) => {
  console.log(scope)
}
// 取消编辑
const cancelEditCell = (scope: any) => {
  console.log(scope)
}
</script>

插槽自定义单元格编辑按钮

查看代码
vue
<template>
  <KTable
    :data="tableData"
    :options="options"
  >
    <!-- 编辑时按钮插槽 -->
    <template #editControlIcon="scope">
      <el-button
        style="margin-left: 0.2em"
        size="small"
        @click="enter(scope)"
        >确认</el-button
      >
    </template>

    <!-- 未编辑时按钮插槽 -->
    <template #editIcon="scope">
      <el-button
        style="margin-left: 0.2em"
        size="small"
        @click="editCell(scope)"
        >编辑</el-button
      >
    </template>
  </KTable>
</template>

<script setup lang="ts">
import { ref } from "vue"
import type { TableProps } from "@tomiaa/vue3-components"
import { KTable } from "@tomiaa/vue3-components"
const tableData = ref<any>([
  {
    date: "2016-05-03",
    name: "Tom",
    address: "No. 189, Grove St, Los Angeles",
  },
  {
    date: "2016-05-01",
    name: "Tom",
    address: "No. 189, Grove St, Los Angeles",
  },
])
const options: TableProps["options"] = [
  {
    label: "名称",
    prop: "name",
  },
  {
    label: "时间",
    prop: "date",
  },
  {
    label: "可编辑",
    prop: "address",
    width: 300,
    editable: true, // 可编辑
  },
]

// 编辑
const editCell = ({ isEdit, row }: any) => {
  console.log(row, "dasdas")
  isEdit.value = true
}
// 确定编辑
const enter = ({ isEdit, row }: any) => {
  console.log(row)
  isEdit.value = false // 取消编辑状态
}
</script>

分页

查看代码
vue
<template>
  <KTable
    show-pagination
    :current-page="pagination.currentPage"
    :total="pagination.total"
    :data="tableData"
    :options="options"
    layout="total, prev, pager, next"
    background
    @update:current-page="handleCurrentChange"
  >
  </KTable>
</template>

<script setup lang="ts">
import { ref } from "vue"
import type { TableProps } from "@tomiaa/vue3-components"
import { KTable } from "@tomiaa/vue3-components"
const tableData = ref<any>([
  {
    date: "2016-05-03",
    name: "Tom",
    address: "No. 189, Grove St, Los Angeles",
  },
  {
    date: "2016-05-01",
    name: "Tom",
    address: "No. 189, Grove St, Los Angeles",
  },
])
const options: TableProps["options"] = [
  {
    label: "名称",
    prop: "name",
  },
  {
    label: "时间",
    prop: "date",
  },
]

const pagination = ref({
  total: 300,
  currentPage: 2,
})

const handleCurrentChange = (num: number) => {
  pagination.value.currentPage = num
  console.log(num, "temp8")
}
</script>

自动调用接口

基础用法

打开控制台查看网络请求

查看代码
vue
<template>
  <KTable
    :options="options"
    get-url="/getList"
    :get-config="{
      method: 'post',
    }"
    with-page-path="pages"
    :with-query="{
      name: '这是携带的查询参数',
    }"
    with-query-path="query"
    data-path="data.result"
    total-path="data.pagination.total"
    show-pagination
    :total="300"
  >
  </KTable>
</template>

<script setup lang="ts">
import type { TableProps } from "@tomiaa/vue3-components"
import { KTable } from "@tomiaa/vue3-components"

const options: TableProps["options"] = [
  {
    label: "名称",
    prop: "name",
  },
  {
    label: "时间",
    prop: "date",
  },
]
</script>

完整示例

查看代码
vue
<template>
  <KTable
    ref="kTable"
    :options="options"
    show-pagination
    :server="myAxios"
    get-url="/getData"
    :get-config="{
      method: 'post',
    }"
    with-page="data"
    with-page-path="pagination"
    :replace-fields="{
      currentPage: 'current',
      pageSize: 'size',
    }"
    :with-query="{
      name: '这里是查询参数',
    }"
    with-query-path="query"
    stringify
    data-path="data.result"
    total-path="data.total"
    show-load-in-get
    element-loading-text="正在加载中"
    :el-loading-text-timeout="3000"
    el-loading-text-timeout-text="加载较慢,请耐心等待"
    empty-tip="正在加载数据中..."
    :empty-tip-timeout="3000"
    empty-tip-timeout-text="数据加载较慢,马上就来..."
    @before-get-data="beforeGetData"
    @after-get-data="afterGetData"
    @fail-to-get-data="failToGetData"
  >
  </KTable>
</template>

<script setup lang="ts">
import type { TableProps } from "@tomiaa/vue3-components"
import { ref, onMounted } from "vue"
import { KTable } from "@tomiaa/vue3-components"
const options: TableProps["options"] = [
  {
    label: "名称",
    prop: "name",
  },
  {
    label: "时间",
    prop: "date",
  },
]

// 模拟 axios 请求
const myAxios: any = (req: any) =>
  new Promise(res => {
    console.log(req, "请求的参数")
    setTimeout(() => {
      res({
        code: 200,
        data: {
          result: [
            {
              date: "2016-05-03",
              name: "Tom",
              address: "No. 189, Grove St, Los Angeles",
            },
            {
              date: "2016-05-01",
              name: "Tom",
              address: "No. 189, Grove St, Los Angeles",
            },
          ],
          total: 390,
        },
        msg: "成功",
      })
    }, 10000)
  })

const beforeGetData = (getConfig: any) => {
  console.log("请求接口之前,axios的参数", getConfig)
}
const afterGetData = (response: any) => {
  console.log("接口请求成功", response)
}
const failToGetData = (error: any) => {
  console.log("接口请求失败", error)
}
const kTable = ref()
onMounted(() => {
  // 手动请求数据
  // kTable.value.getData()
})
</script>

编辑行

查看代码
vue
<template>
  <KTable
    :data="tableData"
    :options="options"
    edit-row
    @confirm-edit-row="confirmEditRow"
    @cancel-edit-row="cancelEditRow"
  >
  </KTable>
</template>

<script setup lang="ts">
import { ref } from "vue"
import type { TableProps } from "@tomiaa/vue3-components"
import { KTable } from "@tomiaa/vue3-components"
const tableData = ref<any>([
  {
    date: "2016-05-03",
    name: "Tom",
    address: "No. 189, Grove St, Los Angeles",
  },
  {
    date: "2016-05-01",
    name: "Tom",
    address: "No. 189, Grove St, Los Angeles",
  },
])
const options: TableProps["options"] = [
  {
    label: "名称",
    prop: "name",
  },
  {
    label: "时间",
    prop: "date",
  },
  {
    label: "编辑行",
    action: true,
  },
]

const confirmEditRow = (scope: any) => {
  console.log(scope, "确定编辑行")
}
const cancelEditRow = (scope: any) => {
  console.log(scope, "取消编辑行")
}
</script>

属性

属性说明类型默认值
options表格配置array(点我查看
editRow点击编辑时是否为编辑行booleanfalse
showPagination是否显示分页booleanfalse
server发送请求的 axios 实例AxiosStaticaxios
getUrl获取分页的请求地址string
withPage获取分页时传入分页对象(pageSize,currentPage)在 axios 中的哪个字段,默认get请求为paramspost请求为datafalse为不携带分页参数string|boolean
withPagePath获取分页时加入的分页对象参数在 axios 的哪个对象路径下,默认在提交的发送的最外层,不建议在get请求中使用,post请求时如填写pages即提交时的参数为{data: {pages: { currentPage: 1, pageSize: 10 }}}string
withQuery请求时的查询参数object
withQueryPath获取分页时查询参数在 axios 的哪个对象路径下string
stringify发送请求是携带的参数序列化,withPage 为 "data" 时生效,只会在请求体中序列化,且Content-Type会被默认设置为application/x-www-form-urlencodedbooleanfalse
getConfig请求分页的配置,为 axios 提交的参数AxiosRequestConfig{method: "get"}
replaceFields要替换请求时分页参数的字段{ pageSize?: string; currentPage?: string }{ pageSize: "pageSize", currentPage: "currentPage" }
dataPath获取数据之后 data 数据的路径stringdata.data
totalPath获取数据之后总条数的路径stringdata.total
showLoadInGet自动获取数据时,在表格上显示 element 的 v-loadingbooleantrue
elementLoadingText显示在 v-loading 加载图标下方的加载文案string正在加载中...
elLoadingTextTimeout超过多少毫秒后更换 v-loading 的 提示文字number8000
elLoadingTextTimeoutText超过 EmptyTipTimeout 毫秒后更换 v-loading 的 提示文字string数据加载较慢,请耐心等待...
emptyTip在自动获取数据时替换empty插槽,table 中显示提示的文字,为假值时则不显示string正在加载中...
emptyTipTimeout超过多少毫秒后更换提示文字number8000
emptyTipTimeoutText超过EmptyTipTimeout毫秒后更换的提示文字string数据加载较慢,请耐心等待...
actionConfig全局的控制栏配置ActionConfig
actionConfig.editText编辑的文字string编辑
actionConfig.deleteText删除的文字string删除
actionConfig.showEdit显示编辑/确认booleantrue
actionConfig.showDelete显示删除/取消booleantrue
editRowEnterText编辑行时确认文字string确定
editRowCloseText编辑行是取消文字string确定
actionConfig.custom函数自定义操作栏function
...rest剩余属性,为el-table属性与el-pagination属性

options-配置

这是options表格的每一列el-column配置,全部为非必填

属性说明类型默认值
slot插槽名string
action是否为操作栏stringfalse
actionConfig操作栏配置,该值存在即视为 action 为 trueobject
actionConfig.editText编辑的文字string编辑
actionConfig.deleteText删除的文字string删除
actionConfig.showEdit显示编辑/确认booleantrue
actionConfig.showDelete显示删除/取消booleantrue
editRowEnterText编辑行时确认文字string确定
editRowCloseText编辑行是取消文字string确定
actionConfig.custom函数自定义操作栏function
editable单元格开启编辑booleanfalse
editableConfig单元格编辑配置,该值存在即视为 editable 为 trueobject
editableConfig.showEnter显示编辑中的确认按钮booleantrue
editableConfig.showClose显示编辑中的取消按钮booleantrue
editableConfig.custom函数自定义单元格编辑function
...rest剩余属性为 el-table-column 的属性

事件

事件名说明回调参数
edit操作栏点击编辑scope
delete操作栏点击删除scope
confirmEditCell单元格内确定编辑scope
cancelEditCell单元格内取消编辑scope
confirmEditRow编辑行确定scope
cancelEditRow编辑行取消scope
beforeGetData自动请求分页之前getConfig
afterGetData自动请求分页成功后AxiosResponse
failToGetData自动请求分页失败AxiosResponse

插槽

插槽名说明作用域
appendel-table 自带插槽,插入至表格最后一行之后的内容, 如果需要对表格的内容进行无限滚动操作,可能需要用到这个 slot。 若表格有合计行,该 slot 会位于合计行之上。
emptyel-table 自带插槽,当数据为空时自定义的内容
headerTable-column 自带插槽,自定义表头的内容{ column, $index }
editIcon单元格编辑按钮插槽{...scope,isEdit: Ref<boolean>}
editControlIcon编辑确认取消按钮插槽{...scope,isEdit: Ref<boolean>}

方法

方法名说明参数
elPaginationel-pagination 的属性和方法
elTableelTable 的属性和方法
getData请求数据

评论

交流群