create-jnrs-template-vue 1.2.1 → 1.2.3

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.
Files changed (69) hide show
  1. package/bin/create.mjs +3 -3
  2. package/jnrs-template-vue/auto-imports.d.ts +4 -0
  3. package/jnrs-template-vue/components.d.ts +0 -1
  4. package/jnrs-template-vue/package.json +3 -4
  5. package/jnrs-template-vue/public/system/menu.json +1 -1
  6. package/jnrs-template-vue/src/App.vue +1 -3
  7. package/jnrs-template-vue/src/api/common/index.ts +2 -2
  8. package/jnrs-template-vue/src/api/demos/index.ts +84 -48
  9. package/jnrs-template-vue/src/api/system/index.ts +10 -10
  10. package/jnrs-template-vue/src/api/user/index.ts +2 -2
  11. package/jnrs-template-vue/src/assets/styles/animation.scss +0 -0
  12. package/jnrs-template-vue/src/assets/styles/common.scss +4 -0
  13. package/jnrs-template-vue/src/assets/styles/fonts.scss +4 -1
  14. package/jnrs-template-vue/src/assets/styles/{main.scss → index.scss} +1 -0
  15. package/jnrs-template-vue/src/assets/styles/init.scss +4 -13
  16. package/jnrs-template-vue/src/assets/styles/root.scss +0 -3
  17. package/jnrs-template-vue/src/components/common/{JnDictTag.vue → DictTag.vue} +1 -1
  18. package/jnrs-template-vue/src/components/{base → common}/PdfView.vue +2 -2
  19. package/jnrs-template-vue/src/components/select/SelectManager.vue +20 -0
  20. package/jnrs-template-vue/src/composables/common/usePagination.ts +4 -4
  21. package/jnrs-template-vue/src/composables/common/useTable.ts +4 -4
  22. package/jnrs-template-vue/src/composables/tools/useMouseSelection.ts +150 -0
  23. package/jnrs-template-vue/src/layout/SideMenu.vue +1 -0
  24. package/jnrs-template-vue/src/layout/TopHeader.vue +1 -1
  25. package/jnrs-template-vue/src/locales/en.ts +1 -1
  26. package/jnrs-template-vue/src/locales/index.ts +1 -1
  27. package/jnrs-template-vue/src/main.ts +1 -1
  28. package/jnrs-template-vue/src/types/index.ts +45 -3
  29. package/jnrs-template-vue/src/views/demos/crud/index.vue +140 -40
  30. package/jnrs-template-vue/src/views/demos/unitTest/RequestPage.vue +1 -1
  31. package/jnrs-template-vue/src/views/demos/unitTest/index.vue +26 -2
  32. package/jnrs-template-vue/src/views/login/index.vue +7 -2
  33. package/jnrs-template-vue/src/views/system/dict/index.vue +2 -2
  34. package/jnrs-template-vue/src/views/system/menu/index.vue +2 -2
  35. package/jnrs-template-vue/src/views/system/mine/baseInfo.vue +1 -1
  36. package/jnrs-template-vue/tsconfig.json +1 -9
  37. package/jnrs-template-vue/vite.config.ts +1 -3
  38. package/jnrs-template-vue/viteMockServe/fail.ts +12 -0
  39. package/jnrs-template-vue/viteMockServe/file.ts +2 -3
  40. package/jnrs-template-vue/viteMockServe/json/tableRes.json +384 -342
  41. package/package.json +1 -1
  42. package/jnrs-template-vue/src/assets/images/fileIcon/iconArchive.png +0 -0
  43. package/jnrs-template-vue/src/assets/images/fileIcon/iconAudio.png +0 -0
  44. package/jnrs-template-vue/src/assets/images/fileIcon/iconCode.png +0 -0
  45. package/jnrs-template-vue/src/assets/images/fileIcon/iconExcel.png +0 -0
  46. package/jnrs-template-vue/src/assets/images/fileIcon/iconFile.png +0 -0
  47. package/jnrs-template-vue/src/assets/images/fileIcon/iconFlash.png +0 -0
  48. package/jnrs-template-vue/src/assets/images/fileIcon/iconGif.png +0 -0
  49. package/jnrs-template-vue/src/assets/images/fileIcon/iconImage.png +0 -0
  50. package/jnrs-template-vue/src/assets/images/fileIcon/iconMac.png +0 -0
  51. package/jnrs-template-vue/src/assets/images/fileIcon/iconOfd.png +0 -0
  52. package/jnrs-template-vue/src/assets/images/fileIcon/iconPdf.png +0 -0
  53. package/jnrs-template-vue/src/assets/images/fileIcon/iconPpt.png +0 -0
  54. package/jnrs-template-vue/src/assets/images/fileIcon/iconText.png +0 -0
  55. package/jnrs-template-vue/src/assets/images/fileIcon/iconUnknown.png +0 -0
  56. package/jnrs-template-vue/src/assets/images/fileIcon/iconVideo.png +0 -0
  57. package/jnrs-template-vue/src/assets/images/fileIcon/iconWindows.png +0 -0
  58. package/jnrs-template-vue/src/assets/images/fileIcon/iconWord.png +0 -0
  59. package/jnrs-template-vue/src/assets/images/fileIcon/iconWps.png +0 -0
  60. package/jnrs-template-vue/src/components/base/JnFileUpload.vue +0 -433
  61. package/jnrs-template-vue/src/components/common/JnDatetime.vue +0 -37
  62. package/jnrs-template-vue/src/components/common/JnEdit.vue +0 -68
  63. package/jnrs-template-vue/src/components/common/JnPagination.vue +0 -83
  64. package/jnrs-template-vue/src/components/common/JnTable.vue +0 -133
  65. package/jnrs-template-vue/src/composables/tools/useReactivityTableHeight.ts +0 -63
  66. /package/jnrs-template-vue/src/components/{base → common}/ImageView.vue +0 -0
  67. /package/jnrs-template-vue/viteMockServe/{fileSrc → file}/mock-pdf.pdf +0 -0
  68. /package/jnrs-template-vue/viteMockServe/{fileSrc → file}/mock-png-0.png +0 -0
  69. /package/jnrs-template-vue/viteMockServe/{fileSrc → file}/mock-png-1.png +0 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-jnrs-template-vue",
