Skip to content
目录

ProTable 筛选分页表格

将filter、table、page组件再次封装的重型组件,大多数情况下你可能只会使用这一个组件,而不是单独使用那三个组件。

为什么使用?

  • 将filter、table、page组合起来的组件,内部实现了联动逻辑
  • 可传入一个获取数据的方法(getData),自动变换table的loadingerror状态

基础用法

filters、columns配置同filter、table组件

姓名
性别
无数据
Total 0
  • 1
Go to
vue
<template>
  <jlc-pro-table 
    :filters="filters" 
    :columns="columns" 
    :get-data="getData" 
    :filter-props="{ columnCount: 3 }"
  >
    <template #table-gender="{ row }">
      {{ genderMap[row.gender] }}
    </template>
  </jlc-pro-table>
</template>

<script setup lang='ts'>
import { JlcProTable } from '@sz-jlc/admin-vue3'

const mockData = [
  {
    name: '小明',
    gender: 1,
    age: 25,
    job: '前端工程师',
    introduction: '高级前端工程师,擅长原生JS,熟悉设计模式。'
  },
  {
    name: '小红',
    gender: 0,
    age: 28,
    job: '测试工程师',
    introduction: '高级测试工程师,6年工作经验,熟悉自动化测试。'
  },
  {
    name: '小军',
    gender: 1,
    age: 32,
    job: 'Java工程师',
    introduction: '资深架构师,解决过无数疑难杂症,擅长系统设计。'
  },
]

const genderMap = {
  0: '',
  1: ''
}

const genderOptions = Object
  .entries(genderMap)
  .map(([value, label]) => ({ value: +value, label }))

const filters = [
  { label: '姓名', key: 'name' },
  { 
    label: '性别', 
    key: 'gender',
    component: 'el-select',
    children: genderOptions.map(item => ({
      component: 'el-option',
      attrs: item
    }))
  },
]

const columns = [
  { label: '姓名', prop: 'name' },
  { label: '性别', slot: 'table-gender'},
  { label: '年龄', prop: 'age' },
  { label: '岗位', prop: 'job' },
  { label: '个人介绍', prop: 'introduction', align: 'left' },
]

const getData = (queryParams: any): Promise<any> => {
  const { name, gender, pageSize, pageNum } = queryParams
  console.log(queryParams)
  return new Promise(resolve => {
    setTimeout(() => {
      // 模拟筛选
      const list = mockData
        .filter(item => {
          if (!name) return true
          return item.name.includes(name)
        })
        .filter(item => {
          if (gender === null || gender === undefined) return true
          return item.gender === gender
        })
      const lastPage = pageNum * pageSize
      resolve({
        // 模拟分页
        list: list.slice(lastPage - pageSize, lastPage),
        total: list.length,
      })
    }, Math.random() * 200)
  })
}
</script>

手动查询

有时并不需要初始就执行查询,具体查询时间自己把控,那么就可以关闭初始查询,再调用query方法。

无数据
Total 0
  • 1
Go to
vue
<template>
  <div style="margin-bottom: 10px;">
    <el-button @click="onQuery()">查询</el-button>
  </div>
  <jlc-pro-table 
    ref="proTableRef"
    :filters="[]" 
    :columns="columns" 
    :get-data="getData"
    :init-get="false"
    :filter-props="{ 
      columnCount: 3,
      defaultPageSize: 2,
      pageSizes: [2, 5, 10]
    }"
  ></jlc-pro-table>
</template>

<script setup lang='ts'>
import { ref } from 'vue'
import { ElButton } from 'element-plus'
import { JlcProTable } from '@sz-jlc/admin-vue3'

const mockData = [
  {
    name: '小明',
    gender: 1,
    age: 25,
    job: '前端工程师',
    introduction: '高级前端工程师,擅长原生JS,熟悉设计模式。'
  },
  {
    name: '小红',
    gender: 0,
    age: 28,
    job: '测试工程师',
    introduction: '高级测试工程师,6年工作经验,熟悉自动化测试。'
  },
  {
    name: '小军',
    gender: 1,
    age: 32,
    job: 'Java工程师',
    introduction: '资深架构师,解决过无数疑难杂症,擅长系统设计。'
  },
]

const proTableRef = ref()

const columns = [
  { label: '姓名', prop: 'name' },
  { label: '年龄', prop: 'age' },
  { label: '岗位', prop: 'job' },
  { label: '个人介绍', prop: 'introduction', align: 'left' },
]

