hy-app 0.2.4 → 0.2.5
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/components/hy-button/hy-button.vue +88 -120
- package/components/hy-calendar/index.scss +1 -1
- package/components/hy-cell/index.scss +2 -2
- package/components/hy-checkbox/index.scss +10 -10
- package/components/hy-code-input/hy-code-input.vue +83 -73
- package/components/hy-code-input/index.scss +31 -1
- package/components/hy-code-input/props.ts +8 -7
- package/components/hy-code-input/typing.d.ts +21 -17
- package/components/hy-config-provider/typing.d.ts +7 -7
- package/components/hy-dropdown-item/hy-dropdown-item.vue +69 -75
- package/components/hy-dropdown-item/index.scss +1 -1
- package/components/hy-float-button/hy-float-button.vue +69 -86
- package/components/hy-form/index.scss +1 -1
- package/components/hy-navbar/index.scss +2 -2
- package/components/hy-notice-bar/index.scss +3 -3
- package/components/hy-picker/hy-picker.vue +9 -8
- package/components/hy-picker/index.scss +6 -2
- package/components/hy-radio/index.scss +2 -2
- package/components/hy-scroll-list/index.scss +1 -1
- package/components/hy-text/hy-text.vue +76 -87
- package/components/hy-text/index.scss +6 -6
- package/components/hy-watermark/hy-watermark.vue +113 -133
- package/components/hy-watermark/index.scss +4 -2
- package/index.scss +1 -1
- package/libs/css/common.scss +9 -1
- package/package.json +2 -2
- package/theme.scss +6 -17
|
@@ -26,16 +26,10 @@
|
|
|
26
26
|
:class="['hy-button', 'hy-reset-button', bemClass]"
|
|
27
27
|
>
|
|
28
28
|
<template v-if="loading">
|
|
29
|
-
<HyLoading
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
></HyLoading>
|
|
34
|
-
<text
|
|
35
|
-
class="hy-button__loading-text"
|
|
36
|
-
:style="[{ fontSize: textSize + 'px' }]"
|
|
37
|
-
>{{ loadingText || text }}</text
|
|
38
|
-
>
|
|
29
|
+
<HyLoading :mode="loadingMode" :size="loadingSize" :color="loadingColor"></HyLoading>
|
|
30
|
+
<text class="hy-button__loading-text" :style="[{ fontSize: textSize + 'px' }]">
|
|
31
|
+
{{ loadingText || text }}
|
|
32
|
+
</text>
|
|
39
33
|
</template>
|
|
40
34
|
<template v-else>
|
|
41
35
|
<HyIcon
|
|
@@ -54,11 +48,7 @@
|
|
|
54
48
|
:customStyle="icon?.customStyle || { marginRight: '2px' }"
|
|
55
49
|
></HyIcon>
|
|
56
50
|
<slot>
|
|
57
|
-
<text
|
|
58
|
-
class="hy-button__text"
|
|
59
|
-
:style="[{ fontSize: textSize + 'px' }]"
|
|
60
|
-
>{{ text }}</text
|
|
61
|
-
>
|
|
51
|
+
<text class="hy-button__text" :style="[{ fontSize: textSize + 'px' }]">{{ text }}</text>
|
|
62
52
|
</slot>
|
|
63
53
|
</template>
|
|
64
54
|
</button>
|
|
@@ -81,17 +71,14 @@
|
|
|
81
71
|
:style="[baseColor, customStyle]"
|
|
82
72
|
>
|
|
83
73
|
<template v-if="loading">
|
|
84
|
-
<HyLoading
|
|
85
|
-
:mode="loadingMode"
|
|
86
|
-
:size="loadingSize"
|
|
87
|
-
:color="loadingColor"
|
|
88
|
-
></HyLoading>
|
|
74
|
+
<HyLoading :mode="loadingMode" :size="loadingSize" :color="loadingColor"></HyLoading>
|
|
89
75
|
<text
|
|
90
76
|
class="hy-button__loading-text"
|
|
91
77
|
:style="[nvueTextStyle]"
|
|
92
78
|
:class="[plain && `hy-button__text--plain--${type}`]"
|
|
93
|
-
>{{ loadingText || text }}</text
|
|
94
79
|
>
|
|
80
|
+
{{ loadingText || text }}
|
|
81
|
+
</text>
|
|
95
82
|
</template>
|
|
96
83
|
<template v-else>
|
|
97
84
|
<HyIcon
|
|
@@ -118,8 +105,9 @@
|
|
|
118
105
|
nvueTextStyle,
|
|
119
106
|
]"
|
|
120
107
|
:class="[plain && `hy-button__text--plain--${type}`]"
|
|
121
|
-
>{{ text }}</text
|
|
122
108
|
>
|
|
109
|
+
{{ text }}
|
|
110
|
+
</text>
|
|
123
111
|
</template>
|
|
124
112
|
</view>
|
|
125
113
|
<!-- #endif -->
|
|
@@ -127,49 +115,39 @@
|
|
|
127
115
|
|
|
128
116
|
<script lang="ts">
|
|
129
117
|
export default {
|
|
130
|
-
name:
|
|
118
|
+
name: 'hy-button',
|
|
131
119
|
options: {
|
|
132
120
|
addGlobalClass: true,
|
|
133
121
|
virtualHost: true,
|
|
134
|
-
styleIsolation:
|
|
122
|
+
styleIsolation: 'shared',
|
|
135
123
|
},
|
|
136
|
-
}
|
|
124
|
+
}
|
|
137
125
|
</script>
|
|
138
126
|
|
|
139
127
|
<script setup lang="ts">
|
|
140
|
-
import { computed, type CSSProperties, toRefs } from
|
|
141
|
-
import { bem, throttle } from
|
|
142
|
-
import defaultProps from
|
|
143
|
-
import { ColorConfig } from
|
|
144
|
-
import type IProps from
|
|
128
|
+
import { computed, type CSSProperties, toRefs } from 'vue'
|
|
129
|
+
import { bem, throttle } from '../../utils'
|
|
130
|
+
import defaultProps from './props'
|
|
131
|
+
import { ColorConfig } from '../../config'
|
|
132
|
+
import type IProps from './typing'
|
|
145
133
|
|
|
146
134
|
// 组件
|
|
147
|
-
import HyIcon from
|
|
148
|
-
import HyLoading from
|
|
135
|
+
import HyIcon from '../hy-icon/hy-icon.vue'
|
|
136
|
+
import HyLoading from '../hy-loading/hy-loading.vue'
|
|
149
137
|
|
|
150
|
-
const props = withDefaults(defineProps<IProps>(), defaultProps)
|
|
151
|
-
const {
|
|
152
|
-
disabled,
|
|
153
|
-
loading,
|
|
154
|
-
throttleTime,
|
|
155
|
-
stop,
|
|
156
|
-
size,
|
|
157
|
-
type,
|
|
158
|
-
plain,
|
|
159
|
-
color,
|
|
160
|
-
icon,
|
|
161
|
-
} = toRefs(props);
|
|
138
|
+
const props = withDefaults(defineProps<IProps>(), defaultProps)
|
|
139
|
+
const { disabled, loading, throttleTime, stop, size, type, plain, color, icon } = toRefs(props)
|
|
162
140
|
const emit = defineEmits([
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
])
|
|
141
|
+
'click',
|
|
142
|
+
'getphonenumber',
|
|
143
|
+
'getuserinfo',
|
|
144
|
+
'error',
|
|
145
|
+
'opensetting',
|
|
146
|
+
'launchapp',
|
|
147
|
+
'agreeprivacyauthorization',
|
|
148
|
+
])
|
|
171
149
|
|
|
172
|
-
const textColor = (ColorConfig as any)[type.value]
|
|
150
|
+
const textColor = (ColorConfig as any)[type.value]
|
|
173
151
|
|
|
174
152
|
/**
|
|
175
153
|
* @description 生成bem风格的类名
|
|
@@ -177,133 +155,123 @@ const textColor = (ColorConfig as any)[type.value];
|
|
|
177
155
|
const bemClass = computed(() => {
|
|
178
156
|
// this.bem为一个computed变量,在mixin中
|
|
179
157
|
if (!color.value) {
|
|
180
|
-
return bem(
|
|
181
|
-
"button",
|
|
182
|
-
props,
|
|
183
|
-
["type", "shape", "size"],
|
|
184
|
-
["disabled", "plain", "hairline"],
|
|
185
|
-
);
|
|
158
|
+
return bem('button', props, ['type', 'shape', 'size'], ['disabled', 'plain', 'hairline'])
|
|
186
159
|
} else {
|
|
187
160
|
// 由于nvue的原因,在有color参数时,不需要传入type,否则会生成type相关的类型,影响最终的样式
|
|
188
|
-
return bem(
|
|
189
|
-
"button",
|
|
190
|
-
props,
|
|
191
|
-
["shape", "size"],
|
|
192
|
-
["disabled", "plain", "hairline"],
|
|
193
|
-
);
|
|
161
|
+
return bem('button', props, ['shape', 'size'], ['disabled', 'plain', 'hairline'])
|
|
194
162
|
}
|
|
195
|
-
})
|
|
163
|
+
})
|
|
196
164
|
|
|
197
165
|
const loadingColor = computed(() => {
|
|
198
166
|
if (plain.value) {
|
|
199
167
|
// 如果有设置color值,则用color值,否则使用type主题颜色
|
|
200
|
-
return color.value ? color.value :
|
|
168
|
+
return color.value ? color.value : ''
|
|
201
169
|
}
|
|
202
|
-
if (type.value ===
|
|
203
|
-
return
|
|
170
|
+
if (type.value === 'info') {
|
|
171
|
+
return '#c9c9c9'
|
|
204
172
|
}
|
|
205
|
-
return
|
|
206
|
-
})
|
|
173
|
+
return '#fff'
|
|
174
|
+
})
|
|
207
175
|
|
|
208
176
|
const iconColorCom = computed((): string => {
|
|
209
177
|
// 如果是镂空状态,设置了color就用color值,否则使用主题颜色,
|
|
210
|
-
if (icon.value?.color) return icon.value?.color
|
|
178
|
+
if (icon.value?.color) return icon.value?.color
|
|
211
179
|
if (plain.value) {
|
|
212
|
-
return color.value ? color.value :
|
|
180
|
+
return color.value ? color.value : ''
|
|
213
181
|
} else {
|
|
214
|
-
return
|
|
182
|
+
return '#ffffff'
|
|
215
183
|
}
|
|
216
|
-
})
|
|
184
|
+
})
|
|
217
185
|
const baseColor = computed((): CSSProperties => {
|
|
218
|
-
let style: CSSProperties = {}
|
|
186
|
+
let style: CSSProperties = {}
|
|
219
187
|
if (color.value) {
|
|
220
188
|
// 针对自定义了color颜色的情况,镂空状态下,就是用自定义的颜色
|
|
221
|
-
style.color = plain.value ? color.value :
|
|
189
|
+
style.color = plain.value ? color.value : 'white'
|
|
222
190
|
if (!plain.value) {
|
|
223
191
|
// 非镂空,背景色使用自定义的颜色
|
|
224
|
-
style[
|
|
192
|
+
style['background'] = color.value
|
|
225
193
|
}
|
|
226
|
-
if (color.value.indexOf(
|
|
194
|
+
if (color.value.indexOf('gradient') !== -1) {
|
|
227
195
|
// 如果自定义的颜色为渐变色,不显示边框,以及通过backgroundImage设置渐变色
|
|
228
196
|
// weex文档说明可以写borderWidth的形式,为什么这里需要分开写?
|
|
229
197
|
// 因为weex是阿里巴巴为了部门业绩考核而做的你懂的东西,所以需要这么写才有效
|
|
230
|
-
style.borderTopWidth = 0
|
|
231
|
-
style.borderRightWidth = 0
|
|
232
|
-
style.borderBottomWidth = 0
|
|
233
|
-
style.borderLeftWidth = 0
|
|
198
|
+
style.borderTopWidth = 0
|
|
199
|
+
style.borderRightWidth = 0
|
|
200
|
+
style.borderBottomWidth = 0
|
|
201
|
+
style.borderLeftWidth = 0
|
|
234
202
|
if (!plain.value) {
|
|
235
|
-
style.backgroundImage = color.value
|
|
203
|
+
style.backgroundImage = color.value
|
|
236
204
|
}
|
|
237
205
|
} else {
|
|
238
206
|
// 非渐变色,则设置边框相关的属性
|
|
239
|
-
style.borderColor = color.value
|
|
240
|
-
style.borderWidth =
|
|
241
|
-
style.borderStyle =
|
|
207
|
+
style.borderColor = color.value
|
|
208
|
+
style.borderWidth = '1px'
|
|
209
|
+
style.borderStyle = 'solid'
|
|
242
210
|
}
|
|
243
211
|
} else {
|
|
244
212
|
// 针对自定义了color颜色的情况,镂空状态下,就是用自定义的颜色
|
|
245
213
|
// style.color = plain.value ? textColor : "";
|
|
246
214
|
}
|
|
247
|
-
return style
|
|
248
|
-
})
|
|
215
|
+
return style
|
|
216
|
+
})
|
|
249
217
|
|
|
250
218
|
// nvue版本按钮的字体不会继承父组件的颜色,需要对每一个text组件进行单独的设置
|
|
251
219
|
const nvueTextStyle = computed((): CSSProperties => {
|
|
252
|
-
let style: CSSProperties = {}
|
|
220
|
+
let style: CSSProperties = {}
|
|
253
221
|
// 针对自定义了color颜色的情况,镂空状态下,就是用自定义的颜色
|
|
254
|
-
if (type.value ===
|
|
255
|
-
style.color =
|
|
222
|
+
if (type.value === 'info') {
|
|
223
|
+
style.color = '#323233'
|
|
256
224
|
}
|
|
257
225
|
if (color.value) {
|
|
258
|
-
style.color = plain.value ? color.value :
|
|
226
|
+
style.color = plain.value ? color.value : 'white'
|
|
259
227
|
}
|
|
260
|
-
style.fontSize = textSize.value +
|
|
261
|
-
return style
|
|
262
|
-
})
|
|
228
|
+
style.fontSize = textSize.value + 'px'
|
|
229
|
+
return style
|
|
230
|
+
})
|
|
263
231
|
/**
|
|
264
232
|
* @description 字体大小
|
|
265
233
|
* */
|
|
266
234
|
const textSize = computed((): number => {
|
|
267
|
-
let fontSize = 14
|
|
268
|
-
if (size.value ===
|
|
269
|
-
if (size.value ===
|
|
270
|
-
if (size.value ===
|
|
271
|
-
if (size.value ===
|
|
272
|
-
return fontSize
|
|
273
|
-
})
|
|
235
|
+
let fontSize = 14
|
|
236
|
+
if (size.value === 'large') fontSize = 16
|
|
237
|
+
if (size.value === 'medium') fontSize = 14
|
|
238
|
+
if (size.value === 'small') fontSize = 12
|
|
239
|
+
if (size.value === 'mini') fontSize = 10
|
|
240
|
+
return fontSize
|
|
241
|
+
})
|
|
274
242
|
|
|
275
243
|
const clickHandler = (e: any) => {
|
|
276
244
|
// 非禁止并且非加载中,才能点击
|
|
277
245
|
if (!disabled.value && !loading.value) {
|
|
278
246
|
// 进行节流控制,每this.throttle毫秒内,只在开始处执行
|
|
279
247
|
throttle(() => {
|
|
280
|
-
emit(
|
|
281
|
-
}, throttleTime.value)
|
|
248
|
+
emit('click', e)
|
|
249
|
+
}, throttleTime.value)
|
|
282
250
|
}
|
|
283
251
|
// 是否阻止事件传播
|
|
284
|
-
stop.value && e.stopPropagation()
|
|
285
|
-
}
|
|
252
|
+
stop.value && e.stopPropagation()
|
|
253
|
+
}
|
|
286
254
|
|
|
287
255
|
const getphonenumber = (e: any) => {
|
|
288
|
-
emit(
|
|
289
|
-
}
|
|
256
|
+
emit('getphonenumber', e)
|
|
257
|
+
}
|
|
290
258
|
const getuserinfo = (e: any) => {
|
|
291
|
-
emit(
|
|
292
|
-
}
|
|
259
|
+
emit('getuserinfo', e)
|
|
260
|
+
}
|
|
293
261
|
const error = (e: any) => {
|
|
294
|
-
emit(
|
|
295
|
-
}
|
|
262
|
+
emit('error', e)
|
|
263
|
+
}
|
|
296
264
|
const opensetting = (e: any) => {
|
|
297
|
-
emit(
|
|
298
|
-
}
|
|
265
|
+
emit('opensetting', e)
|
|
266
|
+
}
|
|
299
267
|
const launchapp = (e: any) => {
|
|
300
|
-
emit(
|
|
301
|
-
}
|
|
268
|
+
emit('launchapp', e)
|
|
269
|
+
}
|
|
302
270
|
const agreeprivacyauthorization = (e: any) => {
|
|
303
|
-
emit(
|
|
304
|
-
}
|
|
271
|
+
emit('agreeprivacyauthorization', e)
|
|
272
|
+
}
|
|
305
273
|
</script>
|
|
306
274
|
|
|
307
275
|
<style lang="scss" scoped>
|
|
308
|
-
@import
|
|
276
|
+
@import './index.scss';
|
|
309
277
|
</style>
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
/* #ifndef APP-NVUE */
|
|
33
33
|
box-sizing: border-box;
|
|
34
34
|
/* #endif */
|
|
35
|
-
font-size: $hy-font-size-
|
|
35
|
+
font-size: $hy-font-size-base;
|
|
36
36
|
align-items: center;
|
|
37
37
|
border-radius: $hy-border-margin-padding-sm;
|
|
38
38
|
overflow: hidden;
|
|
@@ -81,7 +81,7 @@
|
|
|
81
81
|
/*行头部*/
|
|
82
82
|
&-title {
|
|
83
83
|
margin-right: $hy-border-margin-padding-sm;
|
|
84
|
-
flex:
|
|
84
|
+
flex: 33rpx;
|
|
85
85
|
display: flex;
|
|
86
86
|
flex-direction: column;
|
|
87
87
|
|
|
@@ -2,6 +2,15 @@
|
|
|
2
2
|
@use "../../theme.scss" as *;
|
|
3
3
|
|
|
4
4
|
@include b(checkbox) {
|
|
5
|
+
/* #ifndef APP-NVUE */
|
|
6
|
+
@include flex(row);
|
|
7
|
+
/* #endif */
|
|
8
|
+
overflow: hidden;
|
|
9
|
+
flex-direction: row;
|
|
10
|
+
align-items: center;
|
|
11
|
+
margin-bottom: 5px;
|
|
12
|
+
margin-top: 5px;
|
|
13
|
+
|
|
5
14
|
&-group {
|
|
6
15
|
&--row {
|
|
7
16
|
/* #ifndef APP-NVUE */
|
|
@@ -15,15 +24,6 @@
|
|
|
15
24
|
}
|
|
16
25
|
}
|
|
17
26
|
|
|
18
|
-
/* #ifndef APP-NVUE */
|
|
19
|
-
@include flex(row);
|
|
20
|
-
/* #endif */
|
|
21
|
-
overflow: hidden;
|
|
22
|
-
flex-direction: row;
|
|
23
|
-
align-items: center;
|
|
24
|
-
margin-bottom: 5px;
|
|
25
|
-
margin-top: 5px;
|
|
26
|
-
|
|
27
27
|
&-label--left {
|
|
28
28
|
flex-direction: row;
|
|
29
29
|
}
|
|
@@ -98,4 +98,4 @@
|
|
|
98
98
|
color: $hy-text-color--disabled;
|
|
99
99
|
}
|
|
100
100
|
}
|
|
101
|
-
}
|
|
101
|
+
}
|
|
@@ -1,12 +1,7 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<view class="hy-code-input">
|
|
3
3
|
<view
|
|
4
|
-
:class="
|
|
5
|
-
'hy-code-input--item',
|
|
6
|
-
`hy-code-input--item__${mode}`,
|
|
7
|
-
current > index && `hy-code-input--item__${mode}__border`,
|
|
8
|
-
isFocus && current === index && `hy-code-input--item__${mode}__active`,
|
|
9
|
-
]"
|
|
4
|
+
:class="itemClass(index)"
|
|
10
5
|
:style="[itemStyle(index)]"
|
|
11
6
|
v-for="(item, index) in codeLength"
|
|
12
7
|
:key="index"
|
|
@@ -24,8 +19,9 @@
|
|
|
24
19
|
fontWeight: bold ? 'bold' : 'normal',
|
|
25
20
|
color: color,
|
|
26
21
|
}"
|
|
27
|
-
>{{ codeArray[index] }}</text
|
|
28
22
|
>
|
|
23
|
+
{{ codeArray[index] }}
|
|
24
|
+
</text>
|
|
29
25
|
</view>
|
|
30
26
|
<input
|
|
31
27
|
:disabled="disabledKeyboard"
|
|
@@ -47,60 +43,53 @@
|
|
|
47
43
|
|
|
48
44
|
<script lang="ts">
|
|
49
45
|
export default {
|
|
50
|
-
name:
|
|
46
|
+
name: 'hy-code-input',
|
|
51
47
|
options: {
|
|
52
48
|
addGlobalClass: true,
|
|
53
49
|
virtualHost: true,
|
|
54
|
-
styleIsolation:
|
|
50
|
+
styleIsolation: 'shared',
|
|
55
51
|
},
|
|
56
|
-
}
|
|
52
|
+
}
|
|
57
53
|
</script>
|
|
58
54
|
|
|
59
55
|
<script setup lang="ts">
|
|
60
|
-
import {
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
onUnmounted,
|
|
65
|
-
ref,
|
|
66
|
-
toRefs,
|
|
67
|
-
watch,
|
|
68
|
-
} from "vue";
|
|
69
|
-
import type IProps from "./typing";
|
|
70
|
-
import defaultProps from "./props";
|
|
71
|
-
import { addUnit, getPx } from "../../utils";
|
|
56
|
+
import { computed, type CSSProperties, nextTick, onUnmounted, ref, toRefs, watch } from 'vue'
|
|
57
|
+
import type IProps from './typing'
|
|
58
|
+
import defaultProps from './props'
|
|
59
|
+
import { addUnit, getPx } from '../../utils'
|
|
72
60
|
|
|
73
|
-
const props = withDefaults(defineProps<IProps>(), defaultProps)
|
|
61
|
+
const props = withDefaults(defineProps<IProps>(), defaultProps)
|
|
74
62
|
const {
|
|
75
63
|
modelValue,
|
|
76
64
|
focus,
|
|
77
65
|
maxlength,
|
|
66
|
+
border,
|
|
78
67
|
disabledDot,
|
|
79
68
|
size,
|
|
80
69
|
mode,
|
|
81
70
|
hairline,
|
|
82
71
|
space,
|
|
83
72
|
borderColor,
|
|
84
|
-
} = toRefs(props)
|
|
85
|
-
const emit = defineEmits([
|
|
73
|
+
} = toRefs(props)
|
|
74
|
+
const emit = defineEmits(['change', 'finish', 'update:modelValue'])
|
|
86
75
|
|
|
87
|
-
const current = ref(0)
|
|
88
|
-
const inputValue = ref(
|
|
89
|
-
const isFocus = ref(focus.value)
|
|
90
|
-
let timer: ReturnType<typeof setInterval
|
|
91
|
-
const opacity = ref(1)
|
|
92
|
-
const borderWidth = computed(() => (hairline.value ?
|
|
93
|
-
const lineHeight = computed(() => (hairline.value ?
|
|
94
|
-
const boxSize = addUnit(size.value)
|
|
76
|
+
const current = ref(0)
|
|
77
|
+
const inputValue = ref('')
|
|
78
|
+
const isFocus = ref(focus.value)
|
|
79
|
+
let timer: ReturnType<typeof setInterval>
|
|
80
|
+
const opacity = ref(1)
|
|
81
|
+
const borderWidth = computed(() => (hairline.value ? '0.5px' : '2px'))
|
|
82
|
+
const lineHeight = computed(() => (hairline.value ? '2px' : '4px'))
|
|
83
|
+
const boxSize = addUnit(size.value)
|
|
95
84
|
|
|
96
85
|
watch(
|
|
97
86
|
() => modelValue.value,
|
|
98
87
|
(newValue: string | number) => {
|
|
99
|
-
inputValue.value = String(newValue).substring(0, maxlength.value)
|
|
100
|
-
current.value = newValue.toString().length
|
|
88
|
+
inputValue.value = String(newValue).substring(0, maxlength.value)
|
|
89
|
+
current.value = newValue.toString().length
|
|
101
90
|
},
|
|
102
91
|
{ immediate: true },
|
|
103
|
-
)
|
|
92
|
+
)
|
|
104
93
|
|
|
105
94
|
watch(
|
|
106
95
|
() => isFocus.value,
|
|
@@ -108,102 +97,123 @@ watch(
|
|
|
108
97
|
// #ifdef APP-NVUE
|
|
109
98
|
if (newValue) {
|
|
110
99
|
timer = setInterval(() => {
|
|
111
|
-
opacity.value = Math.abs(opacity.value - 1)
|
|
112
|
-
}, 600)
|
|
100
|
+
opacity.value = Math.abs(opacity.value - 1)
|
|
101
|
+
}, 600)
|
|
113
102
|
} else {
|
|
114
|
-
clearInterval(timer)
|
|
103
|
+
clearInterval(timer)
|
|
115
104
|
}
|
|
116
105
|
// #endif
|
|
117
106
|
},
|
|
118
|
-
)
|
|
107
|
+
)
|
|
119
108
|
|
|
120
109
|
onUnmounted(() => {
|
|
121
110
|
// #ifdef APP-NVUE
|
|
122
|
-
clearInterval(timer)
|
|
111
|
+
clearInterval(timer)
|
|
123
112
|
// #endif
|
|
124
|
-
})
|
|
113
|
+
})
|
|
125
114
|
|
|
126
115
|
// 根据长度,循环输入框的个数,因为头条小程序数值不能用于v-for
|
|
127
116
|
const codeLength = computed(() => {
|
|
128
|
-
return new Array(Number(maxlength.value))
|
|
129
|
-
})
|
|
117
|
+
return new Array(Number(maxlength.value))
|
|
118
|
+
})
|
|
130
119
|
// 循环item的样式
|
|
131
120
|
const itemStyle = computed(() => {
|
|
132
121
|
return (index: number) => {
|
|
133
122
|
const style: CSSProperties = {
|
|
134
123
|
width: boxSize,
|
|
135
124
|
height: boxSize,
|
|
136
|
-
|
|
137
|
-
|
|
125
|
+
}
|
|
126
|
+
if (borderColor.value) {
|
|
127
|
+
style['--hy-border-color'] = borderColor.value
|
|
128
|
+
}
|
|
138
129
|
// 盒子模式下,需要额外进行处理
|
|
139
|
-
if (mode.value ===
|
|
130
|
+
if (mode.value === 'box' && border.value) {
|
|
140
131
|
// 设置盒子的边框,如果是细边框,则设置为1px宽度
|
|
141
|
-
style.borderWidth = borderWidth.value
|
|
142
|
-
style.borderStyle =
|
|
143
|
-
style.borderColor = borderColor.value
|
|
132
|
+
style.borderWidth = borderWidth.value
|
|
133
|
+
style.borderStyle = 'solid'
|
|
134
|
+
style.borderColor = borderColor.value
|
|
144
135
|
// 如果盒子间距为0的话
|
|
145
136
|
if (getPx(space.value) === 0) {
|
|
146
137
|
// 给第一和最后一个盒子设置圆角
|
|
147
138
|
if (index === 0) {
|
|
148
|
-
style.borderTopLeftRadius =
|
|
149
|
-
style.borderBottomLeftRadius =
|
|
139
|
+
style.borderTopLeftRadius = '6px'
|
|
140
|
+
style.borderBottomLeftRadius = '6px'
|
|
150
141
|
}
|
|
151
142
|
if (index === codeLength.value.length - 1) {
|
|
152
|
-
style.borderTopRightRadius =
|
|
153
|
-
style.borderBottomRightRadius =
|
|
143
|
+
style.borderTopRightRadius = '6px'
|
|
144
|
+
style.borderBottomRightRadius = '6px'
|
|
154
145
|
}
|
|
155
146
|
// 最后一个盒子的右边框需要保留
|
|
156
147
|
if (index !== codeLength.value.length - 1) {
|
|
157
|
-
style.borderRight =
|
|
148
|
+
style.borderRight = 'none'
|
|
158
149
|
}
|
|
159
150
|
}
|
|
160
151
|
}
|
|
161
152
|
if (index !== codeLength.value.length - 1) {
|
|
162
153
|
// 设置验证码字符之间的距离,通过margin-right设置,最后一个字符,无需右边框
|
|
163
|
-
style.marginRight = addUnit(space.value)
|
|
154
|
+
style.marginRight = addUnit(space.value)
|
|
164
155
|
} else {
|
|
165
156
|
// 最后一个盒子的有边框需要保留
|
|
166
|
-
style.marginRight = 0
|
|
157
|
+
style.marginRight = 0
|
|
167
158
|
}
|
|
168
159
|
|
|
169
|
-
return style
|
|
170
|
-
}
|
|
171
|
-
})
|
|
160
|
+
return style
|
|
161
|
+
}
|
|
162
|
+
})
|
|
163
|
+
|
|
164
|
+
const itemClass = computed(() => {
|
|
165
|
+
return (index: number) => {
|
|
166
|
+
return [
|
|
167
|
+
'hy-code-input--item',
|
|
168
|
+
border.value ? `hy-code-input--item__${mode.value}` : 'hy-code-input--item__not',
|
|
169
|
+
current.value > index &&
|
|
170
|
+
getPx(space.value) != 0 &&
|
|
171
|
+
border.value &&
|
|
172
|
+
`hy-code-input--item__${mode.value}__border`,
|
|
173
|
+
isFocus.value &&
|
|
174
|
+
current.value === index &&
|
|
175
|
+
getPx(space.value) != 0 &&
|
|
176
|
+
(border.value
|
|
177
|
+
? `hy-code-input--item__${mode.value}__active`
|
|
178
|
+
: 'hy-code-input--item__not__active'),
|
|
179
|
+
]
|
|
180
|
+
}
|
|
181
|
+
})
|
|
172
182
|
|
|
173
183
|
/**
|
|
174
184
|
* @description 将输入的值,转为数组,给item历遍时,根据当前的索引显示数组的元素
|
|
175
185
|
*/
|
|
176
186
|
const codeArray = computed(() => {
|
|
177
|
-
return String(inputValue.value).split(
|
|
178
|
-
})
|
|
187
|
+
return String(inputValue.value).split('')
|
|
188
|
+
})
|
|
179
189
|
|
|
180
190
|
/**
|
|
181
191
|
* @description 监听输入框的值发生变化
|
|
182
192
|
* */
|
|
183
193
|
const inputHandler = (e: any) => {
|
|
184
|
-
const value = e.detail.value
|
|
185
|
-
inputValue.value = value
|
|
194
|
+
const value = e.detail.value
|
|
195
|
+
inputValue.value = value
|
|
186
196
|
// 是否允许输入“.”符号
|
|
187
197
|
if (disabledDot.value) {
|
|
188
198
|
nextTick(() => {
|
|
189
|
-
inputValue.value = value.replace(
|
|
190
|
-
})
|
|
199
|
+
inputValue.value = value.replace('.', '')
|
|
200
|
+
})
|
|
191
201
|
}
|
|
192
202
|
// 未达到maxlength之前,发送change事件,达到后发送finish事件
|
|
193
|
-
emit(
|
|
203
|
+
emit('change', value)
|
|
194
204
|
// 修改通过v-model双向绑定的值
|
|
195
|
-
emit(
|
|
205
|
+
emit('update:modelValue', value)
|
|
196
206
|
// 达到用户指定输入长度时,发出完成事件
|
|
197
207
|
if (String(value).length >= Number(maxlength.value)) {
|
|
198
|
-
emit(
|
|
208
|
+
emit('finish', value)
|
|
199
209
|
}
|
|
200
|
-
}
|
|
210
|
+
}
|
|
201
211
|
</script>
|
|
202
212
|
|
|
203
213
|
<style scoped lang="scss">
|
|
204
|
-
@import
|
|
205
|
-
@import
|
|
206
|
-
@import
|
|
214
|
+
@import './index.scss';
|
|
215
|
+
@import '../../libs/css/mixin.scss';
|
|
216
|
+
@import '../../theme.scss';
|
|
207
217
|
@include b(code-input) {
|
|
208
218
|
@include m(item) {
|
|
209
219
|
&__box {
|