wkjp-list-page 1.0.0 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +267 -18
- package/package.json +44 -21
- package/src/components/CommonListPage.vue +997 -365
- package/src/components/FloatingDatePicker.vue +286 -0
- package/src/components/FloatingInput.vue +177 -0
- package/src/components/FloatingSelect.vue +182 -0
package/README.md
CHANGED
|
@@ -1,40 +1,206 @@
|
|
|
1
|
-
# wkjp-
|
|
1
|
+
# wkjp-list-page
|
|
2
2
|
|
|
3
|
-
基于
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
-
|
|
3
|
+
基于 **Vue 2** + **Element UI** 的通用列表页组件 `CommonListPage`:浮动标签搜索区、表格、分页、可选列配置弹窗、可选内置请求托管。
|
|
4
|
+
|
|
5
|
+
## 环境要求
|
|
6
|
+
|
|
7
|
+
- `vue` ^2.6.14
|
|
8
|
+
- `element-ui` ^2.15.14(需引入主题样式 `theme-chalk`,并保证 **icon 字体 woff/ttf** 能被构建工具正确加载)
|
|
8
9
|
|
|
9
10
|
## 安装
|
|
10
11
|
|
|
11
12
|
```bash
|
|
12
|
-
npm i wkjp-
|
|
13
|
+
npm i wkjp-list-page
|
|
13
14
|
```
|
|
14
15
|
|
|
15
|
-
##
|
|
16
|
+
## 全局注册
|
|
16
17
|
|
|
17
18
|
```js
|
|
18
19
|
import Vue from "vue";
|
|
19
20
|
import ElementUI from "element-ui";
|
|
20
21
|
import "element-ui/lib/theme-chalk/index.css";
|
|
21
|
-
import CommonListPage from "wkjp-
|
|
22
|
+
import CommonListPage from "wkjp-list-page";
|
|
22
23
|
|
|
23
24
|
Vue.use(ElementUI);
|
|
24
25
|
Vue.use(CommonListPage);
|
|
25
26
|
```
|
|
26
27
|
|
|
27
|
-
|
|
28
|
+
## 按需引入
|
|
28
29
|
|
|
29
30
|
```js
|
|
30
|
-
import { CommonListPage } from "wkjp-
|
|
31
|
+
import { CommonListPage } from "wkjp-list-page";
|
|
31
32
|
|
|
32
33
|
export default {
|
|
33
34
|
components: { CommonListPage }
|
|
34
35
|
};
|
|
35
36
|
```
|
|
36
37
|
|
|
37
|
-
|
|
38
|
+
---
|
|
39
|
+
|
|
40
|
+
## Props(传参说明)
|
|
41
|
+
|
|
42
|
+
| 属性 | 类型 | 必填 | 默认值 | 说明 |
|
|
43
|
+
|------|------|------|--------|------|
|
|
44
|
+
| `filters` | `Object` | 是 | — | 查询条件对象,与 `searchOption` 里各项的 `prop` 对应;组件会 **原地** `Vue.set` 更新字段,请传入可在父组件中改写的对象(勿用字面量每次新建)。 |
|
|
45
|
+
| `searchOption` | `Array` | 否 | `[]` | 搜索项配置数组,见下文 **searchOption 项结构**。 |
|
|
46
|
+
| `columns` | `Array` | 否 | `[]` | 表格列配置,见下文 **columns 列结构**。 |
|
|
47
|
+
| `tableData` | `Array` | 否 | `[]` | **非托管模式**:表格数据。 |
|
|
48
|
+
| `loading` | `Boolean` | 否 | `false` | **非托管模式**:加载状态。 |
|
|
49
|
+
| `pagination` | `Object` \| `null` | 否 | `null` | **非托管模式**:`{ total, page, pageSize, pSizes? }`;为 `null` 时不显示分页。托管模式下可被用来 **合并** 覆盖内部分页初始值。 |
|
|
50
|
+
| `tableAttrs` | `Object` | 否 | `{}` | 透传给 `el-table`(如 `stripe`、`border`、`height` 等)。 |
|
|
51
|
+
| `api` | `Function` | 否 | `null` | **托管模式**:`(params) => Promise`,返回接口原始数据。 |
|
|
52
|
+
| `buildParams` | `Function` | 否 | `null` | **托管模式**:`(filters, { page, pageSize }) => params`;不传则默认 `{ ...filters, currentPage, pageSize }`。 |
|
|
53
|
+
| `apiAdapter` | `Function` | 否 | `null` | **托管模式**:`(res) => ({ list, total })`;不传则尝试解析 `res.object.list` / `res.object.num`。 |
|
|
54
|
+
| `autoRequest` | `Boolean` | 否 | `true` | **托管模式**:是否在 `created` 时自动请求一次。 |
|
|
55
|
+
| `enableColumnConfig` | `Boolean` | 否 | `false` | 是否显示「配置表单」按钮及列显隐/排序弹窗。 |
|
|
56
|
+
| `tableHeaderBg` | `String` | 否 | `'#e5e9f2'` | 表头单元格背景色;内部合并进 `el-table` 的 `header-cell-style`。若同时在 `tableAttrs.header-cell-style` 里写了 `backgroundColor`,后者会覆盖同名属性(函数返回的对象会与底色合并)。 |
|
|
57
|
+
| `showQueryButton` | `Boolean` | 否 | `true` | 是否在筛选条件后显示蓝色「查询」按钮。**非托管**:点击触发 `query` 事件;**托管**:点击执行 `fetchList({ resetPage: true })`。不需要时可设为 `false`。 |
|
|
58
|
+
| `queryButtonText` | `String` | 否 | `'查询'` | 查询按钮文案。 |
|
|
59
|
+
|
|
60
|
+
### 两种数据模式
|
|
61
|
+
|
|
62
|
+
1. **非托管(外部控制数据)**
|
|
63
|
+
不传 `api`。父组件传入 `tableData`、`loading`、`pagination`,并监听 `query` / `page-change` / `size-change` 自行请求。
|
|
64
|
+
|
|
65
|
+
2. **托管(组件内请求)**
|
|
66
|
+
传入 `api`(可选 `buildParams`、`apiAdapter`)。组件内部维护 `loading`、列表与分页;仍可通过事件与 `fetched` 做额外逻辑。父组件可通过 `ref` 调用实例方法 **`fetchList({ resetPage })`** 手动刷新。
|
|
67
|
+
|
|
68
|
+
---
|
|
69
|
+
|
|
70
|
+
## Events(事件)
|
|
71
|
+
|
|
72
|
+
| 事件名 | 参数 | 说明 |
|
|
73
|
+
|--------|------|------|
|
|
74
|
+
| `query` | — | 非托管:搜索区 **回车** 或部分控件变更触发(见 `autoQuery`)。 |
|
|
75
|
+
| `page-change` | `page: number` | 页码变化;托管时组件内部已拉数,仍会向外抛。 |
|
|
76
|
+
| `size-change` | `size: number` | 每页条数变化;同上。 |
|
|
77
|
+
| `fetched` | `{ list, total, page, pageSize, raw }` | **仅托管模式**:每次 `api` 成功返回后触发。 |
|
|
78
|
+
| `columns-change` | `appliedColumns: Array` | 列配置弹窗点击确定后,返回当前生效列配置(含 `hidden`)。 |
|
|
79
|
+
|
|
80
|
+
---
|
|
81
|
+
|
|
82
|
+
## Slots(插槽)
|
|
83
|
+
|
|
84
|
+
| 插槽名 | 作用域 / 参数 | 说明 |
|
|
85
|
+
|--------|----------------|------|
|
|
86
|
+
| `search-extra` | — | 搜索表单 **内置「查询」按钮之后** 的额外内容(如「重置」「导出」),再往后才是右侧「配置表单」(若开启)。 |
|
|
87
|
+
| 动态名 | 由 `searchOption` 中 `type: 'slot'` 的 `slot` 字段指定 | 参数:`item`、`filters`。 |
|
|
88
|
+
| 动态名 | 由 `columns` 中 `type: 'slot'` 的 `slot` 字段指定 | 参数:`row`、`scope`(与 `el-table-column` 的 `slot-scope` 一致)。 |
|
|
89
|
+
|
|
90
|
+
**搜索区自定义示例:**
|
|
91
|
+
|
|
92
|
+
```js
|
|
93
|
+
// searchOption 中
|
|
94
|
+
{ type: "slot", slot: "myFilter", prop: "x" /* 可选 */ }
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
```vue
|
|
98
|
+
<common-list-page :search-option="searchOption" ...>
|
|
99
|
+
<template #myFilter="{ item, filters }">
|
|
100
|
+
<!-- 自定义内容,可读写 filters -->
|
|
101
|
+
</template>
|
|
102
|
+
</common-list-page>
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
**列自定义示例:**
|
|
106
|
+
|
|
107
|
+
```js
|
|
108
|
+
// columns 中
|
|
109
|
+
{ type: "slot", slot: "actions", label: "操作", width: 160, fixed: "right" }
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
```vue
|
|
113
|
+
<template #actions="{ row }">
|
|
114
|
+
<el-button type="text" @click="onView(row)">详情</el-button>
|
|
115
|
+
</template>
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
---
|
|
119
|
+
|
|
120
|
+
## searchOption 单项结构
|
|
121
|
+
|
|
122
|
+
每一项至少包含 `type`,按类型不同字段如下。
|
|
123
|
+
|
|
124
|
+
### 通用字段
|
|
125
|
+
|
|
126
|
+
| 字段 | 说明 |
|
|
127
|
+
|------|------|
|
|
128
|
+
| `type` | `'input'` \| `'select'` \| `'slot'` \| 日期类型见下 |
|
|
129
|
+
| `prop` | 对应 `filters[prop]`,**建议必填**(`slot` 可省略) |
|
|
130
|
+
| `label` | 浮动标签文案;与 `placeholder` 二选一,优先 `label` |
|
|
131
|
+
| `placeholder` | 无 `label` 时作为浮动标签文案 |
|
|
132
|
+
| `width` | 控件宽度(px 数字在模板里已拼成字符串) |
|
|
133
|
+
| `value` | 可选;若存在则 **显示值优先** 于 `filters[prop]`(`resolveValue`) |
|
|
134
|
+
| `autoQuery` | 默认 `true`;为 `false` 时变更后不自动 `query` / 内部 `fetchList` |
|
|
135
|
+
| `onChange` | `(val) => void`,值变化时回调 |
|
|
136
|
+
|
|
137
|
+
### `type: 'input'`
|
|
138
|
+
|
|
139
|
+
| 字段 | 说明 |
|
|
140
|
+
|------|------|
|
|
141
|
+
| `maxlength` | 原生 maxlength |
|
|
142
|
+
| `height` | 输入框高度,默认 `32px` |
|
|
143
|
+
| `clearable` | 当前实现为 `FloatingInput`,无清空按钮属性(可按需扩展) |
|
|
144
|
+
|
|
145
|
+
输入框仅 **回车** 时对外 `emit('query')`;输入过程只回写 `filters`。
|
|
146
|
+
|
|
147
|
+
### `type: 'select'`
|
|
148
|
+
|
|
149
|
+
| 字段 | 说明 |
|
|
150
|
+
|------|------|
|
|
151
|
+
| `options` | `[{ label, value }, ...]` |
|
|
152
|
+
| `multiple` | 是否多选 |
|
|
153
|
+
| `clearable` | 默认 `true`;设为 `false` 关闭清空 |
|
|
154
|
+
| `filterable` | 可搜索 |
|
|
155
|
+
| `disabled` | 禁用 |
|
|
156
|
+
| `size` | Element `size` |
|
|
157
|
+
|
|
158
|
+
### 日期类 `type`
|
|
159
|
+
|
|
160
|
+
支持:`date`、`daterange`、`datetime`、`datetimerange`、`month`、`year`。
|
|
161
|
+
|
|
162
|
+
| 字段 | 说明 |
|
|
163
|
+
|------|------|
|
|
164
|
+
| `valueFormat` | 默认 `'yyyy-MM-dd'` |
|
|
165
|
+
| `startPlaceholder` / `endPlaceholder` | **范围**时两侧浮动文案,默认「开始日期」「结束日期」 |
|
|
166
|
+
| `unlinkPanels` | 范围面板是否联动,默认 `true` |
|
|
167
|
+
| `rangeSeparator` | 默认 `'至'` |
|
|
168
|
+
| `editable` | 是否可键盘输入,默认 `false` |
|
|
169
|
+
| `width` | 范围默认宽度约 `300px`,可加大避免拥挤 |
|
|
170
|
+
|
|
171
|
+
### `type: 'slot'`
|
|
172
|
+
|
|
173
|
+
| 字段 | 说明 |
|
|
174
|
+
|------|------|
|
|
175
|
+
| `slot` | 与父组件 `<template #[slot]>` 名称一致 |
|
|
176
|
+
|
|
177
|
+
---
|
|
178
|
+
|
|
179
|
+
## columns 列结构
|
|
180
|
+
|
|
181
|
+
非 `slot` 列会 **整体 `v-bind` 到 `el-table-column`**,因此可直接使用 Element 文档中的列属性(`prop`、`label`、`width`、`minWidth`、`fixed`、`align` 等)。
|
|
182
|
+
|
|
183
|
+
组件内部用 `slot-scope` 包了一层默认展示:文本来自 **`resolveCellText`**。
|
|
184
|
+
|
|
185
|
+
| 字段 | 说明 |
|
|
186
|
+
|------|------|
|
|
187
|
+
| `type` | 不为 `'slot'` 时,也可为 `'index'` 等 Element 支持的列类型 |
|
|
188
|
+
| `prop` | 字段名 |
|
|
189
|
+
| `hidden` | `true` 隐藏列 |
|
|
190
|
+
| `valueGetter` | `(row, index) => any` 自定义取值 |
|
|
191
|
+
| `textFormatter` | `(value, row, index) => string` 格式化展示 |
|
|
192
|
+
| `defaultText` | 空值时展示,默认展示为 `'--'` |
|
|
193
|
+
| `type: 'slot'` | 必须同时提供 `slot`(插槽名),`type`/`slot` 不会透传给 `el-table-column` |
|
|
194
|
+
|
|
195
|
+
### 列配置弹窗(`enableColumnConfig: true`)
|
|
196
|
+
|
|
197
|
+
- `fixed: 'left' \| 'right'` 或 `configFixed: true` 的列视为 **固定列**,弹窗内 **不可拖拽换位**。
|
|
198
|
+
- 弹窗内顺序:左固定 → 普通 → 右固定。
|
|
199
|
+
- 确定后列上 `hidden` 与顺序会写入内部 `appliedColumns`,并 `columns-change` 通知父级。
|
|
200
|
+
|
|
201
|
+
---
|
|
202
|
+
|
|
203
|
+
## 完整示例(非托管)
|
|
38
204
|
|
|
39
205
|
```vue
|
|
40
206
|
<template>
|
|
@@ -42,14 +208,97 @@ export default {
|
|
|
42
208
|
:filters="filters"
|
|
43
209
|
:search-option="searchOption"
|
|
44
210
|
:columns="columns"
|
|
45
|
-
:
|
|
46
|
-
:
|
|
211
|
+
:table-data="list"
|
|
212
|
+
:loading="loading"
|
|
213
|
+
:pagination="pagination"
|
|
214
|
+
:table-attrs="{ stripe: true }"
|
|
215
|
+
:table-header-bg="tableHeaderBg"
|
|
216
|
+
show-query-button
|
|
217
|
+
@query="loadData"
|
|
218
|
+
@page-change="onPage"
|
|
219
|
+
@size-change="onSize"
|
|
47
220
|
/>
|
|
48
221
|
</template>
|
|
222
|
+
|
|
223
|
+
<script>
|
|
224
|
+
export default {
|
|
225
|
+
data() {
|
|
226
|
+
return {
|
|
227
|
+
/** 表头背景色,可写死或随主题/皮肤切换 */
|
|
228
|
+
tableHeaderBg: "#eef2f8",
|
|
229
|
+
filters: { name: "", status: "", range: [] },
|
|
230
|
+
list: [],
|
|
231
|
+
loading: false,
|
|
232
|
+
pagination: { total: 0, page: 1, pageSize: 10, pSizes: [10, 20, 50] },
|
|
233
|
+
searchOption: [
|
|
234
|
+
{ type: "input", prop: "name", placeholder: "姓名", autoQuery: false },
|
|
235
|
+
{
|
|
236
|
+
type: "select",
|
|
237
|
+
prop: "status",
|
|
238
|
+
placeholder: "状态",
|
|
239
|
+
options: [{ label: "启用", value: "1" }, { label: "禁用", value: "0" }],
|
|
240
|
+
autoQuery: false
|
|
241
|
+
},
|
|
242
|
+
{
|
|
243
|
+
type: "daterange",
|
|
244
|
+
prop: "range",
|
|
245
|
+
startPlaceholder: "开始日期",
|
|
246
|
+
endPlaceholder: "结束日期",
|
|
247
|
+
width: 380,
|
|
248
|
+
autoQuery: false
|
|
249
|
+
}
|
|
250
|
+
],
|
|
251
|
+
columns: [
|
|
252
|
+
{ type: "index", label: "#", width: 60 },
|
|
253
|
+
{ prop: "name", label: "姓名", minWidth: 120 },
|
|
254
|
+
{ type: "slot", slot: "op", label: "操作", width: 140, fixed: "right" }
|
|
255
|
+
]
|
|
256
|
+
};
|
|
257
|
+
},
|
|
258
|
+
methods: {
|
|
259
|
+
loadData() { /* 请求并赋值 list、pagination */ },
|
|
260
|
+
onPage(p) { this.pagination.page = p; this.loadData(); },
|
|
261
|
+
onSize(s) { this.pagination.pageSize = s; this.pagination.page = 1; this.loadData(); }
|
|
262
|
+
}
|
|
263
|
+
};
|
|
264
|
+
</script>
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
## 托管示例
|
|
268
|
+
|
|
269
|
+
```vue
|
|
270
|
+
<common-list-page
|
|
271
|
+
:filters="filters"
|
|
272
|
+
:search-option="searchOption"
|
|
273
|
+
:columns="columns"
|
|
274
|
+
:api="fetchApi"
|
|
275
|
+
:build-params="buildParams"
|
|
276
|
+
:api-adapter="adapter"
|
|
277
|
+
@fetched="onFetched"
|
|
278
|
+
/>
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
```js
|
|
282
|
+
methods: {
|
|
283
|
+
fetchApi(params) {
|
|
284
|
+
return this.$http.get("/api/list", { params });
|
|
285
|
+
},
|
|
286
|
+
buildParams(filters, { page, pageSize }) {
|
|
287
|
+
return { ...filters, page, size: pageSize };
|
|
288
|
+
},
|
|
289
|
+
adapter(res) {
|
|
290
|
+
return { list: res.data.rows, total: res.data.total };
|
|
291
|
+
},
|
|
292
|
+
onFetched({ list, total }) { /* ... */ }
|
|
293
|
+
}
|
|
49
294
|
```
|
|
50
295
|
|
|
51
|
-
|
|
296
|
+
父组件刷新:`this.$refs.listRef.fetchList({ resetPage: true })`(需给组件加 `ref="listRef"`)。
|
|
297
|
+
|
|
298
|
+
---
|
|
299
|
+
|
|
300
|
+
## 发布 npm
|
|
52
301
|
|
|
53
|
-
1. 修改 `package.json`
|
|
54
|
-
2.
|
|
55
|
-
3.
|
|
302
|
+
1. 修改 `package.json` 的 `name`、`version`
|
|
303
|
+
2. `npm login`
|
|
304
|
+
3. `npm publish`(scoped 包需 `--access public`)
|
package/package.json
CHANGED
|
@@ -1,21 +1,44 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "wkjp-list-page",
|
|
3
|
-
"version": "1.0.
|
|
4
|
-
"description": "Vue2 + ElementUI CommonListPage component",
|
|
5
|
-
"main": "src/index.js",
|
|
6
|
-
"module": "src/index.js",
|
|
7
|
-
"
|
|
8
|
-
"
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
"
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
"
|
|
18
|
-
"
|
|
19
|
-
|
|
20
|
-
"
|
|
21
|
-
|
|
1
|
+
{
|
|
2
|
+
"name": "wkjp-list-page",
|
|
3
|
+
"version": "1.0.1",
|
|
4
|
+
"description": "Vue2 + ElementUI CommonListPage component",
|
|
5
|
+
"main": "src/index.js",
|
|
6
|
+
"module": "src/index.js",
|
|
7
|
+
"scripts": {
|
|
8
|
+
"dev": "webpack-dev-server --config webpack.demo.js --mode development --open",
|
|
9
|
+
"build:demo": "webpack --config webpack.demo.js --mode production"
|
|
10
|
+
},
|
|
11
|
+
"files": [
|
|
12
|
+
"src"
|
|
13
|
+
],
|
|
14
|
+
"keywords": [
|
|
15
|
+
"vue2",
|
|
16
|
+
"element-ui",
|
|
17
|
+
"table",
|
|
18
|
+
"list"
|
|
19
|
+
],
|
|
20
|
+
"peerDependencies": {
|
|
21
|
+
"vue": "^2.6.14",
|
|
22
|
+
"element-ui": "^2.15.14"
|
|
23
|
+
},
|
|
24
|
+
"license": "MIT",
|
|
25
|
+
"devDependencies": {
|
|
26
|
+
"babel-core": "^6.26.3",
|
|
27
|
+
"babel-loader": "^6.2.10",
|
|
28
|
+
"css-loader": "^0.28.11",
|
|
29
|
+
"element-ui": "^2.15.14",
|
|
30
|
+
"html-webpack-plugin": "^4.5.2",
|
|
31
|
+
"style-loader": "^1.3.0",
|
|
32
|
+
"file-loader": "^6.2.0",
|
|
33
|
+
"url-loader": "^4.1.1",
|
|
34
|
+
"vue": "^2.7.16",
|
|
35
|
+
"vue-hot-reload-api": "^2.3.4",
|
|
36
|
+
"vue-loader": "^15.10.2",
|
|
37
|
+
"vue-style-loader": "^4.1.3",
|
|
38
|
+
"vue-template-compiler": "^2.7.16",
|
|
39
|
+
"webpack": "^4.47.0",
|
|
40
|
+
"webpack-cli": "^3.3.12",
|
|
41
|
+
"webpack-dev-server": "^3.11.3"
|
|
42
|
+
},
|
|
43
|
+
"dependencies": {}
|
|
44
|
+
}
|