@tdesign/uniapp 0.7.3 → 0.8.0

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 (197) hide show
  1. package/CHANGELOG.md +23 -0
  2. package/README.md +1 -1
  3. package/dist/action-sheet/README.md +1 -1
  4. package/dist/action-sheet/action-sheet.vue +158 -150
  5. package/dist/action-sheet/props.ts +2 -2
  6. package/dist/action-sheet/type.ts +1 -1
  7. package/dist/avatar/avatar.vue +89 -87
  8. package/dist/avatar-group/avatar-group.vue +69 -67
  9. package/dist/back-top/back-top.vue +60 -58
  10. package/dist/badge/badge.vue +69 -59
  11. package/dist/button/button.vue +121 -116
  12. package/dist/button/props.ts +2 -2
  13. package/dist/button/type.ts +1 -1
  14. package/dist/calendar/calendar-header.vue +4 -4
  15. package/dist/calendar/calendar.vue +308 -297
  16. package/dist/calendar/template.vue +1 -1
  17. package/dist/cascader/README.en-US.md +2 -1
  18. package/dist/cascader/README.md +2 -1
  19. package/dist/cascader/cascader.vue +340 -328
  20. package/dist/cascader/props.ts +6 -1
  21. package/dist/cascader/type.ts +6 -0
  22. package/dist/cell/cell.vue +127 -121
  23. package/dist/cell-group/cell-group.vue +32 -30
  24. package/dist/check-tag/check-tag.vue +73 -71
  25. package/dist/checkbox/checkbox.vue +127 -127
  26. package/dist/checkbox/props.ts +6 -6
  27. package/dist/checkbox/type.ts +3 -3
  28. package/dist/checkbox-group/checkbox-group.vue +175 -173
  29. package/dist/checkbox-group/props.ts +6 -6
  30. package/dist/checkbox-group/type.ts +4 -4
  31. package/dist/col/col.vue +26 -24
  32. package/dist/collapse/collapse.vue +83 -81
  33. package/dist/collapse-panel/collapse-panel.vue +121 -119
  34. package/dist/collapse-panel/props.ts +4 -4
  35. package/dist/collapse-panel/type.ts +2 -2
  36. package/dist/color-picker/README.md +1 -1
  37. package/dist/color-picker/color-picker.vue +324 -322
  38. package/dist/color-picker/props.ts +2 -2
  39. package/dist/color-picker/template.vue +14 -10
  40. package/dist/common/common.ts +1 -0
  41. package/dist/common/style/theme/index.css +5 -5
  42. package/dist/common/utils.js +7 -2
  43. package/dist/common/validator.js +172 -0
  44. package/dist/config-provider/README.en-US.md +184 -0
  45. package/dist/config-provider/README.md +234 -0
  46. package/dist/config-provider/config-provider.vue +105 -0
  47. package/dist/config-provider/config-store.js +70 -0
  48. package/dist/config-provider/props.ts +16 -0
  49. package/dist/config-provider/reactive-state.js +39 -0
  50. package/dist/config-provider/type.ts +401 -0
  51. package/dist/config-provider/use-config.js +29 -0
  52. package/dist/config-provider/utils.js +29 -0
  53. package/dist/count-down/count-down.vue +98 -97
  54. package/dist/date-time-picker/date-time-picker.vue +410 -395
  55. package/dist/demo/demo.vue +1 -0
  56. package/dist/dialog/dialog.vue +175 -173
  57. package/dist/divider/divider.vue +38 -36
  58. package/dist/draggable/draggable.vue +60 -58
  59. package/dist/drawer/README.md +1 -1
  60. package/dist/drawer/drawer.vue +48 -46
  61. package/dist/dropdown-item/dropdown-item.vue +209 -207
  62. package/dist/dropdown-item/props.ts +4 -4
  63. package/dist/dropdown-item/type.ts +3 -3
  64. package/dist/dropdown-menu/dropdown-menu.vue +93 -99
  65. package/dist/empty/empty.vue +43 -42
  66. package/dist/fab/fab.vue +88 -86
  67. package/dist/footer/footer.vue +36 -34
  68. package/dist/form/README.en-US.md +17 -24
  69. package/dist/form/README.md +18 -25
  70. package/dist/form/form.css +1 -166
  71. package/dist/form/form.vue +251 -236
  72. package/dist/form/props.ts +2 -21
  73. package/dist/form/type.ts +7 -70
  74. package/dist/form-item/README.en-US.md +4 -5
  75. package/dist/form-item/README.md +4 -5
  76. package/dist/form-item/form-item.css +69 -96
  77. package/dist/form-item/form-item.vue +315 -336
  78. package/dist/form-item/form-model.ts +125 -173
  79. package/dist/form-item/props.ts +4 -17
  80. package/dist/form-item/type.ts +43 -1
  81. package/dist/grid/grid.vue +53 -51
  82. package/dist/grid-item/grid-item.vue +121 -119
  83. package/dist/guide/README.md +1 -1
  84. package/dist/guide/guide.vue +281 -277
  85. package/dist/icon/README.md +2 -4
  86. package/dist/icon/icon.vue +78 -76
  87. package/dist/image/README.md +1 -1
  88. package/dist/image/image.vue +103 -101
  89. package/dist/image-viewer/image-viewer.vue +160 -158
  90. package/dist/image-viewer/props.ts +2 -2
  91. package/dist/image-viewer/type.ts +1 -1
  92. package/dist/index.js +3 -0
  93. package/dist/indexes/indexes.vue +264 -267
  94. package/dist/indexes-anchor/indexes-anchor.vue +41 -41
  95. package/dist/input/input.vue +192 -192
  96. package/dist/input/props.ts +6 -6
  97. package/dist/input/type.ts +3 -3
  98. package/dist/link/link.vue +73 -71
  99. package/dist/loading/loading.vue +59 -59
  100. package/dist/locale/ar_KW.ts +157 -0
  101. package/dist/locale/en_US.ts +146 -0
  102. package/dist/locale/it_IT.ts +145 -0
  103. package/dist/locale/ja_JP.ts +132 -0
  104. package/dist/locale/ko_KR.ts +132 -0
  105. package/dist/locale/ru_RU.ts +157 -0
  106. package/dist/locale/zh_CN.ts +133 -0
  107. package/dist/locale/zh_TW.ts +132 -0
  108. package/dist/message/message.vue +181 -173
  109. package/dist/message/props.ts +2 -2
  110. package/dist/message/type.ts +1 -1
  111. package/dist/message-item/message-item.vue +192 -184
  112. package/dist/mixins/using-config.js +39 -0
  113. package/dist/navbar/navbar.vue +201 -199
  114. package/dist/notice-bar/notice-bar.vue +175 -171
  115. package/dist/notice-bar/props.ts +2 -2
  116. package/dist/notice-bar/type.ts +1 -1
  117. package/dist/npm/dayjs/esm/locale/ar.js +81 -0
  118. package/dist/npm/dayjs/esm/locale/it.js +39 -0
  119. package/dist/overlay/overlay.vue +50 -48
  120. package/dist/picker/picker.vue +168 -161
  121. package/dist/picker-item/picker-item.vue +269 -269
  122. package/dist/popover/README.md +1 -1
  123. package/dist/popover/popover.vue +262 -261
  124. package/dist/popover/props.ts +4 -4
  125. package/dist/popover/type.ts +2 -2
  126. package/dist/popup/popup.vue +46 -45
  127. package/dist/progress/README.md +1 -1
  128. package/dist/progress/progress.vue +76 -76
  129. package/dist/pull-down-refresh/props.ts +2 -2
  130. package/dist/pull-down-refresh/pull-down-refresh.vue +240 -234
  131. package/dist/pull-down-refresh/type.ts +1 -1
  132. package/dist/qrcode/README.md +1 -1
  133. package/dist/qrcode/components/qrcode-canvas/qrcode-canvas.vue +340 -338
  134. package/dist/qrcode/components/qrcode-status/qrcode-status.vue +6 -6
  135. package/dist/qrcode/qrcode.vue +93 -87
  136. package/dist/radio/props.ts +6 -6
  137. package/dist/radio/radio.vue +118 -120
  138. package/dist/radio/type.ts +3 -3
  139. package/dist/radio-group/props.ts +4 -4
  140. package/dist/radio-group/radio-group.vue +136 -134
  141. package/dist/radio-group/type.ts +4 -4
  142. package/dist/rate/computed.js +2 -2
  143. package/dist/rate/props.ts +4 -4
  144. package/dist/rate/rate.vue +155 -154
  145. package/dist/rate/type.ts +2 -2
  146. package/dist/result/result.vue +41 -39
  147. package/dist/row/row.vue +38 -36
  148. package/dist/scroll-view/scroll-view.vue +24 -22
  149. package/dist/search/props.ts +2 -2
  150. package/dist/search/search.vue +127 -125
  151. package/dist/search/type.ts +1 -1
  152. package/dist/side-bar/side-bar.vue +57 -55
  153. package/dist/side-bar-item/side-bar-item.vue +86 -86
  154. package/dist/skeleton/skeleton.vue +126 -124
  155. package/dist/slider/README.md +1 -1
  156. package/dist/slider/props.ts +2 -2
  157. package/dist/slider/slider.vue +457 -457
  158. package/dist/slider/type.ts +1 -1
  159. package/dist/step-item/step-item.vue +77 -75
  160. package/dist/stepper/props.ts +2 -2
  161. package/dist/stepper/stepper.vue +168 -149
  162. package/dist/stepper/type.ts +1 -1
  163. package/dist/steps/props.ts +2 -2
  164. package/dist/steps/steps.vue +83 -81
  165. package/dist/steps/type.ts +1 -1
  166. package/dist/sticky/sticky.vue +104 -102
  167. package/dist/swipe-cell/swipe-cell.vue +91 -89
  168. package/dist/swiper/README.md +1 -1
  169. package/dist/swiper/swiper.vue +91 -89
  170. package/dist/swiper-nav/swiper-nav.vue +38 -36
  171. package/dist/switch/props.ts +2 -2
  172. package/dist/switch/switch.vue +62 -62
  173. package/dist/switch/type.ts +1 -1
  174. package/dist/tab-bar/tab-bar.vue +88 -86
  175. package/dist/tab-bar-item/tab-bar-item.vue +85 -82
  176. package/dist/tab-panel/tab-panel.vue +66 -64
  177. package/dist/tabs/tabs.vue +294 -287
  178. package/dist/tag/tag.vue +79 -77
  179. package/dist/textarea/props.ts +6 -6
  180. package/dist/textarea/textarea.vue +127 -126
  181. package/dist/textarea/type.ts +3 -3
  182. package/dist/toast/toast.vue +107 -106
  183. package/dist/transition/transition.vue +30 -28
  184. package/dist/tree-select/tree-select.vue +151 -151
  185. package/dist/types/config-provider.d.ts +7 -0
  186. package/dist/types/index.d.ts +2 -0
  187. package/dist/types/popover.d.ts +7 -0
  188. package/dist/upload/README.en-US.md +13 -14
  189. package/dist/upload/README.md +11 -12
  190. package/dist/upload/props.ts +2 -4
  191. package/dist/upload/type.ts +12 -11
  192. package/dist/upload/upload.css +1 -1
  193. package/dist/upload/upload.vue +672 -512
  194. package/dist/watermark/watermark.vue +151 -149
  195. package/global.d.ts +2 -0
  196. package/package.json +15 -3
  197. package/dist/form/form-item-props.ts +0 -56
