wkjp-list-page

Vue2 + ElementUI CommonListPage component
9,010
Install
npm install wkjp-list-page
Latest Version:1.0.55
Vue:2
License:MIT
Last Updated:Aug 28, 2026
Links: npm
Maintainer: llzm

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.14
  • element-ui ^2.15.14(需引入 element-ui/lib/theme-chalk/index.css,并保证图标字体能被构建加载)

安装与注册

npm i wkjp-list-page
import 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 仅开启列配置:弹窗确定后,当前列配置数组。
track 埋点事件:用户点击「展开查询 / 收起查询 / 配置字段 / 重置」时触发,参数 { action, pageKey, timestamp };组件已内置百度统计上报,此事件用于额外接入,详见 §2.15。

2.15 监测「展开查询 / 收起查询 / 配置字段 / 重置」的点击次数(埋点)

情况: 想统计用户对搜索折叠、表头设置这几个操作的使用频率。 说明: 组件 内置了百度统计上报,并在以下四个动作发生时同时 $emit('track', payload),无需消费方手写上报逻辑。

动作 action 值 百度统计「事件操作」 触发时机
展开查询 expand-search 展开查询 点击「展开查询」
收起查询 fold-search 收起查询 点击「收起查询」
配置字段 column-config 配置字段 打开表头设置面板(关闭不计)
重置 clear-query 重置 点击「重置 / 清除查询」按钮

前置条件(零配置): 页面已引入百度统计代码(hm.js,全站一次,通常放 index.html 的 <head>),组件会自动 window._hmt.push(['_trackEvent', '列表页', 动作名, trackPageKey]) 上报。未引入 hm.js 时静默跳过,不报错。可选传 track-page-key 作为事件标签区分列表页。

<common-list-page track-page-key="设备列表" ... />

看数据: 百度统计后台 → 行为分析 → 事件分析,事件类别选「列表页」,按「事件操作」即可看到四个动作各自的触发次数(事件数据通常 次日 才出现)。

额外接其它埋点(可选): 仍可监听 @track,与内置上报并存:

<common-list-page @track="onListTrack" ... />
onListTrack({ action, pageKey, timestamp }) {
  // 例如再推一份到其它 SDK;百度统计已由组件内部自动上报
}

payload 字段:action(动作类型,见上表)、pageKey(即 track-page-key,未传为空串)、timestamp(Date.now() 毫秒时间戳)。


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 展开查询 / 收起 折叠按钮文案。
trackPageKey "" 埋点页面/业务标识,随 track 事件上报以区分列表页(见 §2.15)。
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(已发布版本不可覆盖)。

Related Packages

zfs-component

basic components of zfs

6,473
@fsscxh/zfs-component

basic components of zfs

3,796
ll-form-table

基于vue2.6和element-ui封装的以数据驱动视图的表单表格组件,将表单、表格由`templat...

330 0
otb-module

otb-module是基于现有的element-ui库进行的二次封装,简化组件的各自用法,将所有基础...

9,611
@itagan/form-table

Vue 2.7 + Element UI editable form table component.

1,461 0

Version History

Version Released Vue License
1.0.55 ^2.6.14 MIT
1.0.54 ^2.6.14 MIT
1.0.53 ^2.6.14 MIT
1.0.52 ^2.6.14 MIT
1.0.51 ^2.6.14 MIT