uview-pro 0.6.18 → 0.6.19

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