@@ -8,7 +8,7 @@ export interface TdSliderProps {
8
8
  /**
9
9
  * 是否禁用组件
10
10
  */
11
- disabled?: boolean;
11
+ disabled?: boolean | null;
12
12
  /**
13
13
  * 滑块当前值文本。<br />值为 true 显示默认文案;值为 false 不显示滑块当前值文本;<br />值为 `${value}%` 则表示组件会根据占位符渲染文案;<br />值类型为函数时,参数 `value` 标识滑块值,参数 `position=start` 表示范围滑块的起始值,参数 `position=end` 表示范围滑块的终点值
14
14
  * @default false
@@ -1,23 +1,23 @@
1
1
  <template>
2
2
  <view
3
- :style="tools._style([customStyle])"
4
- :class="tools.cls(classPrefix, [layout, ['readonly', readonly]]) + ' ' + tClass"
3
+ :style="'' + tools._style([customStyle])"
4
+ :class="'' + tools.cls(classPrefix, [layout, ['readonly', readonly]]) + ' ' + tClass"
5
5
  :aria-role="ariaRole || readonly ? 'option' : 'button'"
6
6
  :aria-label="ariaLabel || getAriaLabel(index, title, content)"
7
7
  :aria-current="curStatus == 'process' ? 'step' : ''"
8
8
  @click="onTap"
9
9
  >
10
10
  <view
11
- :class="tools.cls(classPrefix + '__anchor', [layout])"
11
+ :class="'' + tools.cls(classPrefix + '__anchor', [layout])"
12
12
  :aria-hidden="true"
13
13
  >
14
14
  <view
15
15
  v-if="isDot"
16
- :class="tools.cls(classPrefix + '__dot', [curStatus])"
16
+ :class="'' + tools.cls(classPrefix + '__dot', [curStatus])"
17
17
  />
18
18
  <view
19
19
  v-else-if="icon"
20
- :class="tools.cls(classPrefix + '__icon', [curStatus])"
20
+ :class="'' + tools.cls(classPrefix + '__icon', [curStatus])"
21
21
  >
22
22
  <slot
23
23
  v-if="icon == 'slot'"
@@ -31,7 +31,7 @@
31
31
  </view>
32
32
  <view
33
33
  v-else
34
- :class="tools.cls(classPrefix + '__circle', [curStatus])"
34
+ :class="'' + tools.cls(classPrefix + '__circle', [curStatus])"
35
35
  >
36
36
  <t-icon
37
37
  v-if="curStatus == 'finish'"
@@ -47,11 +47,11 @@
47
47
  </view>
48
48
  </view>
49
49
  <view
50
- :class="tools.cls(classPrefix + '__content', [layout, ['last', isLastChild]]) + ' ' + tClassContent"
50
+ :class="'' + tools.cls(classPrefix + '__content', [layout, ['last', isLastChild]]) + ' ' + tClassContent"
51
51
  :aria-hidden="true"
52
52
  >
53
53
  <slot />
54
- <view :class="tools.cls(classPrefix + '__title', [curStatus, layout]) + ' ' + tClassContent">
54
+ <view :class="'' + tools.cls(classPrefix + '__title', [curStatus, layout]) + ' ' + tClassContent">
55
55
  <block v-if="title">
56
56
  {{ title }}
57
57
  </block>
@@ -61,19 +61,19 @@
61
61
  name="title-right"
62
62
  />
63
63
  </view>
64
- <view :class="tools.cls(classPrefix + '__description', [layout]) + ' ' + tClassDescription">
64
+ <view :class="'' + tools.cls(classPrefix + '__description', [layout]) + ' ' + tClassDescription">
65
65
  <block v-if="content">
66
66
  {{ content }}
67
67
  </block>
68
68
  <slot name="content" />
69
69
  </view>
70
- <view :class="tools.cls(classPrefix + '__extra', [layout]) + ' ' + tClassExtra">
70
+ <view :class="'' + tools.cls(classPrefix + '__extra', [layout]) + ' ' + tClassExtra">
71
71
  <slot name="extra" />
72
72
  </view>
73
73
  </view>
74
74
  <view
75
75
  v-if="!isLastChild"
76
- :class="tools.cls(classPrefix + '__line', [curStatus, layout, theme, sequence])"
76
+ :class="'' + tools.cls(classPrefix + '__line', [curStatus, layout, theme, sequence])"
77
77
  :aria-hidden="true"
78
78
  />
79
79
  </view>
@@ -91,83 +91,85 @@ import { ChildrenMixin, RELATION_MAP } from '../common/relation';
91
91
  const name = `${prefix}-steps-item`;
92
92
 
93
93
 
94
- export default uniComponent({
95
- name,
96
- options: {
97
- styleIsolation: 'shared',
98
- virtualHost: true,
99
- },
100
- externalClasses: [
101
- `${prefix}-class`,
102
- `${prefix}-class-content`,
103
- `${prefix}-class-title`,
104
- `${prefix}-class-description`,
105
- `${prefix}-class-extra`,
106
- ],
107
- mixins: [ChildrenMixin(RELATION_MAP.StepItem, {
108
- indexKey: 'tIndex',
109
- })],
110
- props: {
111
- ...props,
112
- },
94
+ export default {
113
95
  components: {
114
96
  TIcon,
115
97
  },
116
- data() {
117
- return {
118
- classPrefix: name,
119
- prefix,
120
- index: 0,
121
- isDot: false,
122
- curStatus: '',
123
- layout: 'vertical',
124
- isLastChild: false,
125
- sequence: 'positive',
126
- tools,
98
+ ...uniComponent({
99
+ name,
100
+ options: {
101
+ styleIsolation: 'shared',
102
+ virtualHost: true,
103
+ },
104
+ externalClasses: [
105
+ `${prefix}-class`,
106
+ `${prefix}-class-content`,
107
+ `${prefix}-class-title`,
108
+ `${prefix}-class-description`,
109
+ `${prefix}-class-extra`,
110
+ ],
111
+ mixins: [ChildrenMixin(RELATION_MAP.StepItem, {
112
+ indexKey: 'tIndex',
113
+ })],
114
+ props: {
115
+ ...props,
116
+ },
117
+ data() {
118
+ return {
119
+ classPrefix: name,
120
+ prefix,
121
+ index: 0,
122
+ isDot: false,
123
+ curStatus: '',
124
+ layout: 'vertical',
125
+ isLastChild: false,
126
+ sequence: 'positive',
127
+ tools,
127
128
 
128
- readonly: false,
129
- theme: '',
130
- };
131
- },
132
- watch: {
133
- status(value) {
134
- const { curStatus } = this;
129
+ readonly: false,
130
+ theme: '',
131
+ };
132
+ },
133
+ watch: {
134
+ status(value) {
135
+ const { curStatus } = this;
135
136
 
136
- if (curStatus === '' || value === curStatus) return;
137
+ if (curStatus === '' || value === curStatus) return;
137
138
 
138
- this.curStatus = value;
139
+ this.curStatus = value;
140
+ },
139
141
  },
140
- },
141
- mounted() {
142
+ mounted() {
142
143
 
143
- },
144
- methods: {
145
- getAriaLabel,
146
- updateStatus({ current, currentStatus, index, theme, layout, items, sequence }) {
147
- let curStatus = this.status;
144
+ },
145
+ methods: {
146
+ getAriaLabel,
147
+ updateStatus({ current, currentStatus, index, theme, layout, items, sequence }) {
148
+ let curStatus = this.status;
148
149
 
149
- if (curStatus === 'default') {
150
- if (index < Number(current)) {
151
- curStatus = 'finish';
152
- } else if (index === Number(current)) {
153
- curStatus = currentStatus;
150
+ if (curStatus === 'default') {
151
+ if (index < Number(current)) {
152
+ curStatus = 'finish';
153
+ } else if (index === Number(current)) {
154
+ curStatus = currentStatus;
155
+ }
154
156
  }
155
- }
156
157
 
157
- this.curStatus = curStatus;
158
- this.index = index;
159
- this.layout = layout;
160
- this.theme = theme;
161
- this.sequence = sequence;
162
- this.isDot = theme === 'dot';
163
- this.isLastChild = index === (sequence === 'positive' ? items.length - 1 : 0);
164
- },
158
+ this.curStatus = curStatus;
159
+ this.index = index;
160
+ this.layout = layout;
161
+ this.theme = theme;
162
+ this.sequence = sequence;
163
+ this.isDot = theme === 'dot';
164
+ this.isLastChild = index === (sequence === 'positive' ? items.length - 1 : 0);
165
+ },
165
166
 
166
- onTap() {
167
- this[RELATION_MAP.StepItem].handleClick(this.index);
167
+ onTap() {
168
+ this[RELATION_MAP.StepItem].handleClick(this.index);
169
+ },
168
170
  },
169
- },
170
- });
171
+ }),
172
+ };
171
173
 
172
174
  </script>
173
175
  <style scoped src="./step-item.css"></style>
@@ -10,8 +10,8 @@ export default {
10
10
  disableInput: Boolean,
11
11
  /** 禁用全部操作 */
12
12
  disabled: {
13
- type: Boolean,
14
- default: undefined,
13
+ type: [Boolean, null],
14
+ default: null as TdStepperProps['disabled'],
15
15
  },
16
16
  /** 输入框宽度,默认单位 `px` */
17
17
  inputWidth: {
@@ -1,6 +1,6 @@
1
1
  <template>
2
2
  <view
3
- :style="tools._style([customStyle])"
3
+ :style="'' + tools._style([customStyle])"
4
4
  :class="classPrefix + ' ' + classPrefix + '--' + size + ' ' + tClass"
5
5
  >
6
6
  <view
@@ -51,7 +51,7 @@
51
51
  import TIcon from '../icon/icon';
52
52
  import { uniComponent } from '../common/src/index';
53
53
  import { prefix } from '../common/config';
54
- import { coalesce } from '../common/utils';
54
+ import { coalesce, nextTick } from '../common/utils';
55
55
  import props from './props';
56
56
  import tools from '../common/utils.wxs';
57
57
 
@@ -59,163 +59,182 @@ import tools from '../common/utils.wxs';
59
59
  const name = `${prefix}-stepper`;
60
60
 
61
61
 
62
- export default uniComponent({
63
- name,
64
- options: {
65
- styleIsolation: 'shared',
66
- },
67
- controlledProps: [
68
- {
69
- key: 'value',
70
- event: 'change',
71
- },
72
- ],
73
- externalClasses: [
74
- `${prefix}-class`,
75
- `${prefix}-class-input`,
76
- `${prefix}-class-minus`,
77
- `${prefix}-class-plus`,
78
- ],
62
+ export default {
79
63
  components: {
80
64
  TIcon,
81
65
  },
82
- props: {
83
- ...props,
84
- },
85
- data() {
86
- return {
87
- currentValue: 0,
88
- classPrefix: name,
89
- prefix,
90
- tools,
91
- disablePlus: false,
92
- disableMinus: false,
93
- };
94
- },
95
- watch: {
96
- value(v) {
97
- this.preValue = Number(v);
98
- this.updateCurrentValue(this.format(this.preValue));
99
- },
100
- },
101
- mounted() {
102
- const { value, defaultValue, min } = this;
103
- const cur = coalesce(value, defaultValue);
104
-
105
- this.updateCurrentValue(cur ? Number(cur) : min);
106
- },
107
- methods: {
108
- isDisabled(type) {
109
- const { min, max, disabled } = this;
110
- const { currentValue } = this;
111
- if (disabled) {
112
- return true;
113
- }
114
- if (type === 'minus' && currentValue <= min) {
115
- return true;
116
- }
117
- if (type === 'plus' && currentValue >= max) {
118
- return true;
119
- }
120
- return false;
121
- },
122
-
123
- getLen(num) {
124
- const numStr = num.toString();
125
- return numStr.indexOf('.') === -1 ? 0 : numStr.split('.')[1].length;
66
+ ...uniComponent({
67
+ name,
68
+ options: {
69
+ styleIsolation: 'shared',
126
70
  },
127
-
128
- add(a, b) {
129
- const maxLen = Math.max(this.getLen(a), this.getLen(b));
130
- const base = 10 ** maxLen;
131
- return Math.round(a * base + b * base) / base;
71
+ controlledProps: [
72
+ {
73
+ key: 'value',
74
+ event: 'change',
75
+ },
76
+ ],
77
+ externalClasses: [
78
+ `${prefix}-class`,
79
+ `${prefix}-class-input`,
80
+ `${prefix}-class-minus`,
81
+ `${prefix}-class-plus`,
82
+ ],
83
+ props: {
84
+ ...props,
132
85
  },
133
-
134
- format(value) {
135
- const { min, max, step } = this;
136
- const len = Math.max(this.getLen(step), this.getLen(value));
137
- // 超过边界取边界值
138
- return Math.max(Math.min(max, value, Number.MAX_SAFE_INTEGER), min, Number.MIN_SAFE_INTEGER).toFixed(len);
86
+ data() {
87
+ return {
88
+ currentValue: 0,
89
+ classPrefix: name,
90
+ prefix,
91
+ tools,
92
+ disablePlus: false,
93
+ disableMinus: false,
94
+ };
139
95
  },
140
-
141
- setValue(value) {
142
- const newValue = Number(this.format(value));
143
-
144
- this.updateCurrentValue(newValue);
145
-
146
- if (this.preValue === newValue) return;
147
-
148
- this.preValue = newValue;
149
- this._trigger('change', { value: newValue });
96
+ watch: {
97
+ value(v) {
98
+ this.preValue = Number(v);
99
+ this.updateCurrentValue(this.format(this.preValue));
100
+ },
150
101
  },
102
+ mounted() {
103
+ const { value, defaultValue, min } = this;
104
+ const cur = coalesce(value, defaultValue);
151
105
 
152
- minusValue() {
153
- if (this.isDisabled('minus')) {
154
- this.$emit('overlimit', { type: 'minus' });
155
- return false;
156
- }
157
- const { currentValue, step } = this;
158
- this.setValue(this.add(currentValue, -step));
106
+ this.updateCurrentValue(cur ? Number(cur) : min);
159
107
  },
160
-
161
- plusValue() {
162
- if (this.isDisabled('plus')) {
163
- this.$emit('overlimit', { type: 'plus' });
108
+ methods: {
109
+ isDisabled(type) {
110
+ const { min, max, disabled } = this;
111
+ const { currentValue } = this;
112
+ if (disabled) {
113
+ return true;
114
+ }
115
+ if (type === 'minus' && currentValue <= min) {
116
+ return true;
117
+ }
118
+ if (type === 'plus' && currentValue >= max) {
119
+ return true;
120
+ }
164
121
  return false;
165
- }
166
- const { currentValue, step } = this;
167
- this.setValue(this.add(currentValue, step));
122
+ },
123
+
124
+ getLen(num) {
125
+ const numStr = num.toString();
126
+ return numStr.indexOf('.') === -1 ? 0 : numStr.split('.')[1].length;
127
+ },
128
+
129
+ add(a, b) {
130
+ const maxLen = Math.max(this.getLen(a), this.getLen(b));
131
+ const base = 10 ** maxLen;
132
+ const result = Math.round(a * base + b * base) / base;
133
+ // 保留运算涉及的最大小数位数,避免精度信息丢失
134
+ return maxLen > 0 ? result.toFixed(maxLen) : result;
135
+ },
136
+
137
+ format(value) {
138
+ const { min, max, step } = this;
139
+ // 使用字符串形式计算小数位数,避免数字隐式转换导致末尾0丢失
140
+ const len = Math.max(this.getLen(step), this.getLen(String(value)));
141
+ // 超过边界取边界值
142
+ return Math.max(Math.min(max, value, Number.MAX_SAFE_INTEGER), min, Number.MIN_SAFE_INTEGER).toFixed(len);
143
+ },
144
+
145
+ setValue(value) {
146
+ const formattedStr = this.format(value);
147
+ const newValue = Number(formattedStr);
148
+
149
+ nextTick().then(() => {
150
+ // 使用 format 返回的字符串更新显示值,避免 Number() 转换丢失末尾0
151
+ this.updateCurrentValue(formattedStr);
152
+ });
153
+
154
+ if (this.preValue === newValue) return;
155
+
156
+ this.preValue = newValue;
157
+ this._trigger('change', { value: newValue });
158
+ },
159
+
160
+ minusValue() {
161
+ if (this.isDisabled('minus')) {
162
+ this.$emit('overlimit', { type: 'minus' });
163
+ return false;
164
+ }
165
+ const { currentValue, step } = this;
166
+ this.setValue(this.add(currentValue, -step));
167
+ },
168
+
169
+ plusValue() {
170
+ if (this.isDisabled('plus')) {
171
+ this.$emit('overlimit', { type: 'plus' });
172
+ return false;
173
+ }
174
+ const { currentValue, step } = this;
175
+ this.setValue(this.add(currentValue, step));
176
+ },
177
+
178
+ filterIllegalChar(value) {
179
+ const v = String(value).replace(/[^0-9.]/g, '');
180
+ const indexOfDot = v.indexOf('.');
181
+ if (this.integer && indexOfDot !== -1) {
182
+ return v.split('.')[0];
183
+ }
184
+
185
+ if (!this.integer && indexOfDot !== -1 && indexOfDot !== v.lastIndexOf('.')) {
186
+ return v.split('.', 2).join('.');
187
+ }
188
+
189
+ return v;
190
+ },
191
+
192
+ updateCurrentValue(value) {
193
+ this.currentValue = value;
194
+ },
195
+
196
+ handleFocus(e) {
197
+ const { value } = e.detail;
198
+
199
+ this.$emit('focus', { value });
200
+ },
201
+
202
+ handleInput(e) {
203
+ const { value } = e.detail;
204
+ // 允许输入空值
205
+ if (value === '') {
206
+ return;
207
+ }
208
+
209
+ const formatted = this.filterIllegalChar(value);
210
+ const newValue = this.format(formatted);
211
+
212
+ const displayValue = this.integer ? newValue : formatted;
213
+ // 当过滤后的值与当前值相同时,需要先清空再回填,强制触发视图更新
214
+ if (String(this.currentValue) === String(displayValue)) {
215
+ this.updateCurrentValue('');
216
+ nextTick().then(() => {
217
+ this.updateCurrentValue(displayValue);
218
+ });
219
+ } else {
220
+ this.updateCurrentValue(displayValue);
221
+ }
222
+
223
+ if (this.integer || /\.\d*[1-9]/.test(formatted)) {
224
+ this.setValue(formatted);
225
+ }
226
+ },
227
+
228
+ handleBlur(e) {
229
+ const { value: rawValue } = e.detail;
230
+ const formatted = this.filterIllegalChar(rawValue);
231
+ const value = this.format(formatted);
232
+
233
+ this.setValue(value);
234
+ this.$emit('blur', { value });
235
+ },
168
236
  },
169
-
170
- filterIllegalChar(value) {
171
- const v = String(value).replace(/[^0-9.]/g, '');
172
- const indexOfDot = v.indexOf('.');
173
- if (this.integer && indexOfDot !== -1) {
174
- return v.split('.')[0];
175
- }
176
-
177
- if (!this.integer && indexOfDot !== -1 && indexOfDot !== v.lastIndexOf('.')) {
178
- return v.split('.', 2).join('.');
179
- }
180
-
181
- return v;
182
- },
183
-
184
- updateCurrentValue(value) {
185
- this.currentValue = value;
186
- },
187
-
188
- handleFocus(e) {
189
- const { value } = e.detail;
190
-
191
- this.$emit('focus', { value });
192
- },
193
-
194
- handleInput(e) {
195
- const { value } = e.detail;
196
- // 允许输入空值
197
- if (value === '') {
198
- return;
199
- }
200
-
201
- const formatted = this.filterIllegalChar(value);
202
- const newValue = this.format(formatted);
203
-
204
- this.updateCurrentValue(this.integer ? newValue : formatted);
205
-
206
- if (this.integer || /\.\d+/.test(formatted)) {
207
- this.setValue(formatted);
208
- }
209
- },
210
-
211
- handleBlur(e) {
212
- const { value: rawValue } = e.detail;
213
- const value = this.format(rawValue);
214
-
215
- this.setValue(value);
216
- this.$emit('blur', { value });
217
- },
218
- },
219
- });
237
+ }),
238
+ };
220
239
  </script>
221
240
  <style scoped src="./stepper.css"></style>
@@ -15,7 +15,7 @@ export interface TdStepperProps {
15
15
  /**
16
16
  * 禁用全部操作
17
17
  */
18
- disabled?: boolean;
18
+ disabled?: boolean | null;
19
19
  /**
20
20
  * 输入框宽度,默认单位 `px`
21
21
  */
@@ -34,8 +34,8 @@ export default {
34
34
  },
35
35
  /** 只读状态 */
36
36
  readonly: {
37
- type: Boolean,
38
- default: undefined,
37
+ type: [Boolean, null],
38
+ default: null as TdStepsProps['readonly'],
39
39
  },
40
40
  /** 步骤条顺序 */
41
41
  sequence: {