UNPKG

vue-pro-table

Version:

一个基于ElementUI封装的table列表页组件,将包含搜索、列表、分页等功能的页面封装成一个组件

496 lines (428 loc) 21.6 kB
# vue-pro-table > 本组件是基于 vue2 开发,如果你正在使用 vue3,请点击[vue3-pro-table](https://github.com/huzhushan/vue3-pro-table)查看 vue3 版的 pro-table 组件 一个基于 ElementUI 封装的 table 列表页组件,将包含搜索、列表、分页等功能的页面封装成一个组件 ## 特性 - 将搜索、列表、分页三者的交互逻辑封装到组件中,节省开发者代码量 - 配置化的请求函数,自动发送请求,自动获取请求参数,自动显示 loading 效果 - 配置化的表格项,跟 el-table-column 的配置属性类似 - 配置化的搜索表单,支持大部分表单元素 - 配置化的分页,跟 el-pagination 的配置属性类似 - 自定义是否显示搜索和分页 - 自定义标题栏和工具栏 - 丰富的插槽提供功能扩展 ## 使用 ### 安装和引入 安装 ```js // npm npm install vue-pro-table // yarn yarn add vue-pro-table ``` 引入 > 该组件依赖 element-ui,需要自行引入 > > ```js > import ElementUI from "element-ui"; > import "element-ui/lib/theme-chalk/index.css"; > Vue.use(ElementUI); > ``` ```js // 引入vue-pro-table import VueProTable from "vue-pro-table"; Vue.use(VueProTable); ``` ### 快速使用 ```vue <template> <vue-pro-table title="列表" :request="getList" :columns="columns"> <template #operate="scope"> <el-button size="mini" type="primary">编辑</el-button> <el-button size="mini" type="danger">删除</el-button> </template> </vue-pro-table> </template> <script> import {getUserList} from 'src/api/xxx'; export default { data() { // 表格列配置,大部分属性跟el-table-column配置一样 columns: [ { label: '序号', type: 'index' }, { label: '名称', prop: 'nickName', width: 180 }, { label: '邮箱', prop: 'userEmail' }, { label: '操作', fixed: 'right', width: 180, align: 'center', tdSlot: 'operate', // 自定义单元格内容的插槽名称 }, ], }, methods: { // 请求函数 async getList(params) { // params是从组件接收的,包含分页和搜索字段。 const { data } = await getUserList(params) // 必须要返回一个对象,包含data数组和total总数 return { data: data.list, total: +data.total, } }, } } </script> ``` 预览效果 > 默认不包含搜索表单 ![列表页](https://raw.githubusercontent.com/huzhushan/pics/master/vue-pro-table/%E5%BE%AE%E4%BF%A1%E6%88%AA%E5%9B%BE_20210226101705.png) ### 请求函数配置 - request,请求列表数据的函数 > 组件加载的时候会自动执行 request 函数,并在加载过程中显示 loading 效果 - 函数接收参数:包含搜索表单的所有字段和分页的 pageNum 和 pageSize - 函数必须返回一个对象,包含: - data: 列表数据的数组 - total:总数,用于分页 ### 表格配置 - border 表格是否有边框。布尔值,默认为 false - columns 属性的配置,是一个数组 | 参数 | 说明 | 类型 | 可选值 | 默认值 | | --------- | ------------------------------------------------------------------------------------------- | ---------------------- | ---------------------- | ------ | | label | 对应 el-table-column 的 label | string | - | - | | type | 对应 el-table-column 的 type | string | selection/index/expand | - | | prop | 对应 el-table-column 的 prop | string | - | - | | width | 对应 el-table-column 的 width | string,number | - | - | | minWidth | 对应 el-table-column 的 min-width | string,number | - | - | | align | 对应 el-table-column 的 align | string | left/center/right | left | | fixed | 对应 el-table-column 的 fixed | string, boolean | true, left, right | - | | sortable | 对应 el-table-column 的 sortable | boolean | false/true | false | | filters | 对应 el-table-column 的 filters | Array[{ text, value }] | - | - | | tdSlot | 单元格要自定义内容时,可以通过此属性配置一个插槽名称,并且是作用域插槽,可以接收 scope 数据 | string | - | - | | labelSlot | 表头要自定义内容时,可以通过此属性配置一个插槽名称,并且是作用域插槽,可以接收 scope 数据 | string | - | - | - row-key 属性配置 对应 el-table 的 row-key,默认值是'id' ### 搜索配置 - search 属性的配置,是一个对象 > 如果不想显示搜索表单,可以不配置 search 或者 search 设置为 false | 参数 | 说明 | 类型 | 可选值 | 默认值 | | ---------- | ----------------------------------------------------------------------------------------- | ----------------- | ------ | ------ | | labelWidth | label 文字长度 | string | - | - | | inputWidth | 表单项长度 | string | - | - | | fields | 表单字段列表,包含 text,select,radio,checkbox,datetime 等类型,所有字段类型配置见下表 | Array[{字段类型}] | - | - | - fields 列表的字段类型配置 | 参数 | 说明 | 类型 | 可选值 | 默认值 | | ------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------- | ------------------------------------------------------------------------------------------------------------- | ------ | | type | 字段类型 | string | text,textarea,select,radio,radio-button,checkbox,checkbox-button,number,date,daterange,datetime,datetimerange | text | | label | label 文本 | string | - | - | | name | 搜索时的提交的参数名称 | string | - | - | | style | 额外的样式 | object | - | - | | defaultValue | 默认值 | - | - | | | options | 当 type 是 select,radio,radio-button,checkbox,checkbox-button 时的枚举选项 | Array[{name, value}] | - | - | | filterable | 当 type 是 select 时,下拉框是否支持模糊搜索 | boolean | true, false | false | | multiple | 当 type 是 select 时,下拉框是否支持多选 | boolean | true, false | false | | transform | 搜索前对表单数据进行转换,比如表单数据是数组,但是搜索的时候需要传递字符串。它是一个函数,默认参数是字段的 value,需要返回转换后的结果 | function(value) | - | - | | trueNames | 当 type 是 daterange,datetimerange 时,开始时间和结束时间是在一个数组里面,但是搜索时可能需要两个字段,这时就需要把开始时间和结束时间分别赋值给两个字段,这两个字段的名称就是通过 trueNames 配置,它是一个数组,例如:trueNames: ['startTime', 'endTime'] | Array[string] | | | | min | 当 type 是 number 时的最小值 | number | - | - | | max | 当 type 是 number 时的最大值 | number | - | - | ### 分页配置 - pagination 属性的配置,是一个对象 > 如果不想显示分页,将 pagination 设置为 false | 参数 | 说明 | 类型 | 可选值 | 默认值 | | --------- | ---------------------------- | ------------- | --------------------------------------- | --------------------------------------- | | layout | 组件布局 | string | total, sizes, prev, pager, next, jumper | total, sizes, prev, pager, next, jumper | | pageSize | 每页显示条目个数 | number | - | 10 | | pageSizes | 每页显示个数选择器的选项设置 | Array[number] | - | [10, 20, 30, 40, 50, 100] | ### 标题栏配置 > 表格上方有一个标题栏,标题栏左侧显示一个标题,右侧是一个可自定义的工具栏 - hide-title-bar 是否隐藏标题栏,布尔值 - title 表格标题 - 自定义表格标题 提供一个具名插槽 title,来自定义标题的内容 - 工具栏 工具栏默认是空的,提供一个具名插槽 toolbar,来自定义工具栏的内容 ### 事件 - selectionChange 如果 columns 中配置了 type 为 selection 的列,可以通过该事件得到已选择的行,参数是一个数组 ### 组件内部方法 - refresh 配置 ref 属性,可以通过 ref 获取组件后调用组件内部的**refresh**方法刷新列表 ### 完整用法 ```vue <template> <vue-pro-table ref="proTable" title="用户列表" :request="getList" :columns="columns" :search="searchConfig" :pagination="paginationConfig" @selectionChange="handleSelectionChange" > <!-- 工具栏 --> <template #toolbar> <el-button type="primary" icon="el-icon-plus" @click="$router.push({ name: 'userAdd' })" >创建账号</el-button > <el-button type="danger" icon="el-icon-refresh" @click="$refs.proTable.refresh()" >刷新</el-button > </template> <!-- 展开行 --> <template #expand="{ row }"> {{ row.userEmail }} </template> <!-- 状态 --> <template #status="{ row }"> <el-tag :type="+row.status === 1 ? 'success' : 'info'">{{ +row.status === 1 ? "启用" : "停用" }}</el-tag> </template> <!-- 表格操作栏 --> <template #page-operate="{ row }"> <el-button type="text" @click=" $router.push({ name: 'userEdit', params: { id: row.id, }, }) " >编辑</el-button > <el-button v-if="+row.status === 1" type="text" @click="setUserStatus(row, 0)" >停用</el-button > <el-button v-else type="text" @click="setUserStatus(row, 1)" >启用</el-button > </template> <!-- 操作栏头部 --> <template #th-operate> <el-input /> </template> </vue-pro-table> </template> <script> import {getUserList} from 'src/api/xxx'; export default { data() { // 表格列配置,大部分属性跟el-table-column配置一样 columns: [ { label: '', type: 'expand', tdSlot: 'expand' }, { label: '全选', type: 'selection' }, { label: '序号', type: 'index' }, { label: '账户名称', prop: 'nickName', sortable: true }, { label: '账号', prop: 'userEmail', width: 80 }, { label: '状态', prop: 'status', tdSlot: 'status', filters: [ { text: '启用', value: 1 }, { text: '禁用', value: 0 }, ], }, { label: '创建时间', prop: 'createTime', align: 'right' }, { label: '最后修改时间', prop: 'updateTime' }, { label: '操作', labelSlot: 'th-operate', fixed: 'right', width: 180, align: 'center', tdSlot: 'page-operate', }, ], // 搜索配置 searchConfig: { labelWidth: '90px', inputWidth: '360px', fields: [ { type: 'text', label: '账户名称', name: 'nickName', defaultValue: 'abc', }, { type: 'textarea', label: '描述', name: 'description', }, { label: '状态', name: 'status', type: 'select', defaultValue: 1, options: [ { name: '已发布', value: 1, }, { name: '未发布', value: 0, }, ], }, { label: '性别', name: 'sex', type: 'radio', options: [ { name: '男', value: 1, }, { name: '女', value: 0, }, ], }, { label: '城市', name: 'city', type: 'radio-button', options: [ { name: '北京', value: 'bj', }, { name: '上海', value: 'sh', }, { name: '广州', value: 'gz', }, { name: '深圳', value: 'sz', }, ], }, { label: '爱好', name: 'hobby', type: 'checkbox', defaultValue: ['吃饭'], options: [ { name: '吃饭', value: '吃饭', }, { name: '睡觉', value: '睡觉', }, { name: '打豆豆', value: '打豆豆', }, ], transform: (val) => val.join(','), }, { label: '水果', name: 'fruit', type: 'checkbox-button', options: [ { name: '苹果', value: '苹果', }, { name: '香蕉', value: '香蕉', }, { name: '橘子', value: '橘子', }, { name: '葡萄', value: '葡萄', }, ], transform: (val) => val.join(','), }, { label: '日期', name: 'date', type: 'date', }, { label: '时间', name: 'datetime', type: 'datetime', defaultValue: '2020-10-10 8:00:00', }, { label: '日期范围', name: 'daterange', type: 'daterange', trueNames: ['startDate', 'endDate'], style: { width: '360px' }, }, { label: '时间范围', name: 'datetimerange', type: 'datetimerange', trueNames: ['startTime', 'endTime'], style: { width: '360px' }, defaultValue: ['2020-10-10 9:00:00', '2020-10-11 18:30:00'], }, { label: '数量', name: 'num', type: 'number', min: 0, max: 10, }, ], }, // 分页配置 paginationConfig: { layout: 'total, prev, pager, next, sizes', // 分页组件显示哪些功能 pageSize: 5, // 每页条数 pageSizes: [5, 10, 20, 50], } }, methods: { // 请求函数 async getList(params) { // params是从组件接收的,包含分页和搜索字段。 const { data } = await getUserList(params) // 必须要返回一个对象,包含data数组和total总数 return { data: data.list, total: +data.total, } }, // 选择 handleSelectionChange(arr) { console.log(arr) }, } } </script> ``` 效果: ![完整用法](https://raw.githubusercontent.com/huzhushan/pics/master/vue-pro-table/%E5%BE%AE%E4%BF%A1%E6%88%AA%E5%9B%BE_20210302144535.png)