const getData = (): any => {
  return {
    list: mockData,
    total: mockData.length
  }
}

const onQuery = () => {
  proTableRef.value.query()
}
</script>

初始页面尺寸

无数据
Total 0
  • 1
Go to
vue
<template>
  <jlc-pro-table 
    ref="proTableRef"
    :filters="[{ key: 'a' }]" 
    :columns="columns" 
    :get-data="getData"
    :filter-props="{ columnCount: 3 }"
    :page-props="{ defaultPageSize: 2, pageSizes: [2, 5, 10] }"
  ></jlc-pro-table>
</template>

<script setup lang='ts'>
import { JlcProTable } from '@sz-jlc/admin-vue3'

const mockData = [
  {
    name: '小明',
    gender: 1,
    age: 25,
    job: '前端工程师',
    introduction: '高级前端工程师,擅长原生JS,熟悉设计模式。'
  },
  {
    name: '小红',
    gender: 0,
    age: 28,
    job: '测试工程师',
    introduction: '高级测试工程师,6年工作经验,熟悉自动化测试。'
  },
  {
    name: '小军',
    gender: 1,
    age: 32,
    job: 'Java工程师',
    introduction: '资深架构师,解决过无数疑难杂症,擅长系统设计。'
  },
]

const columns = [
  { label: '姓名', prop: 'name' },
  { label: '年龄', prop: 'age' },
  { label: '岗位', prop: 'job' },
  { label: '个人介绍', prop: 'introduction', align: 'left' },
]

const getData = (queryParams: any): any => {
  console.log(queryParams)
  const { pageNum, pageSize } = queryParams
  const lastPage = pageNum * pageSize
  return {
    list: mockData.slice(lastPage - pageSize, lastPage),
    total: mockData.length
  }
}
</script>

本地分页

组件实际上并没有提供本地分页功能(因为本地分页并不常见,同时也为了组件的精简),但我们仍然可以基于getData配置轻松实现本地分页,如确有需要组件自动处理分页,后续可以考虑补充。

无数据
Total 0
  • 1
Go to
vue
<template>
  <jlc-pro-table 
    :filters="[]" 
    :columns="columns" 
    :get-data="getData" 
    :filter-props="{ columnCount: 3 }"
    :page-props="{ defaultPageSize: 2, pageSizes: [2, 5, 10] }"
  >
    <template #table-gender="{ row }">
      {{ genderMap[row.gender] }}
    </template>
  </jlc-pro-table>
</template>

<script setup lang='ts'>
import { JlcProTable } from '@sz-jlc/admin-vue3'

const mockData = [
  {
    name: '小明',
    gender: 1,
    age: 25,
    job: '前端工程师',
    introduction: '高级前端工程师,擅长原生JS,熟悉设计模式。'
  },
  {
    name: '小红',
    gender: 0,
    age: 28,
    job: '测试工程师',
    introduction: '高级测试工程师,6年工作经验,熟悉自动化测试。'
  },
  {
    name: '小军',
    gender: 1,
    age: 32,
    job: 'Java工程师',
    introduction: '资深架构师,解决过无数疑难杂症,擅长系统设计。'
  },
]

const genderMap = {
  0: '',
  1: ''
}

const columns = [
  { label: '姓名', prop: 'name' },
  { label: '性别', slot: 'table-gender'},
  { label: '年龄', prop: 'age' },
  { label: '岗位', prop: 'job' },
  { label: '个人介绍', prop: 'introduction', align: 'left' },
]

const getData = (queryParams: any): any => {
  const { pageSize, pageNum } = queryParams
  const list = mockData
  const lastPage = pageNum * pageSize
  return {
    // 模拟分页
    list: list.slice(lastPage - pageSize, lastPage),
    total: list.length,
  }
}
</script>

不分页

不分页实际上就是一个普通的table,filters如果为空数组,就不会渲染; 如果确信就是一个普通的表格展示,也可以直接使用Table组件,但大多数情况下为了后续修改,建议使用ProTable

无数据
vue
<template>
  <jlc-pro-table 
    :filters="[]" 
    :columns="columns" 
    :get-data="getData"
    :is-page="false"
  ></jlc-pro-table>
</template>

<script setup lang='ts'>
import { JlcProTable } from '@sz-jlc/admin-vue3'

