uview-pro 0.0.1
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/changelog.md +6 -0
- package/components/u-action-sheet/u-action-sheet.vue +205 -0
- package/components/u-alert-tips/u-alert-tips.vue +241 -0
- package/components/u-avatar/u-avatar.vue +220 -0
- package/components/u-avatar-cropper/u-avatar-cropper.vue +329 -0
- package/components/u-avatar-cropper/weCropper.d.ts +54 -0
- package/components/u-avatar-cropper/weCropper.js +1267 -0
- package/components/u-avatar-cropper/weCropper.ts +1254 -0
- package/components/u-back-top/u-back-top.vue +156 -0
- package/components/u-badge/u-badge.vue +189 -0
- package/components/u-button/u-button.vue +562 -0
- package/components/u-calendar/u-calendar.vue +725 -0
- package/components/u-car-keyboard/u-car-keyboard.vue +236 -0
- package/components/u-card/u-card.vue +240 -0
- package/components/u-cell-group/u-cell-group.vue +56 -0
- package/components/u-cell-item/u-cell-item.vue +245 -0
- package/components/u-checkbox/u-checkbox.vue +310 -0
- package/components/u-checkbox-group/u-checkbox-group.vue +134 -0
- package/components/u-circle-progress/u-circle-progress.vue +210 -0
- package/components/u-col/u-col.vue +135 -0
- package/components/u-collapse/u-collapse.vue +82 -0
- package/components/u-collapse-item/u-collapse-item.vue +190 -0
- package/components/u-column-notice/u-column-notice.vue +264 -0
- package/components/u-count-down/u-count-down.vue +333 -0
- package/components/u-count-to/u-count-to.vue +297 -0
- package/components/u-divider/u-divider.vue +141 -0
- package/components/u-dropdown/u-dropdown.vue +311 -0
- package/components/u-dropdown-item/u-dropdown-item.vue +135 -0
- package/components/u-empty/u-empty.vue +111 -0
- package/components/u-field/u-field.vue +469 -0
- package/components/u-form/u-form.vue +162 -0
- package/components/u-form-item/u-form-item.vue +476 -0
- package/components/u-full-screen/u-full-screen.vue +80 -0
- package/components/u-gap/u-gap.vue +48 -0
- package/components/u-grid/u-grid.vue +101 -0
- package/components/u-grid-item/u-grid-item.vue +136 -0
- package/components/u-icon/u-icon.vue +389 -0
- package/components/u-image/types.ts +48 -0
- package/components/u-image/u-image.vue +218 -0
- package/components/u-index-anchor/u-index-anchor.vue +101 -0
- package/components/u-index-list/u-index-list.vue +376 -0
- package/components/u-input/u-input.vue +462 -0
- package/components/u-keyboard/u-keyboard.vue +188 -0
- package/components/u-lazy-load/u-lazy-load.vue +288 -0
- package/components/u-line/u-line.vue +71 -0
- package/components/u-line-progress/u-line-progress.vue +128 -0
- package/components/u-link/u-link.vue +87 -0
- package/components/u-loading/u-loading.vue +111 -0
- package/components/u-loadmore/u-loadmore.vue +205 -0
- package/components/u-mask/u-mask.vue +137 -0
- package/components/u-message-input/u-message-input.vue +315 -0
- package/components/u-modal/u-modal.vue +284 -0
- package/components/u-navbar/u-navbar.vue +314 -0
- package/components/u-no-network/image.ts +2 -0
- package/components/u-no-network/u-no-network.vue +311 -0
- package/components/u-notice-bar/u-notice-bar.vue +274 -0
- package/components/u-number-box/u-number-box.vue +344 -0
- package/components/u-number-keyboard/u-number-keyboard.vue +170 -0
- package/components/u-parse/libs/CssHandler.js +100 -0
- package/components/u-parse/libs/MpHtmlParser.js +580 -0
- package/components/u-parse/libs/config.js +80 -0
- package/components/u-parse/libs/handler.wxs +22 -0
- package/components/u-parse/libs/trees.vue +505 -0
- package/components/u-parse/u-parse.vue +645 -0
- package/components/u-picker/u-picker.vue +808 -0
- package/components/u-popup/u-popup.vue +404 -0
- package/components/u-radio/u-radio.vue +272 -0
- package/components/u-radio-group/u-radio-group.vue +116 -0
- package/components/u-rate/u-rate.vue +349 -0
- package/components/u-read-more/u-read-more.vue +199 -0
- package/components/u-row/u-row.vue +95 -0
- package/components/u-row-notice/u-row-notice.vue +273 -0
- package/components/u-search/u-search.vue +298 -0
- package/components/u-section/u-section.vue +175 -0
- package/components/u-select/u-select.vue +387 -0
- package/components/u-skeleton/u-skeleton.vue +230 -0
- package/components/u-slider/u-slider.vue +293 -0
- package/components/u-steps/u-steps.vue +200 -0
- package/components/u-sticky/u-sticky.vue +189 -0
- package/components/u-subsection/u-subsection.vue +388 -0
- package/components/u-swipe-action/u-swipe-action.vue +289 -0
- package/components/u-swiper/u-swiper.vue +305 -0
- package/components/u-switch/u-switch.vue +146 -0
- package/components/u-tabbar/u-tabbar.vue +347 -0
- package/components/u-table/u-table.vue +104 -0
- package/components/u-tabs/u-tabs.vue +322 -0
- package/components/u-tabs-swiper/u-tabs-swiper.vue +426 -0
- package/components/u-tag/u-tag.vue +270 -0
- package/components/u-td/u-td.vue +76 -0
- package/components/u-th/u-th.vue +70 -0
- package/components/u-time-line/u-time-line.vue +39 -0
- package/components/u-time-line-item/u-time-line-item.vue +88 -0
- package/components/u-toast/types.ts +4 -0
- package/components/u-toast/u-toast.vue +238 -0
- package/components/u-top-tips/u-top-tips.vue +118 -0
- package/components/u-tr/u-tr.vue +24 -0
- package/components/u-upload/u-upload.vue +600 -0
- package/components/u-verification-code/u-verification-code.vue +194 -0
- package/components/u-waterfall/u-waterfall.vue +186 -0
- package/iconfont.css +910 -0
- package/index.scss +23 -0
- package/index.ts +166 -0
- package/libs/config/config.ts +26 -0
- package/libs/config/zIndex.ts +37 -0
- package/libs/css/color.scss +155 -0
- package/libs/css/common.scss +176 -0
- package/libs/css/style.components.scss +7 -0
- package/libs/css/style.h5.scss +8 -0
- package/libs/css/style.mp.scss +72 -0
- package/libs/css/style.nvue.scss +3 -0
- package/libs/css/style.vue.scss +175 -0
- package/libs/function/$parent.ts +22 -0
- package/libs/function/addUnit.ts +13 -0
- package/libs/function/color.ts +37 -0
- package/libs/function/colorGradient.ts +123 -0
- package/libs/function/debounce.ts +28 -0
- package/libs/function/deepClone.ts +39 -0
- package/libs/function/deepMerge.ts +34 -0
- package/libs/function/getParent.ts +59 -0
- package/libs/function/getRect.ts +26 -0
- package/libs/function/guid.ts +42 -0
- package/libs/function/md5.ts +397 -0
- package/libs/function/parent.ts +21 -0
- package/libs/function/queryParams.ts +60 -0
- package/libs/function/random.ts +16 -0
- package/libs/function/randomArray.ts +11 -0
- package/libs/function/route.ts +118 -0
- package/libs/function/sys.ts +15 -0
- package/libs/function/test.ts +229 -0
- package/libs/function/throttle.ts +31 -0
- package/libs/function/timeFormat.ts +54 -0
- package/libs/function/timeFrom.ts +48 -0
- package/libs/function/toast.ts +14 -0
- package/libs/function/trim.ts +21 -0
- package/libs/function/type2icon.ts +36 -0
- package/libs/hooks/useEmitter.ts +77 -0
- package/libs/hooks/useParent.ts +29 -0
- package/libs/request/index.ts +237 -0
- package/libs/store/index.ts +88 -0
- package/libs/util/area.ts +1 -0
- package/libs/util/async-validator.js +1356 -0
- package/libs/util/city.ts +1 -0
- package/libs/util/emitter.ts +112 -0
- package/libs/util/mitt.ts +118 -0
- package/libs/util/parent.ts +20 -0
- package/libs/util/province.ts +1 -0
- package/package.json +98 -0
- package/readme.md +165 -0
- package/theme.scss +38 -0
|
@@ -0,0 +1,462 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<view
|
|
3
|
+
class="u-input"
|
|
4
|
+
:class="{
|
|
5
|
+
'u-input--border': border,
|
|
6
|
+
'u-input--error': validateState
|
|
7
|
+
}"
|
|
8
|
+
:style="{
|
|
9
|
+
padding: `0 ${border ? 20 : 0}rpx`,
|
|
10
|
+
borderColor: borderColor,
|
|
11
|
+
textAlign: inputAlign
|
|
12
|
+
}"
|
|
13
|
+
@tap.stop="inputClick"
|
|
14
|
+
>
|
|
15
|
+
<textarea
|
|
16
|
+
v-if="type == 'textarea'"
|
|
17
|
+
class="u-input__input u-input__textarea"
|
|
18
|
+
:style="getStyle"
|
|
19
|
+
:value="defaultValue"
|
|
20
|
+
:placeholder="placeholder"
|
|
21
|
+
:placeholderStyle="placeholderStyle"
|
|
22
|
+
:disabled="disabled"
|
|
23
|
+
:maxlength="inputMaxlength"
|
|
24
|
+
:fixed="fixed"
|
|
25
|
+
:focus="focus"
|
|
26
|
+
:autoHeight="autoHeight"
|
|
27
|
+
:selection-end="uSelectionEnd"
|
|
28
|
+
:selection-start="uSelectionStart"
|
|
29
|
+
:cursor-spacing="getCursorSpacing"
|
|
30
|
+
:show-confirm-bar="showConfirmbar"
|
|
31
|
+
:adjust-position="adjustPosition"
|
|
32
|
+
@input="handleInput"
|
|
33
|
+
@blur="handleBlur"
|
|
34
|
+
@focus="onFocus"
|
|
35
|
+
@confirm="onConfirm"
|
|
36
|
+
/>
|
|
37
|
+
<input
|
|
38
|
+
v-else
|
|
39
|
+
class="u-input__input"
|
|
40
|
+
:type="type == 'password' ? 'text' : type"
|
|
41
|
+
:style="getStyle"
|
|
42
|
+
:value="defaultValue"
|
|
43
|
+
:password="type == 'password' && !showPassword"
|
|
44
|
+
:placeholder="placeholder"
|
|
45
|
+
:placeholderStyle="placeholderStyle"
|
|
46
|
+
:disabled="disabled || type === 'select'"
|
|
47
|
+
:maxlength="inputMaxlength"
|
|
48
|
+
:focus="focus"
|
|
49
|
+
:confirmType="confirmType"
|
|
50
|
+
:cursor-spacing="getCursorSpacing"
|
|
51
|
+
:selection-end="uSelectionEnd"
|
|
52
|
+
:selection-start="uSelectionStart"
|
|
53
|
+
:show-confirm-bar="showConfirmbar"
|
|
54
|
+
:adjust-position="adjustPosition"
|
|
55
|
+
@focus="onFocus"
|
|
56
|
+
@blur="handleBlur"
|
|
57
|
+
@input="handleInput"
|
|
58
|
+
@confirm="onConfirm"
|
|
59
|
+
/>
|
|
60
|
+
<view class="u-input__right-icon u-flex">
|
|
61
|
+
<view class="u-input__right-icon__clear u-input__right-icon__item" @tap="onClear" v-if="clearable && modelValue != '' && focused">
|
|
62
|
+
<u-icon size="32" name="close-circle-fill" color="#c0c4cc" />
|
|
63
|
+
</view>
|
|
64
|
+
<view class="u-input__right-icon__clear u-input__right-icon__item" v-if="passwordIcon && type == 'password'">
|
|
65
|
+
<u-icon size="32" :name="!showPassword ? 'eye' : 'eye-fill'" color="#c0c4cc" @click="showPassword = !showPassword" />
|
|
66
|
+
</view>
|
|
67
|
+
<view
|
|
68
|
+
class="u-input__right-icon--select u-input__right-icon__item"
|
|
69
|
+
v-if="type == 'select'"
|
|
70
|
+
:class="{
|
|
71
|
+
'u-input__right-icon--select--reverse': selectOpen
|
|
72
|
+
}"
|
|
73
|
+
>
|
|
74
|
+
<u-icon name="arrow-down-fill" size="26" color="#c0c4cc"></u-icon>
|
|
75
|
+
</view>
|
|
76
|
+
</view>
|
|
77
|
+
</view>
|
|
78
|
+
</template>
|
|
79
|
+
|
|
80
|
+
<script setup lang="ts">
|
|
81
|
+
import { ref, computed, watch, getCurrentInstance } from 'vue';
|
|
82
|
+
import { $u } from '../..';
|
|
83
|
+
import { dispatch } from '../../libs/util/emitter';
|
|
84
|
+
|
|
85
|
+
defineOptions({
|
|
86
|
+
name: 'u-input'
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* input 输入框
|
|
91
|
+
* @description 此组件为一个输入框,默认没有边框和样式,是专门为配合表单组件u-form而设计的,利用它可以快速实现表单验证,输入内容,下拉选择等功能。
|
|
92
|
+
* @tutorial http://uviewui.com/components/input.html
|
|
93
|
+
* @property {String} type 模式选择,见官网说明
|
|
94
|
+
* @property {Boolean} clearable 是否显示右侧的清除图标(默认true)
|
|
95
|
+
* @property {} v-model 用于双向绑定输入框的值
|
|
96
|
+
* @property {String} input-align 输入框文字的对齐方式(默认left)
|
|
97
|
+
* @property {String} placeholder placeholder显示值(默认 '请输入内容')
|
|
98
|
+
* @property {Boolean} disabled 是否禁用输入框(默认false)
|
|
99
|
+
* @property {String Number} maxlength 输入框的最大可输入长度(默认140)
|
|
100
|
+
* @property {String Number} selection-start 光标起始位置,自动聚焦时有效,需与selection-end搭配使用(默认-1)
|
|
101
|
+
* @property {String Number} maxlength 光标结束位置,自动聚焦时有效,需与selection-start搭配使用(默认-1)
|
|
102
|
+
* @property {String Number} cursor-spacing 指定光标与键盘的距离,单位px(默认0)
|
|
103
|
+
* @property {String} placeholderStyle placeholder的样式,字符串形式,如"color: red;"(默认 "color: #c0c4cc;")
|
|
104
|
+
* @property {String} confirm-type 设置键盘右下角按钮的文字,仅在type为text时生效(默认done)
|
|
105
|
+
* @property {Object} custom-style 自定义输入框的样式,对象形式
|
|
106
|
+
* @property {Boolean} focus 是否自动获得焦点(默认false)
|
|
107
|
+
* @property {Boolean} fixed 如果type为textarea,且在一个"position:fixed"的区域,需要指明为true(默认false)
|
|
108
|
+
* @property {Boolean} password-icon type为password时,是否显示右侧的密码查看图标(默认true)
|
|
109
|
+
* @property {Boolean} border 是否显示边框(默认false)
|
|
110
|
+
* @property {String} border-color 输入框的边框颜色(默认#dcdfe6)
|
|
111
|
+
* @property {Boolean} auto-height 是否自动增高输入区域,type为textarea时有效(默认true)
|
|
112
|
+
* @property {String Number} height 高度,单位rpx(text类型时为70,textarea时为100)
|
|
113
|
+
* @example <u-input v-model="value" :type="type" :border="border" />
|
|
114
|
+
*/
|
|
115
|
+
|
|
116
|
+
const props = defineProps({
|
|
117
|
+
/**
|
|
118
|
+
* 用于双向绑定输入框的值
|
|
119
|
+
*/
|
|
120
|
+
modelValue: {
|
|
121
|
+
type: [String, Number],
|
|
122
|
+
default: ''
|
|
123
|
+
},
|
|
124
|
+
/**
|
|
125
|
+
* 输入框的类型,textarea,text,number
|
|
126
|
+
*/
|
|
127
|
+
type: {
|
|
128
|
+
type: String,
|
|
129
|
+
default: 'text'
|
|
130
|
+
},
|
|
131
|
+
/**
|
|
132
|
+
* 输入框文字的对齐方式(默认left)
|
|
133
|
+
*/
|
|
134
|
+
inputAlign: {
|
|
135
|
+
type: String,
|
|
136
|
+
default: 'left'
|
|
137
|
+
},
|
|
138
|
+
/**
|
|
139
|
+
* placeholder显示值(默认 '请输入内容')
|
|
140
|
+
*/
|
|
141
|
+
placeholder: {
|
|
142
|
+
type: String,
|
|
143
|
+
default: '请输入内容'
|
|
144
|
+
},
|
|
145
|
+
/**
|
|
146
|
+
* 是否禁用输入框(默认false)
|
|
147
|
+
*/
|
|
148
|
+
disabled: {
|
|
149
|
+
type: Boolean,
|
|
150
|
+
default: false
|
|
151
|
+
},
|
|
152
|
+
/**
|
|
153
|
+
* 输入框的最大可输入长度(默认140)
|
|
154
|
+
*/
|
|
155
|
+
maxlength: {
|
|
156
|
+
type: [Number, String],
|
|
157
|
+
default: 140
|
|
158
|
+
},
|
|
159
|
+
/**
|
|
160
|
+
* placeholder的样式,字符串形式,如"color: red;"(默认 "color: #c0c4cc;")
|
|
161
|
+
*/
|
|
162
|
+
placeholderStyle: {
|
|
163
|
+
type: String,
|
|
164
|
+
default: 'color: #c0c4cc;'
|
|
165
|
+
},
|
|
166
|
+
/**
|
|
167
|
+
* 设置键盘右下角按钮的文字,仅在type为text时生效(默认done)
|
|
168
|
+
*/
|
|
169
|
+
confirmType: {
|
|
170
|
+
type: String,
|
|
171
|
+
default: 'done'
|
|
172
|
+
},
|
|
173
|
+
/**
|
|
174
|
+
* 自定义输入框的样式,对象形式
|
|
175
|
+
*/
|
|
176
|
+
customStyle: {
|
|
177
|
+
type: Object,
|
|
178
|
+
default: () => ({})
|
|
179
|
+
},
|
|
180
|
+
/**
|
|
181
|
+
* 如果 textarea 是在一个 position:fixed 的区域,需要显示指定属性 fixed 为 true
|
|
182
|
+
*/
|
|
183
|
+
fixed: {
|
|
184
|
+
type: Boolean,
|
|
185
|
+
default: false
|
|
186
|
+
},
|
|
187
|
+
/**
|
|
188
|
+
* 是否自动获得焦点(默认false)
|
|
189
|
+
*/
|
|
190
|
+
focus: {
|
|
191
|
+
type: Boolean,
|
|
192
|
+
default: false
|
|
193
|
+
},
|
|
194
|
+
/**
|
|
195
|
+
* 密码类型时,是否显示右侧的密码图标(默认true)
|
|
196
|
+
*/
|
|
197
|
+
passwordIcon: {
|
|
198
|
+
type: Boolean,
|
|
199
|
+
default: true
|
|
200
|
+
},
|
|
201
|
+
/**
|
|
202
|
+
* input|textarea是否显示边框(默认false)
|
|
203
|
+
*/
|
|
204
|
+
border: {
|
|
205
|
+
type: Boolean,
|
|
206
|
+
default: false
|
|
207
|
+
},
|
|
208
|
+
/**
|
|
209
|
+
* 输入框的边框颜色(默认#dcdfe6)
|
|
210
|
+
*/
|
|
211
|
+
borderColor: {
|
|
212
|
+
type: String,
|
|
213
|
+
default: '#dcdfe6'
|
|
214
|
+
},
|
|
215
|
+
/**
|
|
216
|
+
* 是否自动增高输入区域,type为textarea时有效(默认true)
|
|
217
|
+
*/
|
|
218
|
+
autoHeight: {
|
|
219
|
+
type: Boolean,
|
|
220
|
+
default: true
|
|
221
|
+
},
|
|
222
|
+
/**
|
|
223
|
+
* type=select时,旋转右侧的图标,标识当前处于打开还是关闭select的状态
|
|
224
|
+
* open-打开,close-关闭
|
|
225
|
+
*/
|
|
226
|
+
selectOpen: {
|
|
227
|
+
type: Boolean,
|
|
228
|
+
default: false
|
|
229
|
+
},
|
|
230
|
+
/**
|
|
231
|
+
* 高度,单位rpx
|
|
232
|
+
*/
|
|
233
|
+
height: {
|
|
234
|
+
type: [Number, String],
|
|
235
|
+
default: ''
|
|
236
|
+
},
|
|
237
|
+
/**
|
|
238
|
+
* 是否可清空(默认true)
|
|
239
|
+
*/
|
|
240
|
+
clearable: {
|
|
241
|
+
type: Boolean,
|
|
242
|
+
default: true
|
|
243
|
+
},
|
|
244
|
+
/**
|
|
245
|
+
* 指定光标与键盘的距离,单位 px(默认0)
|
|
246
|
+
*/
|
|
247
|
+
cursorSpacing: {
|
|
248
|
+
type: [Number, String],
|
|
249
|
+
default: 0
|
|
250
|
+
},
|
|
251
|
+
/**
|
|
252
|
+
* 光标起始位置,自动聚焦时有效,需与selection-end搭配使用(默认-1)
|
|
253
|
+
*/
|
|
254
|
+
selectionStart: {
|
|
255
|
+
type: [Number, String],
|
|
256
|
+
default: -1
|
|
257
|
+
},
|
|
258
|
+
/**
|
|
259
|
+
* 光标结束位置,自动聚焦时有效,需与selection-start搭配使用(默认-1)
|
|
260
|
+
*/
|
|
261
|
+
selectionEnd: {
|
|
262
|
+
type: [Number, String],
|
|
263
|
+
default: -1
|
|
264
|
+
},
|
|
265
|
+
/**
|
|
266
|
+
* 是否自动去除两端的空格(默认true)
|
|
267
|
+
*/
|
|
268
|
+
trim: {
|
|
269
|
+
type: Boolean,
|
|
270
|
+
default: true
|
|
271
|
+
},
|
|
272
|
+
/**
|
|
273
|
+
* 是否显示键盘上方带有”完成“按钮那一栏(默认true)
|
|
274
|
+
*/
|
|
275
|
+
showConfirmbar: {
|
|
276
|
+
type: Boolean,
|
|
277
|
+
default: true
|
|
278
|
+
},
|
|
279
|
+
/**
|
|
280
|
+
* 弹出键盘时是否自动调节高度,uni-app默认值是true
|
|
281
|
+
*/
|
|
282
|
+
adjustPosition: {
|
|
283
|
+
type: Boolean,
|
|
284
|
+
default: true
|
|
285
|
+
},
|
|
286
|
+
/**
|
|
287
|
+
* 输入框的验证状态,用于错误时,边框是否改为红色
|
|
288
|
+
*/
|
|
289
|
+
validateState: {
|
|
290
|
+
type: Boolean,
|
|
291
|
+
default: false
|
|
292
|
+
}
|
|
293
|
+
});
|
|
294
|
+
|
|
295
|
+
const emit = defineEmits(['update:modelValue', 'blur', 'focus', 'confirm', 'click']);
|
|
296
|
+
|
|
297
|
+
const defaultValue = ref(props.modelValue);
|
|
298
|
+
const inputHeight = 70; // input的高度
|
|
299
|
+
const textareaHeight = 100; // textarea的高度
|
|
300
|
+
const validateState = ref(props.validateState); // 当前input的验证状态,用于错误时,边框是否改为红色
|
|
301
|
+
const focused = ref(false); // 当前是否处于获得焦点的状态
|
|
302
|
+
const showPassword = ref(false); // 是否预览密码
|
|
303
|
+
const lastValue = ref(''); // 用于头条小程序,判断@input中,前后的值是否发生了变化
|
|
304
|
+
|
|
305
|
+
// 监听 value 变化
|
|
306
|
+
watch(
|
|
307
|
+
() => props.modelValue,
|
|
308
|
+
(nVal, oVal) => {
|
|
309
|
+
defaultValue.value = nVal;
|
|
310
|
+
// 当值发生变化,且为select类型时(此时input被设置为disabled,不会触发@input事件),模拟触发@input事件
|
|
311
|
+
if (nVal != oVal && props.type == 'select') handleInput({ detail: { value: nVal } });
|
|
312
|
+
}
|
|
313
|
+
);
|
|
314
|
+
|
|
315
|
+
// 监听 validateState 变化
|
|
316
|
+
watch(
|
|
317
|
+
() => props.validateState,
|
|
318
|
+
val => {
|
|
319
|
+
validateState.value = val;
|
|
320
|
+
}
|
|
321
|
+
);
|
|
322
|
+
|
|
323
|
+
// 计算属性
|
|
324
|
+
const inputMaxlength = computed(() => Number(props.maxlength));
|
|
325
|
+
|
|
326
|
+
const getStyle = computed(() => {
|
|
327
|
+
let style: Record<string, any> = {};
|
|
328
|
+
// 如果没有自定义高度,就根据type为input还是textarea来分配一个默认的高度
|
|
329
|
+
style.minHeight = props.height ? props.height + 'rpx' : props.type == 'textarea' ? `${textareaHeight}rpx` : `${inputHeight}rpx`;
|
|
330
|
+
style = Object.assign(style, props.customStyle);
|
|
331
|
+
return style;
|
|
332
|
+
});
|
|
333
|
+
const getCursorSpacing = computed(() => Number(props.cursorSpacing));
|
|
334
|
+
// 光标起始位置
|
|
335
|
+
const uSelectionStart = computed(() => String(props.selectionStart));
|
|
336
|
+
// 光标结束位置
|
|
337
|
+
const uSelectionEnd = computed(() => String(props.selectionEnd));
|
|
338
|
+
|
|
339
|
+
// 事件派发工具
|
|
340
|
+
const instance = getCurrentInstance();
|
|
341
|
+
|
|
342
|
+
// 监听u-form-item发出的错误事件,将输入框边框变红色,失效了
|
|
343
|
+
// uni.$on('on-form-item-error', onFormItemError);
|
|
344
|
+
/**
|
|
345
|
+
* change 事件
|
|
346
|
+
* @param event
|
|
347
|
+
*/
|
|
348
|
+
function handleInput(event: any) {
|
|
349
|
+
let value = event.detail.value;
|
|
350
|
+
// 判断是否去除空格
|
|
351
|
+
if (props.trim) value = $u.trim(value);
|
|
352
|
+
// vue 原生的方法 return 出去
|
|
353
|
+
emit('update:modelValue', value);
|
|
354
|
+
// 当前model 赋值
|
|
355
|
+
defaultValue.value = value;
|
|
356
|
+
// 过一个生命周期再发送事件给u-form-item,否则this.$emit('update:modelValue')更新了父组件的值,但是微信小程序上
|
|
357
|
+
// 尚未更新到u-form-item,导致获取的值为空,从而校验混论
|
|
358
|
+
// 这里不能延时时间太短,或者使用this.$nextTick,否则在头条上,会造成混乱
|
|
359
|
+
setTimeout(() => {
|
|
360
|
+
// 头条小程序由于自身bug,导致中文下,每按下一个键(尚未完成输入),都会触发一次@input,导致错误,这里进行判断处理
|
|
361
|
+
// #ifdef MP-TOUTIAO
|
|
362
|
+
if ($u.trim(value) == lastValue.value) return;
|
|
363
|
+
lastValue.value = value;
|
|
364
|
+
// #endif
|
|
365
|
+
// 通过 emitter 派发事件
|
|
366
|
+
dispatch(instance, 'u-form-item', 'on-form-change', value);
|
|
367
|
+
}, 40);
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
/**
|
|
371
|
+
* blur 事件
|
|
372
|
+
* @param event
|
|
373
|
+
*/
|
|
374
|
+
function handleBlur(event: any) {
|
|
375
|
+
// 最开始使用的是监听图标@touchstart事件,自从hx2.8.4后,此方法在微信小程序出错
|
|
376
|
+
// 这里改为监听点击事件,手点击清除图标时,同时也发生了@blur事件,导致图标消失而无法点击,这里做一个延时
|
|
377
|
+
let value = event.detail.value;
|
|
378
|
+
setTimeout(() => {
|
|
379
|
+
focused.value = false;
|
|
380
|
+
}, 100);
|
|
381
|
+
// vue 原生的方法 return 出去
|
|
382
|
+
emit('blur', value);
|
|
383
|
+
setTimeout(() => {
|
|
384
|
+
// 头条小程序由于自身bug,导致中文下,每按下一个键(尚未完成输入),都会触发一次@input,导致错误,这里进行判断处理
|
|
385
|
+
// #ifdef MP-TOUTIAO
|
|
386
|
+
if ($u.trim(value) == lastValue.value) return;
|
|
387
|
+
lastValue.value = value;
|
|
388
|
+
// #endif
|
|
389
|
+
dispatch(instance, 'u-form-item', 'on-form-blur', value);
|
|
390
|
+
}, 40);
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
function onFormItemError(status: boolean) {
|
|
394
|
+
console.log('onFormItemError', status);
|
|
395
|
+
validateState.value = status;
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
function onFocus(event: any) {
|
|
399
|
+
focused.value = true;
|
|
400
|
+
emit('focus');
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
function onConfirm(e: any) {
|
|
404
|
+
emit('confirm', e.detail.value);
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
function onClear(event: any) {
|
|
408
|
+
emit('update:modelValue', '');
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
function inputClick() {
|
|
412
|
+
emit('click');
|
|
413
|
+
}
|
|
414
|
+
</script>
|
|
415
|
+
|
|
416
|
+
<style lang="scss" scoped>
|
|
417
|
+
@import '../../libs/css/style.components.scss';
|
|
418
|
+
|
|
419
|
+
.u-input {
|
|
420
|
+
position: relative;
|
|
421
|
+
flex: 1;
|
|
422
|
+
@include vue-flex;
|
|
423
|
+
|
|
424
|
+
&__input {
|
|
425
|
+
//height: $u-form-item-height;
|
|
426
|
+
font-size: 28rpx;
|
|
427
|
+
color: $u-main-color;
|
|
428
|
+
flex: 1;
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
&__textarea {
|
|
432
|
+
width: auto;
|
|
433
|
+
font-size: 28rpx;
|
|
434
|
+
color: $u-main-color;
|
|
435
|
+
padding: 10rpx 0;
|
|
436
|
+
line-height: normal;
|
|
437
|
+
flex: 1;
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
&--border {
|
|
441
|
+
border-radius: 6rpx;
|
|
442
|
+
border-radius: 4px;
|
|
443
|
+
border: 1px solid $u-form-item-border-color;
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
&--error {
|
|
447
|
+
border-color: $u-type-error !important;
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
&__right-icon {
|
|
451
|
+
&__item {
|
|
452
|
+
margin-left: 10rpx;
|
|
453
|
+
}
|
|
454
|
+
&--select {
|
|
455
|
+
transition: transform 0.4s;
|
|
456
|
+
&--reverse {
|
|
457
|
+
transform: rotate(-180deg);
|
|
458
|
+
}
|
|
459
|
+
}
|
|
460
|
+
}
|
|
461
|
+
}
|
|
462
|
+
</style>
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<u-popup
|
|
3
|
+
:mask="mask"
|
|
4
|
+
:maskCloseAble="maskCloseAble"
|
|
5
|
+
mode="bottom"
|
|
6
|
+
:popup="false"
|
|
7
|
+
v-model="popupValue"
|
|
8
|
+
length="auto"
|
|
9
|
+
:safeAreaInsetBottom="safeAreaInsetBottom"
|
|
10
|
+
@close="popupClose"
|
|
11
|
+
:zIndex="uZIndex"
|
|
12
|
+
>
|
|
13
|
+
<slot />
|
|
14
|
+
<view class="u-tooltip" v-if="tooltip">
|
|
15
|
+
<view class="u-tooltip-item u-tooltip-cancel" hover-class="u-tooltip-cancel-hover" @tap="onCancel">
|
|
16
|
+
{{ cancelBtn ? cancelText : '' }}
|
|
17
|
+
</view>
|
|
18
|
+
<view v-if="showTips" class="u-tooltip-item u-tooltip-tips">
|
|
19
|
+
{{ tips ? tips : mode == 'number' ? '数字键盘' : mode == 'card' ? '身份证键盘' : '车牌号键盘' }}
|
|
20
|
+
</view>
|
|
21
|
+
<view v-if="confirmBtn" @tap="onConfirm" class="u-tooltip-item u-tooltips-submit" hover-class="u-tooltips-submit-hover">
|
|
22
|
+
{{ confirmBtn ? confirmText : '' }}
|
|
23
|
+
</view>
|
|
24
|
+
</view>
|
|
25
|
+
<block v-if="mode == 'number' || mode == 'card'">
|
|
26
|
+
<u-number-keyboard :random="random" @backspace="backspace" @change="change" :mode="mode" :dotEnabled="dotEnabled"></u-number-keyboard>
|
|
27
|
+
</block>
|
|
28
|
+
<block v-else>
|
|
29
|
+
<u-car-keyboard :random="random" @backspace="backspace" @change="change"></u-car-keyboard>
|
|
30
|
+
</block>
|
|
31
|
+
</u-popup>
|
|
32
|
+
</template>
|
|
33
|
+
|
|
34
|
+
<script setup lang="ts">
|
|
35
|
+
import { computed } from 'vue';
|
|
36
|
+
|
|
37
|
+
defineOptions({
|
|
38
|
+
name: 'u-keyboard'
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* keyboard 键盘
|
|
43
|
+
* @description 此为uViw自定义的键盘面板,内含了数字键盘,车牌号键,身份证号键盘3中模式,都有可以打乱按键顺序的选项。
|
|
44
|
+
* @tutorial https://www.uviewui.com/components/keyboard.html
|
|
45
|
+
* @property {String} mode 键盘类型,见官网基本使用的说明(默认number)
|
|
46
|
+
* @property {Boolean} dot-enabled 是否显示"."按键,只在mode=number时有效(默认true)
|
|
47
|
+
* @property {Boolean} tooltip 是否显示键盘顶部工具条(默认true)
|
|
48
|
+
* @property {String} tips 工具条中间的提示文字,见上方基本使用的说明,如不需要,请传""空字符
|
|
49
|
+
* @property {Boolean} cancel-btn 是否显示工具条左边的"取消"按钮(默认true)
|
|
50
|
+
* @property {Boolean} confirm-btn 是否显示工具条右边的"完成"按钮(默认true)
|
|
51
|
+
* @property {Boolean} mask 是否显示遮罩(默认true)
|
|
52
|
+
* @property {String} confirm-text 确认按钮的文字
|
|
53
|
+
* @property {String} cancel-text 取消按钮的文字
|
|
54
|
+
* @property {Number String} z-index 弹出键盘的z-index值(默认1075)
|
|
55
|
+
* @property {Boolean} random 是否打乱键盘按键的顺序(默认false)
|
|
56
|
+
* @property {Boolean} safe-area-inset-bottom 是否开启底部安全区适配(默认false)
|
|
57
|
+
* @property {Boolean} mask-close-able 是否允许点击遮罩收起键盘(默认true)
|
|
58
|
+
* @event {Function} change 按键被点击(不包含退格键被点击)
|
|
59
|
+
* @event {Function} cancel 键盘顶部工具条左边的"取消"按钮被点击
|
|
60
|
+
* @event {Function} confirm 键盘顶部工具条右边的"完成"按钮被点击
|
|
61
|
+
* @event {Function} backspace 键盘退格键被点击
|
|
62
|
+
* @example <u-keyboard mode="number" v-model="show"></u-keyboard>
|
|
63
|
+
*/
|
|
64
|
+
|
|
65
|
+
const props = defineProps({
|
|
66
|
+
/** 键盘的类型,number-数字键盘,card-身份证键盘,car-车牌号键盘 */
|
|
67
|
+
mode: { type: String, default: 'number' },
|
|
68
|
+
/** 是否显示键盘的"."符号 */
|
|
69
|
+
dotEnabled: { type: Boolean, default: true },
|
|
70
|
+
/** 是否显示顶部工具条 */
|
|
71
|
+
tooltip: { type: Boolean, default: true },
|
|
72
|
+
/** 是否显示工具条中间的提示 */
|
|
73
|
+
showTips: { type: Boolean, default: true },
|
|
74
|
+
/** 工具条中间的提示文字 */
|
|
75
|
+
tips: { type: String, default: '' },
|
|
76
|
+
/** 是否显示工具条左边的"取消"按钮 */
|
|
77
|
+
cancelBtn: { type: Boolean, default: true },
|
|
78
|
+
/** 是否显示工具条右边的"完成"按钮 */
|
|
79
|
+
confirmBtn: { type: Boolean, default: true },
|
|
80
|
+
/** 是否打乱键盘按键的顺序 */
|
|
81
|
+
random: { type: Boolean, default: false },
|
|
82
|
+
/** 是否开启底部安全区适配,开启的话,会在iPhoneX机型底部添加一定的内边距 */
|
|
83
|
+
safeAreaInsetBottom: { type: Boolean, default: false },
|
|
84
|
+
/** 是否允许通过点击遮罩关闭键盘 */
|
|
85
|
+
maskCloseAble: { type: Boolean, default: true },
|
|
86
|
+
/** 通过双向绑定控制键盘的弹出与收起 */
|
|
87
|
+
modelValue: { type: Boolean, default: false },
|
|
88
|
+
/** 是否显示遮罩,某些时候数字键盘时,用户希望看到自己的数值,所以可能不想要遮罩 */
|
|
89
|
+
mask: { type: Boolean, default: true },
|
|
90
|
+
/** z-index值 */
|
|
91
|
+
zIndex: { type: [Number, String], default: '' },
|
|
92
|
+
/** 取消按钮的文字 */
|
|
93
|
+
cancelText: { type: String, default: '取消' },
|
|
94
|
+
/** 确认按钮的文字 */
|
|
95
|
+
confirmText: { type: String, default: '确认' }
|
|
96
|
+
});
|
|
97
|
+
const emit = defineEmits(['change', 'update:modelValue', 'confirm', 'cancel', 'backspace']);
|
|
98
|
+
|
|
99
|
+
const uZIndex = computed(() => (props.zIndex ? props.zIndex : 1075));
|
|
100
|
+
|
|
101
|
+
const popupValue = computed({
|
|
102
|
+
get: () => props.modelValue,
|
|
103
|
+
set: (val: boolean) => emit('update:modelValue', val)
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* 按键被点击(不包含退格键被点击)
|
|
108
|
+
*/
|
|
109
|
+
function change(e: any) {
|
|
110
|
+
emit('change', e);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* 键盘关闭
|
|
115
|
+
*/
|
|
116
|
+
function popupClose() {
|
|
117
|
+
emit('update:modelValue', false);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* 输入完成
|
|
122
|
+
*/
|
|
123
|
+
function onConfirm() {
|
|
124
|
+
popupClose();
|
|
125
|
+
emit('confirm');
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* 取消输入
|
|
130
|
+
*/
|
|
131
|
+
function onCancel() {
|
|
132
|
+
popupClose();
|
|
133
|
+
emit('cancel');
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* 退格键
|
|
138
|
+
*/
|
|
139
|
+
function backspace() {
|
|
140
|
+
emit('backspace');
|
|
141
|
+
}
|
|
142
|
+
</script>
|
|
143
|
+
|
|
144
|
+
<style lang="scss" scoped>
|
|
145
|
+
@import '../../libs/css/style.components.scss';
|
|
146
|
+
|
|
147
|
+
.u-keyboard {
|
|
148
|
+
position: relative;
|
|
149
|
+
z-index: 1003;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
.u-tooltip {
|
|
153
|
+
@include vue-flex;
|
|
154
|
+
justify-content: space-between;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
.u-tooltip-item {
|
|
158
|
+
color: #333333;
|
|
159
|
+
flex: 0 0 33.333333%;
|
|
160
|
+
text-align: center;
|
|
161
|
+
padding: 20rpx 10rpx;
|
|
162
|
+
font-size: 28rpx;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
.u-tooltips-submit {
|
|
166
|
+
text-align: right;
|
|
167
|
+
flex-grow: 1;
|
|
168
|
+
flex-wrap: 0;
|
|
169
|
+
padding-right: 40rpx;
|
|
170
|
+
color: $u-type-primary;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
.u-tooltip-cancel {
|
|
174
|
+
text-align: left;
|
|
175
|
+
flex-grow: 1;
|
|
176
|
+
flex-wrap: 0;
|
|
177
|
+
padding-left: 40rpx;
|
|
178
|
+
color: #888888;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
.u-tooltips-submit-hover {
|
|
182
|
+
color: $u-type-success;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
.u-tooltip-cancel-hover {
|
|
186
|
+
color: #333333;
|
|
187
|
+
}
|
|
188
|
+
</style>
|