3
- "version": "1.2.1",
3
+ "version": "1.2.3",
4
4
  "description": "巨能前端工程化开发,Vue 项目模板脚手架",
5
5
  "keywords": [
6
6
  "vue",
@@ -1,433 +0,0 @@
1
- <!--
2
- @Author : TanRui
3
- @WeChat : Tan578853789
4
- @File : JnFileUpload.vue
5
- @Date : 2025/12/25
6
- @Desc. : 通用上传 & 回显组件 上传类型为File类型 二进制
7
- -->
8
-
9
- <script setup lang="ts">
10
- import type { UploadRawFile, UploadFile, FormInstance } from 'element-plus'
11
- import type { Attachment } from '@/types'
12
- import { ElMessage } from 'element-plus'
13
- import { ref, computed, nextTick } from 'vue'
14
- import { downloadFile } from '@/utils/packages'
15
- import iconUnknown from '@/assets/images/fileIcon/iconUnknown.png'
16
- import iconCode from '@/assets/images/fileIcon/iconCode.png'
17
- import iconWord from '@/assets/images/fileIcon/iconWord.png'
18
- import iconWps from '@/assets/images/fileIcon/iconWps.png'
19
- import iconText from '@/assets/images/fileIcon/iconText.png'
20
- import iconPpt from '@/assets/images/fileIcon/iconPpt.png'
21
- import iconPdf from '@/assets/images/fileIcon/iconPdf.png'
22
- import iconArchive from '@/assets/images/fileIcon/iconArchive.png'
23
- import iconWindows from '@/assets/images/fileIcon/iconWindows.png'
24
- import iconMac from '@/assets/images/fileIcon/iconMac.png'
25
- import iconVideo from '@/assets/images/fileIcon/iconVideo.png'
26
- import iconAudio from '@/assets/images/fileIcon/iconAudio.png'
27
- import iconFlash from '@/assets/images/fileIcon/iconFlash.png'
28
- import iconGif from '@/assets/images/fileIcon/iconGif.png'
29
- import iconImage from '@/assets/images/fileIcon/iconImage.png'
30
- import iconFile from '@/assets/images/fileIcon/iconFile.png'
31
- import iconExcel from '@/assets/images/fileIcon/iconExcel.png'
32
- import iconOfd from '@/assets/images/fileIcon/iconOfd.png'
33
-
34
- type MixedUploadFile = Attachment | UploadRawFile
35
-
36
- interface Props {
37
- /**
38
- * 绑定的模型值(文件列表),默认为空数组
39
- */
40
- modelValue: MixedUploadFile[]
41
-
42
- /**
43
- * 接受的文件类型(如 'image/*'),默认为空字符串
44
- */
45
- accept?: string
46
-
47
- /**
48
- * 是否启用拖拽上传,默认为 false
49
- */
50
- drag?: boolean
51
-
52
- /**
53
- * 单个文件大小限制(单位:MB),默认为 0(不限制)
54
- */
55
- fileSizeMb?: number
56
-
57
- /**
58
- * 最大上传文件数量,0 表示不限制,默认为 0
59
- */
60
- limit?: number
61
-
62
- /**
63
- * Element Plus 组件的尺寸,默认为 'small'
64
- */
65
- size?: '' | 'small' | 'default' | 'large'
66
-
67
- /**
68
- * 父级组件的表单引用(用于触发校验),默认为 null
69
- */
70
- formRef?: FormInstance
71
-
72
- /**
73
- * 父级表单中用于校验的字段名(需配合 formRef 使用),默认为空字符串
74
- */
75
- validateFieldName?: string
76
- }
77
-
78
- const {
79
- modelValue,
80
- accept = '',
81
- drag = false,
82
- fileSizeMb = 100,
83
- limit = 0,
84
- size = 'small',
85
- formRef = null,
86
- validateFieldName = ''
87
- } = defineProps<Props>()
88
-
89
- const emit = defineEmits(['update:modelValue'])
90
-
91
- const loading = ref(false)
92
- const uploadRef = ref()
93
- const isDisable = computed(() => {
94
- return limit && modelValue && modelValue.length >= limit
95
- })
96
-
97
- const fileSizeFmt = (value: number) => {
98
- const units = ['B', 'KB', 'MB', 'GB']
99
- let size = value
100
- let unitIndex = 0
101
-
102
- while (size >= 1024 && unitIndex < units.length - 1) {
103
- size /= 1024
104
- unitIndex++
105
- }
106
-
107
- const fixedDigits = unitIndex === 0 ? 0 : unitIndex === 1 ? 0 : 1
108
- return size.toFixed(fixedDigits) + ' ' + units[unitIndex]
109
- }
110
-
111
- const getAccessoryIcon = (type: string) => {
112
- let icon = iconUnknown
113
- if (type.includes('code')) {
114
- icon = iconCode
115
- } else if (type.includes('text')) {
116
- icon = iconText
117
- } else if (type.includes('wps')) {
118
- icon = iconWps
119
- } else if (type.includes('word')) {
120
- icon = iconWord
121
- } else if (type.includes('ppt')) {
122
- icon = iconPpt
123
- } else if (type.includes('pdf')) {
124
- icon = iconPdf
125
- } else if (type.includes('archive')) {
126
- icon = iconArchive
127
- } else if (type.includes('x-msdownload')) {
128
- icon = iconWindows
129
- } else if (type.includes('x-apple-aspen-config')) {
130
- icon = iconMac
131
- } else if (type.includes('video')) {
132
- icon = iconVideo
133
- } else if (type.includes('audio')) {
134
- icon = iconAudio
135
- } else if (type.includes('flash')) {
136
- icon = iconFlash
137
- } else if (type.includes('gif')) {
138
- icon = iconGif
139
- } else if (type.includes('image')) {
140
- icon = iconImage
141
- } else if (type.includes('file')) {
142
- icon = iconFile
143
- } else if (type.includes('excel')) {
144
- icon = iconExcel
145
- } else if (type.includes('ofd')) {
146
- icon = iconOfd
147
- }
148
- return icon
149
- }
150
-
151
- const loadingProgress = () => {
152
- loading.value = true
153
- }
154
-
155
- const handleChange = (uploadFile: UploadFile) => {
156
- const { status, raw } = uploadFile
157
-
158
- if (status === 'ready' && raw) {
159
- // 数量校验
160
- if (limit && modelValue && modelValue.length >= limit) {
161
- ElMessage({
162
- message: `最多只能上传 ${limit} 个文件!`,
163
- type: 'warning',
164
- grouping: true,
165
- duration: 3000
166
- })
167
- return false
168
- }
169
-
170
- // 文件类型校验
171
- if (accept && accept.split(',').length > 0) {
172
- let flag = false
173
- accept.split(',').forEach((element) => {
174
- if (raw.name.indexOf(element) > -1) {
175
- flag = true
176
- }
177
- })
178
- if (!flag) {
179
- ElMessage({
180
- message: `上传文件只能是 ${accept} 格式!`,
181
- type: 'warning',
182
- grouping: true,
183
- duration: 3000
184
- })
185
- return false
186
- }
187
- }
188
-
189
- // 文件大小校验
190
- if (fileSizeMb && raw.size / 1024 / 1024 > fileSizeMb) {
191
- ElMessage({
192
- message: `上传的文件大小不能超过 ${fileSizeMb} MB!`,
193
- type: 'warning',
194
- grouping: true,
195
- duration: 3000
196
- })
197
- return false
198
- }
199
-
200
- const temp = modelValue
201
- temp.push(uploadFile.raw as UploadRawFile)
202
- emit('update:modelValue', temp)
203
-
204
- nextTick(() => {
205
- if (formRef && validateFieldName) {
206
- formRef.validateField(validateFieldName)
207
- }
208
- uploadRef.value?.clearFiles()
209
- loading.value = false
210
- })
211
- }
212
- }
213
-
214
- const deleteFile = (file: MixedUploadFile) => {
215
- const temp = modelValue
216
- const index = modelValue.findIndex((item) => {
217
- // Attachment 类型
218
- if ('id' in file && 'id' in item) {
219
- return item.id === file.id
220
- }
221
- // UploadRawFile 类型
222
- if ('uid' in file && 'uid' in item) {
223
- return item.uid === file.uid
224
- }
225
- })
226
-
227
- if (index !== -1) {
228
- temp.splice(index, 1)
229
- }
230
-
231
- emit('update:modelValue', temp)
232
-
233
- nextTick(() => {
234
- if (formRef && validateFieldName) {
235
- formRef.validateField(validateFieldName)
236
- }
237
- })
238
- }
239
- </script>
240
-
241
- <template>
242
- <div class="jnFileUpload">
243
- <el-upload
244
- ref="uploadRef"
245
- :http-request="() => {}"
246
- :show-file-list="false"
247
- :multiple="true"
248
- :drag="drag"
249
- :accept="accept"
250
- :disabled="isDisable"
251
- :on-progress="loadingProgress"
252
- :on-change="handleChange"
253
- >
254
- <el-button type="primary" :size="size" :loading="loading" :disabled="isDisable">
255
- 上传
256
- <span v-if="limit" style="display: inline-block; margin-left: 5px">
257
- ({{ modelValue ? modelValue.length : 0 }}/{{ limit }})
258
- </span>
259
- </el-button>
260
- </el-upload>
261
-
262
- <div class="uploadTips" :class="{ uploadTips_isDrag: drag }">
263
- <span v-if="accept">
264
- 文件类型为
265
- <b>{{ accept }}</b>
266
- </span>
267
- <span v-if="accept">
268
- 文件大小为
269
- <b>{{ fileSizeMb }}MB</b>
270
- 以内
271
- </span>
272
- </div>
273
-
274
- <div class="fileList" v-show="modelValue && modelValue.length > 0" v-loading="loading">
275
- <div class="fileLis_item" v-for="(item, index) in modelValue" :key="index">
276
- <!-- Attachment 类型 -->
277
- <template v-if="'id' in item">
278
- <div class="fileLis_item_left">
279
- <span class="fileLis_item_index">{{ index + 1 }}</span>
280
- <img class="fileLis_item_icon" v-if="item.fileType" :src="getAccessoryIcon(item.fileType)" />
281
- <span class="fileLis_item_name">{{ item.fileName }}</span>
282
- <span class="fileLis_item_size">
283
- {{ fileSizeFmt(item.fileSize) }}
284
- </span>
285
- </div>
286
- <div class="fileLis_item_right">
287
- <span class="fileLis_item_btn" @click="downloadFile(item.uniqueFileName, item.fileName)">
288
- <el-icon><Download /></el-icon>
289
- </span>
290
- <span class="fileLis_item_btn fileLis_item_btn_danger" @click="deleteFile(item)">
291
- <el-icon><Delete /></el-icon>
292
- </span>
293
- </div>
294
- </template>
295
-
296
- <!-- UploadRawFile 类型 -->
297
- <template v-if="'uid' in item">
298
- <div class="fileLis_item_left">
299
- <span class="fileLis_item_index">{{ index + 1 }}</span>
300
- <img class="fileLis_item_icon" v-if="item.type" :src="getAccessoryIcon(item.type)" />
301
- <span class="fileLis_item_name">{{ item.name }}</span>
302
- <span class="fileLis_item_size">
303
- {{ fileSizeFmt(item.size) }}
304
- </span>
305
- </div>
306
- <div class="fileLis_item_right">
307
- <span class="fileLis_item_btn fileLis_item_btn_danger" @click="deleteFile(item)">
308
- <el-icon><Delete /></el-icon>
309
- </span>
310
- </div>
311
- </template>
312
- </div>
313
- </div>
314
- </div>
315
- </template>
316
-
317
- <style lang="scss" scoped>
318
- .jnFileUpload {
319
- position: relative;
320
- width: 100%;
321
- color: var(--jnrs-font-primary-06);
322
-
323
- :deep(.el-upload-dragger) {
324
- padding: 30px 0 10px;
325
- }
326
-
327
- .uploadTips {
328
- display: block;
329
- width: 100%;
330
- margin-top: 5px;
331
- line-height: 1.2em;
332
- span {
333
- display: inline-block;
334
- margin-right: 10px;
335
- }
336
- b {
337
- color: var(--el-color-danger, #ff3300);
338
- }
339
- }
340
-
341
- .uploadTips_isDrag {
342
- position: absolute;
343
- top: 4px;
344
- left: 0;
345
- text-align: center;
346
- }
347
-
348
- .fileList {
349
- width: 100%;
350
-
351
- .fileLis_item {
352
- display: flex;
353
- align-items: center;
354
- justify-content: space-between;
355
- width: 100%;
356
- margin-top: 8px;
357
- padding: 5px 0;
358
- border: 1px solid var(--jnrs-font-primary-03);
359
- background: var(--jnrs-background-primary);
360
-
361
- .fileLis_item_left {
362
- flex: 1;
363
- position: relative;
364
- display: flex;
365
- align-items: center;
366
- justify-content: flex-start;
367
- padding-right: 50px;
368
- line-height: 1.1em;
369
- }
370
-
371
- .fileLis_item_right {
372
- flex-shrink: 0;
373
- width: 60px;
374
- display: flex;
375
- align-items: center;
376
- justify-content: flex-end;
377
- padding-right: 4px;
378
- }
379
-
380
- .fileLis_item_index {
381
- flex-shrink: 0;
382
- width: 20px;
383
- height: 20px;
384
- line-height: 20px;
385
- text-align: center;
386
- }
387
-
388
- .fileLis_item_icon {
389
- flex-shrink: 0;
390
- width: 20px;
391
- height: 20px;
392
- }
393
-
394
- .fileLis_item_name {
395
- padding: 0 4px;
396
- word-break: break-all;
397
- }
398
-
399
- .fileLis_item_size {
400
- position: absolute;
401
- right: 0;
402
- width: 50px;
403
- color: #999;
404
- white-space: nowrap;
405
- text-align: right;
406
- }
407
-
408
- .fileLis_item_btn {
409
- flex-shrink: 0;
410
- display: flex;
411
- align-items: center;
412
- justify-content: center;
413
- width: 20px;
414
- height: 20px;
415
- margin: 0 2px;
416
- border-radius: 3px;
417
- font-size: 16px;
418
- color: var(--el-color-primary, #5887f7);
419
- transition: all 0.3s ease;
420
- cursor: pointer;
421
-
422
- &:hover {
423
- background-color: var(--jnrs-card-primary);
424
- }
425
- }
426
-
427
- .fileLis_item_btn_danger {
428
- color: var(--el-color-danger, #ff3300);
429
- }
430
- }
431
- }
432
- }
433
- </style>
@@ -1,37 +0,0 @@
1
- <!--
2
- @Author : TanRui
3
- @WeChat : Tan578853789
4
- @File : JnDatetime.vue
5
- @Date : 2025/12/25
6
- @desc. : 显示时间格式化,第一行是日期,第二行是时间
7
- -->
8
-
9
- <script setup lang="ts">
10
- import { computed } from 'vue'
11
-
12
- interface Props {
13
- value: string
14
- color?: string
15
- }
16
- const { value = '', color = '' } = defineProps<Props>()
17
-
18
- const datetime = computed(() => {
19
- if (value && value.split('T').length === 2) {
20
- return value.split('T')
21
- }
22
- if (value && value.split(' ').length === 2) {
23
- return value.split(' ')
24
- }
25
- return false
26
- })
27
- </script>
28
-
29
- <template>
30
- <template v-if="datetime">
31
- <div style="line-height: 1.2em" :style="{ color: color }">
32
- <div>{{ datetime[0] }}</div>
33
- <span style="opacity: 0.7; font-size: 0.9em">{{ datetime[1] }}</span>
34
- </div>
35
- </template>
36
- <span v-else>{{ value }}</span>
37
- </template>
@@ -1,68 +0,0 @@
1
- <!--
2
- @Author : TanRui
3
- @WeChat : Tan578853789
4
- @File : JnEdit.vue
5
- @Date : 2025/12/25
6
- @Desc. : 表格编辑组件
7
- -->
8
-
9
- <script setup lang="ts">
10
- import { ref } from 'vue'
11
-
12
- interface Props {
13
- /**
14
- * 对话框的宽度,默认值为 50%
15
- */
16
- title?: string
17
- /**
18
- * 对话框的宽度,默认值为 50%
19
- */
20
- width?: string | number
21
- }
22
-
23
- const { width = '50%', title = '' } = defineProps<Props>()
24
-
25
- const emit = defineEmits<{
26
- closed: []
27
- }>()
28
-
29
- const dialogVisible = ref(false)
30
-
31
- const open = () => {
32
- dialogVisible.value = true
33
- }
34
-
35
- const close = () => {
36
- dialogVisible.value = false
37
- }
38
-
39
- const handleClosed = () => {
40
- emit('closed')
41
- }
42
-
43
- defineExpose({
44
- open,
45
- close,
46
- handleClosed
47
- })
48
- </script>
49
-
50
- <template>
51
- <el-dialog
52
- v-model="dialogVisible"
53
- :title="title"
54
- :width="width"
55
- :close-on-click-modal="true"
56
- :close-on-press-escape="true"
57
- draggable
58
- overflow
59
- @closed="handleClosed"
60
- >
61
- <slot></slot>
62
- <template #footer>
63
- <slot name="footer"></slot>
64
- </template>
65
- </el-dialog>
66
- </template>
67
-
68
- <style lang="scss" scoped></style>
@@ -1,83 +0,0 @@
1
- <!--
2
- @Author : TanRui
3
- @WeChat : Tan578853789
4
- @File : JnPagination.vue
5
- @Date : 2025/12/18
6
- @Desc. : 分页组件
7
- -->
8
-
9
- <script setup lang="ts">
10
- import { ref, watch } from 'vue'
11
- import type { ComponentSize } from 'element-plus'
12
-
13
- type PaginationModelValue = {
14
- currentPage: number
15
- pageSize: number
16
- }
17
-
18
- interface PaginationProps {
19
- total: number
20
- modelValue?: PaginationModelValue
21
- size?: ComponentSize
22
- background?: boolean
23
- marginTop?: string
24
- }
25
-
26
- const props = withDefaults(defineProps<PaginationProps>(), {
27
- modelValue: () => ({ currentPage: 1, pageSize: 10 }),
28
- size: 'small',
29
- background: true,
30
- marginTop: '10px'
31
- })
32
-
33
- const emit = defineEmits<{
34
- (e: 'update:modelValue', value: { currentPage: number; pageSize: number }): void
35
- (e: 'change'): void
36
- }>()
37
-
38
- const localPage = ref(props.modelValue.currentPage)
39
- const localSize = ref(props.modelValue.pageSize)
40
-
41
- watch(
42
- () => props.modelValue,
43
- (newVal) => {
44
- localPage.value = newVal.currentPage
45
- localSize.value = newVal.pageSize
46
- },
47
- { deep: true }
48
- )
49
-
50
- // 页码变化
51
- const handleCurrentChange = (page: number) => {
52
- localPage.value = page
53
- const newValue = { currentPage: page, pageSize: localSize.value }
54
- emit('update:modelValue', newValue)
55
- emit('change')
56
- }
57
-
58
- // 每页条数变化时重置到第一页
59
- const handleSizeChange = (size: number) => {
60
- localSize.value = size
61
- localPage.value = 1
62
- const newValue = { currentPage: 1, pageSize: size }
63
- emit('update:modelValue', newValue)
64
- emit('change')
65
- }
66
- </script>
67
-
68
- <template>
69
- <el-pagination
70
- v-model:current-page="localPage"
71
- v-model:page-size="localSize"
72
- :total="total"
73
- :page-sizes="[10, 20, 50, 100]"
74
- :size="size"
75
- :background="background"
76
- layout="->, total, sizes, prev, pager, next, jumper"
77
- :style="{
78
- marginTop: marginTop
79
- }"
80
- @current-change="handleCurrentChange"
81
- @size-change="handleSizeChange"
82
- />
83
- </template>