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,262 @@
1
+ <template>
2
+ <view class="u-datetime-picker">
3
+ <view
4
+ v-if="hasInput"
5
+ class="u-datetime-picker__has-input"
6
+ @click="onShowByClickInput"
7
+ >
8
+ <slot name="trigger" :value="inputValue">
9
+ <HyInput
10
+ :placeholder="placeholder"
11
+ :readonly="!!showByClickInput"
12
+ v-model="inputValue"
13
+ :disabled="disabled"
14
+ :shape="shape"
15
+ :border="border"
16
+ :disabledColor="disabledColor"
17
+ :customStyle="customStyle"
18
+ ></HyInput>
19
+ <view class="input-cover"></view>
20
+ </slot>
21
+ </view>
22
+ <HyPicker
23
+ ref="uPickerRef"
24
+ :show="show || (hasInput && showByClickInput)"
25
+ :popupMode="popupMode"
26
+ :closeOnClickOverlay="closeOnClickOverlay"
27
+ :columns="columns"
28
+ :defaultIndex="defaultIndex"
29
+ :title="title"
30
+ keyName="name"
31
+ :itemHeight="itemHeight"
32
+ :loading="loading"
33
+ :showToolbar="showToolbar"
34
+ :visibleItemCount="visibleItemCount"
35
+ :cancelText="cancelText"
36
+ :cancelColor="cancelColor"
37
+ :confirmColor="confirmColor"
38
+ :toolbarRightSlot="toolbarRightSlot"
39
+ @close="close"
40
+ @cancel="cancel"
41
+ @confirm="confirm"
42
+ @change="change"
43
+ >
44
+ <template #toolbar-right>
45
+ <slot name="toolbar-right">
46
+ {{ confirmText }}
47
+ </slot>
48
+ </template>
49
+ <template #toolbar-bottom>
50
+ <slot name="toolbar-bottom"> </slot>
51
+ </template>
52
+ </HyPicker>
53
+
54
+ <HyList container-height="" list=""></HyList>
55
+ </view>
56
+ </template>
57
+
58
+ <script setup lang="ts">
59
+ import { onMounted, ref, toRefs } from "vue";
60
+ import defaultProps from "./props";
61
+ import IProps from "./typing";
62
+ import address from "../../utils/address.json";
63
+
64
+ // 组件
65
+ import HyInput from "../hy-input/hy-input.vue";
66
+ import HyPicker from "../hy-picker/hy-picker.vue";
67
+
68
+ const props = withDefaults(defineProps<IProps>(), defaultProps);
69
+ const { show, modelValue, hasInput, disabled, separator, closeOnClickOverlay } =
70
+ toRefs(props);
71
+ const emit = defineEmits([
72
+ "close",
73
+ "cancel",
74
+ "confirm",
75
+ "change",
76
+ "update:modelValue"
77
+ ]);
78
+
79
+ // 原来的日期选择器不方便,这里增加一个hasInput选项支持类似element的自带输入框的功能。
80
+ const inputValue = ref<string>(""); // 表单显示值
81
+ const showByClickInput = ref<boolean>(false); // 是否在hasInput模式下显示日期选择弹唱
82
+ const columns = ref<any[]>([]);
83
+ const uPickerRef = ref<InstanceType<typeof HyPicker> | null>();
84
+ const defaultIndex = ref<number[]>([]);
85
+
86
+ function normalizeCityName(city: string) {
87
+ // 定义常见的后缀
88
+ const suffixes = ["市", "省", "自治区", "特别行政区", "县", "区"];
89
+ suffixes.forEach((suffix) => {
90
+ if (city.endsWith(suffix)) {
91
+ city = city.slice(0, -suffix.length);
92
+ }
93
+ });
94
+ return city;
95
+ }
96
+ /**
97
+ * @description 判断城市是否相等
98
+ * */
99
+ const areCitiesEqual = (city1: string, city2: string) => {
100
+ const normalizedCity1 = normalizeCityName(city1);
101
+ const normalizedCity2 = normalizeCityName(city2);
102
+ return normalizedCity1 === normalizedCity2;
103
+ };
104
+ /**
105
+ * @description 更新各列的值
106
+ * */
107
+ const updateColumnValue = (value: string) => {
108
+ let provinceIndex, cityIndex, countyIndex;
109
+ // 判断是初始化有数据就找到对应索引,无数据默认索引为0
110
+ if (value) {
111
+ const addressArr = value.split(separator.value);
112
+ // 查出省索引
113
+ provinceIndex = address.findIndex((item) =>
114
+ areCitiesEqual(item.name, addressArr[0])
115
+ );
116
+ // 查出市索引
117
+ cityIndex = address[provinceIndex].areas.findIndex((item) =>
118
+ areCitiesEqual(item.name, addressArr[1])
119
+ );
120
+
121
+ // 查出县/区索引
122
+ countyIndex = address[provinceIndex].areas[cityIndex].areas.findIndex(
123
+ (item) => areCitiesEqual(item.name, addressArr[2])
124
+ );
125
+ } else {
126
+ provinceIndex = 0;
127
+ cityIndex = 0;
128
+ countyIndex = 0;
129
+ }
130
+ // 省级数组
131
+ const provinceData = address.map((item) => ({
132
+ name: item.name,
133
+ code: item.code
134
+ }));
135
+ // 市级数组
136
+ const cityData = address[provinceIndex].areas.map((item) => ({
137
+ name: item.name,
138
+ code: item.code
139
+ }));
140
+ // 县/区级数组
141
+ const areaData = address[provinceIndex].areas[cityIndex].areas;
142
+
143
+ // 默认索引
144
+ defaultIndex.value = [provinceIndex, cityIndex, countyIndex];
145
+ // 列表
146
+ columns.value = [provinceData, cityData, areaData];
147
+ };
148
+
149
+ const init = () => {
150
+ // 获取当前值
151
+ inputValue.value = modelValue.value;
152
+ // 更新列表
153
+ updateColumnValue(modelValue.value);
154
+ };
155
+
156
+ onMounted(() => {
157
+ init();
158
+ });
159
+
160
+ /**
161
+ * @description 关闭选择器
162
+ * */
163
+ const close = () => {
164
+ if (closeOnClickOverlay.value) {
165
+ if (hasInput.value) {
166
+ showByClickInput.value = false;
167
+ }
168
+ emit("close");
169
+ }
170
+ };
171
+
172
+ /**
173
+ * @description 点击工具栏的取消按钮
174
+ * */
175
+ const cancel = () => {
176
+ if (hasInput.value) {
177
+ showByClickInput.value = false;
178
+ }
179
+ emit("cancel");
180
+ };
181
+
182
+ /**
183
+ * @description 点击工具栏的确定按钮
184
+ * */
185
+ const confirm = ({ value }: { value: Record<string, any>[] }) => {
186
+ inputValue.value = value.map((item) => item.name).join(separator.value);
187
+
188
+ showByClickInput.value = false;
189
+ emit("update:modelValue", inputValue.value);
190
+ emit("confirm", {
191
+ value: inputValue.value
192
+ });
193
+ };
194
+
195
+ /**
196
+ * @description 列发生变化时触发
197
+ * */
198
+ const change = (e: any) => {
199
+ const { columnIndex, index, indexs } = e;
200
+ //如果改变的是第一列
201
+ if (columnIndex === 0) {
202
+ const children1 = address[index].areas.map((item) => {
203
+ return { name: item.name, code: item.code };
204
+ });
205
+ uPickerRef.value?.setColumnValues(1, children1);
206
+ //更换 第二列数据
207
+ const children2 = address[index].areas[indexs[1]].areas.map((item) => ({
208
+ ...item
209
+ }));
210
+ uPickerRef.value?.setColumnValues(2, children2);
211
+ //更换 第三列数据
212
+ }
213
+ if (columnIndex === 1) {
214
+ //如果改变的是第二列
215
+ const children3 = address[indexs[0]].areas[indexs[1]].areas.map((item) => ({
216
+ ...item
217
+ }));
218
+ uPickerRef.value?.setColumnValues(2, children3);
219
+ }
220
+
221
+ // 发出change时间,value为当前选中的时间戳
222
+ emit("change", {
223
+ ...e
224
+ });
225
+ };
226
+
227
+ const onShowByClickInput = () => {
228
+ if (!disabled.value) {
229
+ showByClickInput.value = !showByClickInput.value;
230
+ }
231
+ };
232
+ </script>
233
+
234
+ <style lang="scss" scoped>
235
+ @import "../../libs/css/mixin.scss";
236
+ .hy-datetime-picker {
237
+ flex: 1;
238
+ &__has-input {
239
+ position: relative;
240
+ display: flex;
241
+ flex-direction: column;
242
+ justify-content: center;
243
+ /* #ifndef APP-NVUE */
244
+ width: 100%;
245
+ /* #endif */
246
+ .input-cover {
247
+ opacity: 0;
248
+ position: absolute;
249
+ top: 0;
250
+ bottom: 0;
251
+ left: 0;
252
+ right: 0;
253
+ display: flex;
254
+ flex-direction: column;
255
+ justify-content: center;
256
+ border-radius: 4px;
257
+ border: 1px solid #eee;
258
+ padding: 0 10px;
259
+ }
260
+ }
261
+ }
262
+ </style>
@@ -0,0 +1,27 @@
1
+ import IProps from "./typing";
2
+ import { DateModeEnum } from "../../typing";
3
+
4
+ const defaultProps: IProps = {
5
+ show: false,
6
+ popupMode: "bottom",
7
+ showToolbar: true,
8
+ modelValue: "",
9
+ title: "",
10
+ separator: " ",
11
+ loading: false,
12
+ itemHeight: 44,
13
+ cancelText: "取消",
14
+ confirmText: "确认",
15
+ cancelColor: "#909193",
16
+ confirmColor: "#3c9cff",
17
+ visibleItemCount: 5,
18
+ closeOnClickOverlay: false,
19
+ defaultIndex: [],
20
+ disabled: false,
21
+ hasInput: false,
22
+ placeholder: "请选择地址",
23
+ disabledColor: "#F5F5F5",
24
+ toolbarRightSlot: false
25
+ };
26
+
27
+ export default defaultProps;
@@ -0,0 +1,98 @@
1
+ import { DateModeEnum } from "../../typing";
2
+ import { CSSProperties } from "vue";
3
+
4
+ export default interface IProps {
5
+ /**
6
+ * @description 用于控制选择器的弹出和收起 ( 默认 false )
7
+ * */
8
+ show?: boolean;
9
+ /**
10
+ * @description 弹出层弹出方向
11
+ * */
12
+ popupMode?: HyApp.LayoutType;
13
+ /**
14
+ * @description 是否显示顶部的操作栏 ( 默认 true )
15
+ * */
16
+ showToolbar?: boolean;
17
+ /**
18
+ * @description 绑定值
19
+ * */
20
+ modelValue: string;
21
+ /**
22
+ * @description 顶部标题
23
+ * */
24
+ title?: string;
25
+ /**
26
+ * @description 字符串截取数组条件
27
+ * */
28
+ separator?: string;
29
+ /**
30
+ * @description 是否显示加载中状态 ( 默认 false )
31
+ * */
32
+ loading?: boolean;
33
+ /**
34
+ * @description 各列中,单个选项的高度 ( 默认 44 )
35
+ * */
36
+ itemHeight?: number;
37
+ /**
38
+ * @description 取消按钮的文字 ( 默认 '取消' )
39
+ * */
40
+ cancelText?: string;
41
+ /**
42
+ * @description 确认按钮的文字 ( 默认 '确认' )
43
+ * */
44
+ confirmText?: string;
45
+ /**
46
+ * @description 取消按钮的颜色 ( 默认 '#909193' )
47
+ * */
48
+ cancelColor?: string;
49
+ /**
50
+ * @description 确认按钮的颜色 ( 默认 '#3c9cff' )
51
+ * */
52
+ confirmColor?: string;
53
+ /**
54
+ * @description 每列中可见选项的数量 ( 默认 5 )
55
+ * */
56
+ visibleItemCount?: number;
57
+ /**
58
+ * @description 是否允许点击遮罩关闭选择器 ( 默认 false )
59
+ * */
60
+ closeOnClickOverlay?: boolean;
61
+ /**
62
+ * @description 各列的默认索引
63
+ * @note 类型有问题,需要调整
64
+ * */
65
+ defaultIndex?: Array<any>;
66
+ /**
67
+ * @description 是否禁用输入框 ( 默认 false )
68
+ * */
69
+ disabled?: boolean;
70
+ /**
71
+ * @description 输入框是否显示边框 ( 默认 false )
72
+ * */
73
+ hasInput?: boolean;
74
+ /**
75
+ * @description 输入框提示信息
76
+ * */
77
+ placeholder?: string;
78
+ /**
79
+ * @description 禁用时候输入框颜色
80
+ * */
81
+ disabledColor?: string;
82
+ /**
83
+ * @description 右边插槽
84
+ * */
85
+ toolbarRightSlot?: boolean;
86
+ /**
87
+ * @description 输入框形状
88
+ * */
89
+ shape?: HyApp.ShapeType;
90
+ /**
91
+ * @description 输入框边框
92
+ * */
93
+ border?: HyApp.BorderType;
94
+ /**
95
+ * @description 自定义输入框外部样式
96
+ * */
97
+ customStyle?: CSSProperties;
98
+ }
@@ -0,0 +1,217 @@
1
+ <template>
2
+ <view
3
+ class="hy-avatar"
4
+ :class="avatarClass"
5
+ :style="avatarStyle"
6
+ @tap="clickHandler"
7
+ >
8
+ <slot>
9
+ <!-- #ifdef MP-WEIXIN || MP-QQ || MP-BAIDU -->
10
+ <open-data
11
+ v-if="mpAvatar && allowMp"
12
+ type="userAvatarUrl"
13
+ :style="[
14
+ {
15
+ width: addUnit(size),
16
+ height: addUnit(size)
17
+ }
18
+ ]"
19
+ />
20
+ <!-- #endif -->
21
+ <!-- #ifndef MP-WEIXIN && MP-QQ && MP-BAIDU -->
22
+ <template v-if="mpAvatar && allowMp"></template>
23
+ <!-- #endif -->
24
+ <HyIcon
25
+ v-else-if="icon"
26
+ :name="icon"
27
+ :size="fontSize"
28
+ :color="color"
29
+ ></HyIcon>
30
+ <text
31
+ v-else-if="text"
32
+ :style="{
33
+ justifyContent: 'center',
34
+ textAlign: 'center',
35
+ color: color,
36
+ fontSize: fontSize
37
+ }"
38
+ >{{ text }}</text
39
+ >
40
+ <image
41
+ class="hy-avatar__image"
42
+ v-else
43
+ :class="[`hy-avatar__image--${shape}`]"
44
+ :src="avatarUrl || defaultUrl"
45
+ :mode="mode"
46
+ @error="errorHandler"
47
+ ></image>
48
+ </slot>
49
+ </view>
50
+ </template>
51
+
52
+ <script setup lang="ts">
53
+ import { computed, CSSProperties, toRefs, ref, watch } from "vue";
54
+ import defaultProps from "./props";
55
+ import IProps from "./typing";
56
+ import { addUnit, random } from "../../utils";
57
+
58
+ // 组件
59
+ import HyIcon from "../hy-icon/hy-icon.vue";
60
+
61
+ const props = withDefaults(defineProps<IProps>(), defaultProps);
62
+ const {
63
+ src,
64
+ defaultUrl,
65
+ text,
66
+ icon,
67
+ randomBgColor,
68
+ colorIndex,
69
+ bgColor,
70
+ size,
71
+ shape,
72
+ name,
73
+ customStyle
74
+ } = toRefs(props);
75
+ const emit = defineEmits(["click"]);
76
+
77
+ const base64Avatar =
78
+ "data:image/jpg;base64,/9j/4QAYRXhpZgAASUkqAAgAAAAAAAAAAAAAAP/sABFEdWNreQABAAQAAAA8AAD/4QMraHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLwA8P3hwYWNrZXQgYmVnaW49Iu+7vyIgaWQ9Ilc1TTBNcENlaGlIenJlU3pOVGN6a2M5ZCI/PiA8eDp4bXBtZXRhIHhtbG5zOng9ImFkb2JlOm5zOm1ldGEvIiB4OnhtcHRrPSJBZG9iZSBYTVAgQ29yZSA1LjMtYzAxMSA2Ni4xNDU2NjEsIDIwMTIvMDIvMDYtMTQ6NTY6MjcgICAgICAgICI+IDxyZGY6UkRGIHhtbG5zOnJkZj0iaHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zIyI+IDxyZGY6RGVzY3JpcHRpb24gcmRmOmFib3V0PSIiIHhtbG5zOnhtcD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLyIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bXA6Q3JlYXRvclRvb2w9IkFkb2JlIFBob3Rvc2hvcCBDUzYgKFdpbmRvd3MpIiB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOjREMEQwRkY0RjgwNDExRUE5OTY2RDgxODY3NkJFODMxIiB4bXBNTTpEb2N1bWVudElEPSJ4bXAuZGlkOjREMEQwRkY1RjgwNDExRUE5OTY2RDgxODY3NkJFODMxIj4gPHhtcE1NOkRlcml2ZWRGcm9tIHN0UmVmOmluc3RhbmNlSUQ9InhtcC5paWQ6NEQwRDBGRjJGODA0MTFFQTk5NjZEODE4Njc2QkU4MzEiIHN0UmVmOmRvY3VtZW50SUQ9InhtcC5kaWQ6NEQwRDBGRjNGODA0MTFFQTk5NjZEODE4Njc2QkU4MzEiLz4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+IDw/eHBhY2tldCBlbmQ9InIiPz7/7gAOQWRvYmUAZMAAAAAB/9sAhAAGBAQEBQQGBQUGCQYFBgkLCAYG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";
79
+ // 如果配置randomBgColor参数为true,在图标或者文字的模式下,会随机从中取出一个颜色值当做背景色
80
+ const colors = ref<string[]>([
81
+ "#ffb34b",
82
+ "#f2bba9",
83
+ "#f7a196",
84
+ "#f18080",
85
+ "#88a867",
86
+ "#bfbf39",
87
+ "#89c152",
88
+ "#94d554",
89
+ "#f19ec2",
90
+ "#afaae4",
91
+ "#e1b0df",
92
+ "#c38cc1",
93
+ "#72dcdc",
94
+ "#9acdcb",
95
+ "#77b1cc",
96
+ "#448aca",
97
+ "#86cefa",
98
+ "#98d1ee",
99
+ "#73d1f1",
100
+ "#80a7dc"
101
+ ]);
102
+ const avatarUrl = ref(src.value);
103
+ const allowMp = ref<boolean>(false);
104
+
105
+ watch(
106
+ () => src.value,
107
+ (newVal) => {
108
+ avatarUrl.value = newVal;
109
+ // 如果没有传src,则主动触发error事件,用于显示默认的头像,否则src为''空字符等的时候,会无内容展示
110
+ if (!newVal) {
111
+ errorHandler();
112
+ }
113
+ },
114
+ { immediate: true }
115
+ );
116
+
117
+ const avatarStyle = computed<CSSProperties>(() => {
118
+ const style: CSSProperties = {
119
+ backgroundColor:
120
+ text.value || icon.value
121
+ ? randomBgColor.value
122
+ ? colors.value[colorIndex.value ? colorIndex.value : random(0, 19)]
123
+ : bgColor.value
124
+ : "transparent"
125
+ };
126
+ if (typeof size.value === "number") {
127
+ style.width = addUnit(size.value);
128
+ style.height = addUnit(size.value);
129
+ }
130
+
131
+ return Object.assign(style, customStyle.value);
132
+ });
133
+ const avatarClass = computed<string[]>(() => {
134
+ const classes: string[] = [`hy-avatar--${shape.value}`];
135
+ if (typeof size.value === "string") {
136
+ classes.push(`hy-avatar--${size.value}`);
137
+ }
138
+
139
+ return classes;
140
+ });
141
+
142
+ const init = () => {
143
+ // 目前只有这几个小程序平台具有open-data标签
144
+ // 其他平台可以通过uni.getUserInfo类似接口获取信息,但是需要弹窗授权(首次),不合符组件逻辑
145
+ // 故目前自动获取小程序头像只支持这几个平台
146
+ // #ifdef MP-WEIXIN || MP-QQ || MP-BAIDU
147
+ allowMp.value = true;
148
+ // #endif
149
+ };
150
+ init();
151
+
152
+ /**
153
+ * @description 判断传入的name属性,是否图片路径,只要带有"/"均认为是图片形式
154
+ * */
155
+ const isImg = () => {
156
+ return src.value.indexOf("/") !== -1;
157
+ };
158
+ // 图片加载时失败时触发
159
+ const errorHandler = () => {
160
+ avatarUrl.value = defaultUrl.value || base64Avatar;
161
+ };
162
+
163
+ /**
164
+ * @description 点击头像
165
+ * */
166
+ const clickHandler = (e: Event) => {
167
+ emit("click", name.value, e);
168
+ };
169
+ </script>
170
+
171
+ <style lang="scss" scoped>
172
+ @import "../../libs/css/mixin.scss";
173
+ @import "../../theme.scss";
174
+
175
+ .hy-avatar {
176
+ @include flex;
177
+ align-items: center;
178
+ justify-content: center;
179
+
180
+ &--circle {
181
+ border-radius: $hy-border-radius-circle;
182
+ }
183
+
184
+ &--square {
185
+ border-radius: $hy-border-margin-padding-sm;
186
+ }
187
+
188
+ &--small {
189
+ width: $hy-avatar-size-sm;
190
+ height: $hy-avatar-size-sm;
191
+ }
192
+
193
+ &--medium {
194
+ width: $hy-avatar-size-base;
195
+ height: $hy-avatar-size-base;
196
+ }
197
+
198
+ &--large {
199
+ width: $hy-avatar-size-lg;
200
+ height: $hy-avatar-size-lg;
201
+ }
202
+
203
+ &__image {
204
+ width: 100%;
205
+ height: 100%;
206
+
207
+ &--circle {
208
+ border-radius: $hy-border-radius-circle;
209
+ overflow: hidden;
210
+ }
211
+
212
+ &--square {
213
+ border-radius: $hy-border-margin-padding-sm;
214
+ }
215
+ }
216
+ }
217
+ </style>
@@ -0,0 +1,20 @@
1
+ import IProps from "./typing";
2
+
3
+ const defaultProps: IProps = {
4
+ src: "",
5
+ shape: "circle",
6
+ size: 40,
7
+ mode: "scaleToFill",
8
+ text: "",
9
+ bgColor: "#c0c4cc",
10
+ color: "#ffffff",
11
+ fontSize: 18,
12
+ icon: "",
13
+ mpAvatar: false,
14
+ randomBgColor: false,
15
+ defaultUrl: "",
16
+ colorIndex: 0,
17
+ name: ""
18
+ };
19
+
20
+ export default defaultProps;
@@ -0,0 +1,64 @@
1
+ import { CSSProperties } from "vue";
2
+
3
+ export default interface IProps {
4
+ /**
5
+ * @description 头像路径,如加载失败,将会显示默认头像(不能为相对路径)
6
+ * */
7
+ src: string;
8
+ /**
9
+ * @description 头像形状 ( circle (默认) | square)
10
+ * */
11
+ shape?: HyApp.ShapeType;
12
+ /**
13
+ * @description 头像尺寸,可以为指定字符串(large, default, mini),或者数值 (默认 40 )
14
+ * */
15
+ size?: number | HyApp.SizeType;
16
+ /**
17
+ * @description 头像图片的裁剪类型,与uni的image组件的mode参数一致,如效果达不到需求,可尝试传widthFix值 (默认 'scaleToFill' )
18
+ * */
19
+ mode?: string;
20
+ /**
21
+ * @description 用文字替代图片,级别优先于src
22
+ * */
23
+ text?: string;
24
+ /**
25
+ * @description 背景颜色,一般显示文字时用 (默认 '#c0c4cc' )
26
+ * */
27
+ bgColor?: string;
28
+ /**
29
+ * @description 文字颜色 (默认 '#ffffff' )
30
+ * */
31
+ color?: string;
32
+ /**
33
+ * @description 文字大小 (默认 18 )
34
+ * */
35
+ fontSize?: number | string;
36
+ /**
37
+ * @description 显示的图标
38
+ * */
39
+ icon?: string;
40
+ /**
41
+ * @description 显示小程序头像,只对百度,微信,QQ小程序有效 (默认 false )
42
+ * */
43
+ mpAvatar?: boolean;
44
+ /**
45
+ * @description 是否使用随机背景色 (默认 false )
46
+ * */
47
+ randomBgColor?: boolean;
48
+ /**
49
+ * @description 加载失败的默认头像(组件有内置默认图片)
50
+ * */
51
+ defaultUrl?: string;
52
+ /**
53
+ * @description 如果配置了randomBgColor为true,且配置了此值,则从默认的背景色数组中取出对应索引的颜色值,取值0-19之间
54
+ * */
55
+ colorIndex?: number;
56
+ /**
57
+ * @description 组件标识符 (默认 'level' )
58
+ * */
59
+ name?: string;
60
+ /**
61
+ * @description 定义需要用到的外部样式
62
+ * */
63
+ customStyle?: CSSProperties;
64
+ }