uview-pro 0.1.0 → 0.2.0

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 (244) hide show
  1. package/changelog.md +459 -406
  2. package/components/common/props.ts +22 -0
  3. package/components/u-action-sheet/types.ts +35 -35
  4. package/components/u-action-sheet/u-action-sheet.vue +160 -160
  5. package/components/u-alert-tips/types.ts +39 -39
  6. package/components/u-alert-tips/u-alert-tips.vue +212 -212
  7. package/components/u-avatar/types.ts +34 -34
  8. package/components/u-avatar/u-avatar.vue +193 -193
  9. package/components/u-avatar-cropper/types.ts +23 -23
  10. package/components/u-avatar-cropper/u-avatar-cropper.vue +286 -286
  11. package/components/u-avatar-cropper/weCropper.d.ts +62 -62
  12. package/components/u-avatar-cropper/weCropper.js +1253 -1253
  13. package/components/u-avatar-cropper/weCropper.ts +1255 -1255
  14. package/components/u-back-top/types.ts +39 -39
  15. package/components/u-back-top/u-back-top.vue +125 -125
  16. package/components/u-badge/types.ts +36 -36
  17. package/components/u-badge/u-badge.vue +165 -165
  18. package/components/u-button/types.ts +66 -66
  19. package/components/u-button/u-button.vue +556 -556
  20. package/components/u-calendar/types.ts +63 -63
  21. package/components/u-calendar/u-calendar.vue +592 -592
  22. package/components/u-car-keyboard/types.ts +12 -12
  23. package/components/u-car-keyboard/u-car-keyboard.vue +234 -234
  24. package/components/u-card/types.ts +59 -59
  25. package/components/u-card/u-card.vue +194 -194
  26. package/components/u-cell-group/types.ts +17 -17
  27. package/components/u-cell-group/u-cell-group.vue +50 -50
  28. package/components/u-cell-item/types.ts +54 -54
  29. package/components/u-cell-item/u-cell-item.vue +202 -202
  30. package/components/u-checkbox/types.ts +31 -31
  31. package/components/u-checkbox/u-checkbox.vue +267 -267
  32. package/components/u-checkbox-group/types.ts +32 -32
  33. package/components/u-checkbox-group/u-checkbox-group.vue +79 -79
  34. package/components/u-circle-progress/types.ts +52 -52
  35. package/components/u-circle-progress/u-circle-progress.vue +187 -187
  36. package/components/u-city-select/types.ts +20 -20
  37. package/components/u-city-select/u-city-select.vue +236 -236
  38. package/components/u-col/types.ts +30 -30
  39. package/components/u-col/u-col.vue +123 -123
  40. package/components/u-collapse/types.ts +33 -31
  41. package/components/u-collapse/u-collapse.vue +69 -68
  42. package/components/u-collapse-item/types.ts +27 -25
  43. package/components/u-collapse-item/u-collapse-item.vue +201 -194
  44. package/components/u-column-notice/types.ts +48 -48
  45. package/components/u-column-notice/u-column-notice.vue +176 -176
  46. package/components/u-count-down/types.ts +42 -42
  47. package/components/u-count-down/u-count-down.vue +258 -258
  48. package/components/u-count-to/types.ts +32 -32
  49. package/components/u-count-to/u-count-to.vue +241 -241
  50. package/components/u-divider/types.ts +31 -31
  51. package/components/u-divider/u-divider.vue +121 -121
  52. package/components/u-dropdown/types.ts +32 -32
  53. package/components/u-dropdown/u-dropdown.vue +289 -289
  54. package/components/u-dropdown-item/types.ts +27 -27
  55. package/components/u-dropdown-item/u-dropdown-item.vue +123 -123
  56. package/components/u-empty/types.ts +36 -36
  57. package/components/u-empty/u-empty.vue +88 -88
  58. package/components/u-field/types.ts +69 -69
  59. package/components/u-field/u-field.vue +354 -354
  60. package/components/u-form/u-form.vue +132 -132
  61. package/components/u-form-item/u-form-item.vue +417 -417
  62. package/components/u-full-screen/types.ts +14 -14
  63. package/components/u-full-screen/u-full-screen.vue +82 -82
  64. package/components/u-gap/types.ts +18 -18
  65. package/components/u-gap/u-gap.vue +40 -40
  66. package/components/u-grid/types.ts +19 -19
  67. package/components/u-grid/u-grid.vue +93 -93
  68. package/components/u-grid-item/types.ts +16 -16
  69. package/components/u-grid-item/u-grid-item.vue +130 -130
  70. package/components/u-icon/types.ts +62 -62
  71. package/components/u-icon/u-icon.vue +281 -274
  72. package/components/u-image/types.ts +51 -51
  73. package/components/u-image/u-image.vue +222 -222
  74. package/components/u-index-anchor/types.ts +16 -16
  75. package/components/u-index-anchor/u-index-anchor.vue +86 -86
  76. package/components/u-index-list/types.ts +43 -43
  77. package/components/u-index-list/u-index-list.vue +355 -355
  78. package/components/u-input/types.ts +140 -140
  79. package/components/u-input/u-input.vue +264 -255
  80. package/components/u-keyboard/types.ts +40 -40
  81. package/components/u-keyboard/u-keyboard.vue +158 -158
  82. package/components/u-lazy-load/types.ts +37 -37
  83. package/components/u-lazy-load/u-lazy-load.vue +233 -233
  84. package/components/u-line/types.ts +44 -44
  85. package/components/u-line/u-line.vue +59 -59
  86. package/components/u-line-progress/types.ts +58 -58
  87. package/components/u-line-progress/u-line-progress.vue +109 -109
  88. package/components/u-link/types.ts +43 -43
  89. package/components/u-link/u-link.vue +75 -75
  90. package/components/u-loading/types.ts +35 -35
  91. package/components/u-loading/u-loading.vue +90 -90
  92. package/components/u-loading-popup/types.ts +26 -26
  93. package/components/u-loading-popup/u-loading-popup.vue +239 -239
  94. package/components/u-loadmore/types.ts +79 -79
  95. package/components/u-loadmore/u-loadmore.vue +140 -140
  96. package/components/u-mask/types.ts +43 -43
  97. package/components/u-mask/u-mask.vue +106 -106
  98. package/components/u-message-input/types.ts +74 -74
  99. package/components/u-message-input/u-message-input.vue +255 -255
  100. package/components/u-modal/types.ts +118 -118
  101. package/components/u-modal/u-modal.vue +204 -204
  102. package/components/u-navbar/types.ts +103 -103
  103. package/components/u-navbar/u-navbar.vue +226 -226
  104. package/components/u-no-network/image.ts +2 -2
  105. package/components/u-no-network/types.ts +28 -28
  106. package/components/u-no-network/u-no-network.vue +290 -290
  107. package/components/u-notice-bar/types.ts +111 -111
  108. package/components/u-notice-bar/u-notice-bar.vue +174 -174
  109. package/components/u-number-box/types.ts +42 -42
  110. package/components/u-number-box/u-number-box.vue +312 -312
  111. package/components/u-number-keyboard/types.ts +26 -26
  112. package/components/u-number-keyboard/u-number-keyboard.vue +166 -166
  113. package/components/u-picker/types.ts +123 -123
  114. package/components/u-picker/u-picker.vue +637 -637
  115. package/components/u-popup/types.ts +59 -59
  116. package/components/u-popup/u-popup.vue +359 -359
  117. package/components/u-radio/types.ts +25 -25
  118. package/components/u-radio/u-radio.vue +258 -258
  119. package/components/u-radio-group/types.ts +29 -29
  120. package/components/u-radio-group/u-radio-group.vue +98 -98
  121. package/components/u-rate/types.ts +40 -40
  122. package/components/u-rate/u-rate.vue +234 -234
  123. package/components/u-read-more/types.ts +35 -35
  124. package/components/u-read-more/u-read-more.vue +150 -150
  125. package/components/u-row/types.ts +20 -20
  126. package/components/u-row/u-row.vue +87 -87
  127. package/components/u-row-notice/types.ts +39 -39
  128. package/components/u-row-notice/u-row-notice.vue +213 -213
  129. package/components/u-safe-bottom/u-safe-bottom.vue +46 -46
  130. package/components/u-search/types.ts +53 -53
  131. package/components/u-search/u-search.vue +256 -256
  132. package/components/u-section/types.ts +32 -32
  133. package/components/u-section/u-section.vue +125 -125
  134. package/components/u-select/types.ts +43 -43
  135. package/components/u-select/u-select.vue +361 -361
  136. package/components/u-skeleton/types.ts +20 -20
  137. package/components/u-skeleton/u-skeleton.vue +205 -205
  138. package/components/u-slider/types.ts +32 -32
  139. package/components/u-slider/u-slider.vue +238 -238
  140. package/components/u-status-bar/u-status-bar.vue +65 -65
  141. package/components/u-steps/types.ts +28 -28
  142. package/components/u-steps/u-steps.vue +160 -160
  143. package/components/u-sticky/types.ts +22 -22
  144. package/components/u-sticky/u-sticky.vue +159 -159
  145. package/components/u-subsection/types.ts +36 -36
  146. package/components/u-subsection/u-subsection.vue +328 -328
  147. package/components/u-swipe-action/types.ts +50 -50
  148. package/components/u-swipe-action/u-swipe-action.vue +253 -253
  149. package/components/u-swiper/types.ts +47 -47
  150. package/components/u-swiper/u-swiper.vue +266 -266
  151. package/components/u-switch/types.ts +28 -28
  152. package/components/u-switch/u-switch.vue +136 -136
  153. package/components/u-tabbar/types.ts +36 -36
  154. package/components/u-tabbar/u-tabbar.vue +280 -280
  155. package/components/u-table/types.ts +25 -25
  156. package/components/u-table/u-table.vue +55 -55
  157. package/components/u-tabs/types.ts +51 -51
  158. package/components/u-tabs/u-tabs.vue +284 -284
  159. package/components/u-tabs-swiper/types.ts +53 -53
  160. package/components/u-tabs-swiper/u-tabs-swiper.vue +379 -379
  161. package/components/u-tag/types.ts +37 -37
  162. package/components/u-tag/u-tag.vue +244 -244
  163. package/components/u-td/types.ts +12 -12
  164. package/components/u-td/u-td.vue +87 -87
  165. package/components/u-text/types.ts +69 -0
  166. package/components/u-text/u-text.vue +326 -0
  167. package/components/u-th/types.ts +12 -12
  168. package/components/u-th/u-th.vue +81 -81
  169. package/components/u-time-line/u-time-line.vue +39 -39
  170. package/components/u-time-line-item/types.ts +14 -14
  171. package/components/u-time-line-item/u-time-line-item.vue +78 -78
  172. package/components/u-toast/types.ts +36 -36
  173. package/components/u-toast/u-toast.vue +233 -233
  174. package/components/u-top-tips/types.ts +14 -14
  175. package/components/u-top-tips/u-top-tips.vue +113 -113
  176. package/components/u-tr/types.ts +8 -8
  177. package/components/u-tr/u-tr.vue +24 -24
  178. package/components/u-upload/types.ts +74 -74
  179. package/components/u-upload/u-upload.vue +545 -545
  180. package/components/u-verification-code/types.ts +22 -22
  181. package/components/u-verification-code/u-verification-code.vue +164 -164
  182. package/components/u-waterfall/types.ts +16 -16
  183. package/components/u-waterfall/u-waterfall.vue +175 -175
  184. package/iconfont.css +912 -912
  185. package/index.scss +25 -23
  186. package/index.ts +29 -204
  187. package/libs/config/config.ts +26 -26
  188. package/libs/config/zIndex.ts +37 -37
  189. package/libs/css/color.scss +155 -155
  190. package/libs/css/common.scss +178 -178
  191. package/libs/css/style.components.scss +16 -7
  192. package/libs/css/style.h5.scss +8 -8
  193. package/libs/css/style.mp.scss +72 -72
  194. package/libs/css/style.nvue.scss +15 -3
  195. package/libs/css/style.vue.scss +188 -177
  196. package/libs/function/$parent.ts +21 -21
  197. package/libs/function/addUnit.ts +13 -13
  198. package/libs/function/color.ts +37 -71
  199. package/libs/function/colorGradient.ts +125 -125
  200. package/libs/function/debounce.ts +28 -28
  201. package/libs/function/deepClone.ts +39 -39
  202. package/libs/function/deepMerge.ts +34 -34
  203. package/libs/function/getParent.ts +59 -59
  204. package/libs/function/getRect.ts +26 -26
  205. package/libs/function/guid.ts +42 -42
  206. package/libs/function/md5.ts +391 -391
  207. package/libs/function/parent.ts +21 -21
  208. package/libs/function/queryParams.ts +60 -60
  209. package/libs/function/random.ts +16 -16
  210. package/libs/function/randomArray.ts +11 -11
  211. package/libs/function/route.ts +118 -118
  212. package/libs/function/styleUtils.ts +83 -83
  213. package/libs/function/sys.ts +15 -15
  214. package/libs/function/test.ts +285 -229
  215. package/libs/function/throttle.ts +31 -31
  216. package/libs/function/timeFormat.ts +54 -54
  217. package/libs/function/timeFrom.ts +48 -48
  218. package/libs/function/toast.ts +14 -14
  219. package/libs/function/trim.ts +21 -21
  220. package/libs/function/type2icon.ts +36 -36
  221. package/libs/hooks/index.ts +3 -0
  222. package/libs/hooks/useEmitter.ts +77 -77
  223. package/libs/hooks/useParent.ts +31 -29
  224. package/libs/hooks/useRect.ts +33 -0
  225. package/libs/index.ts +291 -0
  226. package/libs/request/auto-http.ts +76 -76
  227. package/libs/request/index.ts +223 -223
  228. package/libs/store/index.ts +88 -88
  229. package/libs/util/area.ts +3771 -3771
  230. package/libs/util/async-validator.d.ts +62 -62
  231. package/libs/util/async-validator.js +1368 -1368
  232. package/libs/util/city.ts +432 -432
  233. package/libs/util/emitter.ts +102 -102
  234. package/libs/util/mitt.ts +115 -115
  235. package/libs/util/parent.ts +20 -20
  236. package/libs/util/province.ts +37 -37
  237. package/package.json +1 -1
  238. package/readme.md +237 -237
  239. package/theme.scss +38 -38
  240. package/types/components.d.ts +96 -95
  241. package/types/global.d.ts +255 -221
  242. package/types/ignore-errors.d.ts +30 -30
  243. package/types/index.d.ts +19 -90
  244. package/types/uni-app.d.ts +63 -63
