hy-app 0.1.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.
Files changed (206) hide show
  1. package/README.md +42 -0
  2. package/api/http.ts +138 -0
  3. package/api/index.ts +1 -0
  4. package/common/index.ts +1 -0
  5. package/common/versionControl.ts +102 -0
  6. package/components/dialog/TheDialog.vue +128 -0
  7. package/components/dialog/index.ts +38 -0
  8. package/components/hy-address-picker/hy-address-picker.vue +262 -0
  9. package/components/hy-address-picker/props.ts +27 -0
  10. package/components/hy-address-picker/typing.d.ts +98 -0
  11. package/components/hy-avatar/hy-avatar.vue +217 -0
  12. package/components/hy-avatar/props.ts +20 -0
  13. package/components/hy-avatar/typing.d.ts +64 -0
  14. package/components/hy-back-top/hy-back-top.vue +71 -0
  15. package/components/hy-back-top/props.ts +23 -0
  16. package/components/hy-back-top/typing.d.ts +49 -0
  17. package/components/hy-badge/hy-badge.vue +155 -0
  18. package/components/hy-badge/props.ts +19 -0
  19. package/components/hy-badge/typing.d.ts +60 -0
  20. package/components/hy-button/hy-button.vue +394 -0
  21. package/components/hy-button/props.ts +36 -0
  22. package/components/hy-button/typing.d.ts +125 -0
  23. package/components/hy-card/hy-card.vue +198 -0
  24. package/components/hy-card/props.ts +29 -0
  25. package/components/hy-card/typing.d.ts +112 -0
  26. package/components/hy-cell/hy-cell.vue +268 -0
  27. package/components/hy-cell/props.ts +20 -0
  28. package/components/hy-cell/typing.d.ts +98 -0
  29. package/components/hy-check-button/hy-check-button.vue +71 -0
  30. package/components/hy-check-button/props.ts +20 -0
  31. package/components/hy-check-button/typing.d.ts +79 -0
  32. package/components/hy-checkbox/hy-checkbox.vue +299 -0
  33. package/components/hy-checkbox/props.ts +28 -0
  34. package/components/hy-checkbox/typing.d.ts +77 -0
  35. package/components/hy-datetime-picker/hy-datetime-picker.vue +584 -0
  36. package/components/hy-datetime-picker/props.ts +36 -0
  37. package/components/hy-datetime-picker/typing.d.ts +135 -0
  38. package/components/hy-divider/hy-divider.vue +164 -0
  39. package/components/hy-divider/props.ts +21 -0
  40. package/components/hy-divider/typing.d.ts +64 -0
  41. package/components/hy-empty/hy-empty.vue +122 -0
  42. package/components/hy-empty/props.ts +21 -0
  43. package/components/hy-empty/typing.d.ts +68 -0
  44. package/components/hy-folding-panel/hy-folding-panel.vue +94 -0
  45. package/components/hy-folding-panel/props.ts +17 -0
  46. package/components/hy-folding-panel/typing.d.ts +59 -0
  47. package/components/hy-form/hy-form.vue +372 -0
  48. package/components/hy-form/props.ts +15 -0
  49. package/components/hy-form/typing.d.ts +51 -0
  50. package/components/hy-grid/hy-grid.vue +126 -0
  51. package/components/hy-grid/props.ts +16 -0
  52. package/components/hy-grid/typing.d.ts +62 -0
  53. package/components/hy-icon/hy-icon.vue +207 -0
  54. package/components/hy-icon/props.ts +24 -0
  55. package/components/hy-icon/typing.d.ts +80 -0
  56. package/components/hy-input/hy-input.vue +402 -0
  57. package/components/hy-input/props.ts +41 -0
  58. package/components/hy-input/typing.d.ts +148 -0
  59. package/components/hy-line/hy-line.vue +44 -0
  60. package/components/hy-line/props.ts +12 -0
  61. package/components/hy-line/typing.d.ts +32 -0
  62. package/components/hy-line-progress/hy-line-progress.vue +118 -0
  63. package/components/hy-line-progress/props.ts +12 -0
  64. package/components/hy-line-progress/typing.d.ts +28 -0
  65. package/components/hy-list/hy-list.vue +250 -0
  66. package/components/hy-list/props.ts +18 -0
  67. package/components/hy-list/typing.d.ts +50 -0
  68. package/components/hy-login/ThePhoneLogin.vue +106 -0
  69. package/components/hy-login/TheUserLogin.vue +391 -0
  70. package/components/hy-login/hy-login.vue +283 -0
  71. package/components/hy-login/props.ts +32 -0
  72. package/components/hy-login/typing.d.ts +60 -0
  73. package/components/hy-modal/hy-modal.vue +240 -0
  74. package/components/hy-modal/props.ts +24 -0
  75. package/components/hy-modal/typing.d.ts +70 -0
  76. package/components/hy-navbar/hy-navbar.vue +194 -0
  77. package/components/hy-navbar/props.ts +24 -0
  78. package/components/hy-navbar/typing.d.ts +81 -0
  79. package/components/hy-notice-bar/hy-column-notice.vue +130 -0
  80. package/components/hy-notice-bar/hy-notice-bar.vue +82 -0
  81. package/components/hy-notice-bar/hy-row-notice.vue +182 -0
  82. package/components/hy-notice-bar/props.ts +19 -0
  83. package/components/hy-notice-bar/typing.d.ts +56 -0
  84. package/components/hy-number-step/hy-number-step.vue +428 -0
  85. package/components/hy-number-step/props.ts +29 -0
  86. package/components/hy-number-step/typing.d.ts +104 -0
  87. package/components/hy-overlay/hy-overlay.vue +54 -0
  88. package/components/hy-overlay/props.ts +10 -0
  89. package/components/hy-overlay/typing.d.ts +24 -0
  90. package/components/hy-picker/hy-picker.vue +499 -0
  91. package/components/hy-picker/props.ts +30 -0
  92. package/components/hy-picker/typing.d.ts +115 -0
  93. package/components/hy-popup/hy-popup.vue +269 -0
  94. package/components/hy-popup/props.ts +21 -0
  95. package/components/hy-popup/typing.d.ts +68 -0
  96. package/components/hy-price/hy-price.vue +86 -0
  97. package/components/hy-price/props.ts +13 -0
  98. package/components/hy-price/typing.d.ts +36 -0
  99. package/components/hy-qrcode/hy-qrcode.vue +153 -0
  100. package/components/hy-qrcode/props.ts +20 -0
  101. package/components/hy-qrcode/qrcode.js +1364 -0
  102. package/components/hy-qrcode/typing.d.ts +64 -0
  103. package/components/hy-radio/hy-radio.vue +319 -0
  104. package/components/hy-radio/props.ts +28 -0
  105. package/components/hy-radio/typing.d.ts +85 -0
  106. package/components/hy-rate/hy-rate.vue +261 -0
  107. package/components/hy-rate/props.ts +18 -0
  108. package/components/hy-rate/typing.d.ts +60 -0
  109. package/components/hy-read-more/hy-read-more.vue +134 -0
  110. package/components/hy-read-more/props.ts +20 -0
  111. package/components/hy-read-more/typing.d.ts +44 -0
  112. package/components/hy-safe-bottom/hy-safe-bottom.vue +64 -0
  113. package/components/hy-scroll-list/hy-scroll-list.vue +146 -0
  114. package/components/hy-scroll-list/props.ts +12 -0
  115. package/components/hy-scroll-list/typing.d.ts +28 -0
  116. package/components/hy-search/hy-search.vue +294 -0
  117. package/components/hy-search/props.ts +29 -0
  118. package/components/hy-search/typing.d.ts +109 -0
  119. package/components/hy-slider/hy-slider.vue +511 -0
  120. package/components/hy-slider/props.ts +21 -0
  121. package/components/hy-slider/typing.d.ts +68 -0
  122. package/components/hy-steps/hy-steps.vue +352 -0
  123. package/components/hy-steps/props.ts +15 -0
  124. package/components/hy-steps/typing.d.ts +58 -0
  125. package/components/hy-subsection/hy-subsection.vue +272 -0
  126. package/components/hy-subsection/props.ts +16 -0
  127. package/components/hy-subsection/typing.d.ts +44 -0
  128. package/components/hy-swiper/hy-swiper-indicator.vue +105 -0
  129. package/components/hy-swiper/hy-swiper.vue +242 -0
  130. package/components/hy-swiper/props.ts +30 -0
  131. package/components/hy-swiper/typing.d.ts +107 -0
  132. package/components/hy-switch/hy-switch.vue +168 -0
  133. package/components/hy-switch/props.ts +16 -0
  134. package/components/hy-switch/typing.d.ts +48 -0
  135. package/components/hy-tabs/hy-tabs.vue +416 -0
  136. package/components/hy-tabs/props.ts +26 -0
  137. package/components/hy-tabs/typing.d.ts +86 -0
  138. package/components/hy-tag/hy-tag.vue +374 -0
  139. package/components/hy-tag/props.ts +22 -0
  140. package/components/hy-tag/typing.d.ts +76 -0
  141. package/components/hy-textarea/hy-textarea.vue +229 -0
  142. package/components/hy-textarea/props.ts +26 -0
  143. package/components/hy-textarea/typing.d.ts +27 -0
  144. package/components/hy-tooltip/hy-tooltip.vue +332 -0
  145. package/components/hy-tooltip/props.ts +17 -0
  146. package/components/hy-tooltip/typing.d.ts +52 -0
  147. package/components/hy-transition/hy-transition.vue +150 -0
  148. package/components/hy-transition/index.scss +113 -0
  149. package/components/hy-transition/props.ts +10 -0
  150. package/components/hy-transition/typing.d.ts +36 -0
  151. package/components/hy-upload/hy-upload.vue +557 -0
  152. package/components/hy-upload/props.ts +29 -0
  153. package/components/hy-upload/typing.d.ts +147 -0
  154. package/components/hy-warn/hy-warn.vue +228 -0
  155. package/components/hy-warn/props.ts +14 -0
  156. package/components/hy-warn/typing.d.ts +40 -0
  157. package/components/hy-waterfall/hy-waterfall.vue +51 -0
  158. package/components/hy-waterfall/props.ts +10 -0
  159. package/components/hy-waterfall/typing.d.ts +20 -0
  160. package/components/index.ts +162 -0
  161. package/components/message/TheMessage.vue +169 -0
  162. package/components/message/index.ts +54 -0
  163. package/components/u-form/form.js +22 -0
  164. package/components/u-form/hy-form.vue +324 -0
  165. package/components/u-form/props.js +49 -0
  166. package/components/u-form/schema.js +1451 -0
  167. package/components/u-form/u-form.vue +267 -0
  168. package/components/u-form/utils.js +65 -0
  169. package/components/u-form-item/formItem.js +24 -0
  170. package/components/u-form-item/hy-form-item.vue +360 -0
  171. package/components/u-form-item/props.js +57 -0
  172. package/components/u-form-item/u-form-item.vue +294 -0
  173. package/components/yk-dialog/yk-dialog.vue +129 -0
  174. package/components/yk-tabbar/props.ts +49 -0
  175. package/components/yk-tabbar/yk-tabbar.vue +224 -0
  176. package/config/color.ts +6 -0
  177. package/config/icon.ts +366 -0
  178. package/config/index.ts +2 -0
  179. package/global/index.ts +6 -0
  180. package/global/register-properties.ts +37 -0
  181. package/index.ts +8 -0
  182. package/libs/css/common.scss +0 -0
  183. package/libs/css/iconfont.css +379 -0
  184. package/libs/css/iconfont.ttf +0 -0
  185. package/libs/css/mixin.scss +15 -0
  186. package/package.json +42 -0
  187. package/public/icons/error.png +0 -0
  188. package/public/icons/success.png +0 -0
  189. package/public/icons/warning.png +0 -0
  190. package/store/index.ts +1 -0
  191. package/store/userInfo.ts +25 -0
  192. package/theme.scss +94 -0
  193. package/typing/index.ts +7 -0
  194. package/typing/modules/common.d.ts +50 -0
  195. package/typing/modules/dialog.ts +17 -0
  196. package/typing/modules/enum.ts +67 -0
  197. package/typing/modules/form.ts +161 -0
  198. package/typing/modules/http.ts +68 -0
  199. package/typing/modules/icon.d.ts +366 -0
  200. package/typing/modules/img.ts +15 -0
  201. package/typing/modules/rect.ts +10 -0
  202. package/utils/address.json +5890 -0
  203. package/utils/base64.ts +119 -0
  204. package/utils/index.ts +3 -0
  205. package/utils/inside.ts +310 -0
  206. package/utils/utils.ts +446 -0
