@yxhl/specter-pui-vtk 1.0.93 → 1.0.95

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yxhl/specter-pui-vtk",
3
- "version": "1.0.93",
3
+ "version": "1.0.95",
4
4
  "description": "雅心互联 Vue 3 + Vuetify3 组件库",
5
5
  "type": "module",
6
6
  "main": "./dist/specter-pui.umd.js",
@@ -0,0 +1,246 @@
1
+ <template>
2
+ <div class="vtk-single-page">
3
+ <v-row class="pagination-row ma-0" align="center" justify="end">
4
+ <template v-if="hasTotal">
5
+ <span class="page-total d-none d-md-flex">共 {{ rowCount }} 条</span>
6
+
7
+ <v-select
8
+ v-model="pagination.limit"
9
+ :items="pageSizeItems"
10
+ variant="outlined"
11
+ density="compact"
12
+ hide-details
13
+ class="page-select ml-2 d-none d-md-flex"
14
+ @update:model-value="handlePageSizeChange"
15
+ />
16
+
17
+ <v-pagination
18
+ v-model="currentPage"
19
+ :length="pageCount"
20
+ :total-visible="6"
21
+ density="comfortable"
22
+ size="small"
23
+ class="page-pagination"
24
+ @update:model-value="emitPageChange"
25
+ />
26
+
27
+ <span class="page-total ml-2 d-none d-md-flex">到</span>
28
+ <v-text-field
29
+ v-model="pagination.pageno"
30
+ variant="outlined"
31
+ density="compact"
32
+ hide-details
33
+ inputmode="numeric"
34
+ class="page-go ml-2 d-none d-md-flex"
35
+ @keyup.enter="goToPage"
36
+ />
37
+ <span class="page-total ml-2 d-none d-md-flex">页</span>
38
+ </template>
39
+
40
+ <template v-else>
41
+ <span class="page-total d-none d-md-flex">第 {{ currentPage }} 页</span>
42
+
43
+ <v-select
44
+ v-model="pagination.limit"
45
+ :items="pageSizeItems"
46
+ variant="outlined"
47
+ density="compact"
48
+ hide-details
49
+ class="page-select ml-2 d-none d-md-flex"
50
+ @update:model-value="handlePageSizeChange"
51
+ />
52
+
53
+ <div class="d-flex">
54
+ <v-btn
55
+ variant="outlined"
56
+ size="small"
57
+ height="36"
58
+ class="mr-2"
59
+ :disabled="currentPage <= 1"
60
+ @click="previousPage"
61
+ >
62
+ 上一页
63
+ </v-btn>
64
+ <v-btn
65
+ variant="outlined"
66
+ size="small"
67
+ height="36"
68
+ :disabled="!hasNextPage"
69
+ @click="nextPage"
70
+ >
71
+ 下一页
72
+ </v-btn>
73
+ </div>
74
+ </template>
75
+ </v-row>
76
+ </div>
77
+ </template>
78
+
79
+ <script setup>
80
+ import { computed, reactive, ref, watch } from 'vue';
81
+
82
+ defineOptions({
83
+ name: 'VtkSinglePage'
84
+ });
85
+
86
+ const props = defineProps({
87
+ pageData: {
88
+ type: Object,
89
+ default: () => ({})
90
+ },
91
+ pageSizes: {
92
+ type: Array,
93
+ default: () => [15, 20, 30]
94
+ }
95
+ });
96
+
97
+ const emit = defineEmits(['pageChange']);
98
+
99
+ const normalizePositiveInteger = (value, fallback = 1) => {
100
+ const parsedValue = Number.parseInt(value, 10);
101
+ return Number.isInteger(parsedValue) && parsedValue > 0 ? parsedValue : fallback;
102
+ };
103
+
104
+ const initialLimit = computed(() => normalizePositiveInteger(props.pageSizes[0], 15));
105
+ const currentPage = ref(normalizePositiveInteger(props.pageData.pageno));
106
+ const pagination = reactive({
107
+ pageno: currentPage.value,
108
+ limit: normalizePositiveInteger(props.pageData.limit, initialLimit.value)
109
+ });
110
+
111
+ const rowCount = computed(() => Math.max(0, Number(props.pageData.rowCount) || 0));
112
+ const pageCount = computed(() => normalizePositiveInteger(props.pageData.pageCount));
113
+ const hasTotal = computed(() => rowCount.value > 0);
114
+ const pageSizeItems = computed(() => props.pageSizes.map(value => ({
115
+ title: `${value} 条/页`,
116
+ value
117
+ })));
118
+ const rowLength = computed(() => {
119
+ if (Array.isArray(props.pageData.rows)) {
120
+ return props.pageData.rows.length;
121
+ }
122
+
123
+ return Number.isFinite(Number(props.pageData.rows))
124
+ ? Number(props.pageData.rows)
125
+ : null;
126
+ });
127
+ const hasNextPage = computed(() => (
128
+ rowLength.value === null || rowLength.value >= Number(pagination.limit)
129
+ ));
130
+
131
+ watch(
132
+ () => props.pageData,
133
+ newValue => {
134
+ currentPage.value = normalizePositiveInteger(newValue.pageno, currentPage.value);
135
+ pagination.pageno = currentPage.value;
136
+
137
+ if (newValue.limit != null) {
138
+ pagination.limit = normalizePositiveInteger(newValue.limit, pagination.limit);
139
+ }
140
+ },
141
+ { deep: true }
142
+ );
143
+
144
+ watch(currentPage, value => {
145
+ pagination.pageno = value;
146
+ });
147
+
148
+ watch(
149
+ () => props.pageSizes,
150
+ values => {
151
+ if (!values.some(value => Number(value) === Number(pagination.limit))) {
152
+ pagination.limit = initialLimit.value;
153
+ }
154
+ },
155
+ { deep: true }
156
+ );
157
+
158
+ const emitPageChange = () => {
159
+ emit('pageChange', {
160
+ pageno: currentPage.value,
161
+ limit: Number(pagination.limit)
162
+ });
163
+ };
164
+
165
+ const goToPage = () => {
166
+ const targetPage = Number(pagination.pageno);
167
+
168
+ if (Number.isInteger(targetPage) && targetPage >= 1 && targetPage <= pageCount.value) {
169
+ currentPage.value = targetPage;
170
+ emitPageChange();
171
+ return;
172
+ }
173
+
174
+ pagination.pageno = currentPage.value;
175
+ };
176
+
177
+ const handlePageSizeChange = () => {
178
+ currentPage.value = 1;
179
+ emitPageChange();
180
+ };
181
+
182
+ const previousPage = () => {
183
+ if (currentPage.value <= 1) return;
184
+
185
+ currentPage.value -= 1;
186
+ emitPageChange();
187
+ };
188
+
189
+ const nextPage = () => {
190
+ if (!hasNextPage.value) return;
191
+
192
+ currentPage.value += 1;
193
+ emitPageChange();
194
+ };
195
+ </script>
196
+
197
+ <style lang="scss" scoped>
198
+ .vtk-single-page {
199
+ width: 100%;
200
+ min-height: 60px;
201
+ }
202
+
203
+ .pagination-row {
204
+ min-height: 60px;
205
+ padding: 8px 16px;
206
+ }
207
+
208
+ .page-total {
209
+ align-items: center;
210
+ min-height: 36px;
211
+ color: rgba(var(--v-theme-on-surface), var(--v-medium-emphasis-opacity));
212
+ font-size: 13px;
213
+ }
214
+
215
+ .page-select {
216
+ max-width: 120px;
217
+ }
218
+
219
+ .page-go {
220
+ max-width: 72px;
221
+ }
222
+
223
+ .page-select,
224
+ .page-go {
225
+ :deep(.v-input__control),
226
+ :deep(.v-field) {
227
+ min-height: 36px;
228
+ height: 36px;
229
+ font-size: 13px;
230
+ }
231
+
232
+ :deep(.v-field__input) {
233
+ min-height: 36px;
234
+ padding-top: 4px;
235
+ padding-bottom: 4px;
236
+ }
237
+ }
238
+
239
+ .page-pagination {
240
+ :deep(.v-pagination__item),
241
+ :deep(.v-pagination__prev),
242
+ :deep(.v-pagination__next) {
243
+ font-size: 13px;
244
+ }
245
+ }
246
+ </style>
package/src/index.js CHANGED
@@ -20,9 +20,10 @@ export { default as VtkPage } from "./components/assembly/VtkPage.vue";
20
20
  export { default as VtkPdf } from "./components/assembly/VtkPdf.vue";