@@ -1,359 +1,359 @@
1
- <template>
2
- <view v-if="visibleSync" :style="[customStyle, { zIndex: Number(uZindex) - 1 }]" class="u-drawer" hover-stop-propagation>
3
- <u-mask
4
- :duration="duration"
5
- :custom-style="maskCustomStyle"
6
- :maskClickAble="maskCloseAble"
7
- :z-index="Number(uZindex) - 2"
8
- :show="showDrawer && mask"
9
- @click="maskClick"
10
- ></u-mask>
11
- <view
12
- class="u-drawer-content"
13
- @tap="modeCenterClose(mode)"
14
- :class="[
15
- safeAreaInsetBottom ? 'safe-area-inset-bottom' : '',
16
- 'u-drawer-' + mode,
17
- showDrawer ? 'u-drawer-content-visible' : '',
18
- zoom && mode == 'center' ? 'u-animation-zoom' : ''
19
- ]"
20
- @touchmove.stop.prevent
21
- @tap.stop.prevent
22
- :style="[style]"
23
- >
24
- <view class="u-mode-center-box" @tap.stop.prevent @touchmove.stop.prevent v-if="mode == 'center'" :style="[centerStyle]">
25
- <u-icon
26
- @click="close"
27
- v-if="closeable"
28
- class="u-close"
29
- :class="['u-close--' + closeIconPos]"
30
- :name="closeIcon"
31
- :color="closeIconColor"
32
- :size="closeIconSize"
33
- ></u-icon>
34
- <scroll-view class="u-drawer__scroll-view" scroll-y="true">
35
- <slot />
36
- </scroll-view>
37
- </view>
38
- <scroll-view class="u-drawer__scroll-view" scroll-y="true" v-else>
39
- <slot />
40
- </scroll-view>
41
- <view @tap="close" class="u-close" :class="['u-close--' + closeIconPos]">
42
- <u-icon v-if="mode != 'center' && closeable" :name="closeIcon" :color="closeIconColor" :size="closeIconSize"></u-icon>
43
- </view>
44
- </view>
45
- </view>
46
- </template>
47
-
48
- <script setup lang="ts">
49
- import { ref, computed, watch, onMounted, nextTick } from 'vue';
50
- import { $u } from '../..';
51
- import { PopupProps } from './types';
52
-
53
- defineOptions({
54
- name: 'u-popup'
55
- });
56
-
57
- /**
58
- * popup 弹窗
59
- * @description 弹出层容器,用于展示弹窗、信息提示等内容,支持上、下、左、右和中部弹出。组件只提供容器,内部内容由用户自定义
60
- * @tutorial https://uviewpro.cn/zh/components/popup.html
61
- * @property {String} mode 弹出方向(默认left)
62
- * @property {Boolean} mask 是否显示遮罩(默认true)
63
- * @property {Stringr | Number} length mode=left | 见官网说明(默认auto)
64
- * @property {Boolean} zoom 是否开启缩放动画,只在mode为center时有效(默认true)
65
- * @property {Boolean} safe-area-inset-bottom 是否开启底部安全区适配(默认false)
66
- * @property {Boolean} mask-close-able 点击遮罩是否可以关闭弹出层(默认true)
67
- * @property {Object} custom-style 用户自定义样式
68
- * @property {Stringr | Number} negative-top 中部弹出时,往上偏移的值
69
- * @property {Numberr | String} border-radius 弹窗圆角值(默认0)
70
- * @property {Numberr | String} z-index 弹出内容的z-index值(默认1075)
71
- * @property {Boolean} closeable 是否显示关闭图标(默认false)
72
- * @property {String} close-icon 关闭图标的名称,只能uView的内置图标
73
- * @property {String} close-icon-pos 自定义关闭图标位置(默认top-right)
74
- * @property {String} close-icon-color 关闭图标的颜色(默认#909399)
75
- * @property {Number | String} close-icon-size 关闭图标的大小,单位rpx(默认30)
76
- * @event {Function} open 弹出层打开
77
- * @event {Function} close 弹出层收起
78
- * @example <u-popup v-model="show"><view>出淤泥而不染,濯清涟而不妖</view></u-popup>
79
- */
80
-
81
- const props = defineProps(PopupProps);
82
- const emit = defineEmits(['update:modelValue', 'open', 'close']);
83
-
84
- // 组件内部状态
85
- const visibleSync = ref(false);
86
- const showDrawer = ref(false);
87
- const timer = ref<ReturnType<typeof setTimeout> | null>(null);
88
- const closeFromInner = ref(false); // value的值改变,是发生在内部还是外部
89
- // 根据mode的位置,设定其弹窗的宽度(mode = left|right),或者高度(mode = top|bottom)
90
- const style = computed(() => {
91
- let style: Record<string, any> = {};
92
- // 如果是左边或者上边弹出时,需要给translate设置为负值,用于隐藏
93
- if (props.mode == 'left' || props.mode == 'right') {
94
- style = {
95
- width: props.width ? getUnitValue(props.width) : getUnitValue(props.length),
96
- height: '100%',
97
- transform: `translate3D(${props.mode == 'left' ? '-100%' : '100%'},0px,0px)`
98
- };
99
- } else if (props.mode == 'top' || props.mode == 'bottom') {
100
- style = {
101
- width: '100%',
102
- height: props.height ? getUnitValue(props.height) : getUnitValue(props.length),
103
- transform: `translate3D(0px,${props.mode == 'top' ? '-100%' : '100%'},0px)`
104
- };
105
- }
106
- // 如果用户设置了borderRadius值,添加弹窗的圆角
107
- style.zIndex = uZindex.value;
108
- if (props.borderRadius) {
109
- switch (props.mode) {
110
- case 'left':
111
- style.borderRadius = `0 ${props.borderRadius}rpx ${props.borderRadius}rpx 0`;
112
- break;
113
- case 'top':
114
- style.borderRadius = `0 0 ${props.borderRadius}rpx ${props.borderRadius}rpx`;
115
- break;
116
- case 'right':
117
- style.borderRadius = `${props.borderRadius}rpx 0 0 ${props.borderRadius}rpx`;
118
- break;
119
- case 'bottom':
120
- style.borderRadius = `${props.borderRadius}rpx ${props.borderRadius}rpx 0 0`;
121
- break;
122
- default:
123
- }
124
- // 不加可能圆角无效
125
- style.overflow = 'hidden';
126
- }
127
- if (props.duration) style.transition = `all ${Number(props.duration) / 1000}s linear`;
128
- return style;
129
- });
130
-
131
- // 中部弹窗的特有样式
132
- const centerStyle = computed(() => {
133
- let style: Record<string, any> = {};
134
- style.width = props.width ? getUnitValue(props.width) : getUnitValue(props.length);
135
-
136
- // 中部弹出的模式,如果没有设置高度,就用auto值,由内容撑开高度
137
- style.height = props.height ? getUnitValue(props.height) : 'auto';
138
- style.zIndex = uZindex.value;
139
- style.marginTop = `-${$u.addUnit(props.negativeTop)}`;
140
- if (props.borderRadius) {
141
- style.borderRadius = `${props.borderRadius}rpx`;
142
- // 不加可能圆角无效
143
- style.overflow = 'hidden';
144
- }
145
- return style;
146
- });
147
-
148
- // 计算整理后的z-index值
149
- const uZindex = computed(() => (props.zIndex ? props.zIndex : $u.zIndex.popup));
150
-
151
- watch(
152
- () => props.modelValue,
153
- val => {
154
- if (val) {
155
- open();
156
- } else if (!closeFromInner.value) {
157
- close();
158
- }
159
- closeFromInner.value = false;
160
- }
161
- );
162
-
163
- onMounted(() => {
164
- if (props.modelValue) open();
165
- });
166
-
167
- /**
168
- * 判断传入的值,是否带有单位,如果没有,就默认用rpx单位
169
- */
170
- function getUnitValue(val: string | number) {
171
- if (/(%|px|rpx|auto)$/.test(String(val))) return val;
172
- else return val + 'rpx';
173
- }
174
-
175
- /**
176
- * 遮罩被点击
177
- */
178
- function maskClick() {
179
- close();
180
- }
181
-
182
- /**
183
- * 关闭弹窗
184
- */
185
- function close() {
186
- // 标记关闭是内部发生的,否则修改了value值,导致watch中对value检测,导致再执行一遍close
187
- // 造成@close事件触发两次
188
- closeFromInner.value = true;
189
- change('showDrawer', 'visibleSync', false);
190
- }
191
-
192
- /**
193
- * 中部弹出时,点击内容区域关闭弹窗
194
- */
195
- function modeCenterClose(mode: string) {
196
- // 中部弹出时,需要.u-drawer-content将居中内容,此元素会铺满屏幕,点击需要关闭弹窗
197
- // 让其只在mode=center时起作用
198
- if (mode != 'center' || !props.maskCloseAble) return;
199
- close();
200
- }
201
-
202
- /**
203
- * 打开弹窗
204
- */
205
- function open() {
206
- change('visibleSync', 'showDrawer', true);
207
- }
208
-
209
- /**
210
- * 控制弹窗显示/隐藏的动画和状态
211
- * 此处的原理是,关闭时先通过动画隐藏弹窗和遮罩,再移除整个组件
212
- * 打开时,先渲染组件,延时一定时间再让遮罩和弹窗的动画起作用
213
- */
214
- function change(param1: 'showDrawer' | 'visibleSync', param2: 'visibleSync' | 'showDrawer', status: boolean) {
215
- // 如果this.popup为false,意味着为picker,actionsheet等组件调用了popup组件
216
- if (props.popup === true) {
217
- emit('update:modelValue', status);
218
- }
219
- (param1 === 'showDrawer' ? showDrawer : visibleSync).value = status;
220
- if (status) {
221
- // #ifdef H5 || MP
222
- timer.value = setTimeout(() => {
223
- (param2 === 'showDrawer' ? showDrawer : visibleSync).value = status;
224
- emit(status ? 'open' : 'close');
225
- }, 50);
226
- // #endif
227
- // #ifndef H5 || MP
228
- nextTick(() => {
229
- (param2 === 'showDrawer' ? showDrawer : visibleSync).value = status;
230
- emit(status ? 'open' : 'close');
231
- });
232
- // #endif
233
- } else {
234
- timer.value = setTimeout(() => {
235
- (param2 === 'showDrawer' ? showDrawer : visibleSync).value = status;
236
- emit(status ? 'open' : 'close');
237
- }, Number(props.duration));
238
- }
239
- }
240
- </script>
241
-
242
- <style scoped lang="scss">
243
- @import '../../libs/css/style.components.scss';
244
-
245
- .u-drawer {
246
- /* #ifndef APP-NVUE */
247
- display: block;
248
- /* #endif */
249
- position: fixed;
250
- top: 0;
251
- left: 0;
252
- right: 0;
253
- bottom: 0;
254
- overflow: hidden;
255
- }
256
-
257
- .u-drawer-content {
258
- /* #ifndef APP-NVUE */
259
- display: block;
260
- /* #endif */
261
- position: absolute;
262
- z-index: 1003;
263
- transition: all 0.25s linear;
264
- }
265
-
266
- .u-drawer__scroll-view {
267
- width: 100%;
268
- height: 100%;
269
- }
270
-
271
- .u-drawer-left {
272
- top: 0;
273
- bottom: 0;
274
- left: 0;
275
- background-color: #ffffff;
276
- }
277
-
278
- .u-drawer-right {
279
- right: 0;
280
- top: 0;
281
- bottom: 0;
282
- background-color: #ffffff;
283
- }
284
-
285
- .u-drawer-top {
286
- top: 0;
287
- left: 0;
288
- right: 0;
289
- background-color: #ffffff;
290
- }
291
-
292
- .u-drawer-bottom {
293
- bottom: 0;
294
- left: 0;
295
- right: 0;
296
- background-color: #ffffff;
297
- }
298
-
299
- .u-drawer-center {
300
- @include vue-flex;
301
- flex-direction: column;
302
- bottom: 0;
303
- left: 0;
304
- right: 0;
305
- top: 0;
306
- justify-content: center;
307
- align-items: center;
308
- opacity: 0;
309
- z-index: 99999;
310
- }
311
-
312
- .u-mode-center-box {
313
- min-width: 100rpx;
314
- min-height: 100rpx;
315
- /* #ifndef APP-NVUE */
316
- display: block;
317
- /* #endif */
318
- position: relative;
319
- background-color: #ffffff;
320
- }
321
-
322
- .u-drawer-content-visible.u-drawer-center {
323
- transform: scale(1);
324
- opacity: 1;
325
- }
326
-
327
- .u-animation-zoom {
328
- transform: scale(1.15);
329
- }
330
-
331
- .u-drawer-content-visible {
332
- transform: translate3D(0px, 0px, 0px) !important;
333
- }
334
-
335
- .u-close {
336
- position: absolute;
337
- z-index: 3;
338
- }
339
-
340
- .u-close--top-left {
341
- top: 30rpx;
342
- left: 30rpx;
343
- }
344
-
345
- .u-close--top-right {
346
- top: 30rpx;
347
- right: 30rpx;
348
- }
349
-
350
- .u-close--bottom-left {
351
- bottom: 30rpx;
352
- left: 30rpx;
353
- }
354
-
355
- .u-close--bottom-right {
356
- right: 30rpx;
357
- bottom: 30rpx;
358
- }
359
- </style>
1
+ <template>
2
+ <view v-if="visibleSync" :style="[customStyle, { zIndex: Number(uZindex) - 1 }]" class="u-drawer" hover-stop-propagation>
3
+ <u-mask
4
+ :duration="duration"
5
+ :custom-style="maskCustomStyle"
6
+ :maskClickAble="maskCloseAble"
7
+ :z-index="Number(uZindex) - 2"
8
+ :show="showDrawer && mask"
9
+ @click="maskClick"
10
+ ></u-mask>
11
+ <view
12
+ class="u-drawer-content"
13
+ @tap="modeCenterClose(mode)"
14
+ :class="[
15
+ safeAreaInsetBottom ? 'safe-area-inset-bottom' : '',
16
+ 'u-drawer-' + mode,
17
+ showDrawer ? 'u-drawer-content-visible' : '',
18
+ zoom && mode == 'center' ? 'u-animation-zoom' : ''
19
+ ]"
20
+ @touchmove.stop.prevent
21
+ @tap.stop.prevent
22
+ :style="[style]"
23
+ >
24
+ <view class="u-mode-center-box" @tap.stop.prevent @touchmove.stop.prevent v-if="mode == 'center'" :style="[centerStyle]">
25
+ <u-icon
26
+ @click="close"
27
+ v-if="closeable"
28
+ class="u-close"
29
+ :class="['u-close--' + closeIconPos]"
30
+ :name="closeIcon"
31
+ :color="closeIconColor"
32
+ :size="closeIconSize"
33
+ ></u-icon>
34
+ <scroll-view class="u-drawer__scroll-view" scroll-y="true">
35
+ <slot />
36
+ </scroll-view>
37
+ </view>
38
+ <scroll-view class="u-drawer__scroll-view" scroll-y="true" v-else>
39
+ <slot />
40
+ </scroll-view>
41
+ <view @tap="close" class="u-close" :class="['u-close--' + closeIconPos]">
42
+ <u-icon v-if="mode != 'center' && closeable" :name="closeIcon" :color="closeIconColor" :size="closeIconSize"></u-icon>
43
+ </view>
44
+ </view>
45
+ </view>
46
+ </template>
47
+
48
+ <script setup lang="ts">
49
+ import { ref, computed, watch, onMounted, nextTick } from 'vue';
50
+ import { $u } from '../..';
51
+ import { PopupProps } from './types';
52
+
53
+ defineOptions({
54
+ name: 'u-popup'
55
+ });
56
+
57
+ /**
58
+ * popup 弹窗
59
+ * @description 弹出层容器,用于展示弹窗、信息提示等内容,支持上、下、左、右和中部弹出。组件只提供容器,内部内容由用户自定义
60
+ * @tutorial https://uviewpro.cn/zh/components/popup.html
61
+ * @property {String} mode 弹出方向(默认left)
62
+ * @property {Boolean} mask 是否显示遮罩(默认true)
63
+ * @property {Stringr | Number} length mode=left | 见官网说明(默认auto)
64
+ * @property {Boolean} zoom 是否开启缩放动画,只在mode为center时有效(默认true)
65
+ * @property {Boolean} safe-area-inset-bottom 是否开启底部安全区适配(默认false)
66
+ * @property {Boolean} mask-close-able 点击遮罩是否可以关闭弹出层(默认true)
67
+ * @property {Object} custom-style 用户自定义样式
68
+ * @property {Stringr | Number} negative-top 中部弹出时,往上偏移的值
69
+ * @property {Numberr | String} border-radius 弹窗圆角值(默认0)
70
+ * @property {Numberr | String} z-index 弹出内容的z-index值(默认1075)
71
+ * @property {Boolean} closeable 是否显示关闭图标(默认false)
72
+ * @property {String} close-icon 关闭图标的名称,只能uView的内置图标
73
+ * @property {String} close-icon-pos 自定义关闭图标位置(默认top-right)
74
+ * @property {String} close-icon-color 关闭图标的颜色(默认#909399)
75
+ * @property {Number | String} close-icon-size 关闭图标的大小,单位rpx(默认30)
76
+ * @event {Function} open 弹出层打开
77
+ * @event {Function} close 弹出层收起
78
+ * @example <u-popup v-model="show"><view>出淤泥而不染,濯清涟而不妖</view></u-popup>
79
+ */
80
+
81
+ const props = defineProps(PopupProps);
82
+ const emit = defineEmits(['update:modelValue', 'open', 'close']);
83
+
84
+ // 组件内部状态
85
+ const visibleSync = ref(false);
86
+ const showDrawer = ref(false);
87
+ const timer = ref<ReturnType<typeof setTimeout> | null>(null);
88
+ const closeFromInner = ref(false); // value的值改变,是发生在内部还是外部
89
+ // 根据mode的位置,设定其弹窗的宽度(mode = left|right),或者高度(mode = top|bottom)
90
+ const style = computed(() => {
91
+ let style: Record<string, any> = {};
92
+ // 如果是左边或者上边弹出时,需要给translate设置为负值,用于隐藏
93
+ if (props.mode == 'left' || props.mode == 'right') {
94
+ style = {
95
+ width: props.width ? getUnitValue(props.width) : getUnitValue(props.length),
96
+ height: '100%',
97
+ transform: `translate3D(${props.mode == 'left' ? '-100%' : '100%'},0px,0px)`
98
+ };
99
+ } else if (props.mode == 'top' || props.mode == 'bottom') {
100
+ style = {
101
+ width: '100%',
102
+ height: props.height ? getUnitValue(props.height) : getUnitValue(props.length),
103
+ transform: `translate3D(0px,${props.mode == 'top' ? '-100%' : '100%'},0px)`
104
+ };
105
+ }
106
+ // 如果用户设置了borderRadius值,添加弹窗的圆角
107
+ style.zIndex = uZindex.value;
108
+ if (props.borderRadius) {
109
+ switch (props.mode) {
110
+ case 'left':
111
+ style.borderRadius = `0 ${props.borderRadius}rpx ${props.borderRadius}rpx 0`;
112
+ break;
113
+ case 'top':
114
+ style.borderRadius = `0 0 ${props.borderRadius}rpx ${props.borderRadius}rpx`;
115
+ break;
116
+ case 'right':
117
+ style.borderRadius = `${props.borderRadius}rpx 0 0 ${props.borderRadius}rpx`;
118
+ break;
119
+ case 'bottom':
120
+ style.borderRadius = `${props.borderRadius}rpx ${props.borderRadius}rpx 0 0`;
121
+ break;
122
+ default:
123
+ }
124
+ // 不加可能圆角无效
125
+ style.overflow = 'hidden';
126
+ }
127
+ if (props.duration) style.transition = `all ${Number(props.duration) / 1000}s linear`;
128
+ return style;
129
+ });
130
+
131
+ // 中部弹窗的特有样式
132
+ const centerStyle = computed(() => {
133
+ let style: Record<string, any> = {};
134
+ style.width = props.width ? getUnitValue(props.width) : getUnitValue(props.length);
135
+
136
+ // 中部弹出的模式,如果没有设置高度,就用auto值,由内容撑开高度
137
+ style.height = props.height ? getUnitValue(props.height) : 'auto';
138
+ style.zIndex = uZindex.value;
139
+ style.marginTop = `-${$u.addUnit(props.negativeTop)}`;
140
+ if (props.borderRadius) {
141
+ style.borderRadius = `${props.borderRadius}rpx`;
142
+ // 不加可能圆角无效
143
+ style.overflow = 'hidden';
144
+ }
145
+ return style;
146
+ });
147
+
148
+ // 计算整理后的z-index值
149
+ const uZindex = computed(() => (props.zIndex ? props.zIndex : $u.zIndex.popup));
150
+
151
+ watch(
152
+ () => props.modelValue,
153
+ val => {
154
+ if (val) {
155
+ open();
156
+ } else if (!closeFromInner.value) {
157
+ close();
158
+ }
159
+ closeFromInner.value = false;
160
+ }
161
+ );
162
+
163
+ onMounted(() => {
164
+ if (props.modelValue) open();
165
+ });
166
+
167
+ /**
168
+ * 判断传入的值,是否带有单位,如果没有,就默认用rpx单位
169
+ */
170
+ function getUnitValue(val: string | number) {
171
+ if (/(%|px|rpx|auto)$/.test(String(val))) return val;
172
+ else return val + 'rpx';
173
+ }
174
+
175
+ /**
176
+ * 遮罩被点击
177
+ */
178
+ function maskClick() {
179
+ close();
180
+ }
181
+
182
+ /**
183
+ * 关闭弹窗
184
+ */
185
+ function close() {
186
+ // 标记关闭是内部发生的,否则修改了value值,导致watch中对value检测,导致再执行一遍close
187
+ // 造成@close事件触发两次
188
+ closeFromInner.value = true;
189
+ change('showDrawer', 'visibleSync', false);
190
+ }
191
+
192
+ /**
193
+ * 中部弹出时,点击内容区域关闭弹窗
194
+ */
195
+ function modeCenterClose(mode: string) {
196
+ // 中部弹出时,需要.u-drawer-content将居中内容,此元素会铺满屏幕,点击需要关闭弹窗
197
+ // 让其只在mode=center时起作用
198
+ if (mode != 'center' || !props.maskCloseAble) return;
199
+ close();
200
+ }
201
+
202
+ /**
203
+ * 打开弹窗
204
+ */
205
+ function open() {
206
+ change('visibleSync', 'showDrawer', true);
207
+ }
208
+
209
+ /**
210
+ * 控制弹窗显示/隐藏的动画和状态
211
+ * 此处的原理是,关闭时先通过动画隐藏弹窗和遮罩,再移除整个组件
212
+ * 打开时,先渲染组件,延时一定时间再让遮罩和弹窗的动画起作用
213
+ */
214
+ function change(param1: 'showDrawer' | 'visibleSync', param2: 'visibleSync' | 'showDrawer', status: boolean) {
215
+ // 如果this.popup为false,意味着为picker,actionsheet等组件调用了popup组件
216
+ if (props.popup === true) {
217
+ emit('update:modelValue', status);
218
+ }
219
+ (param1 === 'showDrawer' ? showDrawer : visibleSync).value = status;
220
+ if (status) {
221
+ // #ifdef H5 || MP
222
+ timer.value = setTimeout(() => {
223
+ (param2 === 'showDrawer' ? showDrawer : visibleSync).value = status;
224
+ emit(status ? 'open' : 'close');
225
+ }, 50);
226
+ // #endif
227
+ // #ifndef H5 || MP
228
+ nextTick(() => {
229
+ (param2 === 'showDrawer' ? showDrawer : visibleSync).value = status;
230
+ emit(status ? 'open' : 'close');
231
+ });
232
+ // #endif
233
+ } else {
234
+ timer.value = setTimeout(() => {
235
+ (param2 === 'showDrawer' ? showDrawer : visibleSync).value = status;
236
+ emit(status ? 'open' : 'close');
237
+ }, Number(props.duration));
238
+ }
239
+ }
240
+ </script>
241
+
242
+ <style scoped lang="scss">
243
+ @import '../../libs/css/style.components.scss';
244
+
245
+ .u-drawer {
246
+ /* #ifndef APP-NVUE */
247
+ display: block;
248
+ /* #endif */
249
+ position: fixed;
250
+ top: 0;
251
+ left: 0;
252
+ right: 0;
253
+ bottom: 0;
254
+ overflow: hidden;
255
+ }
256
+
257
+ .u-drawer-content {
258
+ /* #ifndef APP-NVUE */
259
+ display: block;
260
+ /* #endif */
261
+ position: absolute;
262
+ z-index: 1003;
263
+ transition: all 0.25s linear;
264
+ }
265
+
266
+ .u-drawer__scroll-view {
267
+ width: 100%;
268
+ height: 100%;
269
+ }
270
+
271
+ .u-drawer-left {
272
+ top: 0;
273
+ bottom: 0;
274
+ left: 0;
275
+ background-color: #ffffff;
276
+ }
277
+
278
+ .u-drawer-right {
279
+ right: 0;
280
+ top: 0;
281
+ bottom: 0;
282
+ background-color: #ffffff;
283
+ }
284
+
285
+ .u-drawer-top {
286
+ top: 0;
287
+ left: 0;
288
+ right: 0;
289
+ background-color: #ffffff;
290
+ }
291
+
292
+ .u-drawer-bottom {
293
+ bottom: 0;
294
+ left: 0;
295
+ right: 0;
296
+ background-color: #ffffff;
297
+ }
298
+
299
+ .u-drawer-center {
300
+ @include vue-flex;
301
+ flex-direction: column;
302
+ bottom: 0;
303
+ left: 0;
304
+ right: 0;
305
+ top: 0;
306
+ justify-content: center;
307
+ align-items: center;
308
+ opacity: 0;
309
+ z-index: 99999;
310
+ }
311
+
312
+ .u-mode-center-box {
313
+ min-width: 100rpx;
314
+ min-height: 100rpx;
315
+ /* #ifndef APP-NVUE */
316
+ display: block;
317
+ /* #endif */
318
+ position: relative;
319
+ background-color: #ffffff;
320
+ }
321
+
322
+ .u-drawer-content-visible.u-drawer-center {
323
+ transform: scale(1);
324
+ opacity: 1;
325
+ }
326
+
327
+ .u-animation-zoom {
328
+ transform: scale(1.15);
329
+ }
330
+
331
+ .u-drawer-content-visible {
332
+ transform: translate3D(0px, 0px, 0px) !important;
333
+ }
334
+
335
+ .u-close {
336
+ position: absolute;
337
+ z-index: 3;
338
+ }
339
+
340
+ .u-close--top-left {
341
+ top: 30rpx;
342
+ left: 30rpx;
343
+ }
344
+
345
+ .u-close--top-right {
346
+ top: 30rpx;
347
+ right: 30rpx;
348
+ }
349
+
350
+ .u-close--bottom-left {
351
+ bottom: 30rpx;
352
+ left: 30rpx;
353
+ }
354
+
355
+ .u-close--bottom-right {
356
+ right: 30rpx;
357
+ bottom: 30rpx;
358
+ }
359
+ </style>