@netang/quasar 0.1.88 → 0.1.89

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.
@@ -1,546 +1,547 @@
1
- <template>
2
- <q-input
3
- class="n-input-number"
4
- :class="{
5
- 'n-input-number--center': center,
6
- }"
7
- :disable="disable"
8
- :readonly="readonly"
9
- v-model="currentValue"
10
- @blur="onBlur"
11
- v-bind="$attrs"
12
- >
13
- <!-- 内部前置插槽 -->
14
- <template #prepend v-if="controls && center">
15
-
16
- <!-- 减少按钮 -->
17
- <q-btn
18
- class="n-input-number__left"
19
- color="default"
20
- icon="remove"
21
- flat
22
- dense
23
- :disable="currentDisableMinus"
24
- @click="onChange('minus')"
25
- />
26
-
27
- <!-- 内部前置插槽 -->
28
- <slot name="prepend" />
29
-
30
- </template>
31
-
32
- <!-- 内部后置插槽 -->
33
- <template #append v-if="controls">
34
-
35
- <!-- 内部后置插槽 -->
36
- <slot name="append" />
37
-
38
- <!-- 减少按钮 -->
39
- <q-btn
40
- color="default"
41
- icon="remove"
42
- flat
43
- dense
44
- :disable="currentDisableMinus"
45
- @click="onChange('minus')"
46
- v-if="! center"
47
- />
48
-
49
- <!-- 增加按钮 -->
50
- <q-btn
51
- class="n-input-number__right"
52
- color="default"
53
- icon="add"
54
- flat
55
- dense
56
- :disable="currentDisablePlus"
57
- @click="onChange('plus')"
58
- />
59
-
60
- </template>
61
-
62
- <!-- 插槽 -->
63
- <template
64
- v-for="slotName in slotNames"
65
- v-slot:[slotName]
66
- >
67
- <slot :name="slotName" />
68
- </template>
69
-
70
- </q-input>
71
- </template>
72
-
73
- <script>
74
- import { computed, ref, watch } from 'vue'
75
- import BigNumber from 'bignumber.js'
76
-
77
- import $n_filter from 'lodash/filter'
78
-
79
- import $n_isValidObject from '@netang/utils/isValidObject'
80
-
81
- export default {
82
-
83
- /**
84
- * 标识
85
- */
86
- name: 'NInputNumber',
87
-
88
- /**
89
- * 声明属性
90
- */
91
- props: {
92
- // 值 v-model
93
- modelValue: {
94
- required: true,
95
- },
96
- // 最小值
97
- min: {
98
- type: [Number, String],
99
- default: 0,
100
- },
101
- // 最大值
102
- max: {
103
- type: [Number, String],
104
- default: Infinity,
105
- },
106
- // 步长, 每次点击时改变的值(默认为 1, centToYuan开启后默认为 100)
107
- step: [Number, String],
108
- // 小数位数(默认为 0, centToYuan开启后默认为 2)
109
- decimalLength: [Number, String],
110
- // 是否禁用减少按钮
111
- disableMinus: Boolean,
112
- // 是否禁用增加按钮
113
- disablePlus: Boolean,
114
- // 是否使用控制按钮
115
- controls: Boolean,
116
- // 居中显示
117
- center: Boolean,
118
- // 不允许输入的值为空
119
- noEmpty: Boolean,
120
- // 是否为人民币的分转元(值为分, 显示为元)
121
- // 如果为 true, 则 min / max / step 的值默认的单位为人民币的分
122
- centToYuan: Boolean,
123
- // 精度舍入模式(默认: 向下取整)
124
- // 参考文档: https://mikemcl.github.io/bignumber.js/#constructor-properties
125
- roundMode: {
126
- type: Number,
127
- default: BigNumber.ROUND_DOWN,
128
- },
129
- // 是否禁用
130
- disable: Boolean,
131
- // 是否只读
132
- readonly: Boolean,
133
- },
134
-
135
- /**
136
- * 声明事件
137
- */
138
- emits: [
139
- 'update:modelValue',
140
- 'blur',
141
- 'minus',
142
- 'plus',
143
- ],
144
-
145
- /**
146
- * 组合式
147
- */
148
- setup(props, { emit, slots }) {
149
-
150
- // ==========【计算属性】=========================================================================================
151
-
152
- /**
153
- * 插槽标识
154
- */
155
- const slotNames = computed(function() {
156
-
157
- if ($n_isValidObject(slots)) {
158
-
159
- // 忽略插槽
160
- const ignoreKeys = []
161
-
162
- if (props.controls) {
163
- ignoreKeys.push('append')
164
-
165
- if (props.center) {
166
- ignoreKeys.push('prepend')
167
- }
168
- }
169
-
170
- const keys = Object.keys(slots)
171
-
172
- if (ignoreKeys.length) {
173
- return $n_filter(keys, e => ignoreKeys.indexOf(e) === -1)
174
- }
175
-
176
- return keys
177
- }
178
-
179
- return []
180
- })
181
-
182
- /**
183
- * 当前最小值
184
- */
185
- const currentMin = computed(function() {
186
- // 格式化数字
187
- return formatNumber(props.min, true, true, null)
188
- })
189
-
190
- /**
191
- * 当前最大值
192
- */
193
- const currentMax = computed(function() {
194
-
195
- // 如果为无限大
196
- if (props.max === Infinity) {
197
- // 则返回无限大
198
- return Infinity
199
- }
200
-
201
- // 格式化数字
202
- return formatNumber(props.max, true, true, null)
203
- })
204
-
205
- /**
206
- * 当前步长(默认为 1, centToYuan开启后默认为 100)
207
- */
208
- const currentStep = computed(function() {
209
-
210
- // 格式化数字
211
- return formatNumber(props.step ?? (props.centToYuan ? 100 : 1), true, true, null)
212
- })
213
-
214
- /**
215
- * 当前小数位数(默认为 0, centToYuan开启后默认为 2)
216
- */
217
- const currentDecimalLength = computed(function() {
218
- return props.decimalLength ?? (props.centToYuan ? 2 : 0)
219
- })
220
-
221
- /**
222
- * 当前是否禁用减少按钮
223
- */
224
- const currentDisableMinus = computed(function () {
225
-
226
- // 如果禁用 || 如果只读 || 禁用减少按钮
227
- if (props.disable || props.readonly || props.disableMinus) {
228
- // 则禁用减少按钮
229
- return true
230
- }
231
-
232
- // 如果没有当前最小值
233
- if (currentMin.value === null) {
234
- // 则不禁用减少按钮
235
- return false
236
- }
237
-
238
- // 将当前值转为 BigNumber 类型
239
- const val = new BigNumber(currentValue.value)
240
-
241
- // 如果当前值不是有效数字
242
- if (! val.isFinite()) {
243
- // 则禁用减少按钮
244
- return true
245
- }
246
-
247
- // 当前值 <= 当前最小值
248
- return val.lte(currentMin.value)
249
- })
250
-
251
- /**
252
- * 当前是否禁用增加按钮
253
- */
254
- const currentDisablePlus = computed(function () {
255
-
256
- // 如果禁用 || 如果只读 || 禁用增加按钮
257
- if (props.disable || props.readonly || props.disablePlus) {
258
- // 则禁用增加按钮
259
- return true
260
- }
261
-
262
- // 如果没有当前最大值
263
- if (currentMax.value === null) {
264
- // 则不禁用增加按钮
265
- return false
266
- }
267
-
268
- // 将当前值转为 BigNumber 类型
269
- const val = new BigNumber(currentValue.value)
270
-
271
- // 如果当前值不是有效数字
272
- if (! val.isFinite()) {
273
- // 则禁用减少按钮
274
- return true
275
- }
276
-
277
- // 当前值 >= 当前最大值
278
- return val.gte(currentMax.value)
279
- })
280
-
281
- // ==========【数据】============================================================================================
282
-
283
- // 格式化为当前值
284
- const currentValue = ref(formatToCurrentValue(props.modelValue, true))
285
-
286
- // 如果当前值 !== 声明值
287
- const rawModelValue = formatToModelValue(currentValue.value)
288
- if (rawModelValue !== props.modelValue) {
289
-
290
- // 触发更新值
291
- emitModelValue(rawModelValue)
292
- }
293
-
294
- // ==========【监听数据】=========================================================================================
295
-
296
- /**
297
- * 监听声明值
298
- */
299
- watch(() => props.modelValue, function (val) {
300
-
301
- // 格式化为当前值
302
- val = formatToCurrentValue(val, true)
303
-
304
- // 如果当前值有变化
305
- if (val !== currentValue.value) {
306
- currentValue.value = val
307
- }
308
- })
309
-
310
- /**
311
- * 监听 当前最小值 / 当前最大值 / 当前小数位数
312
- */
313
- watch([currentMin, currentMax, currentDecimalLength], function () {
314
-
315
- // 格式化当前值
316
- const val = formatToCurrentValue(currentValue.value, false)
317
-
318
- // 如果当前值有变化
319
- if (val !== currentValue.value) {
320
-
321
- // 更新当前值
322
- currentValue.value = val
323
-
324
- // 更新值
325
- emitModelValue(formatToModelValue(val))
326
- }
327
- })
328
-
329
- // ==========【方法】=============================================================================================
330
-
331
- /**
332
- * 触发更新值
333
- */
334
- function emitModelValue(val) {
335
-
336
- // 触发更新值
337
- emit('update:modelValue', val)
338
- }
339
-
340
- /**
341
- * 格式化数字
342
- */
343
- function formatNumber(val, isCentToYuan, isToNumber, defaultValue) {
344
-
345
- // 转为 BigNumber 类型
346
- val = new BigNumber(val)
347
-
348
- // 如果为有效数字
349
- if (val.isFinite()) {
350
-
351
- // 如果不为 0
352
- if (! val.isZero()) {
353
-
354
- // 如果为人民币的分转元
355
- if (props.centToYuan && isCentToYuan) {
356
- // 100
357
- val = val.dividedBy(100)
358
- }
359
-
360
- // 如果设置了小数位数
361
- if (currentDecimalLength.value) {
362
- // 将值舍入 xx 位精度(如 68.345 -> 68.34)
363
- val = val.dp(currentDecimalLength.value, props.roundMode)
364
-
365
- // 否则值为整数
366
- } else {
367
- // 将值取整
368
- val = val.integerValue(props.roundMode)
369
- }
370
- }
371
-
372
- // 转为数字
373
- return isToNumber ? val.toNumber() : val
374
- }
375
-
376
- return defaultValue
377
- }
378
-
379
- /**
380
- * 格式化为更新值
381
- */
382
- function formatToModelValue(value) {
383
-
384
- // 转为 BigNumber 类型
385
- let val = new BigNumber(value)
386
-
387
- // 如果不是有效数字
388
- if (! val.isFinite()) {
389
-
390
- // 返回当前值
391
- return value
392
- }
393
-
394
- // 如果为人民币的分转元
395
- if (props.centToYuan) {
396
- // 乘以 100
397
- val = val.times(100)
398
- // 再取整(分必须是整数)
399
- .integerValue(props.roundMode)
400
- }
401
-
402
- // 将值转为数字
403
- return val.toNumber()
404
- }
405
-
406
- /**
407
- * 格式化值
408
- */
409
- function formatToCurrentValue(value, isCentToYuan) {
410
-
411
- // 格式化数字
412
- const val = formatNumber(value, isCentToYuan, false, false)
413
-
414
- // 如果为有效数字
415
- if (val !== false) {
416
-
417
- // 如果值 >= 最大值
418
- if (currentMax.value !== null && val.gte(currentMax.value)) {
419
-
420
- // 返回最大值
421
- return currentMax.value
422
- }
423
-
424
- // 如果值 <= 最小值
425
- if (currentMin.value !== null && val.lte(currentMin.value)) {
426
-
427
- // 返回最小值
428
- return currentMin.value
429
- }
430
-
431
- // 将值转为数字
432
- return val.toNumber()
433
- }
434
-
435
- if (
436
- // 如果不允许值为空
437
- props.noEmpty
438
- // 如果有最小值
439
- && currentMin.value !== null
440
- ) {
441
- // 则返回最小值
442
- return currentMin.value
443
- }
444
-
445
- return ''
446
- }
447
-
448
- /**
449
- * 失去焦点触发
450
- */
451
- function onBlur() {
452
-
453
- // 格式化当前值
454
- let val = formatToCurrentValue(currentValue.value, false)
455
-
456
- // 如果当前值有变动
457
- if (val !== currentValue.value) {
458
-
459
- // 更新当前值
460
- currentValue.value = val
461
-
462
- // 将当前值转为声明值
463
- val = formatToModelValue(val)
464
-
465
- // 触发更新值
466
- emitModelValue(val)
467
-
468
- // 失去焦点触发
469
- emit('blur', val)
470
- }
471
- }
472
-
473
- /**
474
- * 改变值
475
- */
476
- function onChange(type) {
477
-
478
- // 格式化当前值
479
- const val = formatToCurrentValue(
480
- new BigNumber(+currentValue.value)
481
- // 增加 / 减少
482
- .plus(type === 'minus' ? -currentStep.value : +currentStep.value)
483
- .toNumber()
484
- , false
485
- )
486
-
487
- // 如果当前值有变动
488
- if (val !== currentValue.value) {
489
-
490
- // 更新当前值
491
- currentValue.value = val
492
-
493
- // 触发更新值
494
- emitModelValue(formatToModelValue(val))
495
- }
496
- }
497
-
498
- // ==========【返回】=============================================================================================
499
-
500
- return {
501
- // 插槽标识
502
- slotNames,
503
- // 当前值
504
- currentValue,
505
- // 当前是否禁用减少按钮
506
- currentDisableMinus,
507
- // 当前是否禁用增加按钮
508
- currentDisablePlus,
509
-
510
- // 失去焦点触发
511
- onBlur,
512
- // 改变值
513
- onChange,
514
- }
515
- }
516
- }
517
- </script>
518
-
519
- <style lang="scss">
520
- .n-input-number {
521
-
522
- // 居中显示
523
- &--center {
524
- &.q-field {
525
- &--outlined {
526
- .q-field__control {
527
- .q-field__native {
528
- text-align: center;
529
- }
530
- }
531
- }
532
- }
533
- }
534
-
535
- // 左边按钮
536
- &__left {
537
- margin-left: -8px;
538
- }
539
-
540
- // 右边按钮
541
- &__right {
542
- margin-right: -8px;
543
- }
544
- }
545
- </style>
546
-
1
+ <template>
2
+ <q-input
3
+ class="n-input-number"
4
+ :class="{
5
+ 'n-input-number--center': center,
6
+ }"
7
+ :disable="disable"
8
+ :readonly="readonly"
9
+ v-model="currentValue"
10
+ @blur="onBlur"
11
+ v-bind="$attrs"
12
+ >
13
+ <!-- 内部前置插槽 -->
14
+ <template #prepend v-if="controls && center">
15
+
16
+ <!-- 减少按钮 -->
17
+ <q-btn
18
+ class="n-input-number__left"
19
+ color="default"
20
+ icon="remove"
21
+ flat
22
+ dense
23
+ :disable="currentDisableMinus"
24
+ @click="onChange('minus')"
25
+ />
26
+
27
+ <!-- 内部前置插槽 -->
28
+ <slot name="prepend" />
29
+
30
+ </template>
31
+
32
+ <!-- 内部后置插槽 -->
33
+ <template #append v-if="controls">
34
+
35
+ <!-- 内部后置插槽 -->
36
+ <slot name="append" />
37
+
38
+ <!-- 减少按钮 -->
39
+ <q-btn
40
+ color="default"
41
+ icon="remove"
42
+ flat
43
+ dense
44
+ :disable="currentDisableMinus"
45
+ @click="onChange('minus')"
46
+ v-if="! center"
47
+ />
48
+
49
+ <!-- 增加按钮 -->
50
+ <q-btn
51
+ class="n-input-number__right"
52
+ color="default"
53
+ icon="add"
54
+ flat
55
+ dense
56
+ :disable="currentDisablePlus"
57
+ @click="onChange('plus')"
58
+ />
59
+
60
+ </template>
61
+
62
+ <!-- 插槽 -->
63
+ <template
64
+ v-for="slotName in slotNames"
65
+ v-slot:[slotName]
66
+ >
67
+ <slot :name="slotName" />
68
+ </template>
69
+
70
+ </q-input>
71
+ </template>
72
+
73
+ <script>
74
+ import { computed, ref, watch } from 'vue'
75
+ import BigNumber from 'bignumber.js'
76
+
77
+ import $n_filter from 'lodash/filter'
78
+
79
+ import $n_isValidObject from '@netang/utils/isValidObject'
80
+
81
+ export default {
82
+
83
+ /**
84
+ * 标识
85
+ */
86
+ name: 'NInputNumber',
87
+
88
+ /**
89
+ * 声明属性
90
+ */
91
+ props: {
92
+ // 值 v-model
93
+ modelValue: {
94
+ required: true,
95
+ },
96
+ // 最小值
97
+ min: {
98
+ type: [Number, String],
99
+ default: 0,
100
+ },
101
+ // 最大值
102
+ max: {
103
+ type: [Number, String],
104
+ default: Infinity,
105
+ },
106
+ // 步长, 每次点击时改变的值(默认为 1, centToYuan开启后默认为 100)
107
+ step: [Number, String],
108
+ // 小数位数(默认为 0, centToYuan开启后默认为 2)
109
+ decimalLength: [Number, String],
110
+ // 是否禁用减少按钮
111
+ disableMinus: Boolean,
112
+ // 是否禁用增加按钮
113
+ disablePlus: Boolean,
114
+ // 是否使用控制按钮
115
+ controls: Boolean,
116
+ // 居中显示
117
+ center: Boolean,
118
+ // 不允许输入的值为空
119
+ noEmpty: Boolean,
120
+ // 是否为人民币的分转元(值为分, 显示为元)
121
+ // 如果为 true, 则 min / max / step 的值默认的单位为人民币的分
122
+ centToYuan: Boolean,
123
+ // 精度舍入模式(默认: 向下取整)
124
+ // 参考文档: https://mikemcl.github.io/bignumber.js/#constructor-properties
125
+ roundMode: {
126
+ type: Number,
127
+ default: BigNumber.ROUND_DOWN,
128
+ },
129
+ // 是否禁用
130
+ disable: Boolean,
131
+ // 是否只读
132
+ readonly: Boolean,
133
+ },
134
+
135
+ /**
136
+ * 声明事件
137
+ */
138
+ emits: [
139
+ 'update:modelValue',
140
+ 'blur',
141
+ 'minus',
142
+ 'plus',
143
+ ],
144
+
145
+ /**
146
+ * 组合式
147
+ */
148
+ setup(props, { emit, slots }) {
149
+
150
+ // ==========【计算属性】=========================================================================================
151
+
152
+ /**
153
+ * 插槽标识
154
+ */
155
+ const slotNames = computed(function() {
156
+
157
+ if ($n_isValidObject(slots)) {
158
+
159
+ // 忽略插槽
160
+ const ignoreKeys = []
161
+
162
+ if (props.controls) {
163
+ ignoreKeys.push('append')
164
+
165
+ if (props.center) {
166
+ ignoreKeys.push('prepend')
167
+ }
168
+ }
169
+
170
+ const keys = Object.keys(slots)
171
+
172
+ if (ignoreKeys.length) {
173
+ return $n_filter(keys, e => ignoreKeys.indexOf(e) === -1)
174
+ }
175
+
176
+ return keys
177
+ }
178
+
179
+ return []
180
+ })
181
+
182
+ /**
183
+ * 当前最小值
184
+ */
185
+ const currentMin = computed(function() {
186
+ // 格式化数字
187
+ return formatNumber(props.min, true, true, null)
188
+ })
189
+
190
+ /**
191
+ * 当前最大值
192
+ */
193
+ const currentMax = computed(function() {
194
+
195
+ // 如果为无限大
196
+ if (props.max === Infinity) {
197
+ // 则返回无限大
198
+ return Infinity
199
+ }
200
+
201
+ // 格式化数字
202
+ return formatNumber(props.max, true, true, null)
203
+ })
204
+
205
+ /**
206
+ * 当前步长(默认为 1, centToYuan开启后默认为 100)
207
+ */
208
+ const currentStep = computed(function() {
209
+
210
+ // 格式化数字
211
+ return formatNumber(props.step ?? (props.centToYuan ? 100 : 1), true, true, null)
212
+ })
213
+
214
+ /**
215
+ * 当前小数位数(默认为 0, centToYuan开启后默认为 2)
216
+ */
217
+ const currentDecimalLength = computed(function() {
218
+ return props.decimalLength ?? (props.centToYuan ? 2 : 0)
219
+ })
220
+
221
+ /**
222
+ * 当前是否禁用减少按钮
223
+ */
224
+ const currentDisableMinus = computed(function () {
225
+
226
+ // 如果禁用 || 如果只读 || 禁用减少按钮
227
+ if (props.disable || props.readonly || props.disableMinus) {
228
+ // 则禁用减少按钮
229
+ return true
230
+ }
231
+
232
+ // 如果没有当前最小值
233
+ if (currentMin.value === null) {
234
+ // 则不禁用减少按钮
235
+ return false
236
+ }
237
+
238
+ // 将当前值转为 BigNumber 类型
239
+ const val = new BigNumber(currentValue.value)
240
+
241
+ // 如果当前值不是有效数字
242
+ if (! val.isFinite()) {
243
+ // 则禁用减少按钮
244
+ return true
245
+ }
246
+
247
+ // 当前值 <= 当前最小值
248
+ return val.lte(currentMin.value)
249
+ })
250
+
251
+ /**
252
+ * 当前是否禁用增加按钮
253
+ */
254
+ const currentDisablePlus = computed(function () {
255
+
256
+ // 如果禁用 || 如果只读 || 禁用增加按钮
257
+ if (props.disable || props.readonly || props.disablePlus) {
258
+ // 则禁用增加按钮
259
+ return true
260
+ }
261
+
262
+ // 如果没有当前最大值
263
+ if (currentMax.value === null) {
264
+ // 则不禁用增加按钮
265
+ return false
266
+ }
267
+
268
+ // 将当前值转为 BigNumber 类型
269
+ const val = new BigNumber(currentValue.value)
270
+
271
+ // 如果当前值不是有效数字
272
+ if (! val.isFinite()) {
273
+ // 则禁用减少按钮
274
+ return true
275
+ }
276
+
277
+ // 当前值 >= 当前最大值
278
+ return val.gte(currentMax.value)
279
+ })
280
+
281
+ // ==========【数据】============================================================================================
282
+
283
+ // 格式化为当前值
284
+ const currentValue = ref(formatToCurrentValue(props.modelValue, true))
285
+
286
+ // 如果当前值 !== 声明值
287
+ const rawModelValue = formatToModelValue(currentValue.value)
288
+ if (rawModelValue !== props.modelValue) {
289
+
290
+ // 触发更新值
291
+ emitModelValue(rawModelValue)
292
+ }
293
+
294
+ // ==========【监听数据】=========================================================================================
295
+
296
+ /**
297
+ * 监听声明值
298
+ */
299
+ watch(() => props.modelValue, function (val) {
300
+
301
+ // 格式化为当前值
302
+ val = formatToCurrentValue(val, true)
303
+
304
+ // 如果当前值有变化
305
+ if (val !== currentValue.value) {
306
+ // 更新当前值
307
+ currentValue.value = val
308
+ // 触发更新值
309
+ emitModelValue(formatToModelValue(val))
310
+ }
311
+ })
312
+
313
+ /**
314
+ * 监听 当前最小值 / 当前最大值 / 当前小数位数
315
+ */
316
+ watch([currentMin, currentMax, currentDecimalLength], function () {
317
+
318
+ // 格式化当前值
319
+ const val = formatToCurrentValue(currentValue.value, false)
320
+
321
+ // 如果当前值有变化
322
+ if (val !== currentValue.value) {
323
+ // 更新当前值
324
+ currentValue.value = val
325
+ // 更新值
326
+ emitModelValue(formatToModelValue(val))
327
+ }
328
+ })
329
+
330
+ // ==========【方法】=============================================================================================
331
+
332
+ /**
333
+ * 触发更新值
334
+ */
335
+ function emitModelValue(val) {
336
+
337
+ // 触发更新值
338
+ emit('update:modelValue', val)
339
+ }
340
+
341
+ /**
342
+ * 格式化数字
343
+ */
344
+ function formatNumber(val, isCentToYuan, isToNumber, defaultValue) {
345
+
346
+ // 转为 BigNumber 类型
347
+ val = new BigNumber(val)
348
+
349
+ // 如果为有效数字
350
+ if (val.isFinite()) {
351
+
352
+ // 如果不为 0
353
+ if (! val.isZero()) {
354
+
355
+ // 如果为人民币的分转元
356
+ if (props.centToYuan && isCentToYuan) {
357
+ // 100
358
+ val = val.dividedBy(100)
359
+ }
360
+
361
+ // 如果设置了小数位数
362
+ if (currentDecimalLength.value) {
363
+ // 将值舍入 xx 位精度(如 68.345 -> 68.34)
364
+ val = val.dp(currentDecimalLength.value, props.roundMode)
365
+
366
+ // 否则值为整数
367
+ } else {
368
+ // 将值取整
369
+ val = val.integerValue(props.roundMode)
370
+ }
371
+ }
372
+
373
+ // 转为数字
374
+ return isToNumber ? val.toNumber() : val
375
+ }
376
+
377
+ return defaultValue
378
+ }
379
+
380
+ /**
381
+ * 格式化为更新值
382
+ */
383
+ function formatToModelValue(value) {
384
+
385
+ // 转为 BigNumber 类型
386
+ let val = new BigNumber(value)
387
+
388
+ // 如果不是有效数字
389
+ if (! val.isFinite()) {
390
+
391
+ // 返回当前值
392
+ return value
393
+ }
394
+
395
+ // 如果为人民币的分转元
396
+ if (props.centToYuan) {
397
+ // 乘以 100
398
+ val = val.times(100)
399
+ // 再取整(分必须是整数)
400
+ .integerValue(props.roundMode)
401
+ }
402
+
403
+ // 将值转为数字
404
+ return val.toNumber()
405
+ }
406
+
407
+ /**
408
+ * 格式化值
409
+ */
410
+ function formatToCurrentValue(value, isCentToYuan) {
411
+
412
+ // 格式化数字
413
+ const val = formatNumber(value, isCentToYuan, false, false)
414
+
415
+ // 如果为有效数字
416
+ if (val !== false) {
417
+
418
+ // 如果值 >= 最大值
419
+ if (currentMax.value !== null && val.gte(currentMax.value)) {
420
+
421
+ // 返回最大值
422
+ return currentMax.value
423
+ }
424
+
425
+ // 如果值 <= 最小值
426
+ if (currentMin.value !== null && val.lte(currentMin.value)) {
427
+
428
+ // 返回最小值
429
+ return currentMin.value
430
+ }
431
+
432
+ // 将值转为数字
433
+ return val.toNumber()
434
+ }
435
+
436
+ if (
437
+ // 如果不允许值为空
438
+ props.noEmpty
439
+ // 如果有最小值
440
+ && currentMin.value !== null
441
+ ) {
442
+ // 则返回最小值
443
+ return currentMin.value
444
+ }
445
+
446
+ return ''
447
+ }
448
+
449
+ /**
450
+ * 失去焦点触发
451
+ */
452
+ function onBlur() {
453
+
454
+ // 格式化当前值
455
+ let val = formatToCurrentValue(currentValue.value, false)
456
+
457
+ // 如果当前值有变动
458
+ if (val !== currentValue.value) {
459
+
460
+ // 更新当前值
461
+ currentValue.value = val
462
+
463
+ // 将当前值转为声明值
464
+ val = formatToModelValue(val)
465
+
466
+ // 触发更新值
467
+ emitModelValue(val)
468
+
469
+ // 失去焦点触发
470
+ emit('blur', val)
471
+ }
472
+ }
473
+
474
+ /**
475
+ * 改变值
476
+ */
477
+ function onChange(type) {
478
+
479
+ // 格式化当前值
480
+ const val = formatToCurrentValue(
481
+ new BigNumber(+currentValue.value)
482
+ // 增加 / 减少
483
+ .plus(type === 'minus' ? -currentStep.value : +currentStep.value)
484
+ .toNumber()
485
+ , false
486
+ )
487
+
488
+ // 如果当前值有变动
489
+ if (val !== currentValue.value) {
490
+
491
+ // 更新当前值
492
+ currentValue.value = val
493
+
494
+ // 触发更新值
495
+ emitModelValue(formatToModelValue(val))
496
+ }
497
+ }
498
+
499
+ // ==========【返回】=============================================================================================
500
+
501
+ return {
502
+ // 插槽标识
503
+ slotNames,
504
+ // 当前值
505
+ currentValue,
506
+ // 当前是否禁用减少按钮
507
+ currentDisableMinus,
508
+ // 当前是否禁用增加按钮
509
+ currentDisablePlus,
510
+
511
+ // 失去焦点触发
512
+ onBlur,
513
+ // 改变值
514
+ onChange,
515
+ }
516
+ }
517
+ }
518
+ </script>
519
+
520
+ <style lang="scss">
521
+ .n-input-number {
522
+
523
+ // 居中显示
524
+ &--center {
525
+ &.q-field {
526
+ &--outlined {
527
+ .q-field__control {
528
+ .q-field__native {
529
+ text-align: center;
530
+ }
531
+ }
532
+ }
533
+ }
534
+ }
535
+
536
+ // 左边按钮
537
+ &__left {
538
+ margin-left: -8px;
539
+ }
540
+
541
+ // 右边按钮
542
+ &__right {
543
+ margin-right: -8px;
544
+ }
545
+ }
546
+ </style>
547
+
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@netang/quasar",
3
- "version": "0.1.88",
3
+ "version": "0.1.89",
4
4
  "description": "netang-quasar",
5
5
  "scripts": {
6
6
  "test": "echo \"Error: no test specified\" && exit 1"