hy-app 0.3.10 → 0.3.12

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/api/http.ts CHANGED
@@ -1,8 +1,4 @@
1
- import type {
2
- HttpRequestConfig,
3
- HttpInterceptorManager,
4
- HttpResponse,
5
- } from "../typing";
1
+ import type { HttpRequestConfig } from "../typing";
6
2
  import { objectToUrlParams } from "../utils";
7
3
 
8
4
  export default class Http {
@@ -20,18 +16,27 @@ export default class Http {
20
16
  timeout: 10000,
21
17
  };
22
18
 
19
+ /* 私有回调槽 */
20
+ private _requestHook?: (
21
+ conf: UniNamespace.RequestOptions,
22
+ ) => UniNamespace.RequestOptions;
23
+ private _responseSuccessHook?: (
24
+ res: UniNamespace.RequestSuccessCallbackResult,
25
+ ) => any;
26
+ private _responseFailHook?: (err: UniNamespace.GeneralCallbackResult) => any;
27
+
23
28
  /**
24
29
  * @description 拦截器
25
30
  */
26
31
  interceptor = {
27
32
  /**
28
33
  * @description 请求拦截 请求配置
29
- * @param config
34
+ * @param hook
30
35
  */
31
- request: (config: HttpRequestConfig) => {
32
- if (config) {
33
- this.requestBefore(config);
34
- }
36
+ request: (
37
+ hook: (conf: UniNamespace.RequestOptions) => UniNamespace.RequestOptions,
38
+ ) => {
39
+ this._requestHook = hook;
35
40
  },
36
41
  /**
37
42
  * @description 响应拦截
@@ -39,66 +44,55 @@ export default class Http {
39
44
  * @param fail 失败响应
40
45
  */
41
46
  response: (
42
- success: (response: HttpResponse) => any,
43
- fail: (error: HttpResponse) => any,
47
+ success?: (response: UniNamespace.RequestSuccessCallbackResult) => any,
48
+ fail?: (error: UniNamespace.GeneralCallbackResult) => any,
44
49
  ) => {
45
50
  if (success) {
46
- this.responseSuccess = success;
51
+ this._responseSuccessHook = success;
47
52
  }
48
53
  if (fail) {
49
- this.responseFail = fail;
54
+ this._responseFailHook = fail;
50
55
  }
51
56
  },
52
57
  };
53
58
 
54
59
  /**
55
60
  * @description 请求拦截
56
- * @param config 请求配置
57
- */
58
- requestBefore(config: HttpRequestConfig) {
59
- return config;
60
- }
61
-
62
- /**
63
- * @description 成功响应
64
- * @param response
65
- */
66
- responseSuccess(response: UniNamespace.RequestSuccessCallbackResult) {
67
- return response;
68
- }
69
-
70
- /**
71
- * @description 失败响应
72
- * @param response
61
+ * @param conf 请求配置
73
62
  */
74
- responseFail(response: UniNamespace.GeneralCallbackResult) {
75
- return response;
63
+ private requestBefore(
64
+ conf: UniNamespace.RequestOptions,
65
+ ): UniNamespace.RequestOptions {
66
+ return this._requestHook ? this._requestHook(conf) : conf;
76
67
  }
77
68
 
78
69
  /**
79
70
  * @description uni异步请求
80
71
  * @param options 请求配置
81
72
  */
82
- async request(options: Record<string, any>) {
73
+ async request(options: UniNamespace.RequestOptions) {
83
74
  options.url = this.config.baseURL + options.url || this.config.url;
84
75
  options.data = options.data || this.config.data;
85
76
  options.header = options.header || this.config.header;
86
77
  options.method = options.method || this.config.method;
87
78
  options.responseType = options.responseType || this.config.responseType;
88
79
  options.timeout = options.timeout || this.config.timeout;
89
- return new Promise<any>((resolve, reject) => {
90
- options = this.requestBefore(options);
80
+ /* 合并默认配置 ... */
81
+ return new Promise((resolve, reject) => {
82
+ options = this.requestBefore(options); // ⭐这里会调用钩子
91
83
  uni.request({
92
- url: options.url,
93
- data: options.data,
94
- header: options.header,
95
- method: options.method,
96
- timeout: options.timeout,
97
- success: (response: UniNamespace.RequestSuccessCallbackResult) => {
98
- resolve(this.responseSuccess(response));
84
+ ...options,
85
+ success: (res: UniNamespace.RequestSuccessCallbackResult) => {
86
+ const after = this._responseSuccessHook
87
+ ? this._responseSuccessHook(res)
88
+ : res;
89
+ resolve(after);
99
90
  },
100
- fail: (error: UniNamespace.GeneralCallbackResult) => {
101
- reject(this.responseFail(error));
91
+ fail: (err: UniNamespace.GeneralCallbackResult) => {
92
+ const after = this._responseFailHook
93
+ ? this._responseFailHook(err)
94
+ : err;
95
+ reject(after);
102
96
  },
103
97
  });
104
98
  });
@@ -110,7 +104,7 @@ export default class Http {
110
104
  * @param params 请求JSON参数
111
105
  * @param options 请求配置
112
106
  */
113
- post(url: string, params?: any, options?: Record<string, any>) {
107
+ post(url: string, params?: any, options?: HttpRequestConfig) {
114
108
  return this.request({
115
109
  url: url,
116
110
  method: "POST",
@@ -125,7 +119,7 @@ export default class Http {
125
119
  * @param params URL查询参数
126
120
  * @param options 请求配置
127
121
  */
128
- get(url: string, params?: any, options?: Record<string, any>) {
122
+ get(url: string, params?: any, options?: HttpRequestConfig) {
129
123
  if (params) {
130
124
  url += "?" + objectToUrlParams(params);
131
125
  }
@@ -134,7 +134,7 @@ const props = defineProps({
134
134
  /** 卡片与屏幕两边和上下元素的间距,需带单位,如"30px 20px" */
135
135
  margin: {
136
136
  type: String,
137
- default: "10px",
137
+ default: "0 0 20rpx",
138
138
  },
139
139
  /** 卡片整体的圆角值,单位px */
140
140
  borderRadius: {
@@ -110,18 +110,10 @@ export default {
110
110
  </script>
111
111
 
112
112
  <script setup lang="ts">
113
- import {
114
- computed,
115
- nextTick,
116
- ref,
117
- toRefs,
118
- watch,
119
- getCurrentInstance,
120
- inject,
121
- } from "vue";
113
+ import { computed, nextTick, ref, watch, inject } from "vue";
122
114
  import type { CSSProperties, PropType } from "vue";
123
115
  import HyIcon from "../hy-icon/hy-icon.vue";
124
- import { addUnit, formatObject } from "../../utils";
116
+ import { addUnit, formatObject, sleep } from "../../utils";
125
117
  import { IconConfig } from "../../config";
126
118
  import type { IInputEmits } from "./typing";
127
119
  import type HyIconProps from "../hy-icon/typing";
@@ -322,20 +314,9 @@ const props = defineProps({
322
314
  /** 自定义外部类名 */
323
315
  customClass: String,
324
316
  });
325
- const {
326
- disabled,
327
- disabledColor,
328
- border,
329
- color,
330
- inputAlign,
331
- fontSize,
332
- readonly,
333
- placeholderStyle,
334
- } = toRefs(props);
335
317
  const emit = defineEmits<IInputEmits>();
336
318
  const formItem = inject<FormItemContext | null>("formItem", null);
337
319
 
338
- const instance = getCurrentInstance();
339
320
  // 清除操作
340
321
  const clearInput = ref<boolean>(false);
341
322
  // 输入框的值
@@ -359,9 +340,6 @@ watch(
359
340
  // 在H5中,外部value变化后,修改input中的值,不会触发@input事件,此时手动调用值变化方法
360
341
  if (firstChange.value === false && changeFromInner.value === false) {
361
342
  valueChange(innerValue.value, true);
362
- } else {
363
- // 尝试调用up-form的验证方法
364
- // if (!firstChange.value) formValidate(this, "change");
365
343
  }
366
344
  firstChange.value = false;
367
345
  // 重置changeFromInner的值为false,标识下一次引起默认为外部引起的
@@ -388,7 +366,7 @@ const inputClass = computed((): string => {
388
366
  classes.push(`hy-input--${shape}`);
389
367
  border === "bottom" &&
390
368
  (classes = classes.concat(["hy-border__bottom", "hy-input--no-radius"]));
391
- disabled.value && classes.push("hy-input--disabled");
369
+ props.disabled && classes.push("hy-input--disabled");
392
370
  return classes.join(" ");
393
371
  });
394
372
 
@@ -402,8 +380,8 @@ const wrapperStyle = computed((): CSSProperties => {
402
380
  style.paddingLeft = "9px";
403
381
  style.paddingRight = "9px";
404
382
  // 禁用状态下,被背景色加上对应的样式
405
- if (disabled.value) {
406
- style.backgroundColor = disabledColor.value;
383
+ if (props.disabled) {
384
+ style.backgroundColor = props.disabledColor;
407
385
  }
408
386
  return Object.assign(style, props.customStyle);
409
387
  });
@@ -412,9 +390,9 @@ const wrapperStyle = computed((): CSSProperties => {
412
390
  * */
413
391
  const inputStyle = computed((): CSSProperties => {
414
392
  return {
415
- color: color.value,
416
- fontSize: addUnit(fontSize.value),
417
- textAlign: inputAlign.value,
393
+ color: props.color,
394
+ fontSize: addUnit(props.fontSize),
395
+ textAlign: props.inputAlign,
418
396
  };
419
397
  });
420
398
 
@@ -425,7 +403,7 @@ const borderStyle = computed(() => {
425
403
  return (isFocus: boolean) => {
426
404
  let style: CSSProperties = {};
427
405
  if (isFocus) {
428
- switch (border.value) {
406
+ switch (props.border) {
429
407
  case "surround":
430
408
  style = { border: `1px solid var(--hy-theme-color, #3c9cff)` };
431
409
  break;
@@ -457,14 +435,11 @@ const onInput = (e: any) => {
457
435
  /**
458
436
  * @description 输入框失去焦点时触发
459
437
  * */
460
- const onBlur = (event: InputOnBlurEvent) => {
438
+ const onBlur = async (event: InputOnBlurEvent) => {
461
439
  emit("blur", event, event.detail.value);
462
440
  if (formItem) formItem.handleBlur(event.detail.value);
463
- // H5端的blur会先于点击清除控件的点击click事件触发,导致focused
464
- // 瞬间为false,从而隐藏了清除控件而无法被点击到
465
- setTimeout(() => {
466
- focused.value = false;
467
- }, 150);
441
+ await sleep();
442
+ focused.value = false;
468
443
  };
469
444
  /**
470
445
  * @description 输入框聚焦时触发
@@ -524,7 +499,7 @@ const onClear = () => {
524
499
  */
525
500
  const clickHandler = () => {
526
501
  // 隐藏键盘
527
- if (disabled.value || readonly.value) {
502
+ if (props.disabled || props.readonly) {
528
503
  uni.hideKeyboard();
529
504
  }
530
505
  };
@@ -40,22 +40,19 @@
40
40
  ></HyIcon>
41
41
  </view>
42
42
  <input
43
- confirm-type="search"
44
- @blur="blur"
43
+ :confirm-type="confirmType"
45
44
  :value="keyword"
46
- @confirm="search"
47
- @input="inputChange"
48
45
  :disabled="disabled"
49
- @focus="getFocus"
50
- :focus="focus"
51
46
  :maxlength="maxlength"
52
47
  :adjust-position="adjustPosition"
48
+ :focus="autoFocus"
53
49
  :auto-blur="autoBlur"
54
50
  placeholder-class="hy-search__content__input--placeholder"
55
51
  :placeholder="placeholder"
56
52
  :placeholder-style="`color: ${placeholderColor}`"
57
53
  class="hy-search__content__input"
58
54
  type="text"
55
+ :always-embed="true"
59
56
  :style="[
60
57
  {
61
58
  pointerEvents: disabled ? 'none' : 'auto',
@@ -66,20 +63,24 @@
66
63
  },
67
64
  inputStyle,
68
65
  ]"
66
+ @blur="onBlur"
67
+ @focus="onFocus"
68
+ @confirm="onSearch"
69
+ @input="inputChange"
69
70
  />
70
71
  <view
71
72
  class="hy-search__content__icon hy-search__content__close"
72
- v-if="keyword && clear && focused"
73
- @click="clear"
73
+ v-if="showClear"
74
+ @click="onClear"
74
75
  >
75
- <HyIcon :name="IconConfig.CLOSE" color="#ffffff"></HyIcon>
76
+ <HyIcon :name="IconConfig.CLOSE"></HyIcon>
76
77
  </view>
77
78
  </view>
78
79
  <text
79
80
  :style="[actionStyle]"
80
81
  class="hy-search__action"
81
82
  :class="[(showActionBtn || show) && 'hy-search__action--active']"
82
- @tap.stop.prevent="confirm"
83
+ @tap.stop.prevent="onConfirm"
83
84
  >
84
85
  {{ actionText }}
85
86
  </text>
@@ -101,7 +102,7 @@ export default {
101
102
  import { computed, nextTick, ref, watch } from "vue";
102
103
  import type { PropType, CSSProperties } from "vue";
103
104
  import type { ISearchEmits } from "./typing";
104
- import { sleep, addUnit } from "../../utils";
105
+ import { addUnit } from "../../utils";
105
106
  import { IconConfig } from "../../config";
106
107
  import HyIcon from "../hy-icon/hy-icon.vue";
107
108
  import type HyIconProps from "../hy-icon/typing";
@@ -110,6 +111,7 @@ import type {
110
111
  InputOnConfirmEvent,
111
112
  InputOnFocusEvent,
112
113
  InputOnInputEvent,
114
+ InputConfirmType,
113
115
  } from "@uni-helper/uni-types";
114
116
 
115
117
  /**
@@ -140,16 +142,34 @@ const props = defineProps({
140
142
  type: String,
141
143
  default: "请输入关键字",
142
144
  },
145
+ /**
146
+ * 设置右下角按钮的文字,兼容性详见uni-app文档
147
+ * @valuse send,search,next,go,done
148
+ * */
149
+ confirmType: {
150
+ type: String as PropType<InputConfirmType>,
151
+ default: "search",
152
+ },
143
153
  /** 是否启用清除控件 */
144
- clear: {
154
+ clearable: {
145
155
  type: Boolean,
146
156
  default: true,
147
157
  },
148
158
  /** 是否自动获得焦点 */
149
- focus: {
159
+ autoFocus: {
150
160
  type: Boolean,
151
161
  default: false,
152
162
  },
163
+ /** 键盘收起时,是否自动失去焦点 */
164
+ autoBlur: {
165
+ type: Boolean,
166
+ default: true,
167
+ },
168
+ /** 键盘弹起时,是否自动上推页面 */
169
+ adjustPosition: {
170
+ type: Boolean,
171
+ default: true,
172
+ },
153
173
  /** 是否显示右侧控件 */
154
174
  showAction: {
155
175
  type: Boolean,
@@ -216,16 +236,6 @@ const props = defineProps({
216
236
  },
217
237
  /** 搜索框左边显示内容 */
218
238
  label: String,
219
- /** 键盘弹起时,是否自动上推页面 */
220
- adjustPosition: {
221
- type: Boolean,
222
- default: true,
223
- },
224
- /** 键盘收起时,是否自动失去焦点 */
225
- autoBlur: {
226
- type: Boolean,
227
- default: true,
228
- },
229
239
  /** 定义需要用到的外部样式 */
230
240
  customStyle: {
231
241
  type: Object as PropType<CSSProperties>,
@@ -235,11 +245,11 @@ const props = defineProps({
235
245
  });
236
246
  const emit = defineEmits<ISearchEmits>();
237
247
 
238
- const keyword = ref<string>("");
248
+ const keyword = ref<string>(props.modelValue);
239
249
  // 显示右边搜索按钮
240
250
  const show = ref<boolean>(false);
241
251
  // 标记input当前状态是否处于聚焦中,如果是,才会显示右侧的清除控件
242
- const focused = ref(props.focus);
252
+ const focused = ref(false);
243
253
 
244
254
  watch(
245
255
  () => keyword.value,
@@ -249,17 +259,15 @@ watch(
249
259
  },
250
260
  );
251
261
 
252
- watch(
253
- () => props.modelValue,
254
- (newValue: string) => {
255
- keyword.value = newValue;
256
- },
257
- { immediate: true },
258
- );
259
-
262
+ // 是否显示右边控件
260
263
  const showActionBtn = computed<boolean>(() => {
261
264
  return !props.animation && props.showAction;
262
265
  });
266
+ // 是否显示清除控件
267
+ const showClear = computed(() => {
268
+ const { clearable, disabled } = props;
269
+ return clearable && !disabled && !!focused.value && keyword.value !== "";
270
+ });
263
271
 
264
272
  /**
265
273
  * 值改变触发
@@ -270,7 +278,7 @@ const inputChange = (e: InputOnInputEvent) => {
270
278
  /**
271
279
  * @description 清空输入
272
280
  * */
273
- const clear = () => {
281
+ const onClear = () => {
274
282
  keyword.value = "";
275
283
  // 延后发出事件,避免在父组件监听clear事件时,value为更新前的值(不为空)
276
284
  nextTick(() => {
@@ -280,7 +288,7 @@ const clear = () => {
280
288
  /**
281
289
  * @description 确定搜索
282
290
  * */
283
- const search = (e: InputOnConfirmEvent) => {
291
+ const onSearch = (e: InputOnConfirmEvent) => {
284
292
  emit("search", e, e.detail.value);
285
293
  try {
286
294
  // 收起键盘
@@ -290,7 +298,7 @@ const search = (e: InputOnConfirmEvent) => {
290
298
  /**
291
299
  * @description 点击右边自定义按钮的事件
292
300
  */
293
- const confirm = () => {
301
+ const onConfirm = () => {
294
302
  emit("confirm", keyword.value);
295
303
  try {
296
304
  // 收起键盘
@@ -300,22 +308,17 @@ const confirm = () => {
300
308
  /**
301
309
  * @description 获取焦点
302
310
  * */
303
- const getFocus = (e: InputOnFocusEvent) => {
311
+ const onFocus = (e: InputOnFocusEvent) => {
304
312
  focused.value = true;
305
313
  // 开启右侧搜索按钮展开的动画效果
306
314
  if (props.animation && props.showAction) show.value = true;
307
315
  emit("focus", e, keyword.value);
308
316
  };
309
- /**
310
- * @description 失去焦点
311
- */
312
- const blur = async (e: InputOnBlurEvent) => {
313
- // 最开始使用的是监听图标@touchstart事件,自从hx2.8.4后,此方法在微信小程序出错
314
- // 这里改为监听点击事件,手点击清除图标时,同时也发生了@blur事件,导致图标消失而无法点击,这里做一个延时
317
+
318
+ // 失去焦点
319
+ const onBlur = (e: InputOnBlurEvent) => {
315
320
  show.value = false;
316
321
  emit("blur", e, keyword.value);
317
- await sleep(100);
318
- focused.value = false;
319
322
  };
320
323
  /**
321
324
  * @description 点击搜索框,只有disabled=true时才发出事件,因为禁止了输入,意味着是想跳转真正的搜索页
@@ -13,7 +13,13 @@
13
13
 
14
14
  </text>
15
15
  <view class="hy-text__prefix-icon" v-if="prefixIcon">
16
- <HyIcon :name="prefixIcon" :customStyle="iconStyle"></HyIcon>
16
+ <HyIcon
17
+ :name="prefixIcon"
18
+ :color="color"
19
+ :size="size"
20
+ space="2"
21
+ :customStyle="iconStyle"
22
+ ></HyIcon>
17
23
  </view>
18
24
  <template v-if="openType && isMp">
19
25
  <button
@@ -51,7 +57,12 @@
51
57
  {{ value }}
52
58
  </text>
53
59
  <view class="hy-text__suffix-icon" v-if="suffixIcon">
54
- <HyIcon :name="suffixIcon" :customStyle="iconStyle"></HyIcon>
60
+ <HyIcon
61
+ :name="suffixIcon"
62
+ :color="color"
63
+ :size="size"
64
+ :customStyle="iconStyle"
65
+ ></HyIcon>
55
66
  </view>
56
67
  </view>
57
68
  </template>
@@ -111,3 +111,9 @@ $u-zoom-scale: scale(0.95);
111
111
  .u-zoom-leave-to {
112
112
  transform: $u-zoom-scale
113
113
  }
114
+
115
+ @include b(transition) {
116
+ display: flex;
117
+ justify-content: center;
118
+ align-items: center;
119
+ }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "hy-app",
3
- "version": "0.3.10",
4
- "description": "修复icon图标不显示",
3
+ "version": "0.3.12",
4
+ "description": "http网络请求修复",
5
5
  "main": "./index.ts",
6
6
  "private": false,
7
7
  "scripts": {},
@@ -1,57 +1,6 @@
1
- export interface HttpRequestConfig {
1
+ export interface HttpRequestConfig extends UniNamespace.RequestOptions {
2
2
  /** 请求基地址 */
3
3
  baseURL?: string;
4
- /** 请求服务器接口地址 */
5
- url?: string;
6
-
7
- /** 请求查询参数,自动拼接为查询字符串 */
8
- params?: AnyObject;
9
- /** 请求体参数 */
10
- data?: AnyObject;
11
-
12
- /** 文件对应的 key */
13
- name?: string;
14
- /** HTTP 请求中其他额外的 form data */
15
- formData?: AnyObject;
16
- /** 要上传文件资源的路径。 */
17
- filePath?: string;
18
- /** 需要上传的文件列表。使用 files 时,filePath 和 name 不生效,App、H5( 2.6.15+) */
19
- files?: Array<{
20
- name?: string;
21
- file?: File;
22
- uri: string;
23
- }>;
24
- /** 要上传的文件对象,仅H5(2.6.15+)支持 */
25
- file?: File;
26
-
27
- /** 请求头信息 */
28
- header?: AnyObject;
29
- /** 请求方式 */
30
- method?:
31
- | "GET"
32
- | "POST"
33
- | "PUT"
34
- | "DELETE"
35
- | "CONNECT"
36
- | "HEAD"
37
- | "OPTIONS"
38
- | "TRACE"
39
- | "UPLOAD"
40
- | "DOWNLOAD";
41
- /** 如果设为 json,会尝试对返回的数据做一次 JSON.parse */
42
- dataType?: string;
43
- /** 设置响应的数据类型,支付宝小程序不支持 */
44
- responseType?: "text" | "arraybuffer";
45
- /** 自定义参数 */
46
- custom?: AnyObject;
47
- /** 超时时间,仅微信小程序(2.10.0)、支付宝小程序支持 */
48
- timeout?: number;
49
- /** DNS解析时优先使用ipv4,仅 App-Android 支持 (HBuilderX 2.8.0+) */
50
- firstIpv4?: boolean;
51
- /** 验证 ssl 证书 仅5+App安卓端支持(HBuilderX 2.3.3+) */
52
- sslVerify?: boolean;
53
- /** 跨域请求时是否携带凭证(cookies)仅H5支持(HBuilderX 2.6.15+) */
54
- withCredentials?: boolean;
55
4
  }
56
5
 
57
6
  export interface HttpResponse<T = any> {
package/utils/inside.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  // 内部使用方法
2
- import { inject } from 'vue'
2
+ import { inject } from "vue";
3
3
 
4
4
  /**
5
5
  * 生成bem规则类名
@@ -18,31 +18,33 @@ export const bem = (
18
18
  change?: string[],
19
19
  ): string | string[] => {
20
20
  // 类名前缀
21
- const prefix = `hy-${name}--`
22
- const classes: Record<string, string | boolean> = {}
21
+ const prefix = `hy-${name}--`;
22
+ const classes: Record<string, string | boolean> = {};
23
23
  if (fixed) {
24
24
  fixed.map((item: string) => {
25
25
  // 这里的类名,会一直存在
26
- classes[prefix + props[item]] = true
27
- if (item === 'type' && props['plain']) {
28
- classes[prefix + props[item] + '__plain'] = true
26
+ classes[prefix + props[item]] = true;
27
+ if (item === "type" && props["plain"]) {
28
+ classes[prefix + props[item] + "__plain"] = true;
29
29
  }
30
- })
30
+ });
31
31
  }
32
32
  if (change) {
33
33
  change.map((item: string) => {
34
34
  // 这里的类名,会根据this[item]的值为true或者false,而进行添加或者移除某一个类
35
- props[item] ? (classes[prefix + item] = props[item]) : delete classes[prefix + item]
36
- })
35
+ props[item]
36
+ ? (classes[prefix + item] = props[item])
37
+ : delete classes[prefix + item];
38
+ });
37
39
  }
38
40
  return (
39
41
  Object.keys(classes)
40
42
  // 支付宝,头条小程序无法动态绑定一个数组类名,否则解析出来的结果会带有",",而导致失效
41
43
  // #ifdef MP-ALIPAY || MP-TOUTIAO || MP-LARK
42
- .join(' ')
44
+ .join(" ")
43
45
  // #endif
44
- )
45
- }
46
+ );
47
+ };
46
48
 
47
49
  /**
48
50
  * @description 在u-form的子组件内容发生变化,或者失去焦点时,尝试通知u-form执行校验方法
@@ -51,7 +53,7 @@ export const bem = (
51
53
  */
52
54
  export function formValidate(event) {
53
55
  // const formItem = $parent.call(instance, "u-form-item");
54
- const form = inject('uForm')
56
+ const form = inject("uForm");
55
57
  // 如果发生变化的input或者textarea等,其父组件中有u-form-item或者u-form等,就执行form的validate方法
56
58
  // 同时将form-item的pros传递给form,让其进行精确对象验证
57
59
  // if (formItem && form) {
@@ -65,18 +67,18 @@ export function formValidate(event) {
65
67
  */
66
68
  export function error(err: string) {
67
69
  // 开发环境才提示,生产环境不会提示
68
- if (process.env.NODE_ENV === 'development') {
69
- console.error(`华玥组件提示:${err}`)
70
+ if (process.env.NODE_ENV === "development") {
71
+ console.error(`华玥组件提示:${err}`);
70
72
  }
71
73
  }
72
74
 
73
- export const sleep = (value = 30) => {
75
+ export const sleep = (value = 100) => {
74
76
  return new Promise((resolve) => {
75
77
  setTimeout(() => {
76
- resolve()
77
- }, value)
78
- })
79
- }
78
+ resolve();
79
+ }, value);
80
+ });
81
+ };
80
82
 
81
83
  /**
82
84
  * @param {Number} len uuid的长度
@@ -84,62 +86,67 @@ export const sleep = (value = 30) => {
84
86
  * @param {Nubmer} radix 生成uuid的基数(意味着返回的字符串都是这个基数),2-二进制,8-八进制,10-十进制,16-十六进制
85
87
  */
86
88
  export function guid(len = 32, firstU = true, radix = null) {
87
- const chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split('')
88
- const uuid = []
89
- radix = radix || chars.length
89
+ const chars =
90
+ "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz".split("");
91
+ const uuid = [];
92
+ radix = radix || chars.length;
90
93
 
91
94
  if (len) {
92
95
  // 如果指定uuid长度,只是取随机的字符,0|x为位运算,能去掉x的小数位,返回整数位
93
- for (let i = 0; i < len; i++) uuid[i] = chars[0 | (Math.random() * radix)]
96
+ for (let i = 0; i < len; i++) uuid[i] = chars[0 | (Math.random() * radix)];
94
97
  } else {
95
- let r
98
+ let r;
96
99
  // rfc4122标准要求返回的uuid中,某些位为固定的字符
97
- uuid[8] = uuid[13] = uuid[18] = uuid[23] = '-'
98
- uuid[14] = '4'
100
+ uuid[8] = uuid[13] = uuid[18] = uuid[23] = "-";
101
+ uuid[14] = "4";
99
102
 
100
103
  for (let i = 0; i < 36; i++) {
101
104
  if (!uuid[i]) {
102
- r = 0 | (Math.random() * 16)
103
- uuid[i] = chars[i == 19 ? (r & 0x3) | 0x8 : r]
105
+ r = 0 | (Math.random() * 16);
106
+ uuid[i] = chars[i == 19 ? (r & 0x3) | 0x8 : r];
104
107
  }
105
108
  }
106
109
  }
107
110
  // 移除第一个字符,并用u替代,因为第一个字符为数值时,该guuid不能用作id或者class
108
111
  if (firstU) {
109
- uuid.shift()
110
- return `hy${uuid.join('')}`
112
+ uuid.shift();
113
+ return `hy${uuid.join("")}`;
111
114
  }
112
- return uuid.join('')
115
+ return uuid.join("");
113
116
  }
114
117
 
115
118
  /**
116
119
  * @description 获取设备信息
117
120
  * */
118
121
  export const getWindowInfo = (): UniNamespace.GetWindowInfoResult => {
119
- let ret: UniNamespace.GetWindowInfoResult
122
+ let ret: UniNamespace.GetWindowInfoResult;
120
123
  // #ifdef APP || H5 || MP-WEIXIN
121
- ret = uni.getWindowInfo()
124
+ ret = uni.getWindowInfo();
122
125
  // #endif
123
- return ret
124
- }
126
+ return ret;
127
+ };
125
128
 
126
129
  function pickExclude(obj, keys) {
127
130
  // 某些情况下,type可能会为
128
- if (!['[object Object]', '[object File]'].includes(Object.prototype.toString.call(obj))) {
129
- return {}
131
+ if (
132
+ !["[object Object]", "[object File]"].includes(
133
+ Object.prototype.toString.call(obj),
134
+ )
135
+ ) {
136
+ return {};
130
137
  }
131
138
  return Object.keys(obj).reduce((prev, key) => {
132
139
  if (!keys.includes(key)) {
133
- prev[key] = obj[key]
140
+ prev[key] = obj[key];
134
141
  }
135
- return prev
136
- }, {})
142
+ return prev;
143
+ }, {});
137
144
  }
138
145
 
139
146
  function formatImage(res) {
140
147
  return res.tempFiles.map((item) => ({
141
- ...pickExclude(item, ['path']),
142
- type: 'image',
148
+ ...pickExclude(item, ["path"]),
149
+ type: "image",
143
150
  url: item.path,
144
151
  thumb: item.path,
145
152
  size: item.size,
@@ -147,14 +154,14 @@ function formatImage(res) {
147
154
  name: item.name,
148
155
  file: item,
149
156
  // #endif
150
- }))
157
+ }));
151
158
  }
152
159
 
153
160
  function formatVideo(res) {
154
161
  return [
155
162
  {
156
- ...pickExclude(res, ['tempFilePath', 'thumbTempFilePath', 'errMsg']),
157
- type: 'video',
163
+ ...pickExclude(res, ["tempFilePath", "thumbTempFilePath", "errMsg"]),
164
+ type: "video",
158
165
  url: res.tempFilePath,
159
166
  thumb: res.thumbTempFilePath,
160
167
  size: res.size,
@@ -163,25 +170,25 @@ function formatVideo(res) {
163
170
  file: res,
164
171
  // #endif
165
172
  },
166
- ]
173
+ ];
167
174
  }
168
175
 
169
176
  function formatMedia(res) {
170
177
  return res.tempFiles.map((item) => ({
171
- ...pickExclude(item, ['fileType', 'thumbTempFilePath', 'tempFilePath']),
178
+ ...pickExclude(item, ["fileType", "thumbTempFilePath", "tempFilePath"]),
172
179
  type: res.type,
173
180
  url: item.tempFilePath,
174
- thumb: res.type === 'video' ? item.thumbTempFilePath : item.tempFilePath,
181
+ thumb: res.type === "video" ? item.thumbTempFilePath : item.tempFilePath,
175
182
  size: item.size,
176
183
  // #ifdef H5
177
184
  file: item,
178
185
  // #endif
179
- }))
186
+ }));
180
187
  }
181
188
 
182
189
  function formatFile(res) {
183
190
  return res.tempFiles.map((item) => ({
184
- ...pickExclude(item, ['path']),
191
+ ...pickExclude(item, ["path"]),
185
192
  url: item.path,
186
193
  size: item.size,
187
194
  // #ifdef H5
@@ -189,7 +196,7 @@ function formatFile(res) {
189
196
  type: item.type,
190
197
  file: item,
191
198
  // #endif
192
- }))
199
+ }));
193
200
  }
194
201
 
195
202
  export function chooseFile({
@@ -205,18 +212,18 @@ export function chooseFile({
205
212
  }: any) {
206
213
  return new Promise((resolve, reject) => {
207
214
  switch (accept) {
208
- case 'image':
215
+ case "image":
209
216
  uni.chooseImage({
210
217
  count: multiple ? Math.min(maxCount, 9) : 1,
211
218
  sourceType: capture,
212
219
  sizeType,
213
220
  success: (res) => resolve(formatImage(res)),
214
221
  fail: reject,
215
- })
216
- break
222
+ });
223
+ break;
217
224
  // #ifdef MP-WEIXIN
218
225
  // 只有微信小程序才支持chooseMedia接口
219
- case 'media':
226
+ case "media":
220
227
  wx.chooseMedia({
221
228
  count: multiple ? Math.min(maxCount, 9) : 1,
222
229
  sourceType: capture,
@@ -225,10 +232,10 @@ export function chooseFile({
225
232
  camera,
226
233
  success: (res) => resolve(formatMedia(res)),
227
234
  fail: reject,
228
- })
229
- break
235
+ });
236
+ break;
230
237
  // #endif
231
- case 'video':
238
+ case "video":
232
239
  uni.chooseVideo({
233
240
  sourceType: capture,
234
241
  compressed,
@@ -236,18 +243,18 @@ export function chooseFile({
236
243
  camera,
237
244
  success: (res) => resolve(formatVideo(res)),
238
245
  fail: reject,
239
- })
240
- break
246
+ });
247
+ break;
241
248
  // #ifdef MP-WEIXIN || H5
242
249
  // 只有微信小程序才支持chooseMessageFile接口
243
- case 'file':
250
+ case "file":
244
251
  // #ifdef MP-WEIXIN
245
252
  wx.chooseMessageFile({
246
253
  count: multiple ? maxCount : 1,
247
254
  type: accept,
248
255
  success: (res) => resolve(formatFile(res)),
249
256
  fail: reject,
250
- })
257
+ });
251
258
  // #endif
252
259
  // #ifdef H5
253
260
  // 需要hx2.9.9以上才支持uni.chooseFile
@@ -256,39 +263,39 @@ export function chooseFile({
256
263
  type: accept,
257
264
  success: (res) => resolve(formatFile(res)),
258
265
  fail: reject,
259
- }
266
+ };
260
267
  if (extension.length && extension.length > 0) {
261
- params.extension = extension
268
+ params.extension = extension;
262
269
  }
263
- uni.chooseFile(params)
270
+ uni.chooseFile(params);
264
271
  // #endif
265
- break
272
+ break;
266
273
  // #endif
267
274
  default:
268
275
  // 此为保底选项,在accept不为上面任意一项的时候选取全部文件
269
276
  // #ifdef MP-WEIXIN
270
277
  wx.chooseMessageFile({
271
278
  count: multiple ? maxCount : 1,
272
- type: 'all',
279
+ type: "all",
273
280
  success: (res) => resolve(formatFile(res)),
274
281
  fail: reject,
275
- })
282
+ });
276
283
  // #endif
277
284
  // #ifdef H5
278
285
  // 需要hx2.9.9以上才支持uni.chooseFile
279
286
  let paramsFile = {
280
287
  count: multiple ? maxCount : 1,
281
- type: 'all',
288
+ type: "all",
282
289
  success: (res) => resolve(formatFile(res)),
283
290
  fail: reject,
284
- }
291
+ };
285
292
  if (extension.length && extension.length > 0) {
286
- paramsFile.extension = extension
293
+ paramsFile.extension = extension;
287
294
  }
288
- uni.chooseFile(paramsFile)
295
+ uni.chooseFile(paramsFile);
289
296
  // #endif
290
297
  }
291
- })
298
+ });
292
299
  }
293
300
 
294
301
  /**
@@ -302,27 +309,28 @@ export function chooseFile({
302
309
  export function priceFormat(
303
310
  number: string | number,
304
311
  decimals = 0,
305
- decimalPoint = '.',
306
- thousandsSeparator = ',',
312
+ decimalPoint = ".",
313
+ thousandsSeparator = ",",
307
314
  ) {
308
- number = `${number}`.replace(/[^0-9+-Ee.]/g, '')
309
- const n = !isFinite(+number) ? 0 : +number
310
- const prec = !isFinite(+decimals) ? 0 : Math.abs(decimals)
311
- const sep = typeof thousandsSeparator === 'undefined' ? ',' : thousandsSeparator
312
- const dec = typeof decimalPoint === 'undefined' ? '.' : decimalPoint
313
- let s = ''
315
+ number = `${number}`.replace(/[^0-9+-Ee.]/g, "");
316
+ const n = !isFinite(+number) ? 0 : +number;
317
+ const prec = !isFinite(+decimals) ? 0 : Math.abs(decimals);
318
+ const sep =
319
+ typeof thousandsSeparator === "undefined" ? "," : thousandsSeparator;
320
+ const dec = typeof decimalPoint === "undefined" ? "." : decimalPoint;
321
+ let s = "";
314
322
 
315
- s = (prec ? n + '' : `${Math.round(n)}`).split('.')
316
- const re = /(-?\d+)(\d{3})/
323
+ s = (prec ? n + "" : `${Math.round(n)}`).split(".");
324
+ const re = /(-?\d+)(\d{3})/;
317
325
  while (re.test(s[0])) {
318
- s[0] = s[0].replace(re, `$1${sep}$2`)
326
+ s[0] = s[0].replace(re, `$1${sep}$2`);
319
327
  }
320
328
 
321
- if ((s[1] || '').length < prec) {
322
- s[1] = s[1] || ''
323
- s[1] += new Array(prec - s[1].length + 1).join('0')
329
+ if ((s[1] || "").length < prec) {
330
+ s[1] = s[1] || "";
331
+ s[1] += new Array(prec - s[1].length + 1).join("0");
324
332
  }
325
- return s.join(dec)
333
+ return s.join(dec);
326
334
  }
327
335
 
328
336
  /**
@@ -331,17 +339,20 @@ export function priceFormat(
331
339
  * @return {string}
332
340
  * */
333
341
  export const formatName = (name: string): string => {
334
- let value = ''
342
+ let value = "";
335
343
  if (name.length === 2) {
336
- value = name.substring(0, 1) + '*'
344
+ value = name.substring(0, 1) + "*";
337
345
  } else if (name.length > 2) {
338
- let char = ''
346
+ let char = "";
339
347
  for (let i = 0, len = name.length - 2; i < len; i++) {
340
- char += '*'
348
+ char += "*";
341
349
  }
342
- value = name.substring(0, 1) + char + name.substring(name.length - 1, name.length)
350
+ value =
351
+ name.substring(0, 1) +
352
+ char +
353
+ name.substring(name.length - 1, name.length);
343
354
  } else {
344
- value = name
355
+ value = name;
345
356
  }
346
- return value
347
- }
357
+ return value;
358
+ };