const mockData = [
  {
    name: '小明',
    gender: 1,
    age: 25,
    job: '前端工程师',
    introduction: '高级前端工程师,擅长原生JS,熟悉设计模式。'
  },
  {
    name: '小红',
    gender: 0,
    age: 28,
    job: '测试工程师',
    introduction: '高级测试工程师,6年工作经验,熟悉自动化测试。'
  },
  {
    name: '小军',
    gender: 1,
    age: 32,
    job: 'Java工程师',
    introduction: '资深架构师,解决过无数疑难杂症,擅长系统设计。'
  },
]

const columns = [
  { label: '姓名', prop: 'name' },
  { label: '年龄', prop: 'age' },
  { label: '岗位', prop: 'job' },
  { label: '个人介绍', prop: 'introduction', align: 'left' },
]

const getData = (): any => {
  return {
    list: mockData,
    total: mockData.length
  }
}
</script>

表格多选

实际上如果你看过Table组件的文档,就不需要看以下内容,因为ProTable基本继承于Table组件,但表格多选的功能比较常见,这里还是做一下演示

无数据
Total 0
  • 1
Go to
vue
<template>
  <div style="margin-bottom: 10px;">
    <el-button @click="clearSelection()">clearSelection</el-button>
  </div>
  <jlc-pro-table 
    ref="proTableRef"
    :filters="[]" 
    :columns="columns" 
    :get-data="getData"
    :filter-props="{ columnCount: 3 }"
    @selection-change="onSelectionChange"
  ></jlc-pro-table>
</template>

<script setup lang='ts'>
import { ref } from 'vue'
import { ElButton } from 'element-plus'
import { JlcProTable } from '@sz-jlc/admin-vue3'

const mockData = [
  {
    name: '小明',
    gender: 1,
    age: 25,
    job: '前端工程师',
    introduction: '高级前端工程师,擅长原生JS,熟悉设计模式。'
  },
  {
    name: '小红',
    gender: 0,
    age: 28,
    job: '测试工程师',
    introduction: '高级测试工程师,6年工作经验,熟悉自动化测试。'
  },
  {
    name: '小军',
    gender: 1,
    age: 32,
    job: 'Java工程师',
    introduction: '资深架构师,解决过无数疑难杂症,擅长系统设计。'
  },
]

const proTableRef = ref()

const columns = [
  { type: 'selection' },
  { label: '姓名', prop: 'name' },
  { label: '性别', slot: 'table-gender'},
  { label: '年龄', prop: 'age' },
  { label: '岗位', prop: 'job' },
  { label: '个人介绍', prop: 'introduction', align: 'left' },
]

const getData = (): any => {
  return {
    list: mockData,
    total: mockData.length
  }
}

const onSelectionChange = (selection: any[]) => {
  console.log(selection)
}
const clearSelection = () => {
  proTableRef.value.clearSelection()
}
</script>

属性

属性名说明类型可选值默认值是否必填
filters筛选项列表FilterItem[]--
columns表格列TableColumn[]--
getData
获取数据,需要返回指定的数据格式或者Promise包裹的指定数据格式
{ list: any[], total: number, // 数据及总条数 }
(params?: any) => Promise<Data> | Data--
initGet初始是否查询boolean-true
isPage是否分页boolean-true
filterProps传递给Filter组件的属性object--
filterEvents传递给Filter组件的事件object--
tableProps传递给Table组件的属性object--
tableEvents传递给Table组件的事件object--
pageProps传递给Page组件的属性object--
pageEvents传递给Page组件的事件object--

方法

方法名描述参数
query查询,相当于点击了查询按钮-
refresh刷新
  • needResetPage(是否需要重置Page,默认为false)
setFilter设置筛选表单绑定的值
  • filter(值)
  • queryNow(是否执行查询,会传递给query事件作为回调参数,默认为true)
resetFilter重置Filter组件
  • queryNow(是否执行查询,会传递给query事件作为回调参数,默认为true)
setPage设置page参数
  • queryNow(是否执行查询,会传递给query事件作为回调参数,默认为true)
resetPage重置Page组件
  • queryNow(是否执行查询,会传递给query事件作为回调参数,默认为true)
Table的一些常用方法
  • clearSelection
  • getSelectionRows
  • toggleRowSelection
  • toggleAllSelection
  • toggleRowExpansion
  • setCurrentRow
-

事件

事件名说明回调参数
get-data执行查询时
  • retValue(getData返回的内容,Promise或数据)
got-data获取到数据
  • data(Promise返回的数据或getData返回的数据)
Table组件的一些常用事件
  • select
  • select-all
  • selection-change
  • row-click
  • row-dblclick
  • sort-change
  • current-change
-

插槽

插槽说明
--

深圳嘉立创前端团队