21
21
  export { default as VtkProj } from "./components/assembly/VtkProj.vue";
22
22
  export { default as VtkRadio } from "./components/assembly/VtkRadio.vue";
23
- export { default as VtkSearch } from "./components/assembly/VtkSearch.vue";
24
- export { default as VtkSelect } from "./components/assembly/VtkSelect.vue";
25
- export { default as VtkStepper } from "./components/assembly/VtkStepper.vue";
23
+ export { default as VtkSearch } from "./components/assembly/VtkSearch.vue";
24
+ export { default as VtkSelect } from "./components/assembly/VtkSelect.vue";
25
+ export { default as VtkSinglePage } from "./components/assembly/VtkSinglePage.vue";
26
+ export { default as VtkStepper } from "./components/assembly/VtkStepper.vue";
26
27
  export { default as VtkUpload } from "./components/assembly/VtkUpload.vue";
27
28
 
28
29
  export * from "./commons/location.js";
@@ -65,9 +66,10 @@ import VtkPage from "./components/assembly/VtkPage.vue";
65
66
  import VtkPdf from "./components/assembly/VtkPdf.vue";
66
67
  import VtkProj from "./components/assembly/VtkProj.vue";
67
68
  import VtkRadio from "./components/assembly/VtkRadio.vue";
68
- import VtkSearch from "./components/assembly/VtkSearch.vue";
69
- import VtkSelect from "./components/assembly/VtkSelect.vue";
70
- import VtkStepper from "./components/assembly/VtkStepper.vue";
69
+ import VtkSearch from "./components/assembly/VtkSearch.vue";
70
+ import VtkSelect from "./components/assembly/VtkSelect.vue";
71
+ import VtkSinglePage from "./components/assembly/VtkSinglePage.vue";
72
+ import VtkStepper from "./components/assembly/VtkStepper.vue";
71
73
  import VtkUpload from "./components/assembly/VtkUpload.vue";
72
74
  import VtkMessageComponent from "./components/message/vtkMessage.vue";
73
75
 
@@ -91,9 +93,10 @@ function install(app, options = {}) {
91
93
  VtkPdf,
92
94
  VtkProj,
93
95
  VtkRadio,
94
- VtkSearch,
95
- VtkSelect,
96
- VtkStepper,
96
+ VtkSearch,
97
+ VtkSelect,
98
+ VtkSinglePage,
99
+ VtkStepper,
97
100
  VtkUpload,
98
101
  VtkMessage: VtkMessageComponent
99
102
  };
@@ -140,9 +143,10 @@ export default {
140
143
  VtkPdf,
141
144
  VtkProj,
142
145
  VtkRadio,
143
- VtkSearch,
144
- VtkSelect,
145
- VtkStepper,
146
+ VtkSearch,
147
+ VtkSelect,
148
+ VtkSinglePage,
149
+ VtkStepper,
146
150
  VtkUpload,
147
151
  request,
148
152
  storage,