wkjp-list-page
v1.0.23
Published
Vue2 + ElementUI CommonListPage component
Readme
wkjp-list-page
Vue 2 + Element UI 通用列表页组件 CommonListPage(标签 common-list-page):搜索区、表格、分页;列表数据由组件通过 api 拉取并在内部维护分页与加载状态。
npm 包:wkjp-list-page(api 为必填;block-list-request 默认 false 时组件会正常发起列表请求;设为 true 则拦截本组件内所有对 api 的列表请求,需由父页面在适当时机 this.$refs.xxx.fetchList({ force: true }) 主动拉表。)
环境
vue^2.6.14element-ui^2.15.14(需引入element-ui/lib/theme-chalk/index.css,并保证图标字体能被构建加载)
安装与注册
npm i wkjp-list-pageimport Vue from "vue";
import ElementUI from "element-ui";
import "element-ui/lib/theme-chalk/index.css";
import CommonListPage from "wkjp-list-page";
Vue.use(ElementUI);
Vue.use(CommonListPage);按需引入:import { CommonListPage } from "wkjp-list-page",在 components 里注册即可。
1. 默认就够用的写法
日常列表页,固定会写的通常是:ref、filters、search-option、columns、api。filters 为必填(查询条件对象,会被组件原地改写,不要每次用字面量新建)。api 为必填(返回 Promise,resolve 为接口原始 JSON)。
search-option 和 filters 各管什么?
search-option:像一张「表单说明书」——每一项写 类型(输入框/下拉/日期)、文案、字段名叫什么(prop)、宽度等。它 不存你输入的值。filters:才是真正 存值 的对象,键名要和search-option里每一项的prop对上。组件把el-form绑在它上面,你打字、选日期时改的都是这里;发请求时默认也会把这里面的键值带给接口;「清除查询」也是把这里 恢复成刚进页时的快照。
所以两个都要传:一个说明长什么样,一个装当前筛出来的数据;没有 filters 就没有统一的地方放这些值,也没法和父页面、路由、接口参数对齐。
<common-list-page
ref="deviceListRef"
:filters="deviceListFilters"
:search-option="deviceListSearchOption"
:columns="deviceListColumns"
:api="deviceListApi"
/>// data 示例(命名仅作示例,按你页面改)
deviceListFilters: { keyword: "", status: "" },
deviceListSearchOption: [
{ type: "input", prop: "keyword", label: "关键词" },
{ type: "select", prop: "status", label: "状态", options: [{ label: "全部", value: "" }], autoQuery: true }
],
deviceListColumns: [
{ type: "index", label: "#", width: 55 },
{ prop: "name", label: "名称", minWidth: 140 }
],
// methods
deviceListApi(params) {
return this.$http.get("/api/device/list", { params });
}默认约定:
- 发请求时带什么参数:不写
build-params时,会把filters里所有条件 再加上 当前第几页、每页几条(字段名是currentPage、pageSize,也会写回filters)。若写了build-params,则由你 自己 return 整包参数,既可改分页字段名,也可在filters之外 单独加 路由、父级状态等条件。 - 接口返回怎么用:不写
api-adapter时,认为列表在res.object.list,总条数在res.object.num。 - 首屏列表:默认
block-list-request为false且fetch-on-created为true时,组件会在created里自动fetchList。若fetch-on-created为false,则不在created里请求,由父页面择机fetchList。若block-list-request为true,内部调用一律不请求api;需要数据时请this.$refs.xxx.fetchList({ force: true })(可带resetPage: true)。
下面这些是 可选:先照 §1 能跑起来,遇到对应场景再往组件上 多绑一个属性 即可。
2. 按需求往上加
每一段都是:你可能遇到的情况 → 加什么 → 干什么用。
阅读顺序: 和界面更相关的(列配置、查询/清除、搜索折叠、表格样式、search-extra、内置导出)放在 2.1~2.6;和接口、数据流相关的放在 2.7~2.10(另见 2.10.1 首屏是否自动请求);再往后是插槽、多选、分页选项。
2.1 想让用户在页面上自己勾选显示哪些列、拖顺序
情况: 运营想自定义表头、列太多想藏起来。
默认: columns 达到 10 列及以上(可用 column-config-auto-min 改阈值)时,表格最右侧自动出现 表头设置 齿轮;悬停齿轮显示 「配置字段」 提示(可用 column-config-tooltip 修改)。
可选: :enable-column-config="true" 强制开启;:enable-column-config="false" 强制关闭。
作用: 弹层内可 搜索字段、显示/未显示 分组、开关显隐、拖拽排序;复选框列(type: selection)不出现在设置里且表格始终保留;列上 showInColumnConfig: false 可排除在表头设置外(表格仍显示该列);固定列左侧显示「固定」且不可拖不可关。点 确认 后才会作用到表格并触发 columns-change,点 取消 / 关闭 / 再次点齿轮则放弃本次修改。
2.2 不想要「查询」按钮,或想改按钮上的字
情况: 全部自动查询、不需要单独点一下;或想把「查询」改成「搜索」。
加: :show-query-button="false" 或 :query-button-text="'搜索'"
2.3 搜索条件太多,一屏排不下
默认: searchOption 超过 6 条(可用 search-visible-max 改阈值)时,自动只露出前若干项,并显示「展开查询 / 收起」。
可选: :collapse-search="false" 关闭折叠;:collapse-search="true" 强制开启(未传时亦默认开启,由条数决定)。
可选: :expand-search-text、:fold-search-text 改展开、收起两个词。
2.4 想改表格条纹、边框、高度,或表头颜色
情况: 和 Element 文档一样,想给 el-table 加属性、改表头底色。
加: :table-attrs="{ stripe: true, border: true, height: 400 }" 等;表头底色用 table-header-bg。若你在 table-attrs 里也写了表头背景,以 Element 合并结果为准。
2.5 想在「查询 / 清除」右边加「设备入网」等自己的按钮
情况: 和组件自带按钮排在一行,靠右。
加: 用插槽 search-extra 里写你的按钮(与内置导出按钮同一右侧区域)。
<template #search-extra>
<el-button type="primary" plain @click="exportList">设备入网</el-button>
</template>2.6 列表上要「导出」按钮,并直接调你们的导出接口
情况: 不想自己在 search-extra 里手写导出按钮,希望组件内置一个,和「配置表单」一样摆在右侧。
加: show-export(或 :show-export="true")+ :export-api="你的导出方法"
作用: 内部嵌现有 exportFile 组件。点击导出时,会把当前 filters 展开,并带上 currentPage: 1、pageSize: 999999999(与原先 exportFile 行为一致),再调用你的 export-api;返回需为 { success: true, object: '文件下载地址' },失败则 success: false 并带 message。
<common-list-page
show-export
:export-api="exportDeviceList"
...
/>exportDeviceList(params, headers) {
return this.$http.post("/api/device/export", params, { headers: headers || {} });
}可选: export-button-text、export-button-type(同导出组件的按钮类型)、export-disabled、export-headers、export-before((querys) => boolean,返回 false 则不调接口)、export-max-limit(与当前列表 total 比较,超出则只提示不导出)。
与 §2.5
search-extra里自己写导出 可以并存;内置导出在search-extra右侧。
2.7 接口里不叫 list / num,组件认不出来
情况: 你们后端可能是 data.records、data.total 之类,和默认的 object.list / object.num 对不上。
加: :api-adapter="你的函数"
作用: 告诉组件「从整包返回里,哪一块是表格数据、哪一个是总数」。函数返回 { list, total } 就行。
:api-adapter="deviceListApiAdapter"deviceListApiAdapter(res) {
return { list: res.data.records, total: res.data.total };
}2.8 自己拼请求参数(改分页字段名、或单独加条件)
情况 ①: 后端要的分页字段不叫 currentPage / pageSize,例如要 pageNo、limit。
情况 ②: 除了搜索区里的 filters,还想 多带一些接口要的字段(例如路由里的 id、父页面里的菜单编码、写死的业务类型、从别处算出来的标志位等),这些不一定要出现在表单里。
加: :build-params="你的函数"
作用: 完全由你决定「这次请求最终发给后端的参数对象」长什么样。第一个参数是当前 filters(和搜索区同步),第二个是 { page, pageSize }(组件内当前页、每页条数)。你可以 { ...filters, ... } 再随便加键、删键、改名。
:build-params="deviceListBuildParams"// 只改分页字段名
deviceListBuildParams(filters, { page, pageSize }) {
return { ...filters, pageNo: page, limit: pageSize };
}
// 在 filters 之外再拼查询条件(示例:路由 id + 固定类型)
deviceListBuildParams(filters, { page, pageSize }) {
return {
...filters,
pageNo: page,
limit: pageSize,
deptId: this.$route.params.deptId,
bizType: "DEVICE"
};
}2.9 数据拿到了,想在进表格前统一改一改每一行
情况: 想在列表上加一列展示字段、补默认值、把枚举转成中文等。
加: :transform-list="你的函数"
作用: 在写入表格前处理 list;记得 return 一个数组(可以返回新数组,也可以改完再 return)。
:transform-list="deviceListTransformList"deviceListTransformList(list) {
return list.map((row) => ({ ...row, label: row.name || "--" }));
}2.10 完全由父页面控制列表请求(block-list-request)
迁移: 旧版曾使用
auto-request/autoRequest,已更名为block-list-request/blockListRequest(为true时内部不调api)。
情况: 不希望列表组件在 created、点查询、分页、autoQuery 等场景里自动调 api,由外层统一请求或延后请求。
加: :block-list-request="true"
说明: 默认 block-list-request 为 false:不拦截,与往常一样。为 true 时,组件内部所有 fetchList 都不会真正请求 api(一次都不会)。需要拉表时请 this.$refs.xxx.fetchList({ force: true });从第一页重查可 fetchList({ force: true, resetPage: true })。
补充: 带 force: true 时,仍可用 resetPage: true 从第一页重查;不带 force 且 block-list-request 为 true 时调用 fetchList 仍不会请求。
2.10.1 首屏不在 created 里自动请求(fetch-on-created)
情况: 首屏列表要由父页面先走别的流程(例如先选驾校、先拿路由参数再拼条件),不希望组件一进页就调 api。
加: :fetch-on-created="false"(默认 true,保持原先「created 即拉表」)。
说明: 为 false 时仅跳过 created 里的那一次请求;点「查询」、分页、autoQuery 等仍会照常 fetchList。需要首屏数据时在合适时机 this.$refs.xxx.fetchList()(必要时带 resetPage: true)。
与 block-list-request: 后者为 true 会拦住包括 created 在内的所有内部请求;若只想关掉首屏自动请求、其余仍交给组件,用 fetch-on-created 即可。
2.11 不想要「清除查询」,或想改按钮上的字
情况: 没有「恢复初始条件」的需求;或想把文案改成「重置」。
说明: 「清除」会把筛选条件 恢复成刚进这个页面时的样子,再自动查一遍;不会把「展开查询 / 收起」强制收回去,保持你当前的展开状态。
加: :show-clear-query-button="false" 或 :clear-query-button-text="'重置条件'"
2.12 某一个筛选项或某一列表格格,组件自带类型不够用
情况: 要自己写一个日期联动、树选择、复杂输入;或操作列里一堆按钮。
加:
- 搜索:
searchOption里type: 'slot',写好slot名字;父页面<template #同名="{ item, filters }">。 - 表格列:
columns里type: 'slot'+slot;父页面<template #同名="{ row, scope }">。
2.13 表格要打勾多选
情况: 批量删除、批量导出。
加: columns 里加一列 { type: 'selection', width: 48 },并监听 @selection-change。
2.14 只想改分页器里「每页多少条」那几个选项
情况: 下拉只要 10、20、50,不要默认一长串。
加: :pagination="{ pSizes: [10, 20, 50] }"
说明: 这里的 pagination 只用来合并进组件内部分页(改 pSizes 等),不是让你自己维护当前第几页、总条数——那些仍是组件内部根据接口结果在管。
分页 layout: 当 total 不大于 pSizes 中的最小值(例如共 3 条、最小每页 10 条)时,不显示「每页条数」下拉与「前往页」,只保留总数与翻页;数据超过一页时再显示完整分页控件。
3. 事件一览
| 事件 | 说明 |
|------|------|
| query | 仅 输入框回车 时触发(便于校验等);点「查询」、筛选项变更等由内部 fetchList 完成。 |
| clear-query | 点「清除查询」并恢复条件、发起请求之后;不改变搜索区「展开/收起」状态。 |
| page-change / size-change | 分页变化;组件已请求,事件仍抛出。 |
| selection-change | 表格多选变化。 |
| fetched | 每次 api 成功,参数 { list, total, page, pageSize, raw }。 |
| columns-change | 仅开启列配置:弹窗确定后,当前列配置数组。 |
4. Props 速查
| Prop | 默认 | 说明 |
|------|------|------|
| filters | (必填) | 查询条件,与 searchOption 的 prop 对应。 |
| searchOption | [] | 搜索项配置。 |
| columns | [] | 表格列配置。 |
| api | (必填) | (params) => Promise,内部请求、分页、loading。 |
| pagination | null | 可选,与内部分页对象合并(如只传 { pSizes: [...] })。 |
| buildParams | null | 自定义整包请求参数;可改分页字段名,也可在 filters 外追加条件。 |
| apiAdapter | null | (res) => ({ list, total })。 |
| transformList | null | 入表前改 list。 |
| blockListRequest | false | true:拦截组件内所有列表请求(fetchList 不调 api);拉表用 fetchList({ force: true })。false:不拦截,照常请求。 |
| fetchOnCreated | true | false:不在 created 里自动发起首次列表请求,由父页面择机 fetchList;查询、分页、autoQuery 等仍照常。 |
| enableColumnConfig | (未传) | 未传时 columns.length >= columnConfigAutoMin 自动显示;true / false 强制开/关。 |
| columnConfigAutoMin | 10 | 自动显示表头设置的列数阈值(列数 达到该值及以上 时显示)。 |
| columnConfigTooltip | 配置字段 | 表头设置齿轮图标悬停提示文案。 |
| columnConfigConfirmText | 确认 | 表头设置弹层确认按钮文案。 |
| columnConfigCancelText | 取消 | 表头设置弹层取消按钮文案。 |
| columnConfigFixedText | 固定 | 固定列在拖拽图标位显示的文案。 |
| columnConfigTitle | 表头设置 | 表头设置弹层标题。 |
| columnConfigSearchPlaceholder | 搜索添加更多字段 | 表头设置内搜索框占位。 |
| showExport | false | 为 true 且提供 exportApi 时,在搜索区右侧显示内置 exportFile 导出按钮。 |
| exportApi | null | (params, headers?) => Promise,导出请求;成功返回需含 success、object(下载链接),与内置导出组件约定一致。 |
| exportButtonText | 导出 | 导出按钮文案。 |
| exportButtonType | primary | 导出按钮 type(同 exportFile 的 import-component-type)。 |
| exportDisabled | false | 是否禁用导出按钮。 |
| exportHeaders | null | 导出请求的额外请求头。 |
| exportBefore | null | (querys) => boolean,返回 false 则中止导出。 |
| exportMaxLimit | null | 若设置:当前列表 total 超过该值则提示不导出。 |
| tableAttrs | {} | 透传 el-table。 |
| tableHeaderBg | #e5e9f2 | 表头背景色。 |
| cellEmptyText | -- | 非 slot 列空值占位;列上可用 emptyText / defaultText 单独覆盖。 |
| showQueryButton | true | 是否显示查询按钮。 |
| queryButtonText | 查询 | 查询按钮文案。 |
| showClearQueryButton | true | 是否显示清除查询。 |
| clearQueryButtonText | 清除查询 | 清除按钮文案。 |
| collapseSearch | (未传) | 未传时 searchOption.length > searchVisibleMax 自动折叠;true / false 强制开/关。 |
| searchVisibleMax | null | 折叠时默认展示条数,未传按 6;查询项 超过 该值时出现「展开查询」;显式传 ≤0 则不折叠。 |
| expandSearchText / foldSearchText | 展开查询 / 收起 | 折叠按钮文案。 |
| columnOverflowTooltipChars | 20 | 自动列宽:内容超过该字符数时按该字数定宽并 show-overflow-tooltip。 |
| columnAutoWidthCharPx | 14 | 自动列宽每字符折算像素。 |
| columnAutoWidthPadding | 24 | 自动列宽额外内边距像素。 |
| columnAutoMinWidth | 100 | 自动列宽默认最小宽度(px)。 |
5. searchOption 项(常用)
每项必有 type,常用:input、select、cascader、slot,以及日期:date、daterange、datetime、datetimerange、month、year。
| 字段 | 说明 |
|------|------|
| prop | 对应 filters[prop](slot 可省略)。 |
| label / placeholder | 浮动标签,优先 label。 |
| width | 宽度(数字,内部会加 px)。 |
| autoQuery | 默认 false;为 true 时选择/日期等变更后自动 fetchList(重置第 1 页)。 |
| onChange | (val) => void。 |
| input | clearable 默认 true(有内容时出现清除);false 关闭。另有 maxlength、height;回车触发 query 事件(不自动 fetchList);其它类型若设 autoQuery: true 则变更后自动查。 |
| select | options(平铺选项)、multiple、clearable(默认 true)、filterable、disabled。 |
| cascader | options 为级联树;props 或 cascaderProps 为 el-cascader 的字段映射;filters[prop] 为 路径数组;可选 filterable、collapseTags、showAllLevels、separator、debounce、height。 |
| 日期范围 | daterange 未传 valueFormat 时默认 yyyy-MM-dd(date / month / year / datetime 等同理,与 Element 约定不符时请自行传 valueFormat)。范围上浮文案用 placeholder: [开始文案, 结束文案](与 input 字段名一致;亦支持 placeholders),未传时默认「开始日期」「结束日期」(兼容 startPlaceholder / endPlaceholder)。unlinkPanels 默认 true;另有 rangeSeparator(默认「至」)。可选 gmtKeys: [beginFilterKey, endFilterKey](亦支持 gmtKey)同步写带 00:00:00 / 23:59:59 的起止字段(兼容 gmtBeginKey / gmtEndKey)。 |
6. columns 列(常用)
非 slot 列会 透传 到 el-table-column(prop、label、width、fixed 等)。
内置列类型 selection / index 不做自定义单元格包装;expand 可写 type: 'expand' + slot,用父组件具名插槽渲染展开行内容。
最简写法:{ prop: 'name', label: '姓名' },值为 null / undefined / ''(以及 textFormatter 得到空串)时,默认显示 --;表格上 cell-empty-text 可改全局占位;列上 emptyText(优先)或 defaultText 可单独改该列。
列宽(默认): 列上 未写 width / minWidth 时,按 表头文案 与 当前页单元格展示内容(含 valueGetter / textFormatter)取最长字符数估算 minWidth,且不低于 column-auto-min-width(默认 100px);超过 20 个字符(可用 column-overflow-tooltip-chars 改)时按 20 字折算,并自动 show-overflow-tooltip。已写 width / minWidth 的列不自动改宽,但若未写 showOverflowTooltip 且内容仍超阈值,会自动开 tooltip。slot 列无单元格文本时仅按表头估算。
| 字段 | 说明 |
|------|------|
| type: 'slot' + slot | 自定义列,父组件具名插槽。 |
| hidden | 隐藏。 |
| valueGetter | (row, index) => any,取展示用原始值(不填则用 row[prop])。 |
| textFormatter | (value, row, index) => any,格式化后若为空仍走空值占位。 |
| emptyText / defaultText | 空值时显示文案;emptyText 优先;都不设则用 cell-empty-text(默认 --)。 |
| width / minWidth | 显式指定后不再自动算宽;仍可配合上面的 tooltip 规则。 |
| showOverflowTooltip | 显式 true / false 时优先于自动规则。 |
| showInColumnConfig | 是否出现在 表头设置 弹层,默认 true;为 false 时不出现在设置里(不可被用户隐藏),表格仍渲染。兼容 columnConfigShow。 |
| configFixed | 在表头设置中视为固定列,不可拖、不可关(常与 fixed 联用)。 |
7. 发布 npm
递增 package.json 的 version 后执行 npm publish(已发布版本不可覆盖)。