@@ -0,0 +1,59 @@
1
+ import { CSSProperties } from "vue";
2
+ import { CellContentVo } from "../hy-cell/typing";
3
+
4
+ export interface PanelVo extends CellContentVo {
5
+ /**
6
+ * @description 是否展示
7
+ * */
8
+ spread?: boolean;
9
+ /**
10
+ * @description 展示面板里自定义值
11
+ * */
12
+ content?: string;
13
+ }
14
+ export default interface IProps {
15
+ /**
16
+ * @description 数据集
17
+ * */
18
+ list: PanelVo[];
19
+ /**
20
+ * @description 是否手风琴模式( 默认 false )
21
+ * */
22
+ accordion?: boolean;
23
+ /**
24
+ * @description 头部标题
25
+ * */
26
+ title?: string;
27
+ /**
28
+ * @description 是否显示头部底部边框
29
+ * */
30
+ titleBorder?: boolean;
31
+ /**
32
+ * @description 是否显示cell下边框 (默认 true )
33
+ * */
34
+ border?: boolean;
35
+ /**
36
+ * @description 标题前缀竖线颜色
37
+ * */
38
+ verticalColor?: string;
39
+ /**
40
+ * @description 是否显示标题前缀竖线
41
+ * */
42
+ showVertical?: boolean;
43
+ /**
44
+ * @description 是否禁用(默认false)
45
+ * */
46
+ disabled?: boolean;
47
+ /**
48
+ * @description 单元的大小,可选值为 large,medium,small
49
+ * */
50
+ size?: HyApp.SizeType;
51
+ /**
52
+ * @description 内容面板高度
53
+ * */
54
+ contentHeight?: string | number;
55
+ /**
56
+ * @description 定义需要用到的外部样式
57
+ * */
58
+ customStyle?: CSSProperties;
59
+ }
@@ -0,0 +1,372 @@
1
+ <template>
2
+ <view class="hy-form">
3
+ <view class="hy-form--item" v-for="item in columns" :key="item.field">
4
+ <view v-if="item.label" class="hy-form--item__label" :style="labelStyle">
5
+ <text
6
+ v-if="isRequired(item.rules)"
7
+ style="color: red; font-size: 20px; line-height: 10px"
8
+ >*</text
9
+ >{{ item.label }} <text>:</text>
10
+ </view>
11
+ <view class="hy-form--item__container">
12
+ <view class="hy-form--item__container-content">
13
+ <!-- 输入框 -->
14
+ <view
15
+ class="flex"
16
+ v-if="
17
+ item.type === FormTypeEnum.TEXT ||
18
+ item.type === FormTypeEnum.NUMBER ||
19
+ item.type === FormTypeEnum.PASSWORD
20
+ "
21
+ >
22
+ <HyInput
23
+ v-model="formData[item.field]"
24
+ :type="item.type"
25
+ :placeholder="item.placeholder"
26
+ :disabled="disabled || item.disabled"
27
+ :clearable="item.clearable"
28
+ :readonly="item.readonly"
29
+ :shape="shape || item.shape"
30
+ :border="border || item.border"
31
+ :customStyle="errorStyle(!!errors[item.field])"
32
+ @change="handleChange($event, item)"
33
+ @blur="handleBlur($event, item)"
34
+ ></HyInput>
35
+ </view>
36
+ <!-- 输入框 -->
37
+
38
+ <!-- 上传 -->
39
+ <template v-if="item.type === FormTypeEnum.UPLOAD">
40
+ <HyUpload
41
+ :fileList="formData[item.field]"
42
+ :maxCount="item.maxCount"
43
+ :disabled="item.disabled"
44
+ />
45
+ </template>
46
+ <!-- 上传 -->
47
+
48
+ <!-- 详情 -->
49
+ <template v-if="item.type === FormTypeEnum.DETAIL">
50
+ <view class="detail">
51
+ {{ formData[item.field] }}
52
+ </view>
53
+ </template>
54
+ <!-- 详情 -->
55
+
56
+ <!-- 文本域 -->
57
+ <view class="flex" v-if="item.type === FormTypeEnum.TEXTAREA">
58
+ <HyTextarea
59
+ v-model="formData[item.field]"
60
+ :disabled="disabled || item.disabled"
61
+ :placeholder="item.placeholder"
62
+ :clearable="item.clearable"
63
+ :readonly="item.readonly"
64
+ :shape="shape || item.shape"
65
+ :border="border || item.border"
66
+ :customStyle="errorStyle(!!errors[item.field])"
67
+ @change="handleChange($event, item)"
68
+ @blur="handleBlur($event, item)"
69
+ ></HyTextarea>
70
+ </view>
71
+ <!-- 文本域 -->
72
+
73
+ <!-- 单选框 -->
74
+ <template v-if="item.type === 'radio'">
75
+ <HyRadio
76
+ v-model="formData[item.field]"
77
+ :disabled="disabled || item.disabled"
78
+ :columns="item.actions"
79
+ ></HyRadio>
80
+ </template>
81
+ <!-- 单选框 -->
82
+
83
+ <!-- 开关 -->
84
+ <template v-if="item.type === FormTypeEnum.SWITCH">
85
+ <HySwitch
86
+ v-model="formData[item.field]"
87
+ :disabled="disabled || item.disabled"
88
+ ></HySwitch>
89
+ </template>
90
+ <!-- 开关 -->
91
+
92
+ <!-- 自定义选择器 -->
93
+ <template v-if="item.type === FormTypeEnum.SELECT">
94
+ <HyPicker
95
+ v-model="formData[item.field]"
96
+ :columns="item.select"
97
+ has-input
98
+ :disabled="disabled || item.disabled"
99
+ :placeholder="item.placeholder"
100
+ :shape="shape || item.shape"
101
+ :border="border || item.border"
102
+ :customStyle="errorStyle(!!errors[item.field])"
103
+ ></HyPicker>
104
+ </template>
105
+ <!-- 自定义选择器 -->
106
+
107
+ <!-- 时间选择器 -->
108
+ <template v-if="item.type === FormTypeEnum.DATE">
109
+ <HyDatetimePicker
110
+ v-model="formData[item.field]"
111
+ has-input
112
+ :mode="item.mode"
113
+ :disabled="disabled || item.disabled"
114
+ :placeholder="item.placeholder"
115
+ :shape="shape || item.shape"
116
+ :border="border || item.border"
117
+ :customStyle="errorStyle(!!errors[item.field])"
118
+ ></HyDatetimePicker>
119
+ </template>
120
+ <!-- 时间选择器 -->
121
+
122
+ <!-- 地址选择器 -->
123
+ <template v-if="item.type === FormTypeEnum.ADDRESS">
124
+ <HyAddressPicker
125
+ v-model="formData[item.field]"
126
+ has-input
127
+ :disabled="disabled || item.disabled"
128
+ :placeholder="item.placeholder"
129
+ :shape="shape || item.shape"
130
+ :border="border || item.border"
131
+ :customStyle="errorStyle(!!errors[item.field])"
132
+ ></HyAddressPicker>
133
+ </template>
134
+ <!-- 地址选择器 -->
135
+
136
+ <!-- 自定义插槽 -->
137
+ <view class="flex" v-if="item.type === FormTypeEnum.CUSTOM">
138
+ <slot
139
+ :name="item.field"
140
+ :record="item"
141
+ :errorStyle="errorStyle(!!errors[item.field])"
142
+ ></slot>
143
+ </view>
144
+ <!-- 自定义插槽 -->
145
+ </view>
146
+
147
+ <!-- 提示信息 -->
148
+ <HyTransition :show="!!errors[item.field]" mode="slide-left">
149
+ <view class="hy-form--item__container-warning">{{
150
+ errors[item.field]
151
+ }}</view>
152
+ </HyTransition>
153
+ <!-- 提示信息 -->
154
+ </view>
155
+ </view>
156
+ </view>
157
+ </template>
158
+
159
+ <script setup lang="ts">
160
+ import { computed, CSSProperties, reactive, toRefs } from "vue";
161
+ import IProps from "./typing";
162
+ import defaultProps from "./props";
163
+ import { addUnit, error } from "../../utils";
164
+ import { FormColumnsType, RulesVo, FormTypeEnum } from "../../typing";
165
+
166
+ // 组件
167
+ import HyInput from "../hy-input/hy-input.vue";
168
+ import HyPicker from "../hy-picker/hy-picker.vue";
169
+ import HyUpload from "../hy-upload/hy-upload.vue";
170
+ import HyTextarea from "../hy-textarea/hy-textarea.vue";
171
+ import HySwitch from "../hy-switch/hy-switch.vue";
172
+ import HyRadio from "../hy-radio/hy-radio.vue";
173
+ import HyDatetimePicker from "../hy-datetime-picker/hy-datetime-picker.vue";
174
+ import HyAddressPicker from "../hy-address-picker/hy-address-picker.vue";
175
+ import HyTransition from "../hy-transition/hy-transition.vue";
176
+
177
+ const props = withDefaults(defineProps<IProps>(), defaultProps);
178
+ const { formData, columns, labelWidth, labelAlign, labelPosition } =
179
+ toRefs(props);
180
+ const emit = defineEmits(["click"]);
181
+
182
+ const labelPos = labelPosition.value === "top" ? "column" : "row";
183
+
184
+ /**
185
+ * @description 错误输入框样式
186
+ * */
187
+ const errorStyle = computed(() => {
188
+ return (err: boolean) => {
189
+ const style: CSSProperties = {};
190
+ if (err) {
191
+ style.background = "#FFF2F0";
192
+ }
193
+
194
+ return style;
195
+ };
196
+ });
197
+
198
+ const isRequired = computed(() => {
199
+ return (temp: any) => {
200
+ if (Array.isArray(temp)) {
201
+ return temp.some((item) => item?.required);
202
+ } else {
203
+ return temp?.required;
204
+ }
205
+ };
206
+ });
207
+
208
+ const errors: AnyObject = reactive({});
209
+
210
+ /**
211
+ * @description 标题行内样式
212
+ * */
213
+ const labelStyle = computed(() => {
214
+ return {
215
+ textAlign: labelAlign.value,
216
+ width: addUnit(labelWidth.value)
217
+ };
218
+ });
219
+
220
+ /**
221
+ * @description 错误信息校验
222
+ * */
223
+ const errorMsg = (rule: RulesVo, value: string): string => {
224
+ // 手机正则
225
+ const phoneExpression = /^1[3-9]\d{9}$/;
226
+ // 邮箱正则
227
+ const emitExpression = /^[a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,6}$/;
228
+ // 复杂密码正则
229
+ const passwordExpression =
230
+ /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[!@#$%^&*()_+\-=\[\]{};':"\\|,.<>\/?]).{8,}$/;
231
+ if (rule.required && !value) {
232
+ return rule.message!;
233
+ } else if (
234
+ (rule?.min || rule?.max) &&
235
+ (value.length < rule?.min! || value.length > rule?.max!)
236
+ ) {
237
+ return rule.message!;
238
+ } else if (rule.type === "phone" && !phoneExpression.test(String(value))) {
239
+ return rule.message || "请输入正确的手机号";
240
+ } else if (rule.type === "email" && !emitExpression.test(String(value))) {
241
+ return rule.message || "请输入正确的邮箱格式";
242
+ } else if (
243
+ rule.type === "password" &&
244
+ !passwordExpression.test(String(value))
245
+ ) {
246
+ return (
247
+ rule.message || "至少8个字符串,并且包含大、小写字母、数字和特殊符号"
248
+ );
249
+ } else if (rule?.validator && !rule.validator(rule, value)) {
250
+ return rule.message || "";
251
+ } else {
252
+ return "";
253
+ }
254
+ };
255
+
256
+ /**
257
+ * @description 校验字段
258
+ * */
259
+ const validateField = (
260
+ rules: RulesVo | RulesVo[] | undefined,
261
+ value: string,
262
+ field: string,
263
+ event?: "blur" | "change"
264
+ ) => {
265
+ if (!rules) return;
266
+
267
+ let errorMessage = "";
268
+
269
+ if (Array.isArray(rules)) {
270
+ // 遍历所有规则
271
+ for (const index in rules) {
272
+ // 判断是否有change事件或者blur事件
273
+ if (event && !rules[index]?.trigger?.includes(event)) continue;
274
+ errorMessage = errorMsg(rules[index], value);
275
+ if (errorMessage) {
276
+ errors[field] = errorMessage;
277
+ return;
278
+ }
279
+ // 可以继续添加更多规则
280
+ }
281
+ } else {
282
+ // 必填校验
283
+ if (event && !rules?.trigger?.includes(event)) return;
284
+ errorMessage = errorMsg(rules, value);
285
+ }
286
+
287
+ // 自定义校验规则
288
+ // if (rules.custom) {
289
+ // const customError = rules.custom(value);
290
+ // if (customError) {
291
+ // errorMessage = customError;
292
+ // }
293
+ // }
294
+
295
+ errors[field] = errorMessage;
296
+ };
297
+
298
+ /**
299
+ * @description 提交表单
300
+ * */
301
+ const handleSubmit = () => {
302
+ return new Promise((resolve, reject) => {
303
+ let isValid = true;
304
+
305
+ // 校验所有字段
306
+ props.columns.forEach((col) => {
307
+ validateField(col.rules, formData.value[col.field], col.field);
308
+ if (errors[col.field]) {
309
+ isValid = false;
310
+ }
311
+ });
312
+
313
+ if (isValid) {
314
+ // alert("表单提交成功!");
315
+ resolve(formData.value);
316
+ } else {
317
+ reject();
318
+ error("表单校验失败,请检查输入!");
319
+ }
320
+ });
321
+ };
322
+
323
+ /**
324
+ * @description 输入值触发
325
+ * */
326
+ const handleChange = (event: string, temp: FormColumnsType) => {
327
+ validateField(temp.rules, event, temp.field, "change");
328
+ };
329
+ /**
330
+ * @description 输入值触发
331
+ * */
332
+ const handleBlur = (event: string, temp: FormColumnsType) => {
333
+ validateField(temp.rules, event, temp.field, "blur");
334
+ };
335
+
336
+ defineExpose({
337
+ validateField,
338
+ handleSubmit
339
+ });
340
+ </script>
341
+
342
+ <style lang="scss" scoped>
343
+ @import "../../theme.scss";
344
+ .hy-form {
345
+ &--item {
346
+ display: flex;
347
+ flex-direction: v-bind(labelPos);
348
+ //align-items: center;
349
+ margin-bottom: $hy-border-margin-padding-lg;
350
+ &__label {
351
+ padding: $hy-border-margin-padding-base 0;
352
+ }
353
+ &__container {
354
+ flex: 1;
355
+ display: flex;
356
+ flex-direction: column;
357
+ &-content {
358
+ flex: 1;
359
+ display: flex;
360
+ align-items: center;
361
+ .flex {
362
+ flex: 1;
363
+ }
364
+ }
365
+ &-warning {
366
+ color: $hy-error;
367
+ font-size: $hy-font-size-hint;
368
+ }
369
+ }
370
+ }
371
+ }
372
+ </style>
@@ -0,0 +1,15 @@
1
+ import IProps from "./typing";
2
+
3
+ const defaultProps: IProps = {
4
+ labelPosition: "left",
5
+ labelWidth: "auto",
6
+ labelAlign: "left",
7
+ right: false,
8
+ itemHeight: 40,
9
+ shape: "square",
10
+ border: "surround",
11
+ columns: [],
12
+ formData: {}
13
+ };
14
+
15
+ export default defaultProps;
@@ -0,0 +1,51 @@
1
+ import { FormColumnsType } from "../../typing";
2
+
3
+ export default interface IProps {
4
+ /**
5
+ * @description 表单域提示文字的位置
6
+ * left - 左侧
7
+ * top - 上方
8
+ * */
9
+ labelPosition?: "left" | "top";
10
+ /**
11
+ * @description label宽度
12
+ * 数字 - 固定值
13
+ * auto - 自适应
14
+ * */
15
+ labelWidth?: string | number;
16
+ /**
17
+ * @description 是否右对齐
18
+ * */
19
+ right?: boolean;
20
+ /**
21
+ * @description label字体的对齐方式
22
+ * left - 左对齐
23
+ * center - 中间对齐
24
+ * right - 右对齐
25
+ * */
26
+ labelAlign?: HyApp.LeftRightType | "center";
27
+ /**
28
+ * @description 当行内容高度
29
+ * */
30
+ itemHeight?: number | string;
31
+ /**
32
+ * @description 是否全部禁用
33
+ * */
34
+ disabled?: boolean;
35
+ /**
36
+ * @description 输入框形状
37
+ * */
38
+ shape?: HyApp.ShapeType;
39
+ /**
40
+ * @description 输入框边框
41
+ * */
42
+ border?: HyApp.BorderType;
43
+ /**
44
+ * @description 表单配置
45
+ * */
46
+ columns: FormColumnsType[];
47
+ /**
48
+ * @description 表单值
49
+ * */
50
+ formData: Record<string, any>;
51
+ }
@@ -0,0 +1,126 @@
1
+ <template>
2
+ <view class="hy-grid" ref="hy-grid" :style="gridStyle">
3
+ <template v-for="item in list">
4
+ <view
5
+ class="hy-grid-item"
6
+ hover-class="hy-grid-item--hover-class"
7
+ :hover-stay-time="200"
8
+ @tap="childClick(item)"
9
+ :style="itemStyle"
10
+ >
11
+ <slot :record="item">
12
+ <HyIcon
13
+ :name="item.icon"
14
+ :size="iconSize"
15
+ :round="round"
16
+ label-pos="bottom"
17
+ :space="space"
18
+ :label="item.name"
19
+ ></HyIcon>
20
+ <!-- <view class="hy-grid-item__title">{{ item.name }}</view>-->
21
+ </slot>
22
+ </view>
23
+ </template>
24
+ </view>
25
+ </template>
26
+
27
+ <script setup lang="ts">
28
+ import { computed, CSSProperties, toRefs } from "vue";
29
+ import defaultProps from "./props";
30
+ import IProps from "./typing";
31
+ import { addUnit } from "../../utils";
32
+
33
+ // 组件
34
+ import HyIcon from "../hy-icon/hy-icon.vue";
35
+
36
+ const props = withDefaults(defineProps<IProps>(), defaultProps);
37
+ const { align, customStyle, bgColor, itemHeight, border } = toRefs(props);
38
+ const emit = defineEmits(["click"]);
39
+
40
+ /**
41
+ * @description 宫格对齐方式
42
+ * */
43
+ const gridStyle = computed<CSSProperties>(() => {
44
+ let style: CSSProperties = {};
45
+ switch (align.value) {
46
+ case "left":
47
+ style.justifyContent = "flex-start";
48
+ break;
49
+ case "center":
50
+ style.justifyContent = "center";
51
+ break;
52
+ case "right":
53
+ style.justifyContent = "flex-end";
54
+ break;
55
+ default:
56
+ style.justifyContent = "flex-start";
57
+ }
58
+ return Object.assign(style, customStyle.value || {});
59
+ });
60
+
61
+ const itemStyle = computed<CSSProperties>(() => {
62
+ const style: CSSProperties = {
63
+ background: bgColor.value,
64
+ height: addUnit(itemHeight.value),
65
+ width: "100%",
66
+ border: border.value ? "0.5px solid #c8c7cc66" : ""
67
+ };
68
+ return style;
69
+ });
70
+
71
+ /**
72
+ * @description 点击事件
73
+ * */
74
+ const childClick = (name: string | Record<string, any>) => {
75
+ emit("click", name);
76
+ };
77
+ </script>
78
+
79
+ <style lang="scss" scoped>
80
+ @import "../../libs/css/mixin.scss";
81
+ @import "../../theme.scss";
82
+ .hy-grid {
83
+ /* #ifdef APP-NVUE */
84
+ position: relative;
85
+ box-sizing: border-box;
86
+ overflow: hidden;
87
+ display: block;
88
+ /* #endif */
89
+ justify-content: center;
90
+ @include flex;
91
+ flex-wrap: wrap;
92
+ align-items: center;
93
+ // 在uni-app中应尽量避免使用flex布局以外的方式,因为nvue/uvue等方案都支持flex布局
94
+ // 这里使用grid布局使用为目前20240409uni-app在抖音小程序开启virtualHost时有bug,存在事件失效问题。
95
+ /* #ifndef APP-NVUE */
96
+ display: grid;
97
+ grid-gap: v-bind(gap);
98
+ grid-template-columns: repeat(v-bind(col), 1fr);
99
+ /* #endif */
100
+ &-item {
101
+ align-items: center;
102
+ justify-content: center;
103
+ position: relative;
104
+ flex-direction: column;
105
+ /* #ifndef APP-NVUE */
106
+ box-sizing: border-box;
107
+ display: flex;
108
+ /* #endif */
109
+
110
+ /* #ifdef MP */
111
+ position: relative;
112
+ float: left;
113
+ /* #endif */
114
+
115
+ &--hover-class {
116
+ opacity: 0.7;
117
+ }
118
+
119
+ &__title {
120
+ color: #000;
121
+ line-height: 60rpx;
122
+ font-size: $hy-font-size-sm;
123
+ }
124
+ }
125
+ }
126
+ </style>
@@ -0,0 +1,16 @@
1
+ import IProps from "./typing";
2
+
3
+ const defaultProps: IProps = {
4
+ list: [],
5
+ col: 4,
6
+ border: false,
7
+ itemHeight: "100px",
8
+ align: "left",
9
+ gap: "0px",
10
+ bgColor: "transparent",
11
+ iconSize: "50px",
12
+ round: "6px",
13
+ space: "12px"
14
+ };
15
+
16
+ export default defaultProps;
@@ -0,0 +1,62 @@
1
+ import { CSSProperties } from "vue";
2
+
3
+ interface GridItem {
4
+ /**
5
+ * @description 图片或者icon
6
+ * */
7
+ icon: string;
8
+ /**
9
+ * @description 名称
10
+ * */
11
+ name: string;
12
+ /**
13
+ * @description 自定义内容键值对
14
+ * */
15
+ [key: string]: any;
16
+ }
17
+ export default interface IProps {
18
+ /**
19
+ * @description 数据集
20
+ * */
21
+ list: GridItem[];
22
+ /**
23
+ * @description 宫格的列数(默认 3 )
24
+ * */
25
+ col?: number;
26
+ /**
27
+ * @description 是否显示宫格的边框(默认 false )
28
+ * */
29
+ border?: boolean;
30
+ /**
31
+ * @description 单个宫格高度(默认 60px )
32
+ * */
33
+ itemHeight?: number | string;
34
+ /**
35
+ * @description 宫格对齐方式,表现为数量少的时候,靠左,居中,还是靠右 (默认 'left' )
36
+ * */
37
+ align?: "center" | HyApp.LeftRightType;
38
+ /**
39
+ * @description 间隔(默认 0px)
40
+ * */
41
+ gap?: number | string;
42
+ /**
43
+ * @description 宫格的背景颜色 (默认 'transparent' )
44
+ * */
45
+ bgColor?: string;
46
+ /**
47
+ * @description icon图片大小
48
+ * */
49
+ iconSize?: number | string;
50
+ /**
51
+ * @description icon图片圆角
52
+ * */
53
+ round: number | string;
54
+ /**
55
+ * @description icon图片和文字间距
56
+ * */
57
+ space: number | string;
58
+ /**
59
+ * @description 定义需要用到的外部样式
60
+ * */
61
+ customStyle?: CSSProperties;
62
+ }