select-pagination-element-plus 0.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 +143 -0
- package/README.zh-CN.md +143 -0
- package/dist/SelectPagination.vue.d.ts +215 -0
- package/dist/index.cjs +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +287 -0
- package/dist/style.css +1 -0
- package/package.json +42 -0
package/README.md
ADDED
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
# SelectPagination (Element Plus)
|
|
2
|
+
|
|
3
|
+
[中文文档](./README.zh-CN.md)
|
|
4
|
+
|
|
5
|
+
`SelectPagination` is a Vue 3 + Element Plus `<el-select>` wrapper that supports remote search + paginated loading (infinite load) with optional cache and value echo (detail API).
|
|
6
|
+
|
|
7
|
+
## Features
|
|
8
|
+
|
|
9
|
+
- Remote search + pagination (`api`, `pageKey`, `sizeKey`, `keyword`, `responsePath`)
|
|
10
|
+
- Infinite loading via `IntersectionObserver` (no scroll listener / no Element Plus internal class dependency)
|
|
11
|
+
- Optional cache (`enableCache`, `cacheKey`)
|
|
12
|
+
- Optional “value echo” (`detailApi`)
|
|
13
|
+
- Supports single / multiple select
|
|
14
|
+
- Footer slot to fully customize “loading / no more / load more”
|
|
15
|
+
|
|
16
|
+
## Requirements
|
|
17
|
+
|
|
18
|
+
- Vue 3
|
|
19
|
+
- Element Plus
|
|
20
|
+
|
|
21
|
+
## Install
|
|
22
|
+
|
|
23
|
+
Replace `YOUR_PACKAGE_NAME` with your published npm package name.
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
npm i YOUR_PACKAGE_NAME
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## Basic Usage
|
|
30
|
+
|
|
31
|
+
```vue
|
|
32
|
+
<template>
|
|
33
|
+
<SelectPagination v-model="value" :api="fetchUsers" placeholder="Type to search" />
|
|
34
|
+
</template>
|
|
35
|
+
|
|
36
|
+
<script setup lang="ts">
|
|
37
|
+
import { ref } from 'vue'
|
|
38
|
+
import SelectPagination from 'YOUR_PACKAGE_NAME'
|
|
39
|
+
|
|
40
|
+
const value = ref('')
|
|
41
|
+
|
|
42
|
+
const fetchUsers = async (params: any) => {
|
|
43
|
+
// params = { page, size, name, ...yourExtraParams }
|
|
44
|
+
// Must return an object that contains { content, totalElements } at responsePath (default: data.data)
|
|
45
|
+
return {
|
|
46
|
+
data: {
|
|
47
|
+
data: {
|
|
48
|
+
content: [
|
|
49
|
+
{ id: 'u-1', label: 'User 1', value: 'u-1' },
|
|
50
|
+
{ id: 'u-2', label: 'User 2', value: 'u-2' }
|
|
51
|
+
],
|
|
52
|
+
totalElements: 2
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
</script>
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
## API Response Format
|
|
61
|
+
|
|
62
|
+
By default `responsePath = "data.data"`, which should point to an object like:
|
|
63
|
+
|
|
64
|
+
```ts
|
|
65
|
+
{
|
|
66
|
+
content: any[]
|
|
67
|
+
totalElements: number
|
|
68
|
+
}
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
If your backend returns a different shape, set `responsePath` accordingly.
|
|
72
|
+
|
|
73
|
+
## Props
|
|
74
|
+
|
|
75
|
+
| Prop | Type | Default | Description |
|
|
76
|
+
| --- | --- | --- | --- |
|
|
77
|
+
| modelValue | `string \| number \| any[]` | `''` | v-model |
|
|
78
|
+
| isRemote | `boolean` | `true` | Enables Element Plus remote mode (`:remote`) |
|
|
79
|
+
| api | `(params) => any` or `() => (params) => any` | - | Fetch list API |
|
|
80
|
+
| apiAsync | `boolean` | `false` | If `true`, treat `api` as a factory (`() => apiFn`) |
|
|
81
|
+
| params | `object \| () => object` | `{}` | Extra query params merged into request |
|
|
82
|
+
| labelField | `string` | `'label'` | Option label field |
|
|
83
|
+
| valueField | `string` | `'value'` | Option value field |
|
|
84
|
+
| pageSize | `number` | `10` | Page size |
|
|
85
|
+
| pageKey | `string` | `'page'` | Page number param key |
|
|
86
|
+
| sizeKey | `string` | `'size'` | Page size param key |
|
|
87
|
+
| keyword | `string` | `'name'` | Search keyword param key |
|
|
88
|
+
| responsePath | `string` | `'data.data'` | Path to `{ content, totalElements }` |
|
|
89
|
+
| enableCache | `boolean` | `true` | Cache options/paging/keyword |
|
|
90
|
+
| cacheKey | `string` | `''` | Cache namespace; if empty, generated from `api.name + params` |
|
|
91
|
+
| changeDetail | `boolean` | `false` | Emit selected option detail(s) |
|
|
92
|
+
| detailApi | `(value) => any` | `null` | Fetch option detail for echo |
|
|
93
|
+
| initOptions | `any[]` | `[]` | Initial options appended into options list |
|
|
94
|
+
| popperClass | `string` | `''` | Extra popper class (scoped styles rely on `select-pagination-popper`) |
|
|
95
|
+
| footerSentinelId | `string` | `''` | Custom sentinel element id for infinite loading |
|
|
96
|
+
|
|
97
|
+
## Events
|
|
98
|
+
|
|
99
|
+
| Event | Payload | Description |
|
|
100
|
+
| --- | --- | --- |
|
|
101
|
+
| update:modelValue | `any` | v-model update |
|
|
102
|
+
| change | `any` | same as Element Plus change |
|
|
103
|
+
| change-detail | `any \| any[] \| null` | selected option detail(s) when `changeDetail = true` |
|
|
104
|
+
|
|
105
|
+
## Slots
|
|
106
|
+
|
|
107
|
+
### footer
|
|
108
|
+
|
|
109
|
+
Slot props:
|
|
110
|
+
|
|
111
|
+
- `loading`: `boolean`
|
|
112
|
+
- `hasMore`: `boolean`
|
|
113
|
+
- `options`: `any[]`
|
|
114
|
+
- `loadMore`: `() => void`
|
|
115
|
+
|
|
116
|
+
Example:
|
|
117
|
+
|
|
118
|
+
```vue
|
|
119
|
+
<SelectPagination v-model="value" :api="fetchUsers" footer-sentinel-id="user-select-footer">
|
|
120
|
+
<template #footer="{ loading, hasMore, loadMore }">
|
|
121
|
+
<div v-if="loading" style="padding: 8px 0; text-align: center">Loading...</div>
|
|
122
|
+
<div v-else-if="!hasMore" style="padding: 8px 0; text-align: center">No more</div>
|
|
123
|
+
<div v-else style="padding: 8px 0; text-align: center; cursor: pointer" @click="loadMore">
|
|
124
|
+
Click to load more
|
|
125
|
+
</div>
|
|
126
|
+
</template>
|
|
127
|
+
</SelectPagination>
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
## Exposed Methods
|
|
131
|
+
|
|
132
|
+
Access via template ref:
|
|
133
|
+
|
|
134
|
+
- `loadData(isReset?: boolean)`
|
|
135
|
+
- `clearCache()`
|
|
136
|
+
- `restoreCache()`
|
|
137
|
+
- `updateValue(val)`
|
|
138
|
+
- `loadEchoData()`
|
|
139
|
+
- `setPage(page: number)`
|
|
140
|
+
- `setOptions(options: any[])`
|
|
141
|
+
- `options` (ref)
|
|
142
|
+
- `currentPage` (ref)
|
|
143
|
+
|
package/README.zh-CN.md
ADDED
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
# SelectPagination(Element Plus)
|
|
2
|
+
|
|
3
|
+
[English](./README.md)
|
|
4
|
+
|
|
5
|
+
`SelectPagination` 是一个基于 Vue 3 + Element Plus 的 `<el-select>` 封装组件,支持远程搜索 + 分页加载(无限滚动/触底加载),并提供可选缓存与回显能力(detailApi)。
|
|
6
|
+
|
|
7
|
+
## 特性
|
|
8
|
+
|
|
9
|
+
- 远程搜索 + 分页(`api`, `pageKey`, `sizeKey`, `keyword`, `responsePath`)
|
|
10
|
+
- 使用 `IntersectionObserver` 实现触底加载(不绑定 scroll 事件 / 不依赖 Element Plus 内部 class)
|
|
11
|
+
- 可选缓存(`enableCache`, `cacheKey`)
|
|
12
|
+
- 可选回显(`detailApi`)
|
|
13
|
+
- 支持单选 / 多选
|
|
14
|
+
- `footer` slot 可完全自定义“加载中/没有更多/加载更多”
|
|
15
|
+
|
|
16
|
+
## 环境要求
|
|
17
|
+
|
|
18
|
+
- Vue 3
|
|
19
|
+
- Element Plus
|
|
20
|
+
|
|
21
|
+
## 安装
|
|
22
|
+
|
|
23
|
+
把 `YOUR_PACKAGE_NAME` 替换成你发布到 npm 的包名。
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
npm i YOUR_PACKAGE_NAME
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## 基础使用
|
|
30
|
+
|
|
31
|
+
```vue
|
|
32
|
+
<template>
|
|
33
|
+
<SelectPagination v-model="value" :api="fetchUsers" placeholder="输入关键词搜索" />
|
|
34
|
+
</template>
|
|
35
|
+
|
|
36
|
+
<script setup lang="ts">
|
|
37
|
+
import { ref } from 'vue'
|
|
38
|
+
import SelectPagination from 'YOUR_PACKAGE_NAME'
|
|
39
|
+
|
|
40
|
+
const value = ref('')
|
|
41
|
+
|
|
42
|
+
const fetchUsers = async (params: any) => {
|
|
43
|
+
// params = { page, size, name, ...你额外的 params }
|
|
44
|
+
// 必须在 responsePath(默认:data.data)对应的位置返回 { content, totalElements }
|
|
45
|
+
return {
|
|
46
|
+
data: {
|
|
47
|
+
data: {
|
|
48
|
+
content: [
|
|
49
|
+
{ id: 'u-1', label: '用户 1', value: 'u-1' },
|
|
50
|
+
{ id: 'u-2', label: '用户 2', value: 'u-2' }
|
|
51
|
+
],
|
|
52
|
+
totalElements: 2
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
</script>
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
## 接口返回格式
|
|
61
|
+
|
|
62
|
+
默认 `responsePath = "data.data"`,该路径需要指向如下对象:
|
|
63
|
+
|
|
64
|
+
```ts
|
|
65
|
+
{
|
|
66
|
+
content: any[]
|
|
67
|
+
totalElements: number
|
|
68
|
+
}
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
如果你的后端返回结构不同,调整 `responsePath` 即可。
|
|
72
|
+
|
|
73
|
+
## Props
|
|
74
|
+
|
|
75
|
+
| 参数 | 类型 | 默认值 | 说明 |
|
|
76
|
+
| --- | --- | --- | --- |
|
|
77
|
+
| modelValue | `string \| number \| any[]` | `''` | v-model |
|
|
78
|
+
| isRemote | `boolean` | `true` | 是否启用 Element Plus 的 remote 模式(`:remote`) |
|
|
79
|
+
| api | `(params) => any` 或 `() => (params) => any` | - | 拉取列表数据的 API |
|
|
80
|
+
| apiAsync | `boolean` | `false` | 为 `true` 时,`api` 视为工厂函数(`() => apiFn`) |
|
|
81
|
+
| params | `object \| () => object` | `{}` | 额外查询参数(会合并进请求参数) |
|
|
82
|
+
| labelField | `string` | `'label'` | label 字段名 |
|
|
83
|
+
| valueField | `string` | `'value'` | value 字段名 |
|
|
84
|
+
| pageSize | `number` | `10` | 每页数量 |
|
|
85
|
+
| pageKey | `string` | `'page'` | 页码参数名 |
|
|
86
|
+
| sizeKey | `string` | `'size'` | 每页大小参数名 |
|
|
87
|
+
| keyword | `string` | `'name'` | 搜索关键词参数名 |
|
|
88
|
+
| responsePath | `string` | `'data.data'` | 响应中 `{ content, totalElements }` 的路径 |
|
|
89
|
+
| enableCache | `boolean` | `true` | 是否启用缓存 |
|
|
90
|
+
| cacheKey | `string` | `''` | 缓存命名空间;为空时由 `api.name + params` 生成 |
|
|
91
|
+
| changeDetail | `boolean` | `false` | 是否在 change 时额外返回选中项详情 |
|
|
92
|
+
| detailApi | `(value) => any` | `null` | 回显用详情接口(通过 value 拉取对应 option 数据) |
|
|
93
|
+
| initOptions | `any[]` | `[]` | 初始 options,会合并进 options 列表 |
|
|
94
|
+
| popperClass | `string` | `''` | 额外 popper class(组件样式基于 `select-pagination-popper` 作用域) |
|
|
95
|
+
| footerSentinelId | `string` | `''` | 自定义 footer sentinel 的 DOM id(用于触底加载定位) |
|
|
96
|
+
|
|
97
|
+
## 事件
|
|
98
|
+
|
|
99
|
+
| 事件 | 参数 | 说明 |
|
|
100
|
+
| --- | --- | --- |
|
|
101
|
+
| update:modelValue | `any` | v-model 更新 |
|
|
102
|
+
| change | `any` | 选中值变化 |
|
|
103
|
+
| change-detail | `any \| any[] \| null` | `changeDetail = true` 时返回选中项详情(单选/多选) |
|
|
104
|
+
|
|
105
|
+
## Slots
|
|
106
|
+
|
|
107
|
+
### footer
|
|
108
|
+
|
|
109
|
+
slot 参数:
|
|
110
|
+
|
|
111
|
+
- `loading`: `boolean`
|
|
112
|
+
- `hasMore`: `boolean`
|
|
113
|
+
- `options`: `any[]`
|
|
114
|
+
- `loadMore`: `() => void`
|
|
115
|
+
|
|
116
|
+
示例:
|
|
117
|
+
|
|
118
|
+
```vue
|
|
119
|
+
<SelectPagination v-model="value" :api="fetchUsers" footer-sentinel-id="user-select-footer">
|
|
120
|
+
<template #footer="{ loading, hasMore, loadMore }">
|
|
121
|
+
<div v-if="loading" style="padding: 8px 0; text-align: center">加载中...</div>
|
|
122
|
+
<div v-else-if="!hasMore" style="padding: 8px 0; text-align: center">没有更多了</div>
|
|
123
|
+
<div v-else style="padding: 8px 0; text-align: center; cursor: pointer" @click="loadMore">
|
|
124
|
+
点击加载更多
|
|
125
|
+
</div>
|
|
126
|
+
</template>
|
|
127
|
+
</SelectPagination>
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
## 暴露方法(ref)
|
|
131
|
+
|
|
132
|
+
通过组件 ref 访问:
|
|
133
|
+
|
|
134
|
+
- `loadData(isReset?: boolean)`
|
|
135
|
+
- `clearCache()`
|
|
136
|
+
- `restoreCache()`
|
|
137
|
+
- `updateValue(val)`
|
|
138
|
+
- `loadEchoData()`
|
|
139
|
+
- `setPage(page: number)`
|
|
140
|
+
- `setOptions(options: any[])`
|
|
141
|
+
- `options`(ref)
|
|
142
|
+
- `currentPage`(ref)
|
|
143
|
+
|
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
import { PropType } from 'vue';
|
|
2
|
+
type ApiParams = Record<string, any>;
|
|
3
|
+
type ApiFunction = (params: ApiParams) => any;
|
|
4
|
+
type ApiFactory = () => ApiFunction | Promise<ApiFunction>;
|
|
5
|
+
type ApiProp = ApiFunction | ApiFactory;
|
|
6
|
+
type ParamsSource = ApiParams | (() => ApiParams);
|
|
7
|
+
type DetailApiFunction = (value: any) => any;
|
|
8
|
+
declare var __VLS_16: {
|
|
9
|
+
loading: boolean;
|
|
10
|
+
hasMore: boolean;
|
|
11
|
+
options: any[];
|
|
12
|
+
loadMore: () => void;
|
|
13
|
+
};
|
|
14
|
+
type __VLS_Slots = {} & {
|
|
15
|
+
footer?: (props: typeof __VLS_16) => any;
|
|
16
|
+
};
|
|
17
|
+
declare const __VLS_component: import("vue").DefineComponent<import("vue").ExtractPropTypes<{
|
|
18
|
+
isRemote: {
|
|
19
|
+
type: BooleanConstructor;
|
|
20
|
+
default: boolean;
|
|
21
|
+
};
|
|
22
|
+
modelValue: {
|
|
23
|
+
type: PropType<string | number | Array<any>>;
|
|
24
|
+
default: string;
|
|
25
|
+
};
|
|
26
|
+
api: {
|
|
27
|
+
type: PropType<ApiProp>;
|
|
28
|
+
required: false;
|
|
29
|
+
};
|
|
30
|
+
apiAsync: {
|
|
31
|
+
type: BooleanConstructor;
|
|
32
|
+
default: boolean;
|
|
33
|
+
};
|
|
34
|
+
params: {
|
|
35
|
+
type: PropType<ParamsSource>;
|
|
36
|
+
default: () => {};
|
|
37
|
+
};
|
|
38
|
+
labelField: {
|
|
39
|
+
type: StringConstructor;
|
|
40
|
+
default: string;
|
|
41
|
+
};
|
|
42
|
+
valueField: {
|
|
43
|
+
type: StringConstructor;
|
|
44
|
+
default: string;
|
|
45
|
+
};
|
|
46
|
+
pageSize: {
|
|
47
|
+
type: NumberConstructor;
|
|
48
|
+
default: number;
|
|
49
|
+
};
|
|
50
|
+
pageKey: {
|
|
51
|
+
type: StringConstructor;
|
|
52
|
+
default: string;
|
|
53
|
+
};
|
|
54
|
+
sizeKey: {
|
|
55
|
+
type: StringConstructor;
|
|
56
|
+
default: string;
|
|
57
|
+
};
|
|
58
|
+
keyword: {
|
|
59
|
+
type: StringConstructor;
|
|
60
|
+
default: string;
|
|
61
|
+
};
|
|
62
|
+
responsePath: {
|
|
63
|
+
type: StringConstructor;
|
|
64
|
+
default: string;
|
|
65
|
+
};
|
|
66
|
+
enableCache: {
|
|
67
|
+
type: BooleanConstructor;
|
|
68
|
+
default: boolean;
|
|
69
|
+
};
|
|
70
|
+
cacheKey: {
|
|
71
|
+
type: StringConstructor;
|
|
72
|
+
default: string;
|
|
73
|
+
};
|
|
74
|
+
changeDetail: {
|
|
75
|
+
type: BooleanConstructor;
|
|
76
|
+
default: boolean;
|
|
77
|
+
};
|
|
78
|
+
detailApi: {
|
|
79
|
+
type: PropType<DetailApiFunction | null>;
|
|
80
|
+
default: null;
|
|
81
|
+
};
|
|
82
|
+
initOptions: {
|
|
83
|
+
type: PropType<any[]>;
|
|
84
|
+
default: () => never[];
|
|
85
|
+
};
|
|
86
|
+
popperClass: {
|
|
87
|
+
type: StringConstructor;
|
|
88
|
+
default: string;
|
|
89
|
+
};
|
|
90
|
+
footerSentinelId: {
|
|
91
|
+
type: StringConstructor;
|
|
92
|
+
default: string;
|
|
93
|
+
};
|
|
94
|
+
}>, {
|
|
95
|
+
loadData: (isReset?: boolean) => Promise<void>;
|
|
96
|
+
clearCache: () => void;
|
|
97
|
+
restoreCache: () => boolean;
|
|
98
|
+
updateValue: (val: any) => void;
|
|
99
|
+
loadEchoData: () => Promise<void>;
|
|
100
|
+
options: import("vue").Ref<any[], any[]>;
|
|
101
|
+
currentPage: import("vue").Ref<number, number>;
|
|
102
|
+
setPage: (page: number) => void;
|
|
103
|
+
setOptions: (newOptions: any[]) => void;
|
|
104
|
+
}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
105
|
+
"update:modelValue": (...args: any[]) => void;
|
|
106
|
+
change: (...args: any[]) => void;
|
|
107
|
+
"change-detail": (...args: any[]) => void;
|
|
108
|
+
}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
|
|
109
|
+
isRemote: {
|
|
110
|
+
type: BooleanConstructor;
|
|
111
|
+
default: boolean;
|
|
112
|
+
};
|
|
113
|
+
modelValue: {
|
|
114
|
+
type: PropType<string | number | Array<any>>;
|
|
115
|
+
default: string;
|
|
116
|
+
};
|
|
117
|
+
api: {
|
|
118
|
+
type: PropType<ApiProp>;
|
|
119
|
+
required: false;
|
|
120
|
+
};
|
|
121
|
+
apiAsync: {
|
|
122
|
+
type: BooleanConstructor;
|
|
123
|
+
default: boolean;
|
|
124
|
+
};
|
|
125
|
+
params: {
|
|
126
|
+
type: PropType<ParamsSource>;
|
|
127
|
+
default: () => {};
|
|
128
|
+
};
|
|
129
|
+
labelField: {
|
|
130
|
+
type: StringConstructor;
|
|
131
|
+
default: string;
|
|
132
|
+
};
|
|
133
|
+
valueField: {
|
|
134
|
+
type: StringConstructor;
|
|
135
|
+
default: string;
|
|
136
|
+
};
|
|
137
|
+
pageSize: {
|
|
138
|
+
type: NumberConstructor;
|
|
139
|
+
default: number;
|
|
140
|
+
};
|
|
141
|
+
pageKey: {
|
|
142
|
+
type: StringConstructor;
|
|
143
|
+
default: string;
|
|
144
|
+
};
|
|
145
|
+
sizeKey: {
|
|
146
|
+
type: StringConstructor;
|
|
147
|
+
default: string;
|
|
148
|
+
};
|
|
149
|
+
keyword: {
|
|
150
|
+
type: StringConstructor;
|
|
151
|
+
default: string;
|
|
152
|
+
};
|
|
153
|
+
responsePath: {
|
|
154
|
+
type: StringConstructor;
|
|
155
|
+
default: string;
|
|
156
|
+
};
|
|
157
|
+
enableCache: {
|
|
158
|
+
type: BooleanConstructor;
|
|
159
|
+
default: boolean;
|
|
160
|
+
};
|
|
161
|
+
cacheKey: {
|
|
162
|
+
type: StringConstructor;
|
|
163
|
+
default: string;
|
|
164
|
+
};
|
|
165
|
+
changeDetail: {
|
|
166
|
+
type: BooleanConstructor;
|
|
167
|
+
default: boolean;
|
|
168
|
+
};
|
|
169
|
+
detailApi: {
|
|
170
|
+
type: PropType<DetailApiFunction | null>;
|
|
171
|
+
default: null;
|
|
172
|
+
};
|
|
173
|
+
initOptions: {
|
|
174
|
+
type: PropType<any[]>;
|
|
175
|
+
default: () => never[];
|
|
176
|
+
};
|
|
177
|
+
popperClass: {
|
|
178
|
+
type: StringConstructor;
|
|
179
|
+
default: string;
|
|
180
|
+
};
|
|
181
|
+
footerSentinelId: {
|
|
182
|
+
type: StringConstructor;
|
|
183
|
+
default: string;
|
|
184
|
+
};
|
|
185
|
+
}>> & Readonly<{
|
|
186
|
+
"onUpdate:modelValue"?: ((...args: any[]) => any) | undefined;
|
|
187
|
+
onChange?: ((...args: any[]) => any) | undefined;
|
|
188
|
+
"onChange-detail"?: ((...args: any[]) => any) | undefined;
|
|
189
|
+
}>, {
|
|
190
|
+
isRemote: boolean;
|
|
191
|
+
modelValue: string | number | any[];
|
|
192
|
+
apiAsync: boolean;
|
|
193
|
+
params: ParamsSource;
|
|
194
|
+
labelField: string;
|
|
195
|
+
valueField: string;
|
|
196
|
+
pageSize: number;
|
|
197
|
+
pageKey: string;
|
|
198
|
+
sizeKey: string;
|
|
199
|
+
keyword: string;
|
|
200
|
+
responsePath: string;
|
|
201
|
+
enableCache: boolean;
|
|
202
|
+
cacheKey: string;
|
|
203
|
+
changeDetail: boolean;
|
|
204
|
+
detailApi: DetailApiFunction | null;
|
|
205
|
+
initOptions: any[];
|
|
206
|
+
popperClass: string;
|
|
207
|
+
footerSentinelId: string;
|
|
208
|
+
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
|
209
|
+
declare const _default: __VLS_WithSlots<typeof __VLS_component, __VLS_Slots>;
|
|
210
|
+
export default _default;
|
|
211
|
+
type __VLS_WithSlots<T, S> = T & {
|
|
212
|
+
new (): {
|
|
213
|
+
$slots: S;
|
|
214
|
+
};
|
|
215
|
+
};
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const a=require("vue"),le=require("lodash-es"),ne={style:{width:"100%"}},oe=["id"],re={key:0,class:"loading-more"},se={key:1,class:"no-more"},ie="select-pagination-popper",ue=a.defineComponent({__name:"SelectPagination",props:{isRemote:{type:Boolean,default:!0},modelValue:{type:[String,Number,Array],default:""},api:{type:Function,required:!1},apiAsync:{type:Boolean,default:!1},params:{type:[Object,Function],default:()=>({})},labelField:{type:String,default:"label"},valueField:{type:String,default:"value"},pageSize:{type:Number,default:10},pageKey:{type:String,default:"page"},sizeKey:{type:String,default:"size"},keyword:{type:String,default:"name"},responsePath:{type:String,default:"data.data"},enableCache:{type:Boolean,default:!0},cacheKey:{type:String,default:""},changeDetail:{type:Boolean,default:!1},detailApi:{type:Function,default:null},initOptions:{type:Array,default:()=>[]},popperClass:{type:String,default:""},footerSentinelId:{type:String,default:""}},emits:["update:modelValue","change","change-detail"],setup(v,{expose:C,emit:y}){var K;const V=new Map,t=v,g=y,_=a.useAttrs(),z=((K=a.getCurrentInstance())==null?void 0:K.uid)??Date.now(),I=a.computed(()=>t.footerSentinelId||`select-pagination-footer-${z}`),T=a.computed(()=>{const e=_["popper-class"]??_.popperClass;return typeof e=="string"?e:""}),L=a.computed(()=>[T.value,t.popperClass,ie].filter(Boolean).join(" ")),k=e=>{if(S.value=!0,g("update:modelValue",e),g("change",e),e&&t.changeDetail){let l=null;Array.isArray(e)?l=r.value.filter(n=>e.find(o=>n[d.value]===o)):l=r.value.find(n=>n[d.value]===e),g("change-detail",l)}},r=a.ref([]),s=a.ref(!1),i=a.ref(!0),c=a.ref(1),m=a.ref(""),D=a.ref(!1),S=a.ref(!1),B=V,O=()=>{var n;if(t.cacheKey)return t.cacheKey;const e=((n=t==null?void 0:t.api)==null?void 0:n.name)||"anonymous",l=JSON.stringify(t.params);return`${e}_${btoa(l)}`},R=()=>{if(!t.enableCache)return;const e=O();B.set(e,{options:[...r.value],currentPage:c.value,hasMore:i.value,keyword:m.value})},P=()=>{if(!t.enableCache)return!1;const e=O(),l=B.get(e);return l?(r.value=[...l.options],c.value=l.currentPage,i.value=l.hasMore,m.value=l.keyword,!0):!1},b=()=>{if(!t.enableCache)return;const e=O();B.delete(e)},j=a.computed(()=>t.labelField),d=a.computed(()=>t.valueField),U=(e,l)=>l.split(".").reduce((n,o)=>{if(n!=null)return n[o]},e),E=a.computed(()=>t.isRemote&&typeof t.api=="function");let p=null,h=null;const A=()=>{h&&(h.disconnect(),h=null),p=null},H=e=>{if(!e)return null;let l=e.parentElement;for(;l;){const o=window.getComputedStyle(l).overflowY;if((o==="auto"||o==="scroll"||o==="overlay")&&l.scrollHeight>l.clientHeight)return l;l=l.parentElement}return null},Y=async()=>{if(A(),!E.value)return;await a.nextTick();const e=document.getElementById(I.value);e&&(p=H(e),h=new IntersectionObserver(l=>{const n=l[0];n!=null&&n.isIntersecting&&E.value&&(s.value||i.value&&f())},{root:p,rootMargin:"0px 0px 120px 0px",threshold:0}),h.observe(e))},J=(e=!0)=>{r.value=e&&t.initOptions&&t.initOptions.length>0?[...t.initOptions]:[],c.value=1,i.value=!0,m.value="",s.value=!1},f=async(e=!1)=>{if(s.value)return;let l=0;e||p&&(l=p.scrollTop),e&&(r.value=[],c.value=1,i.value=!0,b()),s.value=!0;try{const o={...(typeof t.params=="function"?t.params():t.params)||{},[t.pageKey]:c.value,[t.sizeKey]:t.pageSize,[t.keyword]:m.value};if(!t.api)return;const u=await(t.apiAsync?await t.api():t.api)(o),F=U(u,t.responsePath);if(F){const q=F.content??[],ee=F.totalElements??0,te=r.value.length;if(e)r.value=q||[];else{const ae=W(q||[]);r.value=[...r.value,...ae]}i.value=r.value.length<ee,i.value&&c.value++,R(),!e&&p&&te>0&&(await a.nextTick(),requestAnimationFrame(()=>{p&&(p.scrollTop=l)}))}else console.error("响应数据格式不正确",u)}catch(n){console.error("加载数据失败",n)}finally{s.value=!1}},w=a.ref(!1),G=e=>{w.value||m.value!==e&&(m.value=e,f(!0))},Q=e=>{e?(!P()&&r.value.length===0&&f(!0),Y()):A()},M=async()=>{const e=Array.isArray(t.modelValue)?t.modelValue.length>0:!!t.modelValue;if(!(!t.detailApi||!e||D.value))try{s.value=!0;let l=[];if(Array.isArray(t.modelValue)){for(const n of t.modelValue)if(n){const o=await t.detailApi(n);o&&o.data&&l.push(o.data)}}else{let o=await t.detailApi(t.modelValue);for(;o&&!o.id&&o.data;)o=o.data;o&&o.id&&(l=[o])}l.length>0&&(r.value=[...l,...r.value]),D.value=!0}catch(l){console.error("加载回显数据失败",l)}finally{s.value=!1}},W=e=>{const l=new Set(r.value.map(n=>n[d.value]));return e.filter(n=>!l.has(n[d.value]))},X=async()=>{t.initOptions&&t.initOptions.length>0&&(r.value=[...t.initOptions]),P()||(await M(),t.modelValue&&r.value.length===0&&await f(!0))};a.onMounted(()=>{X()}),a.watch(()=>t.api,(e,l)=>{e!==l&&(J(!0),b(),l&&!e&&(g("update:modelValue",""),g("change","")),t.modelValue&&e&&f(!0))},{immediate:!1}),a.watch(()=>t.params,(e,l)=>{le.isEqual(e,l)||(b(),t.initOptions&&t.initOptions.length>0&&(r.value=[...t.initOptions]),f(!0),_.multiple?k([]):k(""))},{deep:!0}),a.watch(()=>t.modelValue,async(e,l)=>{e&&e!==l&&t.detailApi&&!S.value&&await M(),S.value&&(S.value=!1)},{immediate:!1});const N=()=>{!s.value&&i.value&&f()},Z=()=>{w.value&&(w.value=!1)};return a.watch(()=>t.initOptions,e=>{if(e&&e.length>0){const l=new Set(r.value.map(o=>o[d.value])),n=e.filter(o=>!l.has(o[d.value]));r.value=[...n,...r.value]}},{immediate:!0,deep:!0}),C({loadData:f,clearCache:b,restoreCache:P,updateValue:k,loadEchoData:M,options:r,currentPage:c,setPage:e=>{c.value=e},setOptions:e=>{r.value=[...e]}}),a.onBeforeUnmount(()=>{A()}),(e,l)=>{const n=a.resolveComponent("el-option"),o=a.resolveComponent("el-select"),x=a.resolveDirective("loading");return a.withDirectives((a.openBlock(),a.createElementBlock("div",ne,[a.createVNode(o,a.mergeProps({"model-value":v.modelValue,"onUpdate:modelValue":k},e.$attrs,{"popper-class":L.value,"remote-method":G,filterable:!0,remote:v.isRemote,onVisibleChange:Q,onCompositionstart:l[0]||(l[0]=u=>w.value=!0),onCompositionend:Z,clearable:"","remote-show-suffix":""}),{default:a.withCtx(()=>[(a.openBlock(!0),a.createElementBlock(a.Fragment,null,a.renderList(r.value,u=>(a.openBlock(),a.createBlock(n,{key:u[d.value]??u.id,label:u[j.value],value:u[d.value],disabled:u.disabled},null,8,["label","value","disabled"]))),128)),a.createElementVNode("div",{id:I.value},[a.renderSlot(e.$slots,"footer",{loading:s.value,hasMore:i.value,options:r.value,loadMore:N},()=>[E.value&&r.value.length>0?(a.openBlock(),a.createElementBlock(a.Fragment,{key:0},[s.value?(a.openBlock(),a.createElementBlock("div",re,"加载中...")):i.value?(a.openBlock(),a.createElementBlock("div",{key:2,class:"more-hint",onClick:N},[...l[1]||(l[1]=[a.createElementVNode("span",{class:"more-text"},"点击或下拉加载更多",-1)])])):(a.openBlock(),a.createElementBlock("div",se,"没有更多数据"))],64)):a.createCommentVNode("",!0)],!0)],8,oe)]),_:3},16,["model-value","popper-class","remote"])])),[[x,s.value]])}}}),ce=(v,C)=>{const y=v.__vccOpts||v;for(const[V,t]of C)y[V]=t;return y},$=ce(ue,[["__scopeId","data-v-88571e50"]]);exports.SelectPagination=$;exports.default=$;
|
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
|
@@ -0,0 +1,287 @@
|
|
|
1
|
+
import { defineComponent as ce, useAttrs as de, getCurrentInstance as pe, computed as h, ref as f, onMounted as fe, watch as k, onBeforeUnmount as ve, resolveComponent as T, resolveDirective as me, withDirectives as ge, openBlock as v, createElementBlock as y, createVNode as he, mergeProps as ye, withCtx as Ce, Fragment as U, renderList as be, createBlock as Se, createElementVNode as j, renderSlot as we, createCommentVNode as Ve, nextTick as H } from "vue";
|
|
2
|
+
import { isEqual as Oe } from "lodash-es";
|
|
3
|
+
const _e = { style: { width: "100%" } }, ke = ["id"], Pe = {
|
|
4
|
+
key: 0,
|
|
5
|
+
class: "loading-more"
|
|
6
|
+
}, Ae = {
|
|
7
|
+
key: 1,
|
|
8
|
+
class: "no-more"
|
|
9
|
+
}, Me = "select-pagination-popper", xe = /* @__PURE__ */ ce({
|
|
10
|
+
__name: "SelectPagination",
|
|
11
|
+
props: {
|
|
12
|
+
isRemote: { type: Boolean, default: !0 },
|
|
13
|
+
modelValue: {
|
|
14
|
+
type: [String, Number, Array],
|
|
15
|
+
default: ""
|
|
16
|
+
},
|
|
17
|
+
api: { type: Function, required: !1 },
|
|
18
|
+
apiAsync: { type: Boolean, default: !1 },
|
|
19
|
+
params: {
|
|
20
|
+
type: [Object, Function],
|
|
21
|
+
default: () => ({})
|
|
22
|
+
},
|
|
23
|
+
labelField: { type: String, default: "label" },
|
|
24
|
+
valueField: { type: String, default: "value" },
|
|
25
|
+
pageSize: { type: Number, default: 10 },
|
|
26
|
+
pageKey: { type: String, default: "page" },
|
|
27
|
+
sizeKey: { type: String, default: "size" },
|
|
28
|
+
keyword: { type: String, default: "name" },
|
|
29
|
+
responsePath: { type: String, default: "data.data" },
|
|
30
|
+
enableCache: { type: Boolean, default: !0 },
|
|
31
|
+
cacheKey: { type: String, default: "" },
|
|
32
|
+
changeDetail: { type: Boolean, default: !1 },
|
|
33
|
+
detailApi: {
|
|
34
|
+
type: Function,
|
|
35
|
+
default: null
|
|
36
|
+
},
|
|
37
|
+
initOptions: { type: Array, default: () => [] },
|
|
38
|
+
popperClass: { type: String, default: "" },
|
|
39
|
+
footerSentinelId: { type: String, default: "" }
|
|
40
|
+
},
|
|
41
|
+
emits: ["update:modelValue", "change", "change-detail"],
|
|
42
|
+
setup(m, { expose: P, emit: S }) {
|
|
43
|
+
var L;
|
|
44
|
+
const A = /* @__PURE__ */ new Map(), t = m, C = S, M = de(), Y = ((L = pe()) == null ? void 0 : L.uid) ?? Date.now(), $ = h(
|
|
45
|
+
() => t.footerSentinelId || `select-pagination-footer-${Y}`
|
|
46
|
+
), J = h(() => {
|
|
47
|
+
const e = M["popper-class"] ?? M.popperClass;
|
|
48
|
+
return typeof e == "string" ? e : "";
|
|
49
|
+
}), G = h(() => [J.value, t.popperClass, Me].filter(Boolean).join(" ")), w = (e) => {
|
|
50
|
+
if (V.value = !0, C("update:modelValue", e), C("change", e), e && t.changeDetail) {
|
|
51
|
+
let a = null;
|
|
52
|
+
Array.isArray(e) ? a = o.value.filter((l) => e.find((n) => l[c.value] === n)) : a = o.value.find((l) => l[c.value] === e), C("change-detail", a);
|
|
53
|
+
}
|
|
54
|
+
}, o = f([]), r = f(!1), s = f(!0), u = f(1), g = f(""), z = f(!1), V = f(!1), x = A, I = () => {
|
|
55
|
+
var l;
|
|
56
|
+
if (t.cacheKey)
|
|
57
|
+
return t.cacheKey;
|
|
58
|
+
const e = ((l = t == null ? void 0 : t.api) == null ? void 0 : l.name) || "anonymous", a = JSON.stringify(t.params);
|
|
59
|
+
return `${e}_${btoa(a)}`;
|
|
60
|
+
}, Q = () => {
|
|
61
|
+
if (!t.enableCache) return;
|
|
62
|
+
const e = I();
|
|
63
|
+
x.set(e, {
|
|
64
|
+
options: [...o.value],
|
|
65
|
+
currentPage: u.value,
|
|
66
|
+
hasMore: s.value,
|
|
67
|
+
keyword: g.value
|
|
68
|
+
});
|
|
69
|
+
}, E = () => {
|
|
70
|
+
if (!t.enableCache) return !1;
|
|
71
|
+
const e = I(), a = x.get(e);
|
|
72
|
+
return a ? (o.value = [...a.options], u.value = a.currentPage, s.value = a.hasMore, g.value = a.keyword, !0) : !1;
|
|
73
|
+
}, O = () => {
|
|
74
|
+
if (!t.enableCache) return;
|
|
75
|
+
const e = I();
|
|
76
|
+
x.delete(e);
|
|
77
|
+
}, W = h(() => t.labelField), c = h(() => t.valueField), X = (e, a) => a.split(".").reduce((l, n) => {
|
|
78
|
+
if (l != null)
|
|
79
|
+
return l[n];
|
|
80
|
+
}, e), F = h(() => t.isRemote && typeof t.api == "function");
|
|
81
|
+
let d = null, b = null;
|
|
82
|
+
const B = () => {
|
|
83
|
+
b && (b.disconnect(), b = null), d = null;
|
|
84
|
+
}, Z = (e) => {
|
|
85
|
+
if (!e) return null;
|
|
86
|
+
let a = e.parentElement;
|
|
87
|
+
for (; a; ) {
|
|
88
|
+
const n = window.getComputedStyle(a).overflowY;
|
|
89
|
+
if ((n === "auto" || n === "scroll" || n === "overlay") && a.scrollHeight > a.clientHeight) return a;
|
|
90
|
+
a = a.parentElement;
|
|
91
|
+
}
|
|
92
|
+
return null;
|
|
93
|
+
}, ee = async () => {
|
|
94
|
+
if (B(), !F.value) return;
|
|
95
|
+
await H();
|
|
96
|
+
const e = document.getElementById($.value);
|
|
97
|
+
e && (d = Z(e), b = new IntersectionObserver(
|
|
98
|
+
(a) => {
|
|
99
|
+
const l = a[0];
|
|
100
|
+
l != null && l.isIntersecting && F.value && (r.value || s.value && p());
|
|
101
|
+
},
|
|
102
|
+
{
|
|
103
|
+
root: d,
|
|
104
|
+
rootMargin: "0px 0px 120px 0px",
|
|
105
|
+
threshold: 0
|
|
106
|
+
}
|
|
107
|
+
), b.observe(e));
|
|
108
|
+
}, te = (e = !0) => {
|
|
109
|
+
o.value = e && t.initOptions && t.initOptions.length > 0 ? [...t.initOptions] : [], u.value = 1, s.value = !0, g.value = "", r.value = !1;
|
|
110
|
+
}, p = async (e = !1) => {
|
|
111
|
+
if (r.value) return;
|
|
112
|
+
let a = 0;
|
|
113
|
+
e || d && (a = d.scrollTop), e && (o.value = [], u.value = 1, s.value = !0, O()), r.value = !0;
|
|
114
|
+
try {
|
|
115
|
+
const n = {
|
|
116
|
+
...(typeof t.params == "function" ? t.params() : t.params) || {},
|
|
117
|
+
[t.pageKey]: u.value,
|
|
118
|
+
[t.sizeKey]: t.pageSize,
|
|
119
|
+
[t.keyword]: g.value
|
|
120
|
+
};
|
|
121
|
+
if (!t.api) return;
|
|
122
|
+
const i = await (t.apiAsync ? await t.api() : t.api)(n), K = X(i, t.responsePath);
|
|
123
|
+
if (K) {
|
|
124
|
+
const R = K.content ?? [], se = K.totalElements ?? 0, ie = o.value.length;
|
|
125
|
+
if (e)
|
|
126
|
+
o.value = R || [];
|
|
127
|
+
else {
|
|
128
|
+
const ue = ne(R || []);
|
|
129
|
+
o.value = [...o.value, ...ue];
|
|
130
|
+
}
|
|
131
|
+
s.value = o.value.length < se, s.value && u.value++, Q(), !e && d && ie > 0 && (await H(), requestAnimationFrame(() => {
|
|
132
|
+
d && (d.scrollTop = a);
|
|
133
|
+
}));
|
|
134
|
+
} else
|
|
135
|
+
console.error("响应数据格式不正确", i);
|
|
136
|
+
} catch (l) {
|
|
137
|
+
console.error("加载数据失败", l);
|
|
138
|
+
} finally {
|
|
139
|
+
r.value = !1;
|
|
140
|
+
}
|
|
141
|
+
}, _ = f(!1), ae = (e) => {
|
|
142
|
+
_.value || g.value !== e && (g.value = e, p(!0));
|
|
143
|
+
}, le = (e) => {
|
|
144
|
+
e ? (!E() && o.value.length === 0 && p(!0), ee()) : B();
|
|
145
|
+
}, D = async () => {
|
|
146
|
+
const e = Array.isArray(t.modelValue) ? t.modelValue.length > 0 : !!t.modelValue;
|
|
147
|
+
if (!(!t.detailApi || !e || z.value))
|
|
148
|
+
try {
|
|
149
|
+
r.value = !0;
|
|
150
|
+
let a = [];
|
|
151
|
+
if (Array.isArray(t.modelValue)) {
|
|
152
|
+
for (const l of t.modelValue)
|
|
153
|
+
if (l) {
|
|
154
|
+
const n = await t.detailApi(l);
|
|
155
|
+
n && n.data && a.push(n.data);
|
|
156
|
+
}
|
|
157
|
+
} else {
|
|
158
|
+
let n = await t.detailApi(t.modelValue);
|
|
159
|
+
for (; n && !n.id && n.data; )
|
|
160
|
+
n = n.data;
|
|
161
|
+
n && n.id && (a = [n]);
|
|
162
|
+
}
|
|
163
|
+
a.length > 0 && (o.value = [...a, ...o.value]), z.value = !0;
|
|
164
|
+
} catch (a) {
|
|
165
|
+
console.error("加载回显数据失败", a);
|
|
166
|
+
} finally {
|
|
167
|
+
r.value = !1;
|
|
168
|
+
}
|
|
169
|
+
}, ne = (e) => {
|
|
170
|
+
const a = new Set(o.value.map((l) => l[c.value]));
|
|
171
|
+
return e.filter((l) => !a.has(l[c.value]));
|
|
172
|
+
}, oe = async () => {
|
|
173
|
+
t.initOptions && t.initOptions.length > 0 && (o.value = [...t.initOptions]), E() || (await D(), t.modelValue && o.value.length === 0 && await p(!0));
|
|
174
|
+
};
|
|
175
|
+
fe(() => {
|
|
176
|
+
oe();
|
|
177
|
+
}), k(
|
|
178
|
+
() => t.api,
|
|
179
|
+
(e, a) => {
|
|
180
|
+
e !== a && (te(!0), O(), a && !e && (C("update:modelValue", ""), C("change", "")), t.modelValue && e && p(!0));
|
|
181
|
+
},
|
|
182
|
+
{ immediate: !1 }
|
|
183
|
+
), k(
|
|
184
|
+
() => t.params,
|
|
185
|
+
(e, a) => {
|
|
186
|
+
Oe(e, a) || (O(), t.initOptions && t.initOptions.length > 0 && (o.value = [...t.initOptions]), p(!0), M.multiple ? w([]) : w(""));
|
|
187
|
+
},
|
|
188
|
+
{ deep: !0 }
|
|
189
|
+
), k(
|
|
190
|
+
() => t.modelValue,
|
|
191
|
+
async (e, a) => {
|
|
192
|
+
e && e !== a && t.detailApi && !V.value && await D(), V.value && (V.value = !1);
|
|
193
|
+
},
|
|
194
|
+
{ immediate: !1 }
|
|
195
|
+
);
|
|
196
|
+
const q = () => {
|
|
197
|
+
!r.value && s.value && p();
|
|
198
|
+
}, re = () => {
|
|
199
|
+
_.value && (_.value = !1);
|
|
200
|
+
};
|
|
201
|
+
return k(
|
|
202
|
+
() => t.initOptions,
|
|
203
|
+
(e) => {
|
|
204
|
+
if (e && e.length > 0) {
|
|
205
|
+
const a = new Set(o.value.map((n) => n[c.value])), l = e.filter(
|
|
206
|
+
(n) => !a.has(n[c.value])
|
|
207
|
+
);
|
|
208
|
+
o.value = [...l, ...o.value];
|
|
209
|
+
}
|
|
210
|
+
},
|
|
211
|
+
{ immediate: !0, deep: !0 }
|
|
212
|
+
), P({
|
|
213
|
+
loadData: p,
|
|
214
|
+
clearCache: O,
|
|
215
|
+
restoreCache: E,
|
|
216
|
+
updateValue: w,
|
|
217
|
+
loadEchoData: D,
|
|
218
|
+
options: o,
|
|
219
|
+
currentPage: u,
|
|
220
|
+
setPage: (e) => {
|
|
221
|
+
u.value = e;
|
|
222
|
+
},
|
|
223
|
+
setOptions: (e) => {
|
|
224
|
+
o.value = [...e];
|
|
225
|
+
}
|
|
226
|
+
}), ve(() => {
|
|
227
|
+
B();
|
|
228
|
+
}), (e, a) => {
|
|
229
|
+
const l = T("el-option"), n = T("el-select"), N = me("loading");
|
|
230
|
+
return ge((v(), y("div", _e, [
|
|
231
|
+
he(n, ye({
|
|
232
|
+
"model-value": m.modelValue,
|
|
233
|
+
"onUpdate:modelValue": w
|
|
234
|
+
}, e.$attrs, {
|
|
235
|
+
"popper-class": G.value,
|
|
236
|
+
"remote-method": ae,
|
|
237
|
+
filterable: !0,
|
|
238
|
+
remote: m.isRemote,
|
|
239
|
+
onVisibleChange: le,
|
|
240
|
+
onCompositionstart: a[0] || (a[0] = (i) => _.value = !0),
|
|
241
|
+
onCompositionend: re,
|
|
242
|
+
clearable: "",
|
|
243
|
+
"remote-show-suffix": ""
|
|
244
|
+
}), {
|
|
245
|
+
default: Ce(() => [
|
|
246
|
+
(v(!0), y(U, null, be(o.value, (i) => (v(), Se(l, {
|
|
247
|
+
key: i[c.value] ?? i.id,
|
|
248
|
+
label: i[W.value],
|
|
249
|
+
value: i[c.value],
|
|
250
|
+
disabled: i.disabled
|
|
251
|
+
}, null, 8, ["label", "value", "disabled"]))), 128)),
|
|
252
|
+
j("div", { id: $.value }, [
|
|
253
|
+
we(e.$slots, "footer", {
|
|
254
|
+
loading: r.value,
|
|
255
|
+
hasMore: s.value,
|
|
256
|
+
options: o.value,
|
|
257
|
+
loadMore: q
|
|
258
|
+
}, () => [
|
|
259
|
+
F.value && o.value.length > 0 ? (v(), y(U, { key: 0 }, [
|
|
260
|
+
r.value ? (v(), y("div", Pe, "加载中...")) : s.value ? (v(), y("div", {
|
|
261
|
+
key: 2,
|
|
262
|
+
class: "more-hint",
|
|
263
|
+
onClick: q
|
|
264
|
+
}, [...a[1] || (a[1] = [
|
|
265
|
+
j("span", { class: "more-text" }, "点击或下拉加载更多", -1)
|
|
266
|
+
])])) : (v(), y("div", Ae, "没有更多数据"))
|
|
267
|
+
], 64)) : Ve("", !0)
|
|
268
|
+
], !0)
|
|
269
|
+
], 8, ke)
|
|
270
|
+
]),
|
|
271
|
+
_: 3
|
|
272
|
+
}, 16, ["model-value", "popper-class", "remote"])
|
|
273
|
+
])), [
|
|
274
|
+
[N, r.value]
|
|
275
|
+
]);
|
|
276
|
+
};
|
|
277
|
+
}
|
|
278
|
+
}), Ie = (m, P) => {
|
|
279
|
+
const S = m.__vccOpts || m;
|
|
280
|
+
for (const [A, t] of P)
|
|
281
|
+
S[A] = t;
|
|
282
|
+
return S;
|
|
283
|
+
}, Ne = /* @__PURE__ */ Ie(xe, [["__scopeId", "data-v-88571e50"]]);
|
|
284
|
+
export {
|
|
285
|
+
Ne as SelectPagination,
|
|
286
|
+
Ne as default
|
|
287
|
+
};
|
package/dist/style.css
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
.loading-more[data-v-88571e50],.no-more[data-v-88571e50],.more-hint[data-v-88571e50]{padding:8px 0;font-size:12px;color:#909399;text-align:center;background-color:#fff;border-top:rgba(144,147,153,.1) solid 1px}.more-hint[data-v-88571e50]{font-size:12px;color:#409eff;cursor:pointer;transition:background-color .3s}.more-hint[data-v-88571e50]:hover{background-color:#f5f7fa}.more-text[data-v-88571e50]{display:inline-block;padding:2px 0}[data-v-88571e50] .select-pagination-popper .el-scrollbar__wrap{max-height:274px;overflow:auto;scroll-behavior:smooth;transition:height .2s ease}[data-v-88571e50] .select-pagination-popper .el-scrollbar__view{padding-bottom:8px}
|
package/package.json
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "select-pagination-element-plus",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"files": [
|
|
6
|
+
"dist",
|
|
7
|
+
"README.md",
|
|
8
|
+
"README.zh-CN.md"
|
|
9
|
+
],
|
|
10
|
+
"main": "./dist/index.cjs",
|
|
11
|
+
"module": "./dist/index.js",
|
|
12
|
+
"types": "./dist/index.d.ts",
|
|
13
|
+
"exports": {
|
|
14
|
+
".": {
|
|
15
|
+
"types": "./dist/index.d.ts",
|
|
16
|
+
"import": "./dist/index.js",
|
|
17
|
+
"require": "./dist/index.cjs"
|
|
18
|
+
}
|
|
19
|
+
},
|
|
20
|
+
"scripts": {
|
|
21
|
+
"build": "vite build && vue-tsc -p tsconfig.build.json --declaration --emitDeclarationOnly --declarationDir dist",
|
|
22
|
+
"typecheck": "vue-tsc --noEmit",
|
|
23
|
+
"prepublishOnly": "npm run build"
|
|
24
|
+
},
|
|
25
|
+
"dependencies": {
|
|
26
|
+
"lodash-es": "^4.17.21"
|
|
27
|
+
},
|
|
28
|
+
"peerDependencies": {
|
|
29
|
+
"element-plus": "^2.0.0",
|
|
30
|
+
"vue": "^3.0.0"
|
|
31
|
+
},
|
|
32
|
+
"devDependencies": {
|
|
33
|
+
"@types/node": "^22.7.5",
|
|
34
|
+
"@vitejs/plugin-vue": "^5.1.4",
|
|
35
|
+
"element-plus": "^2.7.8",
|
|
36
|
+
"typescript": "^5.6.3",
|
|
37
|
+
"vite": "^5.4.8",
|
|
38
|
+
"vue": "^3.5.13",
|
|
39
|
+
"vue-tsc": "^2.1.6"
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|