From d8b41fff43a2cee6a8f714ffa807623b15803786 Mon Sep 17 00:00:00 2001
From: quanyawei <401863037@qq.com>
Date: Fri, 20 Oct 2023 15:21:35 +0800
Subject: [PATCH] fix:立行立改Uniapp小程序新建项目
---
uni_modules/uview-ui/components/u-swipe-action-item/u-swipe-action-item.vue | 190
uni_modules/uview-ui/components/u-dropdown-item/props.js | 36
.hbuilderx/launch.json | 16
uni_modules/uview-ui/components/u-safe-bottom/props.js | 5
uni_modules/uview-ui/libs/mixin/touch.js | 59
utils/storage.js | 30
uni_modules/uview-ui/libs/config/props/checkboxGroup.js | 29
uni_modules/uview-ui/components/u-rate/u-rate.vue | 306
uni_modules/uview-ui/libs/config/props/upload.js | 36
main.js | 25
uni_modules/uview-ui/libs/config/props/codeInput.js | 29
uni_modules/uview-ui/libs/config/props/formItem.js | 23
uni_modules/uview-ui/components/u-empty/props.js | 59
static/logo.png | 0
uni_modules/uview-ui/libs/mixin/button.js | 13
uni_modules/uview-ui/components/u-transition/vue.ani-style.scss | 113
uni_modules/uview-ui/libs/config/props/tabbarItem.js | 20
uni.scss | 77
uni_modules/uview-ui/components/u-button/u-button.vue | 490
uni_modules/uview-ui/components/u-steps-item/props.js | 24
uni_modules/uview-ui/components/u-picker-column/u-picker-column.vue | 27
uni_modules/uview-ui/libs/config/props/numberKeyboard.js | 17
uni_modules/uview-ui/components/u-notify/props.js | 49
uni_modules/uview-ui/libs/config/props/listItem.js | 15
uni_modules/uview-ui/libs/css/nvue.scss | 0
package-lock.json | 11
uni_modules/cl-upload/components/cl-upload/cl-upload.vue | 1031 +
uni_modules/uview-ui/libs/config/props/subsection.js | 23
uni_modules/uview-ui/components/u-cell/u-cell.vue | 229
uni_modules/uview-ui/LICENSE | 21
uni_modules/uview-ui/README.md | 66
uni_modules/uview-ui/components/uview-ui/uview-ui.vue | 15
uni_modules/uview-ui/components/u-tooltip/props.js | 59
uni_modules/uview-ui/libs/config/props/carKeyboard.js | 15
uni_modules/uview-ui/libs/css/common.scss | 97
uni_modules/uview-ui/components/u-loadmore/u-loadmore.vue | 150
uni_modules/uview-ui/components/u-alert/u-alert.vue | 243
uni_modules/uview-ui/components/u-count-down/utils.js | 62
.env.js | 18
uni_modules/uview-ui/components/u-row-notice/u-row-notice.vue | 330
uni_modules/uview-ui/components/u-dropdown-item/u-dropdown-item.vue | 127
uni_modules/uview-ui/components/u-picker-column/props.js | 5
uni_modules/uview-ui/components/u-swiper/props.js | 125
uni_modules/uview-ui/components/u-search/props.js | 118
uni_modules/uview-ui/components/u-row/props.js | 19
static/img/headSculpture.png | 0
uni_modules/uview-ui/components/u-loading-page/u-loading-page.vue | 115
utils/utils.js | 179
uni_modules/uview-ui/libs/config/color.js | 17
uni_modules/uview-ui/components/u-keyboard/props.js | 84
uni_modules/uview-ui/components/u-index-list/props.js | 29
uni_modules/uview-ui/components/u-code-input/props.js | 79
store/modules/index.js | 10
pages/actionChange/components/rectificationInfor.vue | 263
uni_modules/uview-ui/components/u--textarea/u--textarea.vue | 48
uni_modules/uview-ui/libs/config/props/stepsItem.js | 18
uni_modules/uview-ui/components/u-album/u-album.vue | 259
uni_modules/uview-ui/components/u-upload/utils.js | 151
uni_modules/uview-ui/components/u-grid/u-grid.vue | 97
uni_modules/uview-ui/components/u-notice-bar/u-notice-bar.vue | 101
uni_modules/uview-ui/libs/luch-request/adapters/index.js | 97
uni_modules/uview-ui/components/u-avatar-group/u-avatar-group.vue | 103
uni_modules/uview-ui/components/u-datetime-picker/props.js | 116
uni_modules/uview-ui/components/u--form/u--form.vue | 78
uni_modules/uview-ui/components/u-index-anchor/u-index-anchor.vue | 91
uni_modules/uview-ui/components/u-toolbar/u-toolbar.vue | 102
uni_modules/uview-ui/libs/config/props/empty.js | 26
uni_modules/uview-ui/libs/config/props/noticeBar.js | 27
static/img/xinjian.png | 0
uni_modules/uview-ui/libs/config/props/swiper.js | 39
uni_modules/uview-ui/libs/config/props/indexAnchor.js | 19
uni_modules/uview-ui/libs/config/props/countDown.js | 18
static/img/shouyeClick.png | 0
uni_modules/uview-ui/components/u-swipe-action/u-swipe-action.vue | 67
uni_modules/uview-ui/libs/config/props/divider.js | 23
uni_modules/uview-ui/components/u-read-more/props.js | 61
static/img/wode-.png | 0
uni_modules/uview-ui/components/u-tabbar/u-tabbar.vue | 141
uni_modules/uview-ui/components/u-tabs-item/u-tabs-item.vue | 29
uni_modules/uview-ui/components/u-slider/nvue.js | 193
uni_modules/uview-ui/libs/config/props/col.js | 19
pages/actionChange/components/basicInfor.vue | 234
uni_modules/uview-ui/components/u-swipe-action/props.js | 9
uni_modules/uview-ui/components/u-text/u-text.vue | 223
uni_modules/uview-ui/libs/config/props/code.js | 21
uni_modules/uview-ui/components/u-skeleton/u-skeleton.vue | 244
uni_modules/uview-ui/components/u-image/props.js | 84
uni_modules/uview-ui/libs/config/props/alert.js | 22
uni_modules/uview-ui/components/u-radio/props.js | 64
static/img/xinjianClick.png | 0
uni_modules/uview-ui/components/u-table/u-table.vue | 29
uni_modules/uview-ui/components/u-tag/props.js | 84
uni_modules/uview-ui/libs/config/props/noNetwork.js | 18
uni_modules/uview-ui/libs/config/props/tag.js | 29
pages/actionChange/agencyPage/index.vue | 291
uni_modules/uview-ui/components/u-swiper/u-swiper.vue | 255
uni_modules/uview-ui/components/u-index-item/u-index-item.vue | 87
uni_modules/uview-ui/libs/config/props/radioGroup.js | 30
uni_modules/uview-ui/components/u-number-box/props.js | 109
uni_modules/uview-ui/components/u-form/u-form.vue | 214
uni_modules/uview-ui/components/u-grid-item/u-grid-item.vue | 209
uni_modules/uview-ui/components/u-col/u-col.vue | 162
uni_modules/uview-ui/libs/config/props/navbar.js | 32
uni_modules/uview-ui/components/u-car-keyboard/props.js | 14
uni_modules/uview-ui/libs/config/props/readMore.js | 22
uni_modules/uview-ui/components/u-collapse-item/u-collapse-item.vue | 225
uni_modules/uview-ui/components/u-checkbox/props.js | 69
uni_modules/uview-ui/components/u-tooltip/u-tooltip.vue | 365
uni_modules/uview-ui/libs/config/props/actionSheet.js | 25
uni_modules/uview-ui/components/u-index-item/props.js | 5
uni_modules/uview-ui/components/u-sticky/props.js | 40
uni_modules/uview-ui/components/u-button/nvue.scss | 46
uni_modules/uview-ui/package.json | 84
uni_modules/uview-ui/components/u-button/props.js | 161
uni_modules/uview-ui/libs/config/props/image.js | 30
uni_modules/uview-ui/libs/config/props/form.js | 22
uni_modules/uview-ui/components/u-collapse/props.js | 19
uni_modules/uview-ui/libs/config/props/badge.js | 27
uni_modules/uview-ui/components/u-loading-page/props.js | 49
uni_modules/uview-ui/components/u-action-sheet/props.js | 54
uni_modules/uview-ui/libs/function/throttle.js | 30
uni_modules/uview-ui/components/u-datetime-picker/u-datetime-picker.vue | 360
uni_modules/uview-ui/components/u-slider/props.js | 54
uni_modules/uview-ui/components/u-back-top/props.js | 54
uni_modules/uview-ui/components/u-radio/u-radio.vue | 339
uni_modules/uview-ui/components/u-modal/u-modal.vue | 227
uni_modules/uview-ui/libs/config/props/circleProgress.js | 15
uni_modules/uview-ui/components/u-icon/icons.js | 214
.env.prod.js | 4
uni_modules/uview-ui/components/u-subsection/u-subsection.vue | 299
uni_modules/uview-ui/components/u-line/props.js | 33
uni_modules/uview-ui/libs/config/props/transition.js | 18
uni_modules/uview-ui/components/u-toolbar/props.js | 34
uni_modules/uview-ui/libs/config/props/swipterIndicator.js | 19
uni_modules/uview-ui/index.js | 79
uni_modules/uview-ui/components/u-list-item/u-list-item.vue | 116
uni_modules/uview-ui/components/u-swiper-indicator/props.js | 29
uni_modules/uview-ui/libs/config/props/search.js | 37
uni_modules/uview-ui/libs/luch-request/core/defaults.js | 29
uni_modules/uview-ui/libs/config/props/toolbar.js | 21
uni_modules/uview-ui/components/u-dropdown/u-dropdown.vue | 127
uni_modules/uview-ui/libs/function/debounce.js | 29
uni_modules/uview-ui/libs/css/color.scss | 155
uni_modules/uview-ui/libs/config/props/modal.js | 30
uni_modules/uview-ui/components/u-text/props.js | 110
uni_modules/uview-ui/components/u-number-keyboard/props.js | 19
uni_modules/uview-ui/components/u-column-notice/u-column-notice.vue | 160
uni_modules/uview-ui/components/u-album/props.js | 59
uni_modules/uview-ui/libs/css/h5.scss | 0
uni_modules/uview-ui/components/u-steps/u-steps.vue | 80
uni_modules/uview-ui/components/u-dropdown/props.js | 65
uni_modules/uview-ui/components/u-avatar/props.js | 78
uni_modules/uview-ui/libs/config/props/popup.js | 29
uni_modules/uview-ui/index.scss | 23
pages/actionChange/components/approvalnfor.vue | 230
uni_modules/uview-ui/libs/config/props/link.js | 26
uni_modules/uview-ui/components/u-icon/u-icon.vue | 234
uni_modules/uview-ui/libs/config/props/checkbox.js | 27
uni_modules/uview-ui/components/u-avatar/u-avatar.vue | 172
uni_modules/uview-ui/libs/config/props/input.js | 48
uni_modules/uview-ui/libs/util/async-validator.js | 1343 +
uni_modules/uview-ui/components/u-car-keyboard/u-car-keyboard.vue | 311
uni_modules/uview-ui/libs/config/props/slider.js | 25
uni_modules/uview-ui/components/u-text/value.js | 85
uni_modules/uview-ui/components/u-subsection/props.js | 49
uni_modules/uview-ui/libs/config/props/row.js | 17
uni_modules/uview-ui/components/u-calendar/header.vue | 99
uni_modules/uview-ui/components/u-code/props.js | 34
uni_modules/uview-ui/components/u-navbar/u-navbar.vue | 186
uni_modules/uview-ui/components/u-popup/u-popup.vue | 304
uni_modules/uview-ui/components/u-tr/props.js | 5
uni_modules/uview-ui/components/u-steps/props.js | 39
uni_modules/uview-ui/components/u-td/u-td.vue | 31
uni_modules/uview-ui/libs/config/props.js | 190
static/img/shouye.png | 0
uni_modules/uview-ui/components/u-cell/props.js | 110
uni_modules/uview-ui/libs/config/config.js | 34
uni_modules/uview-ui/libs/function/test.js | 288
uni_modules/uview-ui/components/u-steps-item/u-steps-item.vue | 316
uni_modules/uview-ui/components/u-transition/nvue.ani-map.js | 68
uni_modules/uview-ui/libs/luch-request/utils/clone.js | 264
README.md | 4
uni_modules/uview-ui/components/u-calendar/props.js | 144
uni_modules/uview-ui/libs/config/props/statusBar.js | 15
uni_modules/uview-ui/components/u-modal/props.js | 84
uni_modules/uview-ui/components/u-badge/props.js | 72
uni_modules/uview-ui/components/u-collapse-item/props.js | 59
uni_modules/uview-ui/components/u-search/u-search.vue | 303
uni_modules/uview-ui/components/u-parse/node/node.vue | 499
uni_modules/uview-ui/components/u-form-item/props.js | 48
uni_modules/uview-ui/libs/config/props/picker.js | 29
uni_modules/uview-ui/libs/config/props/radio.js | 27
utils/login.js | 42
uni_modules/uview-ui/components/u-no-network/u-no-network.vue | 220
uni_modules/uview-ui/libs/config/props/textarea.js | 36
uni_modules/uview-ui/components/u--text/u--text.vue | 44
uni_modules/uview-ui/libs/config/props/grid.js | 17
uni_modules/uview-ui/libs/config/props/loadmore.js | 32
uni_modules/uview-ui/libs/config/props/datetimePicker.js | 36
uni_modules/uview-ui/components/u-circle-progress/u-circle-progress.vue | 198
uni_modules/uview-ui/libs/luch-request/core/dispatchRequest.js | 3
uni_modules/uview-ui/components/u-button/vue.scss | 80
uni_modules/uview-ui/libs/mixin/mpShare.js | 13
uni_modules/uview-ui/components/u-number-keyboard/u-number-keyboard.vue | 196
uni_modules/uview-ui/libs/config/props/steps.js | 21
uni_modules/uview-ui/libs/config/props/sticky.js | 20
uni_modules/uview-ui/components/u-index-list/u-index-list.vue | 440
uni_modules/uview-ui/components/u-overlay/props.js | 24
uni_modules/uview-ui/components/u-parse/u-parse.vue | 366
pages/actionChange/newPage/index.vue | 410
uni_modules/uview-ui/components/u-no-network/props.js | 19
uni_modules/uview-ui/components/u-transition/u-transition.vue | 92
uni_modules/cl-upload/readme.md | 253
pages/login/register/register.vue | 74
uni_modules/uview-ui/libs/config/props/numberBox.js | 35
uni_modules/uview-ui/components/u-swipe-action-item/wxs.js | 15
uni_modules/uview-ui/components/u-line/u-line.vue | 62
uni_modules/uview-ui/libs/luch-request/core/InterceptorManager.js | 50
uni_modules/uview-ui/components/u-grid/props.js | 19
store/modules/user.js | 111
uni_modules/uview-ui/libs/util/emitter.js | 51
pages/actionChange/workOrderDetails/index.vue | 106
uni_modules/uview-ui/components/u-badge/u-badge.vue | 171
uni_modules/uview-ui/components/u-count-down/props.js | 24
uni_modules/uview-ui/libs/config/props/toast.js | 30
uni_modules/uview-ui/libs/luch-request/core/settle.js | 16
uni_modules/uview-ui/components/u-slider/mpwxs.wxs | 121
uni_modules/cl-upload/components/cl-image/cl-image.vue | 60
uni_modules/uview-ui/libs/luch-request/utils.js | 131
uni_modules/uview-ui/components/u-parse/parser.js | 1075 +
uni_modules/uview-ui/components/u--input/u--input.vue | 73
uni_modules/uview-ui/components/u-list-item/props.js | 9
uni_modules/uview-ui/components/u-row/u-row.vue | 93
uni_modules/uview-ui/components/u-keyboard/u-keyboard.vue | 164
uni_modules/uview-ui/libs/config/props/countTo.js | 25
uni_modules/uview-ui/libs/config/props/rowNotice.js | 21
uni_modules/uview-ui/components/u-divider/u-divider.vue | 116
uni_modules/uview-ui/components/u-action-sheet/u-action-sheet.vue | 278
uni_modules/uview-ui/components/u-td/props.js | 5
uni_modules/uview-ui/components/u-parse/props.js | 45
uni_modules/uview-ui/components/u-link/u-link.vue | 83
uni_modules/uview-ui/components/u-checkbox-group/u-checkbox-group.vue | 103
uni_modules/uview-ui/libs/config/props/tabs.js | 32
uni_modules/uview-ui/libs/css/vue.scss | 27
uni_modules/uview-ui/components/u-form-item/u-form-item.vue | 235
uni_modules/uview-ui/libs/config/props/text.js | 38
uni_modules/uview-ui/libs/config/props/scrollList.js | 20
uni_modules/uview-ui/libs/luch-request/helpers/isAbsoluteURL.js | 14
uni_modules/uview-ui/components/u-textarea/u-textarea.vue | 239
uni_modules/uview-ui/components/u-count-to/props.js | 59
uni_modules/uview-ui/components/u-back-top/u-back-top.vue | 129
uni_modules/uview-ui/components/u-code/u-code.vue | 129
uni_modules/uview-ui/components/u-tabs/u-tabs.vue | 354
uni_modules/uview-ui/libs/css/components.scss | 15
uni_modules/uview-ui/components/u-slider/nvue - 副本.js | 180
uni_modules/uview-ui/components/u-upload/mixin.js | 21
uni_modules/uview-ui/libs/config/props/columnNotice.js | 24
pages/index/index.vue | 5
uni_modules/uview-ui/components/u-radio-group/u-radio-group.vue | 108
uni_modules/uview-ui/libs/config/props/overlay.js | 18
uni_modules/cl-upload/package.json | 82
uni_modules/uview-ui/libs/css/flex.scss | 257
uni_modules/uview-ui/libs/util/dayjs.js | 308
uni_modules/uview-ui/components/u-link/props.js | 39
uni_modules/uview-ui/libs/config/props/list.js | 28
utils/request.js | 74
uni_modules/uview-ui/libs/config/props/tabbar.js | 22
uni_modules/uview-ui/components/u-image/u-image.vue | 232
uni_modules/uview-ui/components/u-loading-icon/u-loading-icon.vue | 343
uni_modules/uview-ui/components/u-notify/u-notify.vue | 211
uni_modules/uview-ui/libs/config/props/collapseItem.js | 25
uni_modules/uview-ui/components/u-textarea/props.js | 119
uni_modules/uview-ui/components/u-checkbox/u-checkbox.vue | 344
uni_modules/uview-ui/libs/config/props/button.js | 42
uni_modules/uview-ui/libs/luch-request/helpers/combineURLs.js | 14
uni_modules/uview-ui/libs/config/props/switch.js | 24
uni_modules/uview-ui/components/u-picker/u-picker.vue | 283
uni_modules/uview-ui/libs/mixin/mpMixin.js | 8
index.html | 20
uni_modules/uview-ui/components/u-count-to/u-count-to.vue | 184
uni_modules/uview-ui/components/u-tag/u-tag.vue | 358
uni_modules/uview-ui/components/u-swipe-action-item/index.wxs | 225
uni_modules/uview-ui/components/u-column-notice/props.js | 55
uni_modules/uview-ui/components/u-radio-group/props.js | 85
uni_modules/uview-ui/libs/util/route.js | 124
uni_modules/uview-ui/components/u-input/u-input.vue | 354
uni_modules/uview-ui/libs/config/props/swipeActionItem.js | 21
uni_modules/uview-ui/libs/config/props/avatarGroup.js | 23
uni_modules/uview-ui/components/u-calendar/month.vue | 579
uni_modules/uview-ui/theme.scss | 44
uni_modules/uview-ui/components/u-upload/u-upload.vue | 558
uni_modules/uview-ui/components/u-scroll-list/u-scroll-list.vue | 224
uni_modules/uview-ui/components/u--image/u--image.vue | 47
.gitignore | 2
uni_modules/uview-ui/libs/config/props/cell.js | 35
uni_modules/uview-ui/libs/config/props/gridItem.js | 16
uni_modules/uview-ui/components/u-divider/props.js | 44
uni_modules/uview-ui/libs/luch-request/index.d.ts | 116
uni_modules/uview-ui/libs/config/props/calendar.js | 42
uni_modules/uview-ui/components/u-col/props.js | 29
uni_modules/uview-ui/libs/config/props/avatar.js | 28
uni_modules/uview-ui/libs/config/props/swipeAction.js | 15
uni_modules/uview-ui/libs/config/props/tooltip.js | 25
uni_modules/uview-ui/libs/luch-request/helpers/buildURL.js | 69
uni_modules/uview-ui/components/u-cell-group/u-cell-group.vue | 61
uni_modules/uview-ui/components/u-upload/props.js | 124
uni_modules/uview-ui/components/u-status-bar/props.js | 8
uni_modules/uview-ui/components/u-gap/u-gap.vue | 38
uni_modules/uview-ui/components/u-picker/props.js | 79
uni_modules/uview-ui/components/u-slider/mpwxs.js | 42
manifest.json | 75
uni_modules/uview-ui/components/u-grid-item/props.js | 14
uni_modules/uview-ui/components/u-loadmore/props.js | 94
uni_modules/uview-ui/libs/function/colorGradient.js | 134
uni_modules/uview-ui/changelog.md | 362
uni_modules/uview-ui/libs/css/mp.scss | 0
uni_modules/uview-ui/components/u-row-notice/props.js | 39
uni_modules/uview-ui/libs/config/props/skeleton.js | 25
uni_modules/uview-ui/libs/function/index.js | 731 +
uni_modules/cl-upload/changelog.md | 77
uni_modules/uview-ui/components/u-avatar-group/props.js | 52
uni_modules/uview-ui/components/u-form/props.js | 45
uni_modules/uview-ui/components/u-index-anchor/props.js | 29
uni_modules/uview-ui/libs/config/props/line.js | 20
uni_modules/uview-ui/libs/config/props/icon.js | 36
uni_modules/uview-ui/libs/config/props/loadingPage.js | 23
uni_modules/uview-ui/libs/luch-request/index.js | 3
uni_modules/uview-ui/libs/config/props/parse.js | 22
uni_modules/uview-ui/components/u-loading-icon/props.js | 59
uni_modules/uview-ui/components/u-calendar/u-calendar.vue | 384
uni_modules/uview-ui/libs/config/props/collapse.js | 17
uni_modules/uview-ui/components/u-swiper-indicator/u-swiper-indicator.vue | 110
uni_modules/uview-ui/components/u-table/props.js | 5
uni_modules/uview-ui/libs/luch-request/core/mergeConfig.js | 103
uni_modules/uview-ui/components/u-status-bar/u-status-bar.vue | 46
uni_modules/uview-ui/libs/css/mixin.scss | 8
uni_modules/uview-ui/components/u-tabs/props.js | 64
uni_modules/uview-ui/components/u-scroll-list/other.js | 0
uni_modules/uview-ui/components/u-tooltip/clipboard.min.js | 58
uni_modules/uview-ui/libs/config/props/keyboard.js | 30
store/index.js | 7
uni_modules/uview-ui/libs/function/digit.js | 167
uni_modules/uview-ui/components/u-transition/props.js | 24
uni_modules/uview-ui/components/u-skeleton/props.js | 59
pages/actionChange/myInfor/index.vue | 91
uni_modules/uview-ui/components/u-tabbar/props.js | 44
utils/http.js | 28
uni_modules/uview-ui/components/u-toast/u-toast.vue | 291
uni_modules/uview-ui/components/u-collapse/u-collapse.vue | 90
uni_modules/uview-ui/components/u-rate/props.js | 69
uni_modules/uview-ui/components/u-line-progress/u-line-progress.vue | 144
uni_modules/uview-ui/components/u-scroll-list/nvue.js | 28
uni_modules/uview-ui/libs/config/props/loadingIcon.js | 30
uni_modules/uview-ui/components/u-circle-progress/props.js | 8
uni_modules/uview-ui/components/u-scroll-list/scrollWxs.wxs | 50
uni_modules/uview-ui/components/u-checkbox-group/props.js | 82
uni_modules/uview-ui/components/u-notice-bar/props.js | 70
uni_modules/uview-ui/components/u-switch/props.js | 54
unpackage/.gitkeep | 0
uni_modules/uview-ui/components/u-list/props.js | 76
uni_modules/uview-ui/components/u-popup/props.js | 79
uni_modules/uview-ui/libs/config/props/indexList.js | 19
uni_modules/uview-ui/components/u-overlay/u-overlay.vue | 68
uni_modules/uview-ui/components/u-line-progress/props.js | 28
uni_modules/uview-ui/components/u-sticky/u-sticky.vue | 212
uni_modules/uview-ui/components/u-alert/props.js | 44
uni_modules/uview-ui/components/u-tr/u-tr.vue | 31
uni_modules/uview-ui/libs/config/props/gap.js | 19
uni_modules/uview-ui/libs/mixin/style.js | 228
uni_modules/uview-ui/components/u-slider/u-slider.vue | 55
uni_modules/uview-ui/components/u-switch/u-switch.vue | 177
.env.dev.js | 6
uni_modules/uview-ui/components/u-list/u-list.vue | 157
uni_modules/uview-ui/components/u-transition/transition.js | 157
uni_modules/uview-ui/components/u-swipe-action-item/nvue.js | 174
pages.json | 70
uni_modules/uview-ui/libs/luch-request/core/buildFullPath.js | 20
uni_modules/uview-ui/components/u-swipe-action-item/props.js | 41
uni_modules/uview-ui/libs/config/props/rate.js | 26
uni_modules/uview-ui/components/u-input/props.js | 187
uni_modules/uview-ui/libs/luch-request/core/Request.js | 198
uni_modules/uview-ui/components/u-slider/mpother.js | 113
uni_modules/uview-ui/components/u-swipe-action-item/index - backup.wxs | 256
uni_modules/uview-ui/components/u-code-input/u-code-input.vue | 252
uni_modules/uview-ui/libs/function/platform.js | 75
uni_modules/uview-ui/components/u-cell-group/props.js | 14
uni_modules/uview-ui/components/u-tabs-item/props.js | 5
static/img/wodeClick.png | 0
uni_modules/uview-ui/components/u-swipe-action-item/nvue - backup.js | 270
uni_modules/uview-ui/components/u-empty/u-empty.vue | 128
uni_modules/uview-ui/libs/util/calendar.js | 546
App.vue | 93
pages/actionChange/components/fileUpload.vue | 87
uni_modules/uview-ui/components/u-read-more/u-read-more.vue | 157
uni_modules/uview-ui/components/u-scroll-list/props.js | 34
uni_modules/uview-ui/components/u-tabbar-item/props.js | 35
uni.promisify.adaptor.js | 10
uni_modules/uview-ui/libs/config/props/cellGroup.js | 17
uni_modules/uview-ui/libs/mixin/openType.js | 25
uni_modules/uview-ui/components/u-number-box/u-number-box.vue | 416
uni_modules/uview-ui/libs/config/props/notify.js | 22
uni_modules/uview-ui/components/u-tabbar-item/u-tabbar-item.vue | 142
pages/login/login.vue | 173
uni_modules/uview-ui/libs/config/props/backtop.js | 27
uni_modules/uview-ui/libs/config/props/section.js | 24
uni_modules/uview-ui/components/u-calendar/util.js | 85
uni_modules/uview-ui/components/u-gap/props.js | 24
uni_modules/uview-ui/components/u-count-down/u-count-down.vue | 163
uni_modules/uview-ui/libs/config/props/album.js | 25
uni_modules/uview-ui/libs/config/props/lineProgress.js | 19
uni_modules/uview-ui/libs/config/zIndex.js | 20
uni_modules/uview-ui/libs/mixin/mixin.js | 160
uni_modules/uview-ui/components/u-icon/props.js | 89
uni_modules/uview-ui/components/u-navbar/props.js | 84
uni_modules/uview-ui/components/u-safe-bottom/u-safe-bottom.vue | 56
415 files changed, 42,875 insertions(+), 0 deletions(-)
diff --git a/.env.dev.js b/.env.dev.js
new file mode 100644
index 0000000..ed166ca
--- /dev/null
+++ b/.env.dev.js
@@ -0,0 +1,6 @@
+const config = {
+ baseUrl: "http://120.26.43.34:8081/api", //������
+ // baseUrl: "http://47.99.64.149:8081/api", //������
+ // baseUrl: "http://192.168.0.9:8081/api", //������
+};
+module.exports = config;
\ No newline at end of file
diff --git a/.env.js b/.env.js
new file mode 100644
index 0000000..5a2a2fd
--- /dev/null
+++ b/.env.js
@@ -0,0 +1,18 @@
+let ENV_CONFIG = {};
+if (process.env.NODE_ENV === "development") {
+ //������������
+ ENV_CONFIG = require(".env.dev.js");
+ console.log("���������������");
+} else {
+ //������������
+ ENV_CONFIG = require(".env.prod.js");
+ console.log("���������������");
+}
+
+//���������������process.uniEnv������
+if (ENV_CONFIG) {
+ process.uniEnv = {};
+ for (let key in ENV_CONFIG) {
+ process.uniEnv[key] = ENV_CONFIG[key];
+ }
+}
diff --git a/.env.prod.js b/.env.prod.js
new file mode 100644
index 0000000..a574ccd
--- /dev/null
+++ b/.env.prod.js
@@ -0,0 +1,4 @@
+const config = {
+ baseUrl: "http://47.99.64.149:8081/api/",
+};
+module.exports = config;
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..685f9fe
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,2 @@
+/unpackage/dist
+/node_modules
\ No newline at end of file
diff --git a/.hbuilderx/launch.json b/.hbuilderx/launch.json
new file mode 100644
index 0000000..81f13f4
--- /dev/null
+++ b/.hbuilderx/launch.json
@@ -0,0 +1,16 @@
+{ // launch.json ���������������������������������������configurations��������������������� app-plus/h5/mp-weixin/mp-baidu/mp-alipay/mp-qq/mp-toutiao/mp-360/
+ // launchtype������������������local���remote, local���������������������������������remote������������������������������
+ "version": "0.0",
+ "configurations": [{
+ "default" :
+ {
+ "launchtype" : "local"
+ },
+ "mp-weixin" :
+ {
+ "launchtype" : "local"
+ },
+ "type" : "uniCloud"
+ }
+ ]
+}
diff --git a/App.vue b/App.vue
new file mode 100644
index 0000000..dd2c821
--- /dev/null
+++ b/App.vue
@@ -0,0 +1,93 @@
+<script>
+ import Vue from 'vue'
+ import {
+ getUserInfor,
+ getDic
+ } from '@/utils/login.js' // ������������
+ import {
+ httpPost,
+ httpGet
+ } from '@/utils/http.js'
+ export default {
+ onLaunch: function() {
+ // ������������������
+ this.getUserInfo()
+ },
+ methods: {
+ /**
+ * ������������
+ * ���������������������������������������������������������������������
+ *
+ */
+ getUserInfo() {
+ uni.login({
+ provider: 'weixin',
+ success(res) {
+ if (res.code) {
+ // ������������������������code������������������������
+ httpGet('/AppUser/wx/login', {
+ 'code': res.code
+ }).then(result => {
+ if (result.data.code === 0) {
+ // ������������
+ uni.clearStorageSync()
+ uni.setStorageSync('token', result.data.token)
+ // setTimeout(() => {
+ // uni.reLaunch({
+ // url: '/pages/actionChange/agencyPage/index',
+ // })
+ // }, 3000)
+ getUserInfor(result.data.token)
+ getDic()
+ } else {
+ // ���������������
+ uni.setStorageSync('openId', result.data.openId)
+ uni.showModal({
+ title: '���������',
+ content: '������������������������������������������',
+ showCancel: false,
+ confirmText: '������',
+ success: res => {
+ if (res.confirm) {
+ uni.reLaunch({
+ url: '/pages/login/login',
+ })
+ }
+ },
+ })
+ }
+ })
+ } else {
+ console.log(res.errMsg)
+ }
+ }
+ })
+ },
+ },
+ }
+</script>
+<style lang="scss">
+ /* ������������������������������������style������������lang="scss"������ */
+ @import "@/uni_modules/uview-ui/index.scss";
+
+ html {
+ height: 100%;
+ }
+
+ .formItemContent {
+ ::v-deep.u-form-item {
+ padding: 8px 0;
+ border-bottom: 1px dashed #bbb;
+ }
+
+ ::v-deep.u-form-item__body,
+ /deep/.u-textarea {
+ padding: 0 !important;
+ }
+
+ ::v-deep.u-form-item__body__left__content__label,
+ /deep/.u-radio__text {
+ font-size: 13px !important;
+ }
+ }
+</style>
\ No newline at end of file
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..b8af7aa
--- /dev/null
+++ b/README.md
@@ -0,0 +1,4 @@
+## moral_applet_allocation
+
+���������������������
+
diff --git a/index.html b/index.html
new file mode 100644
index 0000000..c3ff205
--- /dev/null
+++ b/index.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<html lang="en">
+ <head>
+ <meta charset="UTF-8" />
+ <script>
+ var coverSupport = 'CSS' in window && typeof CSS.supports === 'function' && (CSS.supports('top: env(a)') ||
+ CSS.supports('top: constant(a)'))
+ document.write(
+ '<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0' +
+ (coverSupport ? ', viewport-fit=cover' : '') + '" />')
+ </script>
+ <title></title>
+ <!--preload-links-->
+ <!--app-context-->
+ </head>
+ <body>
+ <div id="app"><!--app-html--></div>
+ <script type="module" src="/main.js"></script>
+ </body>
+</html>
diff --git a/main.js b/main.js
new file mode 100644
index 0000000..3892abb
--- /dev/null
+++ b/main.js
@@ -0,0 +1,25 @@
+import Vue from "vue";
+import App from "./App";
+import * as http from "./utils/http"; // http������������
+import * as login from "./utils/login"; // ������
+import * as utils from "./utils/utils"; // ������������
+// import * as common from './utils/common' // ������������
+import store from "./store";
+import storage from "./utils/storage"; // ������������
+import ".env.js";
+// ������������
+Vue.prototype.$store = store;
+Vue.prototype.$storage = storage;
+Vue.prototype.$http = http;
+Vue.prototype.$login = login;
+Vue.prototype.$utils = utils;
+// Vue.prototype.$common = common
+
+App.mpType = "app";
+const app = new Vue({
+ store,
+ ...App,
+});
+app.$mount();
+import uView from "@/uni_modules/uview-ui";
+Vue.use(uView);
diff --git a/manifest.json b/manifest.json
new file mode 100644
index 0000000..5bf1825
--- /dev/null
+++ b/manifest.json
@@ -0,0 +1,75 @@
+{
+ "name" : "test",
+ "appid" : "__UNI__93C3197",
+ "description" : "",
+ "versionName" : "1.0.0",
+ "versionCode" : "100",
+ "transformPx" : false,
+ /* 5+App������������ */
+ "app-plus" : {
+ "usingComponents" : true,
+ "nvueStyleCompiler" : "uni-app",
+ "compilerVersion" : 3,
+ "splashscreen" : {
+ "alwaysShowBeforeRender" : true,
+ "waiting" : true,
+ "autoclose" : true,
+ "delay" : 0
+ },
+ /* ������������ */
+ "modules" : {},
+ /* ������������������ */
+ "distribute" : {
+ /* android������������ */
+ "android" : {
+ "permissions" : [
+ "<uses-permission android:name=\"android.permission.CHANGE_NETWORK_STATE\"/>",
+ "<uses-permission android:name=\"android.permission.MOUNT_UNMOUNT_FILESYSTEMS\"/>",
+ "<uses-permission android:name=\"android.permission.VIBRATE\"/>",
+ "<uses-permission android:name=\"android.permission.READ_LOGS\"/>",
+ "<uses-permission android:name=\"android.permission.ACCESS_WIFI_STATE\"/>",
+ "<uses-feature android:name=\"android.hardware.camera.autofocus\"/>",
+ "<uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\"/>",
+ "<uses-permission android:name=\"android.permission.CAMERA\"/>",
+ "<uses-permission android:name=\"android.permission.GET_ACCOUNTS\"/>",
+ "<uses-permission android:name=\"android.permission.READ_PHONE_STATE\"/>",
+ "<uses-permission android:name=\"android.permission.CHANGE_WIFI_STATE\"/>",
+ "<uses-permission android:name=\"android.permission.WAKE_LOCK\"/>",
+ "<uses-permission android:name=\"android.permission.FLASHLIGHT\"/>",
+ "<uses-feature android:name=\"android.hardware.camera\"/>",
+ "<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>"
+ ]
+ },
+ /* ios������������ */
+ "ios" : {},
+ /* SDK������ */
+ "sdkConfigs" : {}
+ }
+ },
+ /* ��������������������� */
+ "quickapp" : {},
+ /* ��������������������� */
+ "mp-weixin" : {
+ "appid" : "wx41f4c3c007545088",
+ "setting" : {
+ "urlCheck" : false,
+ "es6" : true,
+ "postcss" : true,
+ "minified" : true
+ },
+ "usingComponents" : true
+ },
+ "mp-alipay" : {
+ "usingComponents" : true
+ },
+ "mp-baidu" : {
+ "usingComponents" : true
+ },
+ "mp-toutiao" : {
+ "usingComponents" : true
+ },
+ "uniStatistics" : {
+ "enable" : false
+ },
+ "vueVersion" : "2"
+}
diff --git a/package-lock.json b/package-lock.json
new file mode 100644
index 0000000..d901b5d
--- /dev/null
+++ b/package-lock.json
@@ -0,0 +1,11 @@
+{
+ "requires": true,
+ "lockfileVersion": 1,
+ "dependencies": {
+ "dayjs": {
+ "version": "1.11.10",
+ "resolved": "https://registry.npmmirror.com/dayjs/-/dayjs-1.11.10.tgz",
+ "integrity": "sha512-vjAczensTgRcqDERK0SR2XMwsF/tSvnvlv6VcF2GIhg6Sx4yOIt/irsr1RDJsKiIyBzJDpCoXiWWq28MqH2cnQ=="
+ }
+ }
+}
diff --git a/pages.json b/pages.json
new file mode 100644
index 0000000..f0efe61
--- /dev/null
+++ b/pages.json
@@ -0,0 +1,70 @@
+{
+ "pages": [
+ //pages���������������������������������������������������https://uniapp.dcloud.io/collocation/pages
+
+ {
+ "path": "pages/actionChange/agencyPage/index",
+ "style": {
+ "navigationBarTitleText": "������",
+ "enablePullDownRefresh": false
+ }
+ },
+ {
+ "path": "pages/login/login"
+ },
+ {
+ "path": "pages/login/register/register",
+ "style": {
+ "navigationBarTitleText": "������",
+ "enablePullDownRefresh": false
+ }
+ },
+ {
+ "path": "pages/actionChange/newPage/index", //���������������������������
+ "style": {
+ "navigationBarTitleText": "���������������",
+ "enablePullDownRefresh": false,
+ "navigationBarHidden":true
+ }
+ },
+ {
+ "path": "pages/actionChange/workOrderDetails/index", //���������������������������
+ "style": {
+ "navigationBarTitleText": "���������������",
+ "enablePullDownRefresh": false
+ }
+ },
+ {
+ "path": "pages/actionChange/myInfor/index",
+ "style": {
+ "navigationBarTitleText": "������",
+ "enablePullDownRefresh": false
+ }
+ }
+ ],
+ "tabBar": {
+ "color": "#515151",
+ "selectedColor": "#3875C5",
+ "list": [
+ {
+ "text": "������",
+ "pagePath": "pages/actionChange/agencyPage/index",
+ "iconPath": "static/img/shouye.png",
+ "selectedIconPath": "static/img/shouyeClick.png"
+ },
+ {
+ "text": "���������������",
+ "pagePath": "pages/actionChange/newPage/index",
+ "iconPath": "static/img/xinjian.png",
+ "selectedIconPath": "static/img/xinjianClick.png"
+ },
+
+ {
+ "text": "������",
+ "iconPath": "static/img/wode-.png",
+ "selectedIconPath": "static/img/wodeClick.png",
+ "pagePath": "pages/actionChange/myInfor/index"
+ }
+ ]
+ }
+}
diff --git a/pages/actionChange/agencyPage/index.vue b/pages/actionChange/agencyPage/index.vue
new file mode 100644
index 0000000..5c535ca
--- /dev/null
+++ b/pages/actionChange/agencyPage/index.vue
@@ -0,0 +1,291 @@
+<template>
+ <view>
+ <view class="hearderInfor">
+ <view>
+ <p class="unit">
+ <text>���������������{{ userInfor.userName ||''}}</text>
+ </p>
+ </view>
+ <view class="headSculpture">
+ <image alt="" src="/static/img/headSculpture.png" />
+ <text>������������{{ userInfor.userName || ''}}</text>
+ </view>
+ </view>
+ <view>
+ <u-tabs :list="list" :scrollable="scrollable" @change="changeTap" />
+ </view>
+ <view class="" v-if="userInfor.userName">
+ <view :key="index" v-for="(item, index) in workOderList" class="workOrderDetail"
+ @tap="handleClick(item, 'edit')">
+ <view class="mainContent">
+ <p class="rowTip" style="justify-content: space-between">
+ <text class=""> ������������: {{ item.allocationNum }}
+ </text>
+ <text class="rowTipContenet_right">
+ <text catchtap class="butsName" @tap.stop="handleClick(item, 'view')"> ������ </text>
+ <text catchtap class="butsName" @tap.stop="handleClick(item, 'edit')">
+ {{ item.stateName }}
+ </text>
+ </text>
+ </p>
+ </view>
+ <u-line color="#bbb" />
+ <view class="mainContent">
+ <p class="rowTip">
+ <view class="rowTipContenet">
+ <view class="wholeLine">
+ <text class="rowTipContenetLabel">������������:</text>
+ <text class="rowTipContenetAll">
+ {{ unitList.find(
+ (a) => item && parseInt(a.unitId) === item.unitId
+ ).unitName
+ }}
+ </text>
+ </view>
+ </view>
+ <view class="rowTipContenet">
+ <view class="wholeLine">
+ <text class="rowTipContenetLabel">������������:</text>
+ <text class="rowTipContenetAll">
+ {{ polluteList.find(
+ (a) => item && parseInt(a.dataKey) === item.polluteType
+ ).dataValue
+ }}
+ </text>
+ </view>
+ </view>
+ </p>
+ </view>
+ <view class="mainContent">
+ <p class="rowTip">
+ <view class="rowTipContenet">
+ <view class="wholeLine">
+ <text class="rowTipContenetLabel">������������:</text>
+ <text class="rowTipContenetAll">
+ {{ dictObj.changeEnum[item.changeType] }}
+ </text>
+ </view>
+ </view>
+ <view class="rowTipContenet">
+ <view class="wholeLine">
+ <text class="rowTipContenetLabel">������������:</text>
+ <text class="rowTipContenetAll">
+ {{ stateFormatter(item.state) }}
+ </text>
+ </view>
+ </view>
+ </p>
+ </view>
+ <view class="mainContent">
+ <p class="rowTip">
+ <view class="rowTipContenet">
+ <view class="wholeLine">
+ <text class="rowTipContenetLabel">������������:</text>
+ <text class="rowTipContenetAll">
+ {{ item.escalationTime }}
+ </text>
+ </view>
+ </view>
+ <view class="rowTipContenet">
+ <view class="wholeLine">
+ <text class="rowTipContenetLabel">������������:</text>
+ <text class="rowTipContenetAll">
+ {{ unitList.find(
+ (a) =>
+ item && parseInt(a.unitId) === item.escalationUnitId
+ ).unitName
+ }}
+ </text>
+ </view>
+ </view>
+ </p>
+ </view>
+ <view class="mainContent">
+ <p class="rowTip">
+ <view class="wholeLine">
+ <text class="rowTipContenetLabel">������������:</text>
+ <text class="rowTipContenetAll">{{ item.pollutePosition }}</text>
+ </view>
+ </p>
+ </view>
+ </view>
+ </view>
+ </view>
+</template>
+<script>
+ import {
+ httpPost,
+ httpGet
+ } from '@/utils/http.js'
+ export default {
+ data() {
+ return {
+ scrollable: false,
+ userInfor: {},
+ dictObj: [],
+ list: [{
+ name: '������',
+ value: 0,
+ }, {
+ name: '���������',
+ value: 1,
+ }, {
+ name: '���������',
+ value: 2,
+ }, {
+ name: '���������',
+ value: 3,
+ }, ],
+ current: 0,
+ workOderList: [],
+ unitList: [],
+ polluteList: [],
+ }
+ },
+ mounted() {
+ console.log('mounted this.userInfo', this.userInfo)
+ },
+ created() {
+ console.log('created this.userInfo', this.userInfo)
+ this.getContaminateList()
+ this.getUnitList()
+ this.getWorkOrder()
+ },
+ onShow() {
+ uni.showTabBar()
+ },
+ methods: {
+ changeTap(data) {
+ this.current = data.value
+ this.getWorkOrder()
+ },
+ // ������������������list
+ getUnitList() {
+ this.$http.httpGet('/allocation/unit').then(res => {
+ this.unitList = res.data
+ this.userInfor = this.$storage.getJson('userInfo')
+ this.dictObj = this.$storage.getJson('dictObj')
+ this.$storage.setJson('unitList', this.unitList)
+ })
+ },
+ getContaminateList() {
+ this.$http.httpGet('/allocation/contaminate').then(res => {
+ this.polluteList = res.data
+ this.$storage.setJson('polluteList', this.polluteList)
+ })
+ },
+ stateFormatter(val) {
+ return this.dictObj.allocationApproveEnum[val]
+ },
+ getWorkOrder() {
+ httpGet('/allocationApp/select', {
+ state: this.current,
+ startTime: '',
+ endTime: '',
+ }).then(res => {
+ this.workOderList = res.data
+ })
+ },
+ handleClick(e, pageState) {
+ this.$http.httpGet('/allocation/detail', {
+ id: e.allocationId
+ }).then(res => {
+ let data = res.data
+ data.pageState = pageState
+ let myData = JSON.stringify(data)
+ uni.navigateTo({
+ url: '/pages/actionChange/workOrderDetails/index?infor=' + myData,
+ })
+ })
+ },
+ },
+ // onShow() {},
+ }
+</script>
+<style scoped lang="scss">
+ /deep/.uni-page-head {
+ display: none;
+ }
+
+ .hearderInfor {
+ font-size: 26.92rpx;
+ height: 223.08rpx;
+ background-color: #3875c5;
+ color: #f2f2f2;
+
+ .unit {
+ text-align: right;
+ padding-right: 19.23rpx;
+ padding-top: 19.23rpx;
+ }
+
+ .headSculpture {
+ display: flex;
+ align-items: center;
+
+ image {
+ height: 117.31rpx;
+ width: 117.31rpx;
+ margin: 0rpx 46.15rpx;
+ }
+ }
+ }
+
+ .textContent {
+ text-align: left;
+ width: 100%;
+ font-size: 28.85rpx;
+ }
+
+ .workOrderDetail {
+ border: 1px solid #bbb;
+ border-radius: 5px;
+ min-height: 288.46rpx;
+ margin: 19.23rpx;
+ padding: 19.23rpx;
+ color: #101010;
+ font-weight: 700;
+ font-size: 26.92rpx;
+
+ /deep/.u-line {
+ margin: 19.23rpx 0px !important;
+ }
+
+ .mainContent {
+ margin-bottom: 10px;
+
+ .rowTip {
+ display: flex;
+
+ .wholeLine {
+ display: flex;
+
+ .rowTipContenetLabel {
+ min-width: 125rpx;
+ }
+ }
+
+ .rowTipContenetAll {
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+ }
+
+ .rowTipContenet {
+ width: 50%;
+ text-align: left;
+ }
+ }
+
+ .butsName {
+ display: inline-block;
+ margin-left: 19.23rpx;
+ color: #1990ff;
+ }
+
+ .rowTipContenet_right {
+ text-align: right !important;
+ }
+ }
+ }
+</style>
\ No newline at end of file
diff --git a/pages/actionChange/components/approvalnfor.vue b/pages/actionChange/components/approvalnfor.vue
new file mode 100644
index 0000000..98bc05c
--- /dev/null
+++ b/pages/actionChange/components/approvalnfor.vue
@@ -0,0 +1,230 @@
+<template>
+ <view class="">
+ <!-- ������������ -->
+ <view class="workOrderDetail">
+ <view class="headerCont">
+ <p class="title">������������</p>
+ </view>
+ <u-line color="#bbb" />
+ <view>
+ <view class="mainContent">
+
+ <u--form labelPosition="left" label-width="70" :model="form" :border-bottom="false" :rules="rules"
+ ref="uForm">
+ <view class="formItemContent">
+ <u-form-item border-bottom label="������������:" prop="checkScore" required :border-bottom="false">
+ <view class="" v-if="basicInfor.pageState==='view'">
+ {{ basicInfor.checkScore ||''}}
+ </view>
+ <u-input v-else v-model="form.checkScore" border="none" placeholder="���������" type="text" />
+ </u-form-item>
+ </view>
+ <view class="formItemContent">
+ <u-form-item border-bottom label="������:" prop="checkDescribe" required :border-bottom="false">
+ <view class="" v-if="basicInfor.pageState==='view'">
+ {{ basicInfor.checkDescribe ||''}}
+ </view>
+ <u--textarea v-else v-model="form.checkDescribe" border="none" placeholder="���������������" />
+ </u-form-item>
+ </view>
+ <view class="formItemContent">
+ <u-form-item border-bottom label="������������" :border-bottom="false">
+ <view class="fileBox" v-if="basicInfor.pageState==='view'">
+ <cl-upload v-model="fileList" :add="false" :action="`''`" cloud-type="other"
+ :remove="false" />
+ </view>
+ <view class="fileBox" v-else>
+ <fileUpload class="rowTipContenetAll" :sys-code="sysCode" @handleFile="handleFile" />
+ </view>
+ </u-form-item>
+ </view>
+ </u--form>
+ </view>
+ </view>
+ </view>
+ </view>
+</template>
+<script>
+ import fileUpload from '../components/fileUpload.vue'
+ export default {
+ components: {
+ fileUpload
+ },
+ props: {
+ basicInfor: {
+ type: Object,
+ default: () => {}
+ },
+ },
+ computed: {
+ pageState() {
+ return this.basicInfor.pageState
+ }
+ },
+ data() {
+ return {
+ sysCode: '1010203',
+ form: {
+ checkScore: 0,
+ checkDescribe: '',
+ },
+ dictObj: this.$storage.getJson('dictObj'),
+ fileList: [],
+ fileBaseList: [],
+ baseUrl: this.$storage.get('baseUrl'),
+ rules: {
+ 'checkScore': {
+ required: true,
+ message: '���������',
+ trigger: ['blur', 'change']
+ },
+ 'checkDescribe': {
+ required: true,
+ message: '���������',
+ trigger: ['blur', 'change']
+ },
+ }
+ }
+ },
+ onLoad: function(option) {
+ //option���object������������������������������������������������
+ console.log(option) //���������������������������������������
+ },
+ onReady() {
+ //onReady ���uni-app���������������������������
+ this.$refs.uForm.setRules(this.rules)
+ },
+ mounted() {
+ console.log('this.basicInfor', this.basicInfor)
+ if (this.basicInfor.fileApproveList && this.basicInfor.fileApproveList.length > 0) {
+ this.basicInfor.fileApproveList.forEach(item => {
+ let name = item.fileType === 1 ? 'name.png' : 'name.mp4'
+ this.fileList.push(`${this.baseUrl}/file/preview/${item.fileId}?${name}`) // ������
+ })
+ console.log('this.fileList', this.basicInfor.fileBaseList)
+ console.log('this.fileList', this.fileList)
+ }
+
+ },
+ methods: {
+ handleFile(data) {
+ this.fileBaseList = data
+ this.form.fileChangeList = this.fileBaseList
+ },
+ formVali() {
+ return new Promise((resolve, reject) => {
+ if(this.basicInfor.pageState!=='view'){
+ this.$refs.uForm.validate().then(res => {
+ resolve(true)
+ })
+ .catch(errors => {
+ reject(false)
+ uni.$u.toast('������������')
+ })
+ } else{
+ resolve(true)
+ }
+
+ });
+
+ }
+
+ },
+ }
+</script>
+
+<style scoped lang="scss">
+ /deep/.u-line {
+ margin: 19.23rpx 0px !important;
+ }
+
+ .workOrderDetail {
+ border: 1px solid #bbb;
+ border-radius: 5px;
+ min-height: 288.46rpx;
+ margin: 19.23rpx;
+ padding: 19.23rpx;
+ color: #101010;
+ font-weight: 700;
+ font-size: 26.92rpx;
+
+ .headerCont {
+ display: flex;
+ justify-content: space-between;
+ font-size: 15px;
+ }
+
+ .mainContent {
+ margin-bottom: 10px;
+ font-weight: 500;
+
+ .rowTip {
+ // display: flex;
+ padding: 8px 0;
+ border-bottom: 1px dashed #bbb;
+
+ .wholeLine {
+ display: flex;
+ align-items: center;
+
+ .rowTipContenetLabel {
+ min-width: 125rpx;
+ }
+ }
+
+ .rowTipContenetAll {
+ width: calc(100% - 125rpx; );
+ }
+
+ .rowTipContenet {
+ width: 50%;
+ text-align: left;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+
+ .butsName {
+ display: inline-block;
+ margin-left: 19.23rpx;
+ color: #1990ff;
+ }
+ }
+ }
+
+ .rowTipContenet_right {
+ text-align: right !important;
+ }
+ }
+ }
+
+ /deep/.u-form-item {
+ padding: 8px 0;
+ border-bottom: 1px dashed #bbb;
+ }
+
+ /deep/.u-form-item__body,
+ /deep/.u-textarea {
+ padding: 0 !important;
+ }
+
+ /deep/.u-form-item__body__left__content__label,
+ /deep/.u-radio__text {
+ font-size: 13px !important;
+ }
+
+ .fileBox {
+ display: -webkit-box;
+ display: -webkit-flex;
+ display: flex;
+ position: relative;
+ width: 100%;
+ height: 100%;
+ -webkit-box-orient: vertical;
+ -webkit-box-direction: normal;
+ -webkit-flex-direction: column;
+ flex-direction: column;
+ -webkit-box-pack: center;
+ -webkit-justify-content: center;
+ justify-content: center;
+ }
+</style>
\ No newline at end of file
diff --git a/pages/actionChange/components/basicInfor.vue b/pages/actionChange/components/basicInfor.vue
new file mode 100644
index 0000000..f7e26bb
--- /dev/null
+++ b/pages/actionChange/components/basicInfor.vue
@@ -0,0 +1,234 @@
+<template>
+ <view class="">
+ <!-- ������������ -->
+ <view class="workOrderDetail">
+ <view class="headerCont">
+ <p class="title">������������</p>
+ <p>���������{{ basicInfor.allocationNum }}</p>
+ </view>
+ <u-line color="#bbb" />
+ <view>
+ <view class="mainContent">
+ <p class="rowTip">
+ <view class="rowTipContenet">
+ <view class="wholeLine">
+ <text class="rowTipContenetLabel">������������:</text>
+ <text class="rowTipContenetAll">
+ {{ unitName }}
+ </text>
+ </view>
+ </view>
+ <view class="rowTipContenet">
+ <view class="wholeLine">
+ <text class="rowTipContenetLabel">������������:</text>
+ <text class="rowTipContenetAll">
+ {{ polluteType }}
+ </text>
+ </view>
+ </view>
+ </p>
+ <p class="rowTip">
+ <view class="rowTipContenet">
+ <view class="wholeLine">
+ <text class="rowTipContenetLabel">������������:</text>
+ <!-- this.dictObj.investigationEnum[val.investigationType] -->
+ <text class="rowTipContenetAll">
+ {{ dictObj.investigationEnum[basicInfor.investigationType] ||'' }}
+ </text>
+ </view>
+ </view>
+ <view class="rowTipContenet">
+ <view class="wholeLine">
+ <text class="rowTipContenetLabel">������������:</text>
+ <text class="rowTipContenetAll">
+ {{ dictObj.changeEnum[basicInfor.changeType] ||'' }}
+ </text>
+ </view>
+ </view>
+ </p>
+ <p class="rowTip">
+ <view class="rowTipContenet">
+ <view class="wholeLine">
+ <text class="rowTipContenetLabel">������������:</text>
+ <text class="rowTipContenetAll">
+ {{ escalationUnitName }}
+ </text>
+ </view>
+ </view>
+ <view class="rowTipContenet">
+ <view class="wholeLine">
+ <text class="rowTipContenetLabel">���������:</text>
+ <text class="rowTipContenetAll">{{ basicInfor.escalationName ||'' }}</text>
+ </view>
+ </view>
+ </p>
+ <p class="rowTip">
+ <view class="wholeLine">
+ <text class="rowTipContenetLabel">������������:</text>
+ <text class="rowTipContenetAll">{{ basicInfor.escalationTime ||'' }}</text>
+ </view>
+ </p>
+ <p class="rowTip">
+ <view class="wholeLine">
+ <text class="rowTipContenetLabel">������������:</text>
+ <text class="rowTipContenetAll">{{ basicInfor.pollutePosition ||'' }}</text>
+ </view>
+ </p>
+ <p class="rowTip">
+ <view class="wholeLine">
+ <text class="rowTipContenetLabel">������������:</text>
+ <text v-if="fileList.length>0" class="rowTipContenetAll">
+ <cl-upload
+ v-model="fileList"
+ :action="`''`"
+ :add="false"
+ cloud-type="other"
+ :remove="false"
+ />
+ </text>
+ </view>
+ </p>
+ </view>
+ </view>
+ </view>
+ </view>
+</template>
+<script>
+export default {
+ props: {
+ basicInfor: {
+ type: Object,
+ default: ()=> {}
+ },
+ },
+ data() {
+ return {
+ polluteList: this.$storage.getJson('polluteList'),
+ unitList: this.$storage.getJson('unitList'),
+ dictObj: this.$storage.getJson('dictObj'),
+ fileList: [],
+ baseUrl: this.$storage.get('baseUrl'),
+ }
+ },
+ computed: {
+ unitName(){
+ let data ={}
+ if(this.basicInfor.unitId){
+ data=this.unitList&& this.unitList.find(
+ (a)=> parseInt(a.unitId) === this.basicInfor.unitId
+ )
+ console.log('nnnnnn', this.unitList)
+ console.log('nnnnnn', this.basicInfor.unitId)
+
+ }
+ return data.unitName || ''
+ },
+ escalationUnitName(){
+ let data ={}
+ if(this.basicInfor.unitId){
+ data=this.unitList&& this.unitList.find(
+ (a)=> parseInt(a.unitId) === this.basicInfor.escalationUnitId
+ )
+ console.log('nnnnnn', this.unitList)
+ console.log('nnnnnn', this.basicInfor.unitId)
+
+ }
+ return data.unitName || ''
+
+ },
+ polluteType(){
+ let data ={}
+ if(this.basicInfor.polluteType){
+ data=this.polluteList.find(
+ (a)=> parseInt(a.dataKey) === this.basicInfor.polluteType
+ )
+ }
+ return data.dataValue ||''
+ }
+ },
+ watch: {
+ basicInfor: {
+ handler: function(newValue, oldValue) {
+ // ������������������
+ this.basicInfor=newValue
+ },
+ deep: true
+ }
+ },
+ onLoad: function (option) {
+ //option���object������������������������������������������������
+ console.log(option) //���������������������������������������
+ },
+ mounted() {
+ if(this.basicInfor.fileBaseList&&this.basicInfor.fileBaseList.length>0){
+ this.basicInfor.fileBaseList.forEach(item=> {
+ this.baseUrl='http://120.26.43.34:8081/api/'
+ let name = item.fileType === 1 ? 'name.png' : ''
+ this.fileList.push(`${this.baseUrl}/file/preview/${item.fileId}?${name}`) // ������
+ this.fileList.push('http://120.26.43.34:8081/api//file/preview/145?name.png') // ������
+ })
+ console.log('this.fileList', this.basicInfor.fileBaseList)
+ console.log('this.fileList', this.fileList)
+ }
+
+ },
+ methods: {},
+}
+</script>
+
+<style scoped lang="scss">
+/deep/.u-line {
+ margin: 19.23rpx 0px !important;
+}
+.workOrderDetail {
+ border: 1px solid #bbb;
+ border-radius: 5px;
+ min-height: 288.46rpx;
+ margin: 19.23rpx;
+ padding: 19.23rpx;
+ color: #101010;
+ font-weight: 700;
+ font-size: 26.92rpx;
+ .headerCont {
+ display: flex;
+ justify-content: space-between;
+ font-size: 15px;
+ }
+ .mainContent {
+ margin-bottom: 10px;
+ font-weight: 500;
+ .rowTip {
+ display: flex;
+ padding: 8px 0;
+ border-bottom: 1px dashed #bbb;
+ .wholeLine {
+ display: flex;
+ width: 100%;
+ align-items: center;
+ .rowTipContenetLabel {
+ min-width: 125rpx;
+ }
+ .rowTipContenetAll{
+ width: calc(100% - 125rpx);
+ }
+ }
+
+ .rowTipContenet {
+ width: 50%;
+ text-align: left;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+ .butsName {
+ display: inline-block;
+ margin-left: 19.23rpx;
+ color: #1990ff;
+ }
+ }
+ }
+ .rowTipContenet_right {
+ text-align: right !important;
+ }
+ }
+}
+</style>
diff --git a/pages/actionChange/components/fileUpload.vue b/pages/actionChange/components/fileUpload.vue
new file mode 100644
index 0000000..c9d6d82
--- /dev/null
+++ b/pages/actionChange/components/fileUpload.vue
@@ -0,0 +1,87 @@
+<template>
+ <view class="">
+ <cl-upload
+ v-model="fileList"
+ :action="uploadTermExcelUrl"
+ cloud-type="other"
+ :data="{ sysCode }"
+ :headers="hearder"
+ :image-form-data="{
+ compress: true,
+ }"
+ :list-style="{
+ columns: 3,
+ columnGap: '10rpx',
+ rowGap: '10rpx',
+ padding: '10rpx',
+ radius: '20rpx'
+ }"
+ use-before-delete
+ @beforeDelete="beforeDelete"
+ @onSuccess="onSuccess"
+ />
+ </cl-upload>
+ </view>
+</template>
+
+<script>
+export default {
+ props: {
+ sysCode: {
+ type: String,
+ },
+ },
+ data() {
+ return {
+ fileList: [],
+ upLoadList: [],
+ beforFileList: [],
+ baseUrl: this.$storage.get('baseUrl'),
+ token: this.$storage.get('token'),
+ }
+ },
+ computed: {
+ uploadTermExcelUrl() {
+ return `${this.baseUrl}/file/upload` || ''
+ },
+ hearder() {
+ let obj = { token: this.token, Authorization: this.token }
+ return obj
+ },
+ },
+ methods: {
+ onSuccess(res) {
+ console.log(res.data.fileId)
+ let fileId = res.data.fileId
+ let name = res.data.fileType === 1 ? 'name.png' : ''
+ this.fileList.push(`${this.baseUrl}/file/preview/${fileId}?${name}`) // ������
+ this.upLoadList.push(res.data)
+ console.log(this.fileList)
+ this.$emit('handleFile', this.upLoadList)
+ },
+ /**
+ * ���������������
+ * @param {Object} item ���������������������������������������
+ * @param {Number} index ������������������������������������
+ * @param {Function} next ���������������������������������������������
+ * */
+ beforeDelete(item, index, next) {
+
+ uni.showModal({
+ title: '������������',
+ content: '���������������������������������',
+ success: res=> {
+ if (res.confirm) {
+ this.fileList.splice(index, 1)
+ this.upLoadList.splice(index, 1)
+ console.log('this.fileList', this.upLoadList)
+ this.$emit('handleFile', this.upLoadList)
+ }
+ }
+ })
+ },
+ },
+}
+</script>
+
+<style></style>
diff --git a/pages/actionChange/components/rectificationInfor.vue b/pages/actionChange/components/rectificationInfor.vue
new file mode 100644
index 0000000..8f532aa
--- /dev/null
+++ b/pages/actionChange/components/rectificationInfor.vue
@@ -0,0 +1,263 @@
+<template>
+ <view class="">
+ <!-- ������������ -->
+ <view class="workOrderDetail">
+ <view class="headerCont">
+ <p class="title">������������</p>
+ </view>
+ <u-line color="#bbb" />
+ <view>
+ <view class="mainContent">
+ <u--form labelPosition="left" label-width="70" :model="form" :border-bottom="false" :rules="rules"
+ ref="uForm">
+ <view class="formItemContent">
+ <u-form-item label="������������:" required :border-bottom="false">
+ <view class="" v-if="pageState">
+ {{ dictObj.yesOrNo[basicInfor.isChange] ||''}}
+ </view>
+ <u-radio-group v-else v-model="form.isChange" @change="radioGroupChange">
+ <u-radio :key="index" v-for="(item, index) in list"
+ :custom-style="{marginRight: '8px'}" :label="item.name" :name="item.value" />
+ </u-radio-group>
+ </u-form-item>
+ </view>
+ <view class="formItemContent">
+ <u-form-item label="���������:" prop="changeName" :border-bottom="false" required>
+ <view class="" v-if="pageState">
+ {{ basicInfor.changeName ||''}}
+ </view>
+ <u-input v-else v-model="form.changeName" border="none" placeholder="���������" type="text" />
+ </u-form-item>
+ </view>
+ <view class="formItemContent">
+ <u-form-item label="������������" prop="changeDescribe" :border-bottom="false" required>
+ <view class="" v-if="pageState">
+ {{ basicInfor.changeDescribe ||''}}
+ </view>
+ <u--textarea v-else v-model="form.changeDescribe" border="none" placeholder="���������������" />
+ </u-form-item>
+ </view>
+
+ <view class="formItemContent">
+ <u-form-item label="������������" :border-bottom="false">
+ <view class="fileBox" v-if="pageState">
+ <cl-upload v-model="fileList" :add="false" :action="`''`" cloud-type="other"
+ :remove="false" />
+ </view>
+ <view class="fileBox" v-else>
+ <fileUpload class="rowTipContenetAll" :sys-code="sysCode"
+ @handleFile="handleFile" />
+ </view>
+ </u-form-item>
+ </view>
+ </u--form>
+ </view>
+ </view>
+ </view>
+ </view>
+</template>
+<script>
+ import fileUpload from '../components/fileUpload.vue'
+ export default {
+ components: {
+ fileUpload
+ },
+ props: {
+ basicInfor: {
+ type: Object,
+ default: () => {}
+ },
+ },
+ watch: {
+ basicInfor: {
+ handler: function(newValue, oldValue) {
+ // ������������������
+ this.basicInfor = newValue
+ },
+ deep: true
+ }
+ },
+ computed: {
+ pageState() {
+ return this.basicInfor.pageState === 'view' || this.basicInfor.state >= 30
+ }
+ },
+ data() {
+ return {
+ sysCode: '1010202',
+ list: [{
+ name: '���',
+ value: 0,
+ },
+ {
+ name: '���',
+ value: 1,
+ },
+ ],
+ form: {
+ isChange: 0,
+ changeName: '',
+ changeDescribe: '',
+ },
+ dictObj: this.$storage.getJson('dictObj'),
+ fileList: [],
+ fileBaseList: [],
+ baseUrl: this.$storage.get('baseUrl'),
+ rules: {
+ 'changeName': {
+ required: true,
+ message: '���������',
+ trigger: ['blur', 'change']
+ },
+ 'changeDescribe': {
+ required: true,
+ message: '���������',
+ trigger: ['blur', 'change']
+ },
+ }
+ }
+ },
+ onLoad: function(option) {
+ //option���object������������������������������������������������
+ console.log(option) //���������������������������������������
+ },
+ onReady() {
+ //onReady ���uni-app���������������������������
+ this.$refs.uForm.setRules(this.rules)
+ },
+ mounted() {
+ if (this.basicInfor.fileChangeList && this.basicInfor.fileChangeList.length > 0) {
+ this.basicInfor.fileChangeList.forEach(item => {
+ let name = item.fileType === 1 ? 'name.png' : 'name.mp4'
+ this.fileList.push(`${this.baseUrl}/file/preview/${item.fileId}?${name}`) // ������
+ })
+ console.log('this.fileList', this.basicInfor.fileBaseList)
+ console.log('this.fileList', this.fileList)
+ }
+ },
+ methods: {
+ radioGroupChange(e) {
+ console.log('radioGroupe���e', e)
+ },
+ handleFile(data) {
+ this.fileBaseList = data
+ this.form.fileChangeList = this.fileBaseList
+ },
+ formVali() {
+ return new Promise((resolve, reject) => {
+ if (!this.pageState) {
+ this.$refs.uForm.validate().then(res => {
+ resolve(true)
+ })
+ .catch(errors => {
+ reject(false)
+ uni.$u.toast('������������')
+ })
+ } else {
+ resolve(true)
+ }
+
+ });
+
+ }
+ },
+ }
+</script>
+
+<style scoped lang="scss">
+ /deep/.u-line {
+ margin: 19.23rpx 0px !important;
+ }
+
+ .workOrderDetail {
+ border: 1px solid #bbb;
+ border-radius: 5px;
+ min-height: 288.46rpx;
+ margin: 19.23rpx;
+ padding: 19.23rpx;
+ color: #101010;
+ font-weight: 700;
+ font-size: 26.92rpx;
+
+ .headerCont {
+ display: flex;
+ justify-content: space-between;
+ font-size: 15px;
+ }
+
+ .mainContent {
+ margin-bottom: 10px;
+ font-weight: 500;
+
+ .rowTip {
+ padding: 8px 0;
+ border-bottom: 1px dashed #bbb;
+
+ .wholeLine {
+ display: flex;
+ width: 100%;
+ align-items: center;
+
+ .rowTipContenetLabel {
+ min-width: 125rpx;
+ }
+ }
+
+ .rowTipContenetAll {
+ width: calc(100% - 125rpx; );
+ }
+
+ .rowTipContenet {
+ width: 50%;
+ text-align: left;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+
+ .butsName {
+ display: inline-block;
+ margin-left: 19.23rpx;
+ color: #1990ff;
+ }
+ }
+ }
+
+ .rowTipContenet_right {
+ text-align: right !important;
+ }
+ }
+ }
+
+ .formItemContent {
+ /deep/.u-form-item {
+ padding: 8px 0;
+ border-bottom: 1px dashed #bbb;
+ }
+
+ /deep/.u-form-item__body,
+ /deep/.u-textarea {
+ padding: 0 !important;
+ }
+
+ /deep/.u-form-item__body__left__content__label,
+ /deep/.u-radio__text {
+ font-size: 13px !important;
+ }
+ }
+
+ .fileBox {
+ display: -webkit-box;
+ display: -webkit-flex;
+ display: flex;
+ position: relative;
+ width: 100%;
+ height: 100%;
+ -webkit-box-orient: vertical;
+ -webkit-box-direction: normal;
+ -webkit-flex-direction: column;
+ flex-direction: column;
+ -webkit-box-pack: center;
+ -webkit-justify-content: center;
+ justify-content: center;
+ }
+</style>
\ No newline at end of file
diff --git a/pages/actionChange/myInfor/index.vue b/pages/actionChange/myInfor/index.vue
new file mode 100644
index 0000000..b63dc6c
--- /dev/null
+++ b/pages/actionChange/myInfor/index.vue
@@ -0,0 +1,91 @@
+<template>
+ <view class="mainContent">
+ <view class="headerAvatar">
+ <view class="">
+ <u-avatar :text="firstFont" fontSize="40" randomBgColor size='100'></u-avatar>
+ </view>
+ </view>
+ <view class="inforBox">
+ <u-cell-group>
+ <u-cell icon="server-man" title="������" :value="userInfor.userName"></u-cell>
+ <u-cell icon="account-fill" title="������" :value="userInfor.account"></u-cell>
+ <u-cell icon="integral-fill" title="������������" :value="unitName"></u-cell>
+ <u-cell icon="phone-fill" title="���������" :value="userInfor.mobile"></u-cell>
+ </u-cell-group>
+ </view>
+ <view class="bunts">
+ <u-button type="error" text="������" @click="goOut"></u-button>
+ </view>
+ </view>
+</template>
+<script>
+ import {
+ created
+ } from '../../../uni_modules/uview-ui/libs/mixin/mixin'
+ export default {
+ data() {
+ return {
+ loading: false,
+ userInfor: {},
+ unitList: []
+ }
+ },
+ computed: {
+ unitName() {
+ let data = ''
+ if (this.unitList.length > 0) {
+ data = this.unitList.find(a => parseInt(a.unitId) === this.userInfor.unitId).unitName
+ }
+ return data || ''
+ },
+ firstFont() {
+ return this.userInfor.userName[0] || '���'
+ }
+ },
+ created() {
+ this.$http.httpGet('/allocation/unit').then(res => {
+ this.unitList = res.data
+ })
+ this.userInfor = this.$storage.getJson('userInfo')
+ console.log('userInfor', this.userInfor.userName[0])
+ },
+ methods: {
+ goOut() {
+ uni.showModal({
+ title: '������',
+ content: '������������������',
+ success: res => {
+ if (res.confirm) {
+ this.$http.httpGet('/AppUser/wx/exit', {
+ userId: this.userInfor.userId
+ }).then(res => {
+ uni.clearStorageSync()
+ uni.reLaunch({
+ url: '/pages/login/login',
+ })
+ }).catch(uni.$u.toast('������������'))
+ }
+ }
+ })
+ }
+ }
+ }
+</script>
+<style lang="scss" scoped>
+ .mainContent {
+ padding: 20px;
+ }
+
+ .headerAvatar {
+ display: flex;
+ justify-content: center;
+ }
+
+ .inforBox {
+ margin-top: 57.69rpx;
+ }
+
+ .bunts {
+ margin-top: 57.69rpx;
+ }
+</style>
\ No newline at end of file
diff --git a/pages/actionChange/newPage/index.vue b/pages/actionChange/newPage/index.vue
new file mode 100644
index 0000000..e33c5bf
--- /dev/null
+++ b/pages/actionChange/newPage/index.vue
@@ -0,0 +1,410 @@
+<template>
+ <view class="mianContent">
+ <p class="title">������������</p>
+ <u-form
+ ref="uForm"
+ label-width="65"
+ :model="form"
+ :rules="rules"
+ >
+ <u-form-item
+ border-bottom
+ label="������������:"
+ prop="unitId"
+ required
+ @click="
+ showCheckBox = true;
+ hideKeyboard('unitList', 'unitId');
+ "
+ >
+ <u--input
+ v-model="form.unitId"
+ border="none"
+ disabled
+ disabled-color="#ffffff"
+ placeholder="���������"
+ />
+ <u-icon slot="right" name="arrow-right" />
+ </u-form-item>
+
+ <u-form-item
+ border-bottom
+ label="������������:"
+ prop="polluteType"
+ required
+ @click="
+ showCheckBox = true;
+ hideKeyboard('polluteList', 'polluteType');
+ "
+ >
+ <u-input
+ v-model="form.polluteType"
+ border="none"
+ disabled
+ disabled-color="#ffffff"
+ placeholder="���������"
+ type="select"
+ />
+ <u-icon slot="right" name="arrow-right" />
+ </u-form-item>
+ <u-form-item
+ border="none"
+ border-bottom
+ label="������������:"
+ prop="changeType"
+ required
+ @click="
+ showCheckBox = true;
+ hideKeyboard('changeEnum', 'changeType');
+ "
+ >
+ <u-input
+ v-model="form.changeType"
+ border="none"
+ disabled
+ disabled-color="#ffffff"
+ placeholder="���������"
+ type="select"
+ />
+ <u-icon slot="right" name="arrow-right" />
+ </u-form-item>
+ <u-form-item
+ border-bottom
+ label="������������:"
+ placeholder="���������"
+ required
+ >
+ <u-input v-model="form.changeDay" border="none" type="number" />
+ </u-form-item>
+ <u-form-item
+ border-bottom
+ label="������������:"
+ prop="escalationUnitId"
+ required
+ @click="
+ showCheckBox = true;
+ hideKeyboard('unitList', 'escalationUnitId');
+ "
+ >
+ <u-input
+ v-model="form.escalationUnitId"
+ border="none"
+ disabled
+ disabled-color="#ffffff"
+ placeholder="���������"
+ type="select"
+ />
+ <u-icon slot="right" name="arrow-right" />
+ </u-form-item>
+ <u-form-item
+ border-bottom
+ label="���������:"
+ prop="escalationName"
+ required
+ >
+ <u-input
+ v-model="form.escalationName"
+ border="none"
+ placeholder="���������"
+ type="text"
+ />
+ </u-form-item>
+ <u-form-item
+ border-bottom
+ label="������������:"
+ prop="investigationType"
+ required
+ >
+ <u-radio-group v-model="form.investigationType" style="font-size: 13px;">
+ <u-radio
+ :key="index"
+ v-for="(item, index) in Dic.investigationEnum"
+ :custom-style="{marginRight: '8px'}"
+ :label="item.name"
+ :name="item.value"
+ />
+ </u-radio-group>
+ </u-form-item>
+ <u-form-item
+ border-bottom
+ label="������������:"
+ prop="escalationTime"
+ required
+ @click="showeEscalationTime = true"
+ >
+ <u-input
+ v-model="form.escalationTime"
+ border="none"
+ disabled
+ disabled-color="#ffffff"
+ placeholder="���������"
+ type="select"
+ />
+ <u-icon slot="right" name="arrow-right" />
+ <u-datetime-picker
+ ref="datetimePicker"
+ v-model="timeFormet"
+ mode="date"
+ :show="showeEscalationTime"
+ @confirm="checkTime"
+ />
+ </u-form-item>
+ <u-form-item
+ border-bottom
+ label="������������:"
+ prop="pollutePosition"
+ required
+ >
+ <u-input
+ v-model="form.pollutePosition"
+ border="none"
+ placeholder="���������"
+ type="text"
+ />
+ </u-form-item>
+ <u-form-item
+ border-bottom
+ label="������������:"
+ prop="problemDescribe"
+ required
+ >
+ <u--textarea v-model="form.problemDescribe" border="none" placeholder="���������������" />
+ </u-form-item>
+ <u-form-item border-bottom label="������������:">
+ <view class="fileBox">
+ <fileUpload :sys-code="sysCode" @handleFile="handleFile" />
+ </view>
+ </u-form-item>
+ </u-form>
+ <u-action-sheet
+ v-if="actionOptionList.length > 0"
+ :actions="actionOptionList"
+ :show="showCheckBox"
+ title="���������"
+ @close="showCheckBox = false"
+ @select="selectBack"
+ />
+ <view class="bunts">
+ <u-button shape="square" @click="close">������</u-button>
+ <u-button shape="square" type="primary" @click="submit">������</u-button>
+ </view>
+ </view>
+</template>
+
+<script>
+import fileUpload from '../components/fileUpload.vue'
+export default {
+ components: {
+ fileUpload
+ },
+ data() {
+ return {
+ sysCode: '1010201', //
+ showCheckBox: false,
+ showeEscalationTime: false,
+ actionOptionList: [],
+ rules: {
+ 'unitId': {
+ required: true,
+ message: '���������',
+ trigger: ['blur', 'change']
+ },
+ 'polluteType': {
+ required: true,
+ message: '���������',
+ trigger: ['blur', 'change']
+ },
+ 'changeType': {
+ required: true,
+ message: '���������',
+ trigger: ['blur', 'change']
+ },
+ 'changeDay': {
+ required: true,
+ message: '���������',
+ trigger: ['blur', 'change']
+ },
+ 'escalationName': {
+ required: true,
+ message: '���������',
+ trigger: ['blur']
+ },
+ 'escalationUnitId': {
+ required: true,
+ message: '���������',
+ trigger: ['blur', 'change']
+ },
+ 'escalationTime': {
+ required: true,
+ message: '���������',
+ trigger: ['blur']
+ }, 'problemDescribe': {
+ required: true,
+ message: '���������',
+ trigger: ['blur']
+ }, 'pollutePosition': {
+ required: true,
+ message: '���������',
+ trigger: ['blur']
+ },
+ },
+ currentKey: '',
+ Dic: this.$storage.getJson('dict'),
+ changeEnum: [],
+ timeFormet: Number(new Date()),
+ form: {
+ unitId: '',
+ polluteType: '',
+ changeType: '',
+ changeDay: '',
+ escalationName: '',
+ escalationUnitId: '',
+ escalationTime: '',
+ problemDescribe: '',
+ pollutePosition: '',
+ },
+ sumbitForm: {
+ unitId: '',
+ polluteType: '',
+ changeType: '',
+ changeDay: '',
+ escalationName: '',
+ escalationUnitId: '',
+ escalationTime: '',
+ problemDescribe: '',
+ pollutePosition: '',
+ },
+ unitList: [],
+ polluteList: [],
+ fileBaseList: [],
+ }
+ },
+ onReady() {
+ //onReady ���uni-app���������������������������
+ this.$refs.uForm.setRules(this.rules)
+ },
+ onShow(){
+ uni.hideTabBar()
+ },
+ created() {
+ this.changeEnum = this.Dic.changeEnum
+ this.getUnitList()
+ this.getContaminateList()
+ },
+ methods: {
+ handleFile(data){
+ this.fileBaseList=data
+ },
+ close(){
+ uni.reLaunch({
+ url: '/pages/actionChange/agencyPage/index',
+ })
+ },
+ hideKeyboard(data, key) {
+ this.actionOptionList = []
+ let list = this[data]
+
+ this.currentKey = key
+ list.forEach((item)=> {
+ item.name = item.dataValue || item.name || item.unitName
+ item.value = item.dataKey || item.value|| item.unitId
+ })
+
+ this.actionOptionList = list
+ },
+ selectBack(e) {
+ this.form[this.currentKey] = e.name
+ this.sumbitForm[this.currentKey] = e.value
+
+ },
+ checkTime(e) {
+ this.showeEscalationTime = false
+ let data = this.$utils.dateFormatter(e.value)
+ this.form.escalationTime = data
+ this.sumbitForm.escalationTime = data
+ },
+ submit() {
+ this.$refs.uForm.validate().then(res=> {
+ this.sumbitForm.problemDescribe=this.form.problemDescribe
+ this.sumbitForm.pollutePosition=this.form.pollutePosition
+ this.sumbitForm.changeDay=this.form.changeDay
+ this.sumbitForm.escalationName=this.form.escalationName
+ this.sumbitForm.fileBaseList=this.fileBaseList
+ this.sumbitForm.state='10'
+ console.log('this.sumbitForm', this.sumbitForm)
+ this.$http.httpPost('/allocation/insert', {...this.sumbitForm}).then((res)=> {
+ uni.$u.toast('������������')
+ this.close()
+ })
+ }).catch(errors=> {
+ uni.$u.toast('������������')
+ })
+ },
+ // ������������������list
+ getUnitList() {
+ this.$http.httpGet('/allocation/unit').then((res)=> {
+ this.unitList = res.data
+ })
+ },
+ getContaminateList() {
+ this.$http.httpGet('/allocation/contaminate').then((res)=> {
+ this.polluteList = res.data
+ })
+ },
+ },
+}
+</script>
+
+<style scoped lang="scss">
+ uni-page-body {
+ padding-top: 10px;
+ }
+
+ .mianContent {
+ margin: 19.23rpx;
+ border-radius: 5px;
+ .title {
+ padding: 9.62rpx;
+ font-size: 16px;
+ font-weight: 700;
+ color: #101010;
+ border-bottom: 1px solid #bbb;
+ }
+
+ /deep/.u-form-item {
+ padding-left: 10px;
+ }
+
+ /deep/.u-form-item__body {
+ padding: 5px 0px !important;
+ font-size: 13px!important;
+ }
+ /deep/.u-form-item__body__left__content__label,/deep/.u-input__content__field-wrapper__field,/deep/.u-radio__text{
+ font-size: 13px!important;
+ }
+ }
+ .bunts {
+ display: flex;
+ margin-top: 20px;
+ margin-bottom: 96.15rpx;
+ padding-bottom: 20px;
+ .u-button {
+ width: 288.46rpx;
+ }
+ }
+ .fileBox{
+ display: -webkit-box;
+ display: -webkit-flex;
+ display: flex;
+ position: relative;
+ width: 100%;
+ height: 100%;
+ -webkit-box-orient: vertical;
+ -webkit-box-direction: normal;
+ -webkit-flex-direction: column;
+ flex-direction: column;
+ -webkit-box-pack: center;
+ -webkit-justify-content: center;
+ justify-content: center;
+ }
+</style>
\ No newline at end of file
diff --git a/pages/actionChange/workOrderDetails/index.vue b/pages/actionChange/workOrderDetails/index.vue
new file mode 100644
index 0000000..1e79165
--- /dev/null
+++ b/pages/actionChange/workOrderDetails/index.vue
@@ -0,0 +1,106 @@
+<template>
+ <view class="mainContent">
+ <basicInfor :basic-infor="basicInfor" />
+ <rectificationInfor ref="rectificationInfor" :basic-infor="basicInfor" />
+ <approvalnfor ref="approvalnfor" v-if="basicInfor.state >= 30" :basic-infor="basicInfor" />
+ <view class="bunts">
+ <u-button shape="square" @click="close">������</u-button>
+ <u-button
+ v-if="pageState==='edit'"
+ shape="square"
+ type="primary"
+ @click="submit"
+ >
+ ������
+ </u-button>
+ </view>
+ </view>
+</template>
+<script>
+import basicInfor from '../components/basicInfor.vue'
+import rectificationInfor from '../components/rectificationInfor.vue'
+import approvalnfor from '../components/approvalnfor.vue'
+export default {
+ components: {
+ basicInfor,
+ rectificationInfor,
+ approvalnfor,
+ },
+ data() {
+ return {
+ basicInfor: {}
+ }
+ },
+ computed: {
+ pageState() {
+ return this.basicInfor.pageState
+ }
+ },
+ onLoad: function(option) {
+ console.log('option', option)
+ //option���object������������������������������������������������
+ this.basicInfor = JSON.parse(option.infor)
+
+ },
+ onBackPress(e) {
+ uni.navigateTo({
+ url: '/pages/actionChange/agencyPage/index',
+ })
+ return false
+ },
+ methods: {
+ radioGroupChange(e) {
+ console.log('radioGroupe���e', this.workForme.isChange)
+ },
+ close() {
+ let pages = getCurrentPages() // ������������
+ let beforePage = pages[pages.length - 3] // ������������
+ //beforePage.$vm.reFresh = Math.random()//������������������������
+ uni.navigateBack({
+ delta: 1, //������������������������������������������2
+ success: function() {
+ // beforePage.$vm.reFresh()
+ }
+ })
+ },
+ submit() {
+ Promise.all([this.$refs.rectificationInfor && this.$refs.rectificationInfor.formVali(), this.$refs
+ .approvalnfor && this.$refs.approvalnfor.formVali()
+ ]) //
+ .then(()=> {
+ let api = this.basicInfor.state >= 30 ? '/allocation/check' : '/allocation/change' //������
+ let form = this.basicInfor.state >=30 ? this.$refs.approvalnfor.form : this.$refs.rectificationInfor.form
+ let data = {
+ allocationId: this.basicInfor.allocationId,
+ ...form,
+ state: this.basicInfor.state,
+ }
+ this.$http.httpPost(api, data).then((res)=> {
+ this.close()
+ })
+ })
+ .catch(err=> {
+ console.log('���������������������', err)
+ })
+
+ }
+ },
+}
+</script>
+
+<style scoped lang="scss">
+ .mainContent {
+ padding-bottom: 38.46rpx;
+ }
+
+ .bunts {
+ display: flex;
+ margin-top: 20px;
+ margin-bottom: 96.15rpx;
+ padding: 0 20px;
+
+ .u-button {
+ width: 288.46rpx;
+ }
+ }
+</style>
\ No newline at end of file
diff --git a/pages/index/index.vue b/pages/index/index.vue
new file mode 100644
index 0000000..6445b39
--- /dev/null
+++ b/pages/index/index.vue
@@ -0,0 +1,5 @@
+<template />
+
+<script></script>
+
+<style></style>
diff --git a/pages/login/login.vue b/pages/login/login.vue
new file mode 100644
index 0000000..147529c
--- /dev/null
+++ b/pages/login/login.vue
@@ -0,0 +1,173 @@
+<template>
+ <view class="page">
+ <view class="tit">
+ <view class="imageContent">
+ <image src="/static/logo.png" style="width: 67.31rpx; height: 100rpx" />
+ </view>
+ <view class="">
+ <text>������������������������</text>
+ </view>
+ </view>
+ <view class="formConten">
+ <view>
+ <u-form ref="uForm" label-position="left" :model="form" :labelStyle="labelStyle">
+ <u-form-item label="������:" prop="account">
+ <u-input v-model="form.account" color='#fff' placeholder="���������������" />
+ </u-form-item>
+ <u-form-item label="������:" prop="password">
+ <u-input v-model="form.password" :password-icon="passwordIcon" color='#fff' placeholder="���������������"
+ type="password" />
+ </u-form-item>
+ </u-form>
+ </view>
+ <view class="loginContent">
+ <p>
+ <navigator style="display: inline-block;" url="/pages/login/register/register">
+ <text style="text-decoration: underline">������������</text>
+ </navigator>
+ </p>
+ <u-button @click="submit">������</u-button>
+ </view>
+ </view>
+ </view>
+</template>
+<script>
+ import {
+ login,
+ getUserInfor,
+ getDic
+ } from '@/utils/login.js' // ������������
+ import {
+ httpPost,
+ httpGet
+ } from '@/utils/http.js'
+ export default {
+ data() {
+ return {
+ labelStyle: {
+ color: '#fff'
+ },
+ passwordIcon: false,
+ form: {
+ account: '',
+ password: '',
+ },
+ rules: {
+ account: [{
+ required: true,
+ message: '���������������',
+ // ���������������������������������������������������
+ trigger: ['change', 'blur'],
+ }, ],
+ password: [{
+ required: true,
+ message: '���������������',
+ trigger: ['change', 'blur'],
+ }, ],
+ },
+ }
+ },
+ onReady() {
+ //onReady ���uni-app���������������������������
+ this.$refs.uForm.setRules(this.rules)
+ },
+ methods: {
+ submit() {
+ this.$refs.uForm.validate().then(res => {
+ this.getlogin()
+ }).catch(errors => {
+ uni.$u.toast('������������')
+ })
+ },
+ //������
+ getlogin() {
+ let openId = this.$storage.get('openId')
+ login({
+ ...this.form,
+ openId
+ }).then(response => {
+ this.$storage.set('token', response.data.token)
+ getDic()
+ getUserInfor(response.data.token)
+ uni.hideLoading()
+ uni.switchTab({
+ url: '/pages/actionChange/agencyPage/index',
+ })
+ // this.$storage.setJson("accountInFor", this.form);
+ // console.log('this.$store', this.$store)
+ // this.$store.commit('token', token)
+ }).catch(errors => {
+ uni.showToast({
+ title: errors,
+ icon: 'none',
+ })
+ })
+ },
+ },
+ }
+</script>
+<style scoped lang="scss">
+ uni-page-body {
+ height: 100%;
+ }
+
+ .page {
+ color: #ffffff;
+ background: #3875c5;
+ height: 100%;
+ }
+
+ .tit {
+ padding-top: 307.69rpx;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ font-size: 53.85rpx;
+ }
+
+ .formConten {
+ padding: 0 76.92rpx;
+ color: #ffffff;
+ }
+
+ .u-form-item {
+ color: #ffffff;
+ font-size: 28.85rpx;
+ font-weight: 700;
+ }
+
+ // /deep/.uni-input-wrapper {
+ // background: #fff;
+ // border-radius: 5px;
+ // }
+ // /deep/.uni-input-placeholder {
+ // padding-left: 10px;
+ // }
+ /deep/.u-form-item__body__left__content__label {
+ color: #fff;
+ }
+
+ // /deep/.uni-input-input {
+ // padding-left: 10px;
+ // }
+ .loginContent {
+ margin-top: 38.46rpx;
+
+ p {
+ text-align: right;
+ margin-bottom: 20px;
+
+ a {
+ color: #fff;
+ }
+ }
+
+ .u-btn--default {
+ width: 80%;
+ }
+ }
+
+ uni-navigator {
+ display: inline-block;
+ }
+</style>
\ No newline at end of file
diff --git a/pages/login/register/register.vue b/pages/login/register/register.vue
new file mode 100644
index 0000000..a3482e3
--- /dev/null
+++ b/pages/login/register/register.vue
@@ -0,0 +1,74 @@
+<template>
+ <view>
+ <view class="imageContent">
+ <image
+ src="/static/logo.png"
+ style="width: 267.31rpx; height: 403.85rpx"
+ />
+ </view>
+ <view class="formContent">
+ <u-form ref="uForm" label-width="70" :model="form">
+ <u-form-item label="������">
+ <u-input v-model="form.name" placeholder="���������������������" />
+ </u-form-item>
+ <u-form-item label="������">
+ <u-input v-model="form.intro" placeholder="���������������" />
+ </u-form-item>
+ <u-form-item label="������������">
+ <u-input v-model="form.intro" placeholder="���������������������" />
+ </u-form-item>
+ </u-form>
+ <p class="tips">
+ <text>���������������������������������������������������������������������������������������</text>
+ </p>
+ <u-button @click="submit">������</u-button>
+ </view>
+ </view>
+</template>
+
+<script>
+export default {
+ data() {
+ return {
+ form: {},
+ rules: {
+ name: [
+ {
+ required: true,
+ message: '���������������',
+ // ���������������������������������������������������
+ trigger: ['change', 'blur'],
+ },
+ ],
+ password: [
+ {
+ required: true,
+ message: '���������������',
+ trigger: ['change', 'blur'],
+ },
+ ],
+ },
+ }
+ },
+ onReady() {
+ this.$refs.uForm.setRules(this.rules)
+ },
+ methods: {},
+ // ������������onReady���������������������onLoad������������������������������������������
+}
+</script>
+
+<style scoped lang="scss">
+.imageContent {
+ text-align: center;
+ margin: 38.46rpx 0rpx;
+}
+.formContent {
+ padding: 0rpx 48.08rpx;
+}
+.tips {
+ font-size: 12px;
+ margin: 38.46rpx 0;
+}
+
+</style>
diff --git a/static/img/headSculpture.png b/static/img/headSculpture.png
new file mode 100644
index 0000000..479675f
--- /dev/null
+++ b/static/img/headSculpture.png
Binary files differ
diff --git a/static/img/shouye.png b/static/img/shouye.png
new file mode 100644
index 0000000..6cc733a
--- /dev/null
+++ b/static/img/shouye.png
Binary files differ
diff --git a/static/img/shouyeClick.png b/static/img/shouyeClick.png
new file mode 100644
index 0000000..f0effdd
--- /dev/null
+++ b/static/img/shouyeClick.png
Binary files differ
diff --git a/static/img/wode-.png b/static/img/wode-.png
new file mode 100644
index 0000000..bcc3f2f
--- /dev/null
+++ b/static/img/wode-.png
Binary files differ
diff --git a/static/img/wodeClick.png b/static/img/wodeClick.png
new file mode 100644
index 0000000..6687d89
--- /dev/null
+++ b/static/img/wodeClick.png
Binary files differ
diff --git a/static/img/xinjian.png b/static/img/xinjian.png
new file mode 100644
index 0000000..0449374
--- /dev/null
+++ b/static/img/xinjian.png
Binary files differ
diff --git a/static/img/xinjianClick.png b/static/img/xinjianClick.png
new file mode 100644
index 0000000..69439e8
--- /dev/null
+++ b/static/img/xinjianClick.png
Binary files differ
diff --git a/static/logo.png b/static/logo.png
new file mode 100644
index 0000000..f60a2c3
--- /dev/null
+++ b/static/logo.png
Binary files differ
diff --git a/store/index.js b/store/index.js
new file mode 100644
index 0000000..293363c
--- /dev/null
+++ b/store/index.js
@@ -0,0 +1,7 @@
+import Vue from 'vue'
+import Vuex from 'vuex'
+import modules from './modules/index.js'
+Vue.use(Vuex)
+
+const store = new Vuex.Store(modules)
+export default store
diff --git a/store/modules/index.js b/store/modules/index.js
new file mode 100644
index 0000000..b32b44c
--- /dev/null
+++ b/store/modules/index.js
@@ -0,0 +1,10 @@
+import _ from 'lodash'
+
+const files = require.context('.', false, /\.js$/)
+const modules = {}
+
+files.keys().forEach(key => {
+ if (key === './index.js') return
+ _.mergeWith(modules,files(key).default)
+})
+export default modules
diff --git a/store/modules/user.js b/store/modules/user.js
new file mode 100644
index 0000000..166094c
--- /dev/null
+++ b/store/modules/user.js
@@ -0,0 +1,111 @@
+import Vue from "vue";
+export default {
+ state: {
+ user: null,
+ tonken:''
+ },
+ mutations: {
+ login(state, user) {
+ state.user = user;
+ // ������������������
+ Vue.prototype.$cache.set("_userInfo", user, 0);
+ },
+ tonken(state, data) {
+ state.tonken = data;
+ // ������������������
+ Vue.prototype.$cache.set("state",tonken,0);
+ },
+ logout(state) {
+ state.user = null;
+ // ������������������������
+ Vue.prototype.$cache.delete("_userInfo");
+ },
+ },
+ actions: {
+ autoLogin({ commit, getters, dispatch }) {
+ console.log('Vue.prototype.$storage',Vue.prototype.$storage.get("tonken"))
+ let tonken = Vue.prototype.$storage.get("tonken");
+ console.log("tonken", tonken);
+ // ���������������������������������������������������������������������
+ if (tonken) {
+ const params = {
+ account: accountInFor.account,
+ password: accountInFor.password,
+ };
+ uni.showLoading({
+ title: "���������������...",
+ });
+ dispatch("login", params)
+ .then((res) => {
+ uni.hideLoading();
+ // uni.showToast({
+ // title: '������������������',
+ // icon: 'success'
+ // })
+ })
+ .catch(() => {
+ uni.hideLoading();
+ uni.showToast({
+ title: "���������������������������������",
+ icon: "none",
+ });
+ setTimeout(() => {
+ uni.reLaunch({
+ url: "/pages/login/login",
+ });
+ }, 1000);
+ });
+ } else {
+ // ������������������������������������������������������������
+ uni.showModal({
+ title: "���������",
+ content: "������������������������������������������",
+ showCancel: false,
+ confirmText: "������",
+ success: (res) => {
+ if (res.confirm) {
+ uni.reLaunch({
+ url: "/pages/login/login",
+ });
+ }
+ },
+ });
+ }
+ },
+ login({ commit }, params) {
+ return new Promise((resolve, reject) => {
+ Vue.prototype.$login
+ .login(params)
+ .then((res) => {
+ if (res.ok()) {
+ console.log(response);
+ this.$storage.set("token", response.data.token);
+ this.$storage.setJson("accountInFor", this.form);
+ let token = this.$storage.get("token");
+ commit("login", tmp);
+ resolve(res);
+ } else {
+ reject(res);
+ }
+ })
+ .catch((err) => {
+ reject(err);
+ });
+ });
+ },
+ logout({ commit }) {
+ commit("logout");
+ uni.reLaunch({
+ url: "/pages/login/login",
+ });
+ },
+ },
+ getters: {
+ user: (state) => {
+ if (state.user) {
+ return state.user;
+ }
+ // return Vue.prototype.$cache.get('_userInfo')
+ },
+ },
+};
diff --git a/uni.promisify.adaptor.js b/uni.promisify.adaptor.js
new file mode 100644
index 0000000..47fbce1
--- /dev/null
+++ b/uni.promisify.adaptor.js
@@ -0,0 +1,10 @@
+uni.addInterceptor({
+ returnValue (res) {
+ if (!(!!res && (typeof res === "object" || typeof res === "function") && typeof res.then === "function")) {
+ return res;
+ }
+ return new Promise((resolve, reject) => {
+ res.then((res) => res[0] ? reject(res[0]) : resolve(res[1]));
+ });
+ },
+});
\ No newline at end of file
diff --git a/uni.scss b/uni.scss
new file mode 100644
index 0000000..417a13f
--- /dev/null
+++ b/uni.scss
@@ -0,0 +1,77 @@
+/**
+ * ���������uni-app���������������������������
+ *
+ * uni-app ������������������������������������https://ext.dcloud.net.cn������������������������������������������������������
+ * ���������������������������������������������scss������������������������������������������������������������������ import ���������������������������������������������������������������������������������App
+ *
+ */
+
+/**
+ * ������������App������������������������������������������������������������������������������������������������������������������������������
+ *
+ * ���������������������������������scss��������������������������������������� scss ������������������������������������������ import ������������
+ */
+
+/* ������������ */
+
+/* ������������������ */
+$uni-color-primary: #007aff;
+$uni-color-success: #4cd964;
+$uni-color-warning: #f0ad4e;
+$uni-color-error: #dd524d;
+
+/* ������������������ */
+$uni-text-color: #333; //���������
+$uni-text-color-inverse: #fff; //������
+$uni-text-color-grey: #999; //���������������������������������������������
+$uni-text-color-placeholder: #808080;
+$uni-text-color-disable: #c0c0c0;
+
+/* ������������ */
+$uni-bg-color: #ffffff;
+$uni-bg-color-grey: #f8f8f8;
+$uni-bg-color-hover: #f1f1f1; //������������������
+$uni-bg-color-mask: rgba(0, 0, 0, 0.4); //������������
+
+/* ������������ */
+$uni-border-color: #c8c7cc;
+
+/* ������������ */
+
+/* ������������ */
+$uni-font-size-sm: 12px;
+$uni-font-size-base: 14px;
+$uni-font-size-lg: 16;
+
+/* ������������ */
+$uni-img-size-sm: 20px;
+$uni-img-size-base: 26px;
+$uni-img-size-lg: 40px;
+
+/* Border Radius */
+$uni-border-radius-sm: 2px;
+$uni-border-radius-base: 3px;
+$uni-border-radius-lg: 6px;
+$uni-border-radius-circle: 50%;
+
+/* ������������ */
+$uni-spacing-row-sm: 5px;
+$uni-spacing-row-base: 10px;
+$uni-spacing-row-lg: 15px;
+
+/* ������������ */
+$uni-spacing-col-sm: 4px;
+$uni-spacing-col-base: 8px;
+$uni-spacing-col-lg: 12px;
+
+/* ��������� */
+$uni-opacity-disabled: 0.3; // ���������������������������
+
+/* ������������������ */
+$uni-color-title: #2c405a; // ������������������
+$uni-font-size-title: 20px;
+$uni-color-subtitle: #555555; // ������������������
+$uni-font-size-subtitle: 26px;
+$uni-color-paragraph: #3f536e; // ������������������
+$uni-font-size-paragraph: 15px;
+@import "@/uni_modules/uview-ui/theme.scss";
diff --git a/uni_modules/cl-upload/changelog.md b/uni_modules/cl-upload/changelog.md
new file mode 100644
index 0000000..123de9b
--- /dev/null
+++ b/uni_modules/cl-upload/changelog.md
@@ -0,0 +1,77 @@
+## 1.4.0���2023-07-04���
+������unicloud������������������
+## 1.3.9���2023-06-28���
+���������������������������������
+## 1.3.8���2023-06-02���
+���������������������������������������������������; ���������������������������������;
+## 1.3.7���2023-05-22���
+���������������������������������; ������������������������
+## 1.3.6���2023-05-22���
+���������������������������������
+## 1.3.5���2023-05-04���
+���������������cloudType���other���������������������������������������������������
+## 1.3.4���2023-04-27���
+���������������unicloud���������������������������������������
+## 1.3.3���2023-04-27���
+������������������������������
+## 1.3.2���2023-04-24���
+������������APP������cloudType:other ������������http������������
+## 1.3.1���2023-04-19���
+������������������
+## 1.3.0���2023-04-19���
+������������������������������; ���������������������������������������
+## 1.2.9���2023-03-22���
+������������������
+## 1.2.8���2023-03-22���
+������������������
+## 1.2.7���2023-03-21���
+������������������������������������
+## 1.2.6���2023-03-21���
+������������������������������������
+## 1.2.5���2023-03-08���
+������vue3���v-model������������
+## 1.2.4���2023-03-06���
+1.������������������������������video������������������;
+2.������unicloud������v-model���������������;
+## 1.2.3���2023-02-02���
+������������������������������������
+## 1.2.2���2023-02-01���
+������������������������������������������
+## 1.2.1���2023-01-31���
+������������������������
+## 1.2.0���2022-12-12���
+������uniCloud������
+## 1.1.9���2022-12-12���
+1. ������������������������
+2. ������������������
+## 1.1.8���2022-12-09���
+���������������������������������������������������
+## 1.1.7���2022-12-01���
+������h5������������������������������������������������������������
+## 1.1.6���2022-11-24���
+������������������������������������
+## 1.1.5���2022-11-07���
+������������������
+## 1.1.4���2022-11-07���
+���������������������������������������������������������������������
+## 1.1.3���2022-10-28���
+������������������������
+## 1.1.1���2022-10-28���
+������������������
+## 1.1.0���2022-08-25���
+������base64������������
+## 1.0.9���2022-08-25���
+���������������������������������������
+## 1.0.8���2022-08-01���
+���������������������������
+## 1.0.6���2022-07-30���
+������������������
+## 1.0.5���2022-07-30���
+1. aspect-ratio���������������������height������������
+2. ������������������������������������
+## 1.0.3���2022-07-30���
+���������������������������������
+## 1.0.2���2022-07-30���
+���������������������������������������
+## 1.0.1���2022-07-29���
+���������������
diff --git a/uni_modules/cl-upload/components/cl-image/cl-image.vue b/uni_modules/cl-upload/components/cl-image/cl-image.vue
new file mode 100644
index 0000000..61fc4eb
--- /dev/null
+++ b/uni_modules/cl-upload/components/cl-image/cl-image.vue
@@ -0,0 +1,60 @@
+<template>
+ <image class="image" :src="imgSrc" mode="aspectFill" :disabled="false" :controls='false' @error="imgerror"></image>
+</template>
+
+<script>
+ export default {
+ props: {
+ src: {
+ type: String,
+ default: ''
+ },
+ cloudType: {
+ type: String,
+ default: 'oss'
+ },
+ },
+ data() {
+ return {
+ imgSrc: ''
+ };
+ },
+ mounted() {
+ this.setCloudFunction()
+ },
+ methods: {
+ imgerror(even) {
+ this.imgSrc = `https://mp-61599c79-d7ee-4a75-a24b-e5a288da6dd3.cdn.bspapp.com/cloudstorage/887c60f0-27f8-46d1-8769-2c45be0f3d7d.png`
+ },
+ setCloudFunction() {
+ const fileType = this.src.split('.').pop();
+ const IMAGE_REGEXP = /(jpeg|jpg|gif|png|svg|webp|jfif|bmp|dpg|image)/i
+ if (IMAGE_REGEXP.test(fileType)) {
+ return this.imgSrc = this.src;
+ }
+
+ switch (this.cloudType){
+ case 'oss':
+ this.imgSrc = this.src + '?x-oss-process=video/snapshot,t_0,f_jpg'
+ break;
+ case 'process':
+ this.imgSrc = this.src + '?ci-process=snapshot&time=0.01'
+ break;
+ case 'vframe':
+ this.imgSrc = this.src + '?vframe/jpg/offset/0'
+ break;
+ default:
+ this.imgSrc = this.src
+ break;
+ }
+ }
+ }
+ }
+</script>
+
+<style lang="scss" scoped>
+ .image {
+ width: 100%;
+ height: 100%;
+ }
+</style>
diff --git a/uni_modules/cl-upload/components/cl-upload/cl-upload.vue b/uni_modules/cl-upload/components/cl-upload/cl-upload.vue
new file mode 100644
index 0000000..ee28b16
--- /dev/null
+++ b/uni_modules/cl-upload/components/cl-upload/cl-upload.vue
@@ -0,0 +1,1031 @@
+<template>
+ <view class="cl-updata">
+ <view class="file-list" :style="[listRowStyle]">
+
+ <view v-for="(item, index) in previewList" @tap="clickSelectedFile(item, index)" class="file-list-row"
+ :style="[rowStyle]" :key="index">
+
+ <image
+ class="_image"
+ v-if="fileUrlType(item) === 'image'"
+ :src="item.path"
+ :style="[imgStyle]"
+ mode="aspectFill">
+ </image>
+
+ <view v-else class="_video" :style="[imgStyle]">
+
+ <!-- #ifdef MP-WEIXIN || MP-ALIPAY -->
+ <video
+ v-if="!autoUpload || cloudType === 'other'"
+ class="_video"
+ :style="[imgStyle]"
+ :src="item.path"
+ :show-center-play-btn="false"
+ :show-fullscreen-btn="false"
+ :show-play-btn="false"
+ :show-loading="false"
+ :enable-progress-gesture="false"
+ :controls="false">
+ <view @tap="previewVideo(item, index)" class="play">
+ <image style="width: 100%;" :src="playImg" mode="widthFix"></image>
+ </view>
+ </video>
+
+ <!-- #endif -->
+
+ <!-- #ifdef APP-PLUS -->
+ <video
+ v-if="cloudType === 'other'"
+ class="_video"
+ :style="[imgStyle]"
+ :src="item.path"
+ :poster="item.path"
+ :controls="false"
+ :show-center-play-btn="false"
+ :show-fullscreen-btn="false"
+ :show-play-btn="false"
+ :show-loading="false"
+ :enable-progress-gesture="false">
+ <cover-image class="app_play" :src="playImg" @tap="previewVideo(item, index)"></cover-image>
+ <cover-view class="remove" v-if="remove" @tap="deleteSelectedFile(item, index)">
+ <cover-image class="image" :src="deleteImg" mode="widthFix" @tap="deleteSelectedFile(item, index)"></cover-image>
+ </cover-view>
+ </video>
+ <!-- #endif -->
+
+ <!-- #ifndef MP-WEIXIN || MP-ALIPAY || APP-PLUS -->
+ <video
+ v-if="cloudType === 'other'"
+ class="_video"
+ :autoplay="false"
+ :style="[imgStyle]"
+ :src="item.path"
+ :controls="false"
+ :show-center-play-btn="false"
+ :show-fullscreen-btn="false"
+ :show-play-btn="false"
+ :show-loading="false"
+ :enable-progress-gesture="false" >
+ <cover-view @tap="previewVideo(item, index)" class="play">
+ <cover-image style="width: 100%;" :src="playImg" mode="widthFix"></cover-image>
+ </cover-view>
+ </video>
+
+ <!-- #endif -->
+
+ <template v-else>
+ <cl-image class="pay" :style="[imgStyle]" :cloudType="cloudType"
+ :src="(item.poster || item.path)"></cl-image>
+
+ <view class="play" @tap="previewVideo(item, index)">
+ <image class="play-img" :src="playImg" mode="widthFix"></image>
+ </view>
+ </template>
+
+ </view>
+
+ <view class="remove" v-if="remove" @tap.stop="deleteSelectedFile(item, index)">
+ <image class="image" :src="deleteImg" mode="widthFix"></image>
+ </view>
+ </view>
+
+ <view v-if="add && FileList.length < max" @tap="selectFileTypeOnAdd" :style="[rowStyle]" class="file-list-row">
+ <slot name="addImg">
+ <div class="add-image">
+ <image class="_image" :src="addImg" mode="widthFix"></image>
+ </div>
+ </slot>
+ </view>
+ </view>
+
+
+ <view v-if="tempVideoUrl" class="mask">
+ <image @tap="tempVideoUrl = ''" class="_root" :src="closeImg" mode="widthFix"></image>
+
+ <view class="block" @tap.stop>
+ <video class="block_video" autoplay :src="tempVideoUrl"></video>
+ </view>
+ </view>
+ </view>
+</template>
+
+<script>
+import ClImage from '../cl-image/cl-image.vue'
+export default {
+ name: "cl-upload",
+ components: { ClImage },
+ props: {
+ //������������������
+ // #ifdef VUE2
+ value: {
+ type: Array,
+ default: () => [],
+ },
+ // #endif
+
+ // #ifdef VUE3
+ modelValue: {
+ type: Array,
+ default: () => [],
+ },
+ // #endif
+
+ // ��������������� oss��������� vframe��������� process��������� other������
+ cloudType: {
+ type: String,
+ default: 'oss'
+ },
+ // ���������,������������������������
+ fileName: {
+ type: String,
+ default: 'file'
+ },
+ // ������������ 'image', 'video', 'all'
+ fileType: {
+ type: String,
+ default: 'all'
+ },
+ // ������������������
+ imageFormData: {
+ type: Object | null,
+ default: () => { }
+ },
+ // ������������������
+ videoFromData: {
+ type: Object,
+ default: () => { }
+ },
+
+ // ������������������������������
+ action: {
+ type: String,
+ default: ''
+ },
+
+ // ������������, ���unicloud���������������
+ // https://uniapp.dcloud.net.cn/uniCloud/storage.html#storage-dir
+ cloudPathAsRealPath: {
+ type: Boolean,
+ default: false
+ },
+
+ // ���������������������������
+ headers: {
+ type: Object,
+ default: () => { }
+ },
+
+ // ������������������������������
+ data: {
+ type: Object,
+ default: () => { }
+ },
+
+ // ������������������������
+ isPreviewImage: {
+ type: Boolean,
+ default: true
+ },
+
+ // ������������������������������������"default" - ������������������������ "number" - ������������������������ "none" - ���������������������
+ indicator: {
+ type: String,
+ default: 'none'
+ },
+ // ������������������������������������������
+ autoUpload: {
+ type: Boolean,
+ default: true
+ },
+ // ������������������������
+ remove: {
+ type: Boolean,
+ default: true
+ },
+ // ������������������
+ add: {
+ type: Boolean,
+ default: true
+ },
+ // ������������������
+ max: {
+ type: Number,
+ default: 9
+ },
+ // ������������������������
+ maxVideo: {
+ type: Number,
+ default: 0
+ },
+ // ������������
+ listStyle: {
+ type: Object,
+ default: () => { }
+ },
+ // ������������������������
+ deleteTitle: {
+ type: String,
+ default: '������'
+ },
+ // ������������������������
+ deleteText: {
+ type: String,
+ default: '������������������������'
+ },
+ // ������������
+ loadingText: {
+ type: String,
+ default: '���������������...'
+ },
+ // ���������������������������
+ useBeforeDelete: {
+ type: Boolean,
+ default: false
+ },
+ // ���������������������������
+ useBeforeUpload: {
+ type: Boolean,
+ default: false
+ },
+ // ������������������
+ addImg: {
+ type: String,
+ default: 'https://mp-61599c79-d7ee-4a75-a24b-e5a288da6dd3.cdn.bspapp.com/cloudstorage/bb1550b3-e0a8-4a90-a86f-00f8c6afa9fb.png'
+ },
+ // ������������������
+ playImg: {
+ type: String,
+ default: 'https://mp-61599c79-d7ee-4a75-a24b-e5a288da6dd3.cdn.bspapp.com/cloudstorage/ae40402f-aa53-4344-b553-2322799bebd6.png'
+ },
+ // ������������������
+ deleteImg: {
+ type: String,
+ default: 'https://mp-61599c79-d7ee-4a75-a24b-e5a288da6dd3.cdn.bspapp.com/cloudstorage/d20177a5-417e-4c5d-a266-1988361c543d.png'
+ },
+ // ������������������������
+ closeImg: {
+ type: String,
+ default: 'https://mp-61599c79-d7ee-4a75-a24b-e5a288da6dd3.cdn.bspapp.com/cloudstorage/cde4362d-7ec7-4cac-a692-12e1f576be1e.png'
+ },
+ },
+ data() {
+ return {
+ // ������������
+ FileList: [],
+
+ // ������������������
+ tempVideoUrl: '',
+
+ // ������������������
+ tempFile_paths: [],
+
+ };
+ },
+ watch: {
+ // #ifdef VUE2
+ 'value': {
+ handler: function (newVal, oldVal) {
+ this.FileList = newVal;
+ },
+ deep: true,
+ immediate: true
+ },
+ // #endif
+
+ // #ifdef VUE3
+ 'modelValue': {
+ handler: function (newVal, oldVal) {
+ this.FileList = newVal;
+ },
+ deep: true,
+ immediate: true
+ },
+ // #endif
+ },
+ computed: {
+ previewList() {
+ return this.FileList.map(item => {
+ return {
+ path: item.path || item,
+ poster: item.poster || ''
+ }
+ })
+ },
+ listRowStyle() {
+ const style = {
+ 'grid-template-columns': `repeat(${this.listStyle?.columns || 4}, 1fr)`, // ������������
+ 'grid-column-gap': this.listStyle?.columnGap || '40rpx', // ���������
+ 'grid-row-gap': this.listStyle?.rowGap || '40rpx', // ���������
+ 'padding': this.listStyle?.padding || '0rpx' // ���������������
+ }
+
+ return style;
+ },
+ rowStyle() {
+ const { height = '140rpx', ratio } = this.listStyle || {};
+ const style = {
+ 'aspect-ratio': height ? '' : ratio || '1/1', // ������������
+ 'height': height,
+ };
+
+ return style;
+ },
+
+ imgStyle() {
+ const style = {
+ 'border-radius': this.listStyle?.radius || '6rpx', // ������������
+ }
+ return style;
+ }
+ },
+ methods: {
+ /**
+ * ���������������������
+ * @param {object} item ������������
+ * @param {number} selectedFileIndex ������������
+ * */
+ deleteSelectedFile(item, selectedFileIndex) {
+
+ const fileToDelete = this.FileList[selectedFileIndex];
+
+ // ���������������
+ if (this.useBeforeDelete) {
+ this.$emit('beforeDelete', fileToDelete, selectedFileIndex, () => {
+ return deleteFileFromList()
+ })
+ }
+
+ if (!this.useBeforeDelete) {
+ uni.showModal({
+ title: this.deleteTitle,
+ content: this.deleteText,
+ success: (res) => {
+ if (res.confirm) {
+ deleteFileFromList()
+ }
+ }
+ });
+ }
+
+ const deleteFileFromList = () => {
+ const tempFileIndex = this.tempFile_paths.indexOf(item || item.path);
+
+ if (tempFileIndex > -1) {
+ this.tempFile_paths.splice(tempFileIndex, 1)
+ }
+
+ this.FileList.splice(selectedFileIndex, 1)
+
+ // #ifdef VUE2
+ this.$emit('input', this.FileList)
+ // #endif
+
+ // #ifdef VUE3
+ this.$emit("update:modelValue", this.FileList);
+ // #endif
+ }
+
+ },
+
+ /**
+ * ���������������������
+ * @param {object} item ������������
+ * @param {number} index ������������
+ * */
+ clickSelectedFile(item, index) {
+ this.previewImage(item?.path ?? item, index);
+ this.$emit('onImage', {
+ item,
+ index
+ })
+ },
+
+ /**
+ * ������������������������
+ * */
+ selectFileTypeOnAdd() {
+
+ switch (this.fileType) {
+ case 'image':
+ this.handleFileSelection(1);
+ break;
+ case 'video':
+ this.handleFileSelection(2);
+ break;
+ case 'all':
+ uni.showActionSheet({
+ itemList: ['������', '������'],
+ success: (res) => {
+ const tapIndex = res.tapIndex;
+ if (tapIndex === 0) {
+ this.handleFileSelection(1);
+ } else {
+ this.handleFileSelection(2);
+ }
+ },
+ fail: (res) => {
+ console.error(res.errMsg);
+ }
+ });
+ break;
+ default:
+ this.handleFileSelection(1);
+ break;
+ }
+ },
+
+
+ /**
+ * ������������������������
+ * @param { number } updataType ������������ 1:������ 2������
+ * */
+ async handleFileSelection(updataType) {
+ const that = this;
+ if (updataType === 1) {
+
+ const data = Object.assign({}, {
+ // ������������������������������������������9
+ count: 9,
+ // ������ mediaType ��� image ������������������������������������
+ // #ifndef MP-TOUTIAO
+ sizeType: ['original', 'compressed'],
+ // #endif
+ // album ������������������camera ������������������������������������
+ sourceType: ['camera', 'album'],
+
+ compress: false
+ }, this.imageFormData)
+
+ data['count'] = this.max - this.FileList.length
+
+ uni.chooseImage({
+ ...data,
+ success: async (res) => {
+ let tempFiles = res.tempFiles
+ const compress = that.imageFormData?.compress || false;
+
+ // ������������������������
+ if (that.imageFormData?.size ?? false) {
+ const maxSize = that.imageFormData.size * 1024 * 1024
+
+ tempFiles.map((imgInfo, index) => {
+ if (imgInfo.size > maxSize) {
+ tempFiles.splice(index, 1)
+ that.$emit('onImageSize', imgInfo)
+ return uni.showToast({
+ title: `������������������${that.imageFormData.size}MB`,
+ duration: 2000,
+ icon: 'none'
+ });
+ }
+ })
+ }
+
+ // ������������������
+ if (compress) {
+ const compressedImagePathList = tempFiles.map(imageItem => {
+ return that.compressImage(imageItem.path)
+ })
+
+ Promise.all(compressedImagePathList).then(result => {
+ upload(result);
+ })
+
+ } else {
+ upload(tempFiles);
+ }
+
+ function upload(tempImages) {
+ if (that.autoUpload) {
+ tempImages.map(item => {
+ that.onBeforeUploadFile(item, 'image')
+ })
+ } else {
+ that.FileList = [...that.FileList, ...tempImages]
+ tempImages.map(item => {
+ that.tempFile_paths.push(item)
+ })
+ }
+ }
+
+ },
+ fail(err) {
+ console.error('������������������', err)
+ that.$emit('onError', err)
+ }
+
+ })
+ }
+
+ if (updataType === 2) {
+
+ // ������������������������������
+ const VIDEO_REGEXP = /\.(mp4|flv|avi)/i
+ const videoList = await that.FileList.filter(item => {
+ const fileUrl = item?.url ?? item
+ return VIDEO_REGEXP.test(fileUrl)
+ })
+
+ if (that.maxVideo > 0 && videoList.length >= that.maxVideo) {
+ that.$emit('onVideoMax', that.maxVideo, videoList.length)
+ return uni.showToast({
+ title: '���������������������',
+ duration: 2000,
+ icon: 'none'
+ });
+ }
+
+ const data = Object.assign({}, {
+ // ��������������������������������������������������������� 60 ������
+ maxDuration: 60,
+ // #ifndef MP-TOUTIAO
+ // 'front'���'back'���������'back'
+ camera: "back",
+ // #endif
+
+ // album ���������������������camera ������������������������������������������
+ sourceType: ['camera', 'album'],
+ // ��������������������������������������������������� true������������������
+ compressed: true,
+ // 'front'���'back'���������'back'
+ }, this.videoFromData)
+
+ uni.chooseVideo({
+ ...data,
+ success: (res) => {
+ let tempFilePath = { ...res }
+ tempFilePath['path'] = res.tempFilePath
+
+ // ������������������������
+ if (that.videoFromData?.size ?? false) {
+ const maxSize = that.videoFromData.size * 1024 * 1024
+
+ if (tempFilePath.size > maxSize) {
+ uni.showToast({
+ title: `������������������${that.videoFromData.size}MB`,
+ duration: 2000,
+ icon: 'none'
+ });
+ return false;
+ }
+
+ }
+ if (that.autoUpload) {
+ that.onBeforeUploadFile(tempFilePath, 'video')
+ } else {
+ that.FileList.push(tempFilePath)
+ that.tempFile_paths.push(tempFilePath)
+ }
+ },
+ fail(err) {
+ console.error('������������������', err)
+ }
+
+ })
+ }
+ },
+
+ /**
+ * ���������������
+ * @param { tempFile } ������������
+ * @return { Promise }
+ * */
+ onBeforeUploadFile(tempFile) {
+ if (this.useBeforeUpload) {
+ return this.$emit('beforeUpload', tempFile, () => {
+ return this.updataFile(tempFile);
+ })
+ }
+ return this.updataFile(tempFile);
+ },
+
+ /**
+ * ������������������������
+ * @param { tempFile } ������������
+ * @return { Promise }
+ * */
+ updataFile(tempFile) {
+ const that = this;
+ const filePath = tempFile.path || tempFile;
+ const fileType = this.fileUrlType(filePath) == 'image' ? '.png' : '.mp4';
+ const fileName = tempFile.name || Date.now() + fileType;
+
+ uni.showLoading({
+ title: this.loadingText,
+ icon: 'loading'
+ })
+
+ return new Promise((resolve, reject) => {
+ // uniCloud������
+ if (that.action === 'uniCloud') {
+
+ uniCloud.uploadFile({
+ cloudPath: String(fileName),
+ filePath: filePath,
+ // #ifdef MP-ALIPAY
+ fileType: fileType,
+ // #endif
+ cloudPathAsRealPath: this.cloudPathAsRealPath,
+
+ onUploadProgress: (progressEvent) => {
+ const percentCompleted = Math.round(
+ (progressEvent.loaded * 100) / progressEvent.total
+ );
+ that.$emit('onProgress', percentCompleted)
+ },
+ success(result) {
+ if (that.autoUpload) {
+ that.FileList.push(result.fileID)
+ } else {
+ that.FileList.map((item, index) => {
+ if (item === filePath || item.path === filePath) {
+ that.FileList.splice(index, 1, result.fileID)
+ }
+ })
+ }
+
+ // #ifdef VUE2
+ that.$emit('input', that.FileList)
+ // #endif
+ // #ifdef VUE3
+ that.$emit("update:modelValue", that.FileList);
+ // #endif
+
+ resolve(result.fileID)
+ uni.hideLoading();
+ that.$emit('onProgress', {
+ ...result
+ })
+ },
+ fail: (error) => {
+ uni.hideLoading();
+ console.error('error', error);
+ that.$emit('onError', error)
+ reject(error)
+ }
+ })
+ return false;
+ }
+
+ // ������������������
+ const uploadTask = uni.uploadFile({
+ url: that.action,
+ filePath: filePath,
+ name: that.fileName,
+ formData: that.data,
+ header: that.headers,
+ // #ifdef MP-ALIPAY
+ fileType: filetype,
+ // #endif
+ success: (uploadFileRes) => {
+ const data = JSON.parse(uploadFileRes.data)
+ uni.hideLoading();
+ that.success(data)
+
+ if (!this.autoUpload) {
+ that.FileList.map((item, index) => {
+ if (item === filePath || item.path === filePath) {
+ that.FileList.splice(index, 1)
+ }
+ })
+ }
+
+ resolve(data)
+ },
+ fail: (error) => {
+ uni.hideLoading();
+ console.error('error', error);
+ that.$emit('onError', error)
+ reject(error)
+ }
+ });
+
+ uploadTask.onProgressUpdate((res) => {
+ that.$emit('onProgress', {
+ ...res,
+ ...tempFile
+ })
+ });
+ })
+ },
+
+ /**
+ * ������������
+ * */
+ submit() {
+
+ return new Promise((resolve, reject) => {
+ if (this.tempFile_paths.length <= 0) {
+ resolve([])
+ }
+
+ const uploadedFilePaths = this.tempFile_paths.map(item => {
+ return this.onBeforeUploadFile(item || item.path)
+ })
+
+ Promise.all(uploadedFilePaths).then(res => {
+ this.tempFile_paths = []
+ resolve(res)
+ }).catch(err => {
+ reject(err)
+ })
+ })
+
+ },
+
+ /**
+ * ������������
+ * @param {array} data ������������������������
+ * @return {array} ������������
+ * */
+ success(data) {
+ this.$emit('onSuccess', data);
+
+ // ���������������������-���������������
+ // const list = data.map(item=> {
+ // return JSON.parse(item).data.link;
+ // })
+ // this.$emit('input', [...this.FileList, ...list]);
+ },
+ /**
+ * ������������
+ * @param {array} tempFilePaths ������������������
+ * @return {array} ���������������������������
+ * */
+ async compressImage(tempFilePaths) {
+ const that = this;
+
+ return new Promise((resolve, reject) => {
+
+ if (typeof tempFilePaths !== 'string') {
+ console.error('������������������')
+ reject([])
+ }
+
+ uni.showLoading({
+ title: '���������...',
+ icon: 'loading',
+ })
+
+ // #ifdef H5
+ this.canvasDataURL(tempFilePaths, {
+ quality: that.imageFormData.quality / 100
+ }, (base64Codes) => {
+ resolve(base64Codes);
+ uni.hideLoading();
+ })
+ // #endif
+
+ // #ifndef H5
+ uni.compressImage({
+ src: tempFilePaths,
+ quality: that.imageFormData.quality || 80,
+ success: res => {
+ resolve(res.tempFilePath);
+ uni.hideLoading();
+ },
+ fail(err) {
+ reject(err);
+ uni.hideLoading();
+ }
+ })
+ // #endif
+
+ })
+ },
+
+ /**
+ * H5������������������
+ * @param {string} path ������������
+ * @param {object} obj ������������
+ * @param {function} callback ������������
+ * @return {string} base64
+ * */
+ canvasDataURL(path, obj, callback) {
+ var img = new Image();
+ img.src = path;
+ img.onload = function () {
+ var that = this;
+ // ���������������������
+ var w = that.width,
+ h = that.height,
+ scale = w / h;
+ w = obj.width || w;
+ h = obj.height || (w / scale);
+ var quality = 0.8; // ���������������������0.8
+ //������canvas
+ var canvas = document.createElement('canvas');
+ var ctx = canvas.getContext('2d');
+ // ������������������
+ var anw = document.createAttribute("width");
+ anw.nodeValue = w;
+ var anh = document.createAttribute("height");
+ anh.nodeValue = h;
+ canvas.setAttributeNode(anw);
+ canvas.setAttributeNode(anh);
+ ctx.drawImage(that, 0, 0, w, h);
+ // ������������
+ if (obj.quality && obj.quality <= 1 && obj.quality > 0) {
+ quality = obj.quality;
+ }
+ // quality������������������������������������������
+ var base64 = canvas.toDataURL('image/jpeg', quality);
+ // ������������������base64������
+ callback(base64);
+ }
+ },
+
+ /**
+ * ������������
+ * @param {string, object} item ������������
+ * */
+ previewImage(item) {
+ if (this.fileUrlType(item) === 'video') return false;
+ if (!this.isPreviewImage) return false;
+
+ const imgs = this.FileList.filter(item => {
+ return this.fileUrlType(item) !== 'video'
+ }).map(item => item?.path ?? item)
+ const current = imgs.indexOf(item || item.path);
+
+ uni.previewImage({
+ current: current,
+ urls: imgs,
+ success() {
+ },
+ fail(err) {
+ console.log(err);
+ }
+ })
+ },
+
+ /**
+ * ������������
+ * @param {string, object} item ������������
+ * @param {number} index ������
+ * */
+ previewVideo(item, index) {
+ this.$emit('onVideo', {
+ item,
+ index
+ })
+ this.tempVideoUrl = item.path;
+ },
+
+ /**
+ * ������img������
+ * @param {string, object} item ������������
+ * @return {boolean} ������img������
+ * */
+ fileUrlType(file) {
+ const filePath = file.path || file;
+
+ if (this.isBase64(filePath)) return 'image'
+
+ const fileType = filePath.split('.').pop();
+
+ const IMAGE_REGEXP = /(jpeg|jpg|gif|png|svg|webp|jfif|bmp|dpg|image)/i
+ if (IMAGE_REGEXP.test(fileType)) {
+ return 'image';
+ } else {
+ return 'video';
+ }
+ },
+ // ���������������base64
+ isBase64(str) {
+ if (str === '' || typeof str !== 'string') return console.error('������������������, base64', str);
+ return str.includes('blob:') || str.includes('data:image');
+ }
+ }
+}
+</script>
+
+<style lang="scss" scoped>
+.cl-updata {
+
+ .file-list {
+ display: grid;
+
+ &-row {
+ display: inline-flex;
+ align-items: center;
+ position: relative;
+
+ .play-img {
+ width: 100%;
+ }
+
+ ._image {
+ height: 100%;
+ width: 100%;
+ }
+
+ ._video {
+ position: relative;
+ width: 100%;
+ height: 100%;
+ overflow: hidden;
+ }
+
+ .video-fixed {
+ position: absolute;
+ top: 0;
+ left: 0;
+ bottom: 0;
+ width: 100%;
+ height: 100%;
+ border-radius: 10rpx;
+ z-index: 96;
+ }
+
+ .play {
+ position: absolute;
+ top: 50%;
+ left: 50%;
+ transform: translate(-50%, -50%);
+ width: 30%;
+ z-index: 95;
+ }
+
+ .app_play {
+ position: absolute;
+ top: 50%;
+ left: 50%;
+ transform: translate(-50%, -50%);
+ width: 50rpx;
+ height: 50rpx;
+ }
+
+ .remove {
+ position: absolute;
+ top: 0;
+ right: 0;
+ background-color: #373737;
+ height: 50rpx;
+ width: 50rpx;
+ border-bottom-left-radius: 200rpx;
+ z-index: 97;
+
+ .image {
+ width: 20rpx;
+ height: 20rpx;
+ position: absolute;
+ right: 12rpx;
+ top: 12rpx;
+ }
+ }
+ }
+
+ .add-image {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ border: 2rpx dashed #ccc;
+ width: 100%;
+ height: 100%;
+ border-radius: 5rpx;
+
+ &:active {
+ opacity: 0.8;
+ }
+
+ ._image {
+ width: 40%;
+ }
+ }
+ }
+
+ .mask {
+ background-color: #000;
+ position: fixed;
+ top: 0;
+ right: 0;
+ bottom: 0;
+ left: 0;
+ z-index: 99;
+
+ .block {
+ padding: 0 30rpx;
+ position: absolute;
+ top: 50%;
+ left: 50%;
+ transform: translate(-50%, -50%);
+ width: 100%;
+
+ .block_video {
+ width: 100%;
+ height: 78vh;
+ }
+ }
+
+ ._root {
+ width: 60rpx;
+ height: 60rpx;
+ position: absolute;
+ left: 40rpx;
+ top: 5vh
+ }
+ }
+}
+</style>
diff --git a/uni_modules/cl-upload/package.json b/uni_modules/cl-upload/package.json
new file mode 100644
index 0000000..a8e3a0d
--- /dev/null
+++ b/uni_modules/cl-upload/package.json
@@ -0,0 +1,82 @@
+{
+ "id": "cl-upload",
+ "displayName": "��������������������� ���������������������������������������uniCloud������ ���������",
+ "version": "1.4.0",
+ "description": "������������������������������������������������������������������uniCloud���������������������������������",
+ "keywords": [
+ "������������������������������������������������",
+ "uniCloud������"
+],
+ "repository": "",
+ "engines": {
+ "HBuilderX": "^3.5.3"
+ },
+ "dcloudext": {
+ "type": "component-vue",
+ "sale": {
+ "regular": {
+ "price": "0.00"
+ },
+ "sourcecode": {
+ "price": "0.00"
+ }
+ },
+ "contact": {
+ "qq": ""
+ },
+ "declaration": {
+ "ads": "���",
+ "data": "���",
+ "permissions": "���"
+ },
+ "npmurl": ""
+ },
+ "uni_modules": {
+ "dependencies": [],
+ "encrypt": [],
+ "platforms": {
+ "cloud": {
+ "tcb": "y",
+ "aliyun": "y"
+ },
+ "client": {
+ "Vue": {
+ "vue2": "y",
+ "vue3": "y"
+ },
+ "App": {
+ "app-vue": "u",
+ "app-nvue": "u"
+ },
+ "H5-mobile": {
+ "Safari": "y",
+ "Android Browser": "y",
+ "���������������(Android)": "y",
+ "QQ���������(Android)": "y"
+ },
+ "H5-pc": {
+ "Chrome": "y",
+ "IE": "y",
+ "Edge": "y",
+ "Firefox": "y",
+ "Safari": "y"
+ },
+ "���������": {
+ "������": "y",
+ "������": "y",
+ "������": "u",
+ "������������": "y",
+ "QQ": "u",
+ "������": "u",
+ "������": "u",
+ "������": "u",
+ "������": "u"
+ },
+ "���������": {
+ "������": "u",
+ "������": "u"
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/uni_modules/cl-upload/readme.md b/uni_modules/cl-upload/readme.md
new file mode 100644
index 0000000..528b5f2
--- /dev/null
+++ b/uni_modules/cl-upload/readme.md
@@ -0,0 +1,253 @@
+### cl-upload ������������
+
+> ���������������������������������������������������������������������������������
+
+
+> `���������������������������������������������������������������������������������������������������������������������,���������������������������������������������������������������������������������������������promise������ ������������`
+
+### ������������
+1. ratio ���������������������������������������������������height������������
+2. ������������������������������������������������������������������������
+3. ������������������������������������������������������������api������������������������������������������������������������������������������
+4. **������������������`https`, http���������������������������������**
+5. ������������������`https`������������`cloudType: other`
+
+### H5������������
+
+
+#### list������������
+
+1. ������������
+```
+['������1','������2']
+```
+2. JSON������
+```
+[
+ {
+ path: '������1.png',
+ // ������������
+ },
+ {
+ path: '������2.mp4',
+ poster: '���������������.png'
+ // ������������
+ },
+ {
+ path: '������3.mp4',
+ poster: require('../../static/c1.png'), // ������������������������������
+ // ������������
+ },
+]
+```
+
+#### ������������
+
+```
+<cl-upload v-model="list" action="������������" @onSuccess="onSuccess"></cl-upload>
+
+methods: {
+ /**
+ * ������������������������������������������
+ * ���������������������������������������������������������������
+ * */
+ onSuccess(reslut) {
+ // ������������������������������������������list������������������������
+ this.list.push(reslut.url)
+ },
+}
+```
+### uniCloud������
+> ������������������������,������������������
+
+```
+<cl-upload v-model="list" action="uniCloud"></cl-upload>
+```
+
+### ���������������
+> ������ listStyle ������������������������������������������������������������������
+
+```
+<cl-upload v-model="list" :listStyle="{
+ columns: 2,
+ columnGap: '20rpx',
+ rowGap:'20rpx',
+ padding:'10rpx',
+ height:'300rpx',
+ radius:'20rpx'
+}">
+ <template v-slot:addImg>
+ <view class="newAddImg">
+ <view>���</view>
+ <text >������</text>
+ </view>
+ </template>
+</cl-upload>
+```
+
+### ������������
+> ���������������������������������������
+```
+<cl-upload v-model="list" :add="false" :remove="false"></cl-upload>
+```
+
+### ������������
+
+> ������ autoUpload ��������������������������������������������� refs ������������������������������������������������������������������������������
+
+```
+<cl-upload
+ ref="upload2"
+ v-model="list2"
+ :autoUpload="false"></cl-upload>
+
+<button @tap="submit">������������</button>
+
+methods: {
+ submit() {
+ /**
+ * ������������������������������
+ * */
+ this.$refs.upload2.submit().then(reslut=>{
+ console.log(reslut); // ���������������������������������������
+
+ // ������������������������������������������������
+ // ������uniCloud������������
+ const imgUrls = reslut.list.map(imgInfo=> imgInfo.url);
+ this.list2 = [...this.list2, ...imgUrls]
+ })
+ },
+}
+```
+
+### ���������������������������������
+```
+/ **
+* ��������������������� useBeforeDelete
+* ��������������������� useBeforeUpload
+*/
+<cl-upload v-model="list"
+ useBeforeDelete
+ useBeforeUpload
+ @beforeDelete="beforeDelete"
+ @beforeUpload="beforeUpload"></cl-upload>
+
+
+methods: {
+ /**
+ * ���������������
+ * @param {Object} item ���������������������������������������
+ * @param {Number} index ������������������������������������
+ * @param {Function} next ���������������������������������������������
+ * */
+ beforeDelete(item, index, next) {
+ uni.showModal({
+ title: '������������',
+ content: '���������������������������������',
+ success: res => {
+ if (res.confirm) {
+ // ���������������������
+ setTimeout(() => {
+ next();
+ }, 1000);
+ }
+ }
+ });
+ },
+ /**
+ * ���������������
+ * @param {Object} tempFile ������������������������
+ * @param {Function} next ���������������������������������������������
+ * */
+ beforeUpload(tempFile, next) {
+ // ���������������������
+ // ������������������������������������������������������next(), ���������������������������list
+ }
+}
+```
+
+## API
+
+| ������ | ������ | ������ | ��������� | ��������� |
+| --- | --- | --- | --- | --- |
+| action | ������������ | String |-| uniCloud |
+| cloudPathAsRealPath | ������������, ���unicloud���������������`1.4.0` `HBuilderX 3.8.5` | Boolean |false| true |
+| cloudType | ���������������(������������������������������������������ other���������video������������,������������������������������) | String |oss| ���������:oss ���������:vframe ���������:process ������:other |
+| headers | ��������������������������� | Object | - |- |
+| data | ������������������������������ | Object | - | - |
+| fileName| ���������,������������������������ | String | file | - |
+| fileType | ������������ | String | all | 'image', 'video', 'all' |
+| imageFormData | ������������������ | Object | - | - |
+| videoFromData | ������������������ | Object | - | - |
+| listStyle | ������������ |Object | - | - |
+| isPreviewImage | ������������������������ | Boolean | true |false |
+| remove | ������������������������ | Boolean | true |false |
+| add | ������������������ | Boolean | true |false |
+| max | ������������������ | Number | 9 | - |
+| maxVideo | ������������������������ | Number | ��������� | - |
+| deleteTitle| ������������������������ | String | ������ | - |
+| deleteText| ������������������������ | String | ������������������������ | - |
+| loadingText| ������������ | String | ���������������... | - |
+| useBeforeDelete| ��������������������������� | Boolean | false | true |
+| useBeforeUpload | ��������������������������� | Boolean | false | true |
+| addImg| ������������������ | String | - | - |
+| playImg| ������������������ | String | - | - |
+| deleteImg| ������������������ | String | - | - |
+| closeImg| ������������������������ | String | - | - |
+
+#### imageFormData
+
+| ������ | ������ | ������ | ��������� | ��������� |
+| --- | --- | --- | --- | --- |
+| count | ��������������������������������� | number |9| - |
+| sizeType | original ���������compressed ��������� | array | ������������������ |- |
+| sourceType | ������������������ | array | ['camera ', 'album'] | ['camera ', 'album'] |
+| compress | ������������������������ | Boolean | false | true |
+| quality | ������������ | number | 80 | - |
+| size | ������������ | number | - | ������MB |
+
+#### videoFromData
+
+| ������ | ������ | ������ | ��������� | ��������� |
+| --- | --- | --- | --- | --- |
+| maxDuration | ������������������������������ | number |60| ������60��� |
+| camera | ������������������������ | array | - |- |
+| compressed | ��������������������������������������� | Boolean | true |- |
+| sourceType | ������������������ | array | ['camera ', 'album'] | ['camera ', 'album'] |
+| size | ������������ | number | - | ������MB |
+
+#### listStyle
+
+| ������ | ������ | ������ | ��������� | ��������� |
+| --- | --- | --- | --- | --- |
+| columns | ������������ | number |4| - |
+| columnGap | ��������� | string | '40rpx' |- |
+| rowGap | ��������� | string | '40rpx' |- |
+| padding | ��������������� | string | '0 0rpx' |- |
+| ratio | ������������ | string | '1/1' | ������������������������,������������height������ |
+| height | ������������ | string | '140rpx' |- |
+| radius | ������������ | string | '6rpx' |- |
+
+#### Events
+
+| ��������� | ������ | ������������ |
+| --- | --- | --- |
+| onSuccess | ������������ | data: ��������������������� |
+| onError | ������������ | error:������������ |
+| onImage | ������������ | item: ������������ index: ������������ |
+| onVideo | ������������ | item: ������������ index: ������������ |
+| onProgress | ������������ | onProgress������������|
+| onVideoMax | ������������������������������ | maxVideo, fileLength|
+| onImageSize | ������������������������������ | ������������ |
+| beforeDelete | ��������������� | item: ������������ index:������������ next:������������������������ |
+| beforeUpload | ��������������� | tempFile: ������������ next:������������������������ |
+
+#### onProgress������������
+| ��������� | ������ |
+| --- | --- |
+| progress | ��������������������� |
+| totalBytesSent | ��������������������������� |
+| totalBytesExpectedToSend | ������������������������������������ |
+
+
+### [������������������������ uniapp ������QQ��� 553291781](https://jq.qq.com/?_wv=1027&k=5UkMN1QX)
\ No newline at end of file
diff --git a/uni_modules/uview-ui/LICENSE b/uni_modules/uview-ui/LICENSE
new file mode 100644
index 0000000..4db40ef
--- /dev/null
+++ b/uni_modules/uview-ui/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2023 www.uviewui.com
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/uni_modules/uview-ui/README.md b/uni_modules/uview-ui/README.md
new file mode 100644
index 0000000..c78ff47
--- /dev/null
+++ b/uni_modules/uview-ui/README.md
@@ -0,0 +1,66 @@
+<p align="center">
+ <img alt="logo" src="https://uviewui.com/common/logo.png" width="120" height="120" style="margin-bottom: 10px;">
+</p>
+<h3 align="center" style="margin: 30px 0 30px;font-weight: bold;font-size:40px;">uView 2.0</h3>
+<h3 align="center">������������������������UI������</h3>
+
+[](https://github.com/umicro/uView2.0)
+[](https://github.com/umicro/uView2.0)
+[](https://github.com/umicro/uView2.0/issues)
+[](https://uviewui.com)
+[](https://gitee.com/umicro/uView2.0/releases)
+[](https://en.wikipedia.org/wiki/MIT_License)
+
+## ������
+
+uView UI������[uni-app](https://uniapp.dcloud.io/)������������nvue���uni-app������������������������������������������������������������������������������������
+
+## [���������������https://uviewui.com](https://uviewui.com)
+
+
+## ������
+
+���������������**������**���������������������������������������
+<br>
+<br>
+<img src="https://uviewui.com/common/weixin_mini_qrcode.png" width="220" height="220" >
+
+
+## ������
+
+- [������������](https://www.uviewui.com/)
+- [������������](https://www.uviewui.com/components/changelog.html)
+- [������������](https://www.uviewui.com/components/changeGuide.html)
+- [������������](https://www.uviewui.com/cooperation/about.html)
+
+## ������������
+
+���������������������QQ������������������[������������](https://www.uviewui.com/components/addQQGroup.html)
+
+## ������PR
+
+> ���������������������������������������PR������������������������������������uView2.0���������������������������������������������������h5���ios app���android app���������nvue���������vue���������
+> ������������������������bug������������������������������������������������������������������������������������������������������������������������������
+
+## ������
+
+#### **uni-app������������������** ������ [https://ext.dcloud.net.cn/plugin?id=1593](https://ext.dcloud.net.cn/plugin?id=1593)
+
+���������[������������������](https://www.uviewui.com/components/install.html)������������������������
+
+## ������������
+
+���������[������������](https://uviewui.com/components/quickstart.html)������������������������
+
+## ������������
+������easycom���������������������������������������`import`������������������������������
+
+```html
+<template>
+ <u-button text="������"></u-button>
+</template>
+```
+
+## ������������
+uView������[MIT](https://en.wikipedia.org/wiki/MIT_License)���������������������������������������������������������������������������������uView���������������������������
+
diff --git a/uni_modules/uview-ui/changelog.md b/uni_modules/uview-ui/changelog.md
new file mode 100644
index 0000000..f2bae72
--- /dev/null
+++ b/uni_modules/uview-ui/changelog.md
@@ -0,0 +1,362 @@
+## 2.0.36���2023-03-27���
+# uView2.0������������������������������������������
+
+1. ������`deepClone` & `deepMerge`������
+2. ������������
+## 2.0.34���2022-09-24���
+# uView2.0������������������������������������������
+
+1. `u-input`���`u-textarea`������`ignoreCompositionEvent`������
+2. ������`route`���������������������������������
+3. ������`u-no-network`������`z-index`���������������
+4. ������`textarea`���������h5���confirmType=""���������������
+5. `u-rate`������`nvue`
+6. ������������������������������������������(���������������������������������������������������2017���������������������������)
+7. `form-item`������`labelPosition`������
+8. `u-calendar`������`maxDate`������������������������������������������������08���00������������������������������������ (#724)
+9. `u-radio`���������������������������������������������label������ (#680)
+10. ������`timeFormat`���������safari��������������������� (#664)
+## 2.0.33���2022-06-17���
+# uView2.0������������������������������������������
+
+1. ������`loadmore`������`lineColor`������������������
+2. ������`u-parse`������`imgtap`���`linktap`���������������
+## 2.0.32���2022-06-16���
+# uView2.0������������������������������������������
+1. `u-loadmore`���������������������������/������
+2. ������`u-swiper-action`���������������������������������������������
+3. ������`u-list`������������
+4. ������`notice-bar`������������������������������������������������������
+5. `u-loading-page`���������������������������������`iconSize`
+6. ������`u-tooltip`������`color`������������������������
+7. ������`u--input`������������`blur`���������������`undefined`���bug
+8. `u-code-input`������������������������������������������������������������`adjustPosition`
+9. ������`image`������`load`���������������������������
+10. ������`button`������`loadingSize`������������������
+10. ������������
+## 2.0.31���2022-04-19���
+# uView2.0������������������������������������������
+
+1. ������`upload`���`vue`������������������������������������������������
+2. ���������������������������������������������������������������������������������
+3. ������`u-code-input`���������`nvue`���������������`app`������������������������������`app`������������������
+4. ������`actionSheet`���������������������������������������������������������
+5. ������������
+## 2.0.30���2022-04-04���
+# uView2.0������������������������������������������
+
+1. `u-rate`������`readonly`������
+2. `tabs`������������������������������
+3. ������`u-subsection` `mode`���`subsection`������������������������������������
+4. `u-code-input`������������������������
+5. ������`popup`���`open`���������������
+6. ������`u-flex-column`���������������
+7. ������`u-datetime-picker`���������������������������������
+8. ������`u-datetime-picker`���������������������������������������
+9. `u-swiper`������`m3u8`������
+10. `u-swiper`������������image���video������
+11. ������`swiper`���������������������������������������`type`������
+12. ������`u-row-notice`������������������
+13. ������`u-switch`���������`unit`���`rpx`���,`nodeStyle`���������������
+14. ������`datetime-picker`������`showToolbar`���`visibleItemCount`���������������������
+15. ������`upload`���������������������������������������������`previewImage`���������������`false`������������������������������������������
+16. ������`u-checkbox-group`������`shape`���������������������
+17. ������`u-upload`���`capture`������������������������������������������
+18. ������`u-action-sheet`������������������������������������������
+19. ������`u-list`������������������������������������
+20. ������`u-text`���������������������������������
+21. ������`u-textarea`���������������������
+22. ������������
+## 2.0.29���2022-03-13���
+# uView2.0������������������������������������������
+
+1. ������`u--text`������������`decoration`������������������������
+2. ������`u-datetime-picker`������`formatter`���������������������
+3. ������`u-datetime-picker` `intercept` ���������undefined
+4. ��������������������� uni..config.unit = 'rpx'��������������������� `transform` ���������������������������������������������
+5. ������mixin���bem������������������������������������������������������������
+6. ���������������������������������������������`u-datetime-picker`���������������������������������������bug
+7. ������`u-datetime-picker`������`formatter`���������������������
+8. ������`u-image`������`loading`������������������
+9. ������`config.unit`������������`rpx`������������������������������������������������������
+10. ������`u-datetime-picker`������`itemHeight`������������
+11. ������������
+## 2.0.28���2022-02-22���
+# uView2.0������������������������������������������
+
+1. search������������searchIconSize������
+2. ������Safari/Webkit������������������������2022-02-17 12:00:56
+3. ������text value.js ���������������format������������
+4. priceFormat���������������������������������
+5. priceFormat������������������������������������������
+6. ������������rules������
+7. ������avatar������src������������������������������
+8. ������������
+## 2.0.27���2022-01-28���
+# uView2.0������������������������������������������
+
+1.������������
+## 2.0.26���2022-01-28���
+# uView2.0������������������������������������������
+
+1.������������
+## 2.0.25���2022-01-27���
+# uView2.0������������������������������������������
+
+1. ������text������mode=price������������������������������������������
+2. ������$u.setConfig()������������������uView���������config, props, zIndex, color������������������[������uView������������������](https://uviewui.com/components/setting.html#%E9%BB%98%E8%AE%A4%E5%8D%95%E4%BD%8D%E9%85%8D%E7%BD%AE)
+3. ������form���������errorType=toast���������������������������������������������������
+4. ������$u.addUnit()������������������������������������������
+## 2.0.24���2022-01-25���
+# uView2.0������������������������������������������
+
+1. ������swiper���current���������0���������������
+2. ������u-icon������stop���������������������
+3. ���������������������������������rpx���������������
+4. ������Layout������ vue������gutter���������������������������
+5. ������search���������������������������rpx -> px���
+6. ������u-image slot ���������������������������������������
+7. ������u-index-list���footer���������header���������������������������
+8. ���������������������u-popup������������������
+9. ������u-image���nvue-app���������������
+10. ������u-popup������������
+11. ������u-tooltip������
+12. ������box-sizing���app������������
+13. ������u-navbar���������������������������������
+14. ������������
+## 2.0.23���2022-01-24���
+# uView2.0������������������������������������������
+
+1. ������image���������hx3.3.9���nvue���������������������������������
+2. ������col������gutter���������rpx������������������������������
+3. ������text���������������������������������������������
+4. navbar������titleStyle������
+5. ���������hx3.3.9���������nvue���������������������������������
+## 2.0.22���2022-01-19���
+# uView2.0������������������������������������������
+
+1. $u.page()���������������������������������������������������������
+2. picker������������immediateChange������
+3. ������$u.pages()������
+## 2.0.21���2022-01-19���
+# uView2.0������������������������������������������
+
+1. ���������form���������������������rules���������������������model������
+2. ���������������������������������rpx���������������
+3. ������������������������������tabbar������������safeAreaInsetBottom������������placeholder���������������������
+4. ������swiper���current���������0���������������
+5. ������u-icon������stop���������������������
+6. ������upload���������accept=all���������������������
+7. ���������text������mode���phone���call���������������������
+8. ������u-form clearValidate������
+9. ������������
+## 2.0.20���2022-01-14���
+# uView2.0������������������������������������������
+
+1. ������calendar������������������������������������������������������������������������������������
+2. ������Slider������disabled props ������������
+3. ������u-notice-bar������������������������index������������������
+4. ������u-collapse-item���vue������������app������������������������������������
+5. ���������������������������������������
+6. ������������������������������������������������������������
+7. ���������������������������������������������
+8. search������������������������icon������
+9. ������u-form clearValidate���������������
+10. upload h5���������������������������������������name���������
+11. ������upload���������������url���blob���������������������������
+12. u-code-input ���������������������������������������������
+13. ������Upload������ disabled���true������������������hoverClass������������
+14. ������������ios app���grid������������������
+15. ������������
+## 2.0.19���2021-12-29���
+# uView2.0������������������������������������������
+
+1. ���������������������������������������������������������������HbuilderX3.3.4���������������������->������������������������������������������������������������������������
+2. ���������������������setData������������������������������$u.route()���������������������������������
+3. navbar������autoBack������
+4. ������avatar���������������������
+5. ������cell������������������
+6. ������������
+## 2.0.18���2021-12-28���
+# uView2.0������������������������������������������
+
+1. ������app���������������������
+2. ������������������������������setData���������������������
+3. ������������������
+4. ���������������������������������0������������������������������
+5. ������SwipeAction������������������������������������������
+6. ������input���placeholder������������������������������true������
+7. ������divider������click������������������
+8. ������u-code-input maxlength ������������ String ���������������������
+9. ��������� grid������ 1���2��� ���������������algin���������������������
+10. ������form-item���label���top������������������������������������
+11. ������������
+## 2.0.17���2021-12-26���
+## uView���������������������������������������������������������������������������������������������������������������������������������[������������uView](https://www.oschina.net/project/top_cn_2021/?id=583)
+
+# uView2.0������������������������������������������
+
+1. ������HBuilderX3.3.3.20211225���������������������������
+2. calendar������������monthNum������
+3. navbar������center slot
+## 2.0.16���2021-12-25���
+## uView���������������������������������������������������������������������������������������������������������������������������������[������������uView](https://www.oschina.net/project/top_cn_2021/?id=583)
+
+# uView2.0������������������������������������������
+
+1. ���������������������setData������������
+2. ������count-down������change���������������������
+## 2.0.15���2021-12-21���
+## uView���������������������������������������������������������������������������������������������������������������������������������[������������uView](https://www.oschina.net/project/top_cn_2021/?id=583)
+
+# uView2.0������������������������������������������
+
+1. ������Cell���������titleWidth������
+2. ������cheakbox������ischecked���������
+3. ������keyboard������������"."���������������������
+4. ������number-keyboard���������������������"."������������
+5. ������Input��������� readonly������
+6. ������u-avatar ������������app���H5������������������
+7. ������Upload������deletable������
+8. ������upload���������maxSize������������������
+9. ������tabs lineWidth���������������������������������������������������������������
+10. ������rate������������padding���view���������������������������������������������������������������������������������
+## 2.0.13���2021-12-14���
+## [���������������������������364463526](https://jq.qq.com/?_chanwv=1027&k=mCxS3TGY)
+
+# uView2.0������������������������������������������
+
+1. ���������������������������rpx������������������������������������������������������
+## 2.0.12���2021-12-14���
+## [���������������������������364463526](https://jq.qq.com/?_chanwv=1027&k=mCxS3TGY)
+
+# uView2.0������������������������������������������
+
+1. ������tabs���������vue������������������������������
+2. ������upload���������������������������������������������������
+3. ������uni.$u.config.unit���������������������������������������������������[������������������](https://www.uviewui.com/components/setting.html#%E9%BB%98%E8%AE%A4%E5%8D%95%E4%BD%8D%E9%85%8D%E7%BD%AE)
+4. ������textarea������������������v-model���������������������������������
+5. ������nvue������������������������������������������
+## 2.0.11���2021-12-13���
+## [���������������������������364463526](https://jq.qq.com/?_chanwv=1027&k=mCxS3TGY)
+
+# uView2.0������������������������������������������
+
+1. text������align���������������������
+2. subsection������������keyName������
+3. upload������������������[Object file]���������������
+4. ������notify������������������
+5. codeInput������������disabledDot������
+6. ������actionSheet������round���������������������
+7. calendar������������round���������������������������
+8. ������swipeAction���������vue���������������������������������
+9. button���������throttleTime���������������������������
+10. ������u-notify������������������close()���������������
+11. input������readonly���������������
+12. tag������type���������info���������������
+## 2.0.10���2021-12-08���
+## [���������������������������364463526](https://jq.qq.com/?_chanwv=1027&k=mCxS3TGY)
+
+# uView2.0������������������������������������������
+
+1. ������button sendMessagePath���������������
+2. ������DatetimePicker���������title������
+3. ������u-toast������loading=true���������
+4. ������u-text���������������0������
+5. ������u-toast���������icon���������������������
+6. button���icon���������������������������������
+7. IndexList���������������#
+## 2.0.9���2021-12-01���
+## [���������������������������232041042](https://jq.qq.com/?_wv=1027&k=KnbeceDU)
+
+# uView2.0������������������������������������������
+
+1. ������swiper���height������100%���(���vue������)������������������������click���������������������������
+2. ������tabs���������list���������������������������������������list������������������������������������
+3. ������datetime-picker������������������������������������������������������������������������������������v-model������������������
+4. ������upload������������������������������������������������������������������
+## 2.0.8���2021-12-01���
+## [���������������������������232041042](https://jq.qq.com/?_wv=1027&k=KnbeceDU)
+
+# uView2.0������������������������������������������
+
+1. ������toast���position������������������
+2. ������input���ios nvue������������������������������
+3. avatar-group������������extraValue���������������������������������������������
+4. tabs������������keyName���������������������������������������������
+5. ������text���������������������������������������������
+6. ������picker������item������������������������
+## 2.0.7���2021-11-30���
+## [���������������������������232041042](https://jq.qq.com/?_wv=1027&k=KnbeceDU)
+
+# uView2.0������������������������������������������
+
+1. ������radio���checkbox������������v-model������������������
+2. ������form������validator������������������������
+3. ������backtop������mode���������������������������������������
+4. ������Album���previewFullImage���������������������
+5. ������u-datetime-picker������mode='time'���������������������������������������������������
+## 2.0.6���2021-11-27���
+## [���������������������������232041042](https://jq.qq.com/?_wv=1027&k=KnbeceDU)
+
+# uView2.0������������������������������������������
+
+1. ������tag���������vue���������������������������
+2. ������popup������������������������������������������
+3. ������tabs������lineColor������������������������������
+4. propgress������������������������������������������������
+## 2.0.5���2021-11-25���
+## [���������������������������232041042](https://jq.qq.com/?_wv=1027&k=KnbeceDU)
+
+# uView2.0������������������������������������������
+
+1. calendar���vue������������������������
+2. form������labelPosition���errorType���������������������
+3. input������inputAlign���������������
+4. ������������������
+## 2.0.4���2021-11-23���
+## [���������������������������232041042](https://jq.qq.com/?_wv=1027&k=KnbeceDU)
+
+# uView2.0������������������������������������������
+
+0. input������������@confirm���������������subfix���prefix������������
+1. component.scss���������������vue���������������������������
+2. ������subsection���vue������������������������������
+3. tag���������bgColor������������������������
+4. upload������������������������
+5. ���������������������������
+## 2.0.3���2021-11-16���
+## [���������������������������1129077272](https://jq.qq.com/?_wv=1027&k=KnbeceDU)
+
+# uView2.0������������������������������������������
+
+1. uView2.0���������������������nvue
+2. uView2.0���1.x���������������������������������������������������������
+3. ������uView2.0������������������������������������������������
+4. ���������������������1.x������������������������[������1.x](https://www.uviewui.com/components/diff1.x.html)
+5. ������modal���confirm������������������������������
+6. ������input������@input������������������������
+7. ������������������
+## 2.0.2���2021-11-16���
+## [���������������������������1129077272](https://jq.qq.com/?_wv=1027&k=KnbeceDU)
+
+# uView2.0������������������������������������������
+
+1. uView2.0���������������������nvue
+2. uView2.0���1.x���������������������������������������������������������
+3. ������uView2.0������������������������������������������������
+4. ���������������������1.x������������������������[������1.x](https://www.uviewui.com/components/diff1.x.html)
+5. ������input������formatter������������������
+6. ������loading-icon���������scss���������������������������������������scss
+## 2.0.0(2020-11-15)
+## [���������������������������1129077272](https://jq.qq.com/?_wv=1027&k=KnbeceDU)
+
+# uView2.0������������������������������������������
+
+1. uView2.0���������������������nvue
+2. uView2.0���1.x���������������������������������������������������������
+3. ������uView2.0������������������������������������������������
+4. ���������������������1.x������������������������[������1.x](https://www.uviewui.com/components/diff1.x.html)
+5. ������input������formatter������������������
+
+
diff --git a/uni_modules/uview-ui/components/u--form/u--form.vue b/uni_modules/uview-ui/components/u--form/u--form.vue
new file mode 100644
index 0000000..fdfc212
--- /dev/null
+++ b/uni_modules/uview-ui/components/u--form/u--form.vue
@@ -0,0 +1,78 @@
+<template>
+ <uvForm
+ ref="uForm"
+ :model="model"
+ :rules="rules"
+ :errorType="errorType"
+ :borderBottom="borderBottom"
+ :labelPosition="labelPosition"
+ :labelWidth="labelWidth"
+ :labelAlign="labelAlign"
+ :labelStyle="labelStyle"
+ :customStyle="customStyle"
+ >
+ <slot />
+ </uvForm>
+</template>
+
+<script>
+ /**
+ * ���������������������������������nvue������u-form���uni-app������������������u-form���nvue������������form������
+ * ���������nvue���������������u--form���������������������u-form.vue���������������������������
+ */
+ import uvForm from '../u-form/u-form.vue';
+ import props from '../u-form/props.js'
+ export default {
+ // #ifdef MP-WEIXIN
+ name: 'u-form',
+ // #endif
+ // #ifndef MP-WEIXIN
+ name: 'u--form',
+ // #endif
+ mixins: [uni.$u.mpMixin, props, uni.$u.mixin],
+ components: {
+ uvForm
+ },
+ created() {
+ this.children = []
+ },
+ methods: {
+ // ������������������������������������������������������������������������������������������������������������������������������������
+ setRules(rules) {
+ this.$refs.uForm.setRules(rules)
+ },
+ validate() {
+ /**
+ * ������������������������������this.$parent���������������������u--form������������������������u-form
+ * ���������u-form������������������������������children������������������������������������������������������u-form������������
+ * ������������������������������������������������u--form���children���������u-form������children
+ */
+ // #ifdef MP-WEIXIN
+ this.setMpData()
+ // #endif
+ return this.$refs.uForm.validate()
+ },
+ validateField(value, callback) {
+ // #ifdef MP-WEIXIN
+ this.setMpData()
+ // #endif
+ return this.$refs.uForm.validateField(value, callback)
+ },
+ resetFields() {
+ // #ifdef MP-WEIXIN
+ this.setMpData()
+ // #endif
+ return this.$refs.uForm.resetFields()
+ },
+ clearValidate(props) {
+ // #ifdef MP-WEIXIN
+ this.setMpData()
+ // #endif
+ return this.$refs.uForm.clearValidate(props)
+ },
+ setMpData() {
+ this.$refs.uForm.children = this.children
+ }
+ },
+ }
+</script>
diff --git a/uni_modules/uview-ui/components/u--image/u--image.vue b/uni_modules/uview-ui/components/u--image/u--image.vue
new file mode 100644
index 0000000..21b7ab1
--- /dev/null
+++ b/uni_modules/uview-ui/components/u--image/u--image.vue
@@ -0,0 +1,47 @@
+<template>
+ <uvImage
+ :src="src"
+ :mode="mode"
+ :width="width"
+ :height="height"
+ :shape="shape"
+ :radius="radius"
+ :lazyLoad="lazyLoad"
+ :showMenuByLongpress="showMenuByLongpress"
+ :loadingIcon="loadingIcon"
+ :errorIcon="errorIcon"
+ :showLoading="showLoading"
+ :showError="showError"
+ :fade="fade"
+ :webp="webp"
+ :duration="duration"
+ :bgColor="bgColor"
+ :customStyle="customStyle"
+ @click="$emit('click')"
+ @error="$emit('error')"
+ @load="$emit('load')"
+ >
+ <template v-slot:loading>
+ <slot name="loading"></slot>
+ </template>
+ <template v-slot:error>
+ <slot name="error"></slot>
+ </template>
+ </uvImage>
+</template>
+
+<script>
+ /**
+ * ���������������������������������nvue������u-image���uni-app������������������u-image���nvue������������image������
+ * ���������nvue���������������u--image���������������������u-iamge.vue���������������������������
+ */
+ import uvImage from '../u-image/u-image.vue';
+ import props from '../u-image/props.js';
+ export default {
+ name: 'u--image',
+ mixins: [uni.$u.mpMixin, props, uni.$u.mixin],
+ components: {
+ uvImage
+ },
+ }
+</script>
\ No newline at end of file
diff --git a/uni_modules/uview-ui/components/u--input/u--input.vue b/uni_modules/uview-ui/components/u--input/u--input.vue
new file mode 100644
index 0000000..1e58b01
--- /dev/null
+++ b/uni_modules/uview-ui/components/u--input/u--input.vue
@@ -0,0 +1,73 @@
+<template>
+ <uvInput
+ :value="value"
+ :type="type"
+ :fixed="fixed"
+ :disabled="disabled"
+ :disabledColor="disabledColor"
+ :clearable="clearable"
+ :password="password"
+ :maxlength="maxlength"
+ :placeholder="placeholder"
+ :placeholderClass="placeholderClass"
+ :placeholderStyle="placeholderStyle"
+ :showWordLimit="showWordLimit"
+ :confirmType="confirmType"
+ :confirmHold="confirmHold"
+ :holdKeyboard="holdKeyboard"
+ :focus="focus"
+ :autoBlur="autoBlur"
+ :disableDefaultPadding="disableDefaultPadding"
+ :cursor="cursor"
+ :cursorSpacing="cursorSpacing"
+ :selectionStart="selectionStart"
+ :selectionEnd="selectionEnd"
+ :adjustPosition="adjustPosition"
+ :inputAlign="inputAlign"
+ :fontSize="fontSize"
+ :color="color"
+ :prefixIcon="prefixIcon"
+ :suffixIcon="suffixIcon"
+ :suffixIconStyle="suffixIconStyle"
+ :prefixIconStyle="prefixIconStyle"
+ :border="border"
+ :readonly="readonly"
+ :shape="shape"
+ :customStyle="customStyle"
+ :formatter="formatter"
+ :ignoreCompositionEvent="ignoreCompositionEvent"
+ @focus="$emit('focus')"
+ @blur="e => $emit('blur', e)"
+ @keyboardheightchange="$emit('keyboardheightchange')"
+ @change="e => $emit('change', e)"
+ @input="e => $emit('input', e)"
+ @confirm="e => $emit('confirm', e)"
+ @clear="$emit('clear')"
+ @click="$emit('click')"
+ >
+ <!-- #ifdef MP -->
+ <slot name="prefix"></slot>
+ <slot name="suffix"></slot>
+ <!-- #endif -->
+ <!-- #ifndef MP -->
+ <slot name="prefix" slot="prefix"></slot>
+ <slot name="suffix" slot="suffix"></slot>
+ <!-- #endif -->
+ </uvInput>
+</template>
+
+<script>
+ /**
+ * ���������������������������������nvue������u-input���uni-app������������������u-input���nvue������������input������
+ * ���������nvue���������������u--input���������������������u-input.vue���������������������������
+ */
+ import uvInput from '../u-input/u-input.vue';
+ import props from '../u-input/props.js'
+ export default {
+ name: 'u--input',
+ mixins: [uni.$u.mpMixin, props, uni.$u.mixin],
+ components: {
+ uvInput
+ },
+ }
+</script>
\ No newline at end of file
diff --git a/uni_modules/uview-ui/components/u--text/u--text.vue b/uni_modules/uview-ui/components/u--text/u--text.vue
new file mode 100644
index 0000000..44ee52a
--- /dev/null
+++ b/uni_modules/uview-ui/components/u--text/u--text.vue
@@ -0,0 +1,44 @@
+<template>
+ <uvText
+ :type="type"
+ :show="show"
+ :text="text"
+ :prefixIcon="prefixIcon"
+ :suffixIcon="suffixIcon"
+ :mode="mode"
+ :href="href"
+ :format="format"
+ :call="call"
+ :openType="openType"
+ :bold="bold"
+ :block="block"
+ :lines="lines"
+ :color="color"
+ :decoration="decoration"
+ :size="size"
+ :iconStyle="iconStyle"
+ :margin="margin"
+ :lineHeight="lineHeight"
+ :align="align"
+ :wordWrap="wordWrap"
+ :customStyle="customStyle"
+ @click="$emit('click')"
+ ></uvText>
+</template>
+
+<script>
+/**
+ * ���������������������������������nvue������u-text���uni-app������������������u-text���nvue������������input������
+ * ���������nvue���������������u--input���������������������u-text.vue���������������������������
+ * ���������v-bind="$attrs"���������������������������������������������������������������������������
+ */
+import uvText from "../u-text/u-text.vue";
+import props from "../u-text/props.js";
+export default {
+ name: "u--text",
+ mixins: [uni.$u.mpMixin, props, uni.$u.mixin],
+ components: {
+ uvText,
+ },
+};
+</script>
diff --git a/uni_modules/uview-ui/components/u--textarea/u--textarea.vue b/uni_modules/uview-ui/components/u--textarea/u--textarea.vue
new file mode 100644
index 0000000..f4df0b9
--- /dev/null
+++ b/uni_modules/uview-ui/components/u--textarea/u--textarea.vue
@@ -0,0 +1,48 @@
+<template>
+ <uvTextarea
+ :value="value"
+ :placeholder="placeholder"
+ :height="height"
+ :confirmType="confirmType"
+ :disabled="disabled"
+ :count="count"
+ :focus="focus"
+ :autoHeight="autoHeight"
+ :fixed="fixed"
+ :cursorSpacing="cursorSpacing"
+ :cursor="cursor"
+ :showConfirmBar="showConfirmBar"
+ :selectionStart="selectionStart"
+ :selectionEnd="selectionEnd"
+ :adjustPosition="adjustPosition"
+ :disableDefaultPadding="disableDefaultPadding"
+ :holdKeyboard="holdKeyboard"
+ :maxlength="maxlength"
+ :border="border"
+ :customStyle="customStyle"
+ :formatter="formatter"
+ :ignoreCompositionEvent="ignoreCompositionEvent"
+ @focus="e => $emit('focus')"
+ @blur="e => $emit('blur')"
+ @linechange="e => $emit('linechange', e)"
+ @confirm="e => $emit('confirm')"
+ @input="e => $emit('input', e)"
+ @keyboardheightchange="e => $emit('keyboardheightchange')"
+ ></uvTextarea>
+</template>
+
+<script>
+ /**
+ * ���������������������������������nvue������u--textarea���uni-app������������������u-textarea���nvue������������textarea������
+ * ���������nvue���������������u--textarea���������������������u-textarea.vue���������������������������
+ */
+ import uvTextarea from '../u-textarea/u-textarea.vue';
+ import props from '../u-textarea/props.js'
+ export default {
+ name: 'u--textarea',
+ mixins: [uni.$u.mpMixin, props, uni.$u.mixin],
+ components: {
+ uvTextarea
+ },
+ }
+</script>
diff --git a/uni_modules/uview-ui/components/u-action-sheet/props.js b/uni_modules/uview-ui/components/u-action-sheet/props.js
new file mode 100644
index 0000000..e96e04f
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-action-sheet/props.js
@@ -0,0 +1,54 @@
+export default {
+ props: {
+ // ������������������������ ���������false���
+ show: {
+ type: Boolean,
+ default: uni.$u.props.actionSheet.show
+ },
+ // ������
+ title: {
+ type: String,
+ default: uni.$u.props.actionSheet.title
+ },
+ // ���������������������������
+ description: {
+ type: String,
+ default: uni.$u.props.actionSheet.description
+ },
+ // ������
+ actions: {
+ type: Array,
+ default: uni.$u.props.actionSheet.actions
+ },
+ // ������������������������������������������������
+ cancelText: {
+ type: String,
+ default: uni.$u.props.actionSheet.cancelText
+ },
+ // ������������������������������������������
+ closeOnClickAction: {
+ type: Boolean,
+ default: uni.$u.props.actionSheet.closeOnClickAction
+ },
+ // ������������������������������true���
+ safeAreaInsetBottom: {
+ type: Boolean,
+ default: uni.$u.props.actionSheet.safeAreaInsetBottom
+ },
+ // ������������������������
+ openType: {
+ type: String,
+ default: uni.$u.props.actionSheet.openType
+ },
+ // ������������������������������ (������true)
+ closeOnClickOverlay: {
+ type: Boolean,
+ default: uni.$u.props.actionSheet.closeOnClickOverlay
+ },
+ // ���������
+ round: {
+ type: [Boolean, String, Number],
+ default: uni.$u.props.actionSheet.round
+ }
+ }
+}
diff --git a/uni_modules/uview-ui/components/u-action-sheet/u-action-sheet.vue b/uni_modules/uview-ui/components/u-action-sheet/u-action-sheet.vue
new file mode 100644
index 0000000..26d5d8d
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-action-sheet/u-action-sheet.vue
@@ -0,0 +1,278 @@
+
+<template>
+ <u-popup
+ :show="show"
+ mode="bottom"
+ @close="closeHandler"
+ :safeAreaInsetBottom="safeAreaInsetBottom"
+ :round="round"
+ >
+ <view class="u-action-sheet">
+ <view
+ class="u-action-sheet__header"
+ v-if="title"
+ >
+ <text class="u-action-sheet__header__title u-line-1">{{title}}</text>
+ <view
+ class="u-action-sheet__header__icon-wrap"
+ @tap.stop="cancel"
+ >
+ <u-icon
+ name="close"
+ size="17"
+ color="#c8c9cc"
+ bold
+ ></u-icon>
+ </view>
+ </view>
+ <text
+ class="u-action-sheet__description"
+ :style="[{
+ marginTop: `${title && description ? 0 : '18px'}`
+ }]"
+ v-if="description"
+ >{{description}}</text>
+ <slot>
+ <u-line v-if="description"></u-line>
+ <view class="u-action-sheet__item-wrap">
+ <template v-for="(item, index) in actions">
+ <!-- #ifdef MP -->
+ <button
+ :key="index"
+ class="u-reset-button"
+ :openType="item.openType"
+ @getuserinfo="onGetUserInfo"
+ @contact="onContact"
+ @getphonenumber="onGetPhoneNumber"
+ @error="onError"
+ @launchapp="onLaunchApp"
+ @opensetting="onOpenSetting"
+ :lang="lang"
+ :session-from="sessionFrom"
+ :send-message-title="sendMessageTitle"
+ :send-message-path="sendMessagePath"
+ :send-message-img="sendMessageImg"
+ :show-message-card="showMessageCard"
+ :app-parameter="appParameter"
+ @tap="selectHandler(index)"
+ :hover-class="!item.disabled && !item.loading ? 'u-action-sheet--hover' : ''"
+ >
+ <!-- #endif -->
+ <view
+ class="u-action-sheet__item-wrap__item"
+ @tap.stop="selectHandler(index)"
+ :hover-class="!item.disabled && !item.loading ? 'u-action-sheet--hover' : ''"
+ :hover-stay-time="150"
+ >
+ <template v-if="!item.loading">
+ <text
+ class="u-action-sheet__item-wrap__item__name"
+ :style="[itemStyle(index)]"
+ >{{ item.name }}</text>
+ <text
+ v-if="item.subname"
+ class="u-action-sheet__item-wrap__item__subname"
+ >{{ item.subname }}</text>
+ </template>
+ <u-loading-icon
+ v-else
+ custom-class="van-action-sheet__loading"
+ size="18"
+ mode="circle"
+ />
+ </view>
+ <!-- #ifdef MP -->
+ </button>
+ <!-- #endif -->
+ <u-line v-if="index !== actions.length - 1"></u-line>
+ </template>
+ </view>
+ </slot>
+ <u-gap
+ bgColor="#eaeaec"
+ height="6"
+ v-if="cancelText"
+ ></u-gap>
+ <view hover-class="u-action-sheet--hover">
+ <text
+ @touchmove.stop.prevent
+ :hover-stay-time="150"
+ v-if="cancelText"
+ class="u-action-sheet__cancel-text"
+ @tap="cancel"
+ >{{cancelText}}</text>
+ </view>
+ </view>
+ </u-popup>
+</template>
+
+<script>
+ import openType from '../../libs/mixin/openType'
+ import button from '../../libs/mixin/button'
+ import props from './props.js';
+ /**
+ * ActionSheet ������������
+ * @description ������������������������������������������������������������������������������������������������������������uni���uni.showActionSheetAPI������������������������������������������������������
+ * @tutorial https://www.uviewui.com/components/actionSheet.html
+ *
+ * @property {Boolean} show ������������������������ ��������� false ���
+ * @property {String} title ������������������
+ * @property {String} description ���������������������������
+ * @property {Array<Object>} actions ���������������������������������������������
+ * @property {String} cancelText ���������������������������,������������������������
+ * @property {Boolean} closeOnClickAction ������������������������������������������ ��������� true ���
+ * @property {Boolean} safeAreaInsetBottom ��������������������� ��������� true ���
+ * @property {String} openType ������������������������ (contact | launchApp | getUserInfo | openSetting ���getPhoneNumber ���error )
+ * @property {Boolean} closeOnClickOverlay ������������������������������ (������ true )
+ * @property {Number|String} round ��������������������������� (������ 0 )
+ * @property {String} lang ������������������������������������zh_CN ���������������zh_TW ���������������en ������
+ * @property {String} sessionFrom ���������������openType="contact"���������
+ * @property {String} sendMessageTitle ������������������������������openType="contact"���������
+ * @property {String} sendMessagePath ���������������������������������������������������openType="contact"���������
+ * @property {String} sendMessageImg ������������������������������openType="contact"���������
+ * @property {Boolean} showMessageCard ������������������������������������������������������ true������������������������������������������������"���������������������������"������������������������������������������������������������openType="contact"��������� ��������� false ���
+ * @property {String} appParameter ������ APP ��������� APP ������������������openType=launchApp ���������
+ *
+ * @event {Function} select ������ActionSheet������������������
+ * @event {Function} close ���������������������������
+ * @event {Function} getuserinfo ������������������������������������������������������������������������ detail ��������� wx.getUserInfo ������������������openType="getUserInfo"���������
+ * @event {Function} contact ���������������������openType="contact"���������
+ * @event {Function} getphonenumber ������������������������������openType="getPhoneNumber"���������
+ * @event {Function} error ���������������������������������������������������openType="error"���������
+ * @event {Function} launchapp ������ APP ������������������openType="launchApp"���������
+ * @event {Function} opensetting ������������������������������������openType="openSetting"���������
+ * @example <u-action-sheet :actions="list" :title="title" :show="show"></u-action-sheet>
+ */
+ export default {
+ name: "u-action-sheet",
+ // ������props���������methods���������������mixin���������������������������������������
+ mixins: [openType, button, uni.$u.mixin, props],
+ data() {
+ return {
+
+ }
+ },
+ computed: {
+ // ���������������������
+ itemStyle() {
+ return (index) => {
+ let style = {};
+ if (this.actions[index].color) style.color = this.actions[index].color
+ if (this.actions[index].fontSize) style.fontSize = uni.$u.addUnit(this.actions[index].fontSize)
+ // ������������������������
+ if (this.actions[index].disabled) style.color = '#c0c4cc'
+ return style;
+ }
+ },
+ },
+ methods: {
+ closeHandler() {
+ // ���������������������������������������close������
+ if(this.closeOnClickOverlay) {
+ this.$emit('close')
+ }
+ },
+ // ������������������
+ cancel() {
+ this.$emit('close')
+ },
+ selectHandler(index) {
+ const item = this.actions[index]
+ if (item && !item.disabled && !item.loading) {
+ this.$emit('select', item)
+ if (this.closeOnClickAction) {
+ this.$emit('close')
+ }
+ }
+ },
+ }
+ }
+</script>
+
+<style lang="scss" scoped>
+ @import "../../libs/css/components.scss";
+ $u-action-sheet-reset-button-width:100% !default;
+ $u-action-sheet-title-font-size: 16px !default;
+ $u-action-sheet-title-padding: 12px 30px !default;
+ $u-action-sheet-title-color: $u-main-color !default;
+ $u-action-sheet-header-icon-wrap-right:15px !default;
+ $u-action-sheet-header-icon-wrap-top:15px !default;
+ $u-action-sheet-description-font-size:13px !default;
+ $u-action-sheet-description-color:14px !default;
+ $u-action-sheet-description-margin: 18px 15px !default;
+ $u-action-sheet-item-wrap-item-padding:15px !default;
+ $u-action-sheet-item-wrap-name-font-size:16px !default;
+ $u-action-sheet-item-wrap-subname-font-size:13px !default;
+ $u-action-sheet-item-wrap-subname-color: #c0c4cc !default;
+ $u-action-sheet-item-wrap-subname-margin-top:10px !default;
+ $u-action-sheet-cancel-text-font-size:16px !default;
+ $u-action-sheet-cancel-text-color:$u-content-color !default;
+ $u-action-sheet-cancel-text-font-size:15px !default;
+ $u-action-sheet-cancel-text-hover-background-color:rgb(242, 243, 245) !default;
+
+ .u-reset-button {
+ width: $u-action-sheet-reset-button-width;
+ }
+
+ .u-action-sheet {
+ text-align: center;
+ &__header {
+ position: relative;
+ padding: $u-action-sheet-title-padding;
+ &__title {
+ font-size: $u-action-sheet-title-font-size;
+ color: $u-action-sheet-title-color;
+ font-weight: bold;
+ text-align: center;
+ }
+
+ &__icon-wrap {
+ position: absolute;
+ right: $u-action-sheet-header-icon-wrap-right;
+ top: $u-action-sheet-header-icon-wrap-top;
+ }
+ }
+
+ &__description {
+ font-size: $u-action-sheet-description-font-size;
+ color: $u-tips-color;
+ margin: $u-action-sheet-description-margin;
+ text-align: center;
+ }
+
+ &__item-wrap {
+
+ &__item {
+ padding: $u-action-sheet-item-wrap-item-padding;
+ @include flex;
+ align-items: center;
+ justify-content: center;
+ flex-direction: column;
+
+ &__name {
+ font-size: $u-action-sheet-item-wrap-name-font-size;
+ color: $u-main-color;
+ text-align: center;
+ }
+
+ &__subname {
+ font-size: $u-action-sheet-item-wrap-subname-font-size;
+ color: $u-action-sheet-item-wrap-subname-color;
+ margin-top: $u-action-sheet-item-wrap-subname-margin-top;
+ text-align: center;
+ }
+ }
+ }
+
+ &__cancel-text {
+ font-size: $u-action-sheet-cancel-text-font-size;
+ color: $u-action-sheet-cancel-text-color;
+ text-align: center;
+ padding: $u-action-sheet-cancel-text-font-size;
+ }
+
+ &--hover {
+ background-color: $u-action-sheet-cancel-text-hover-background-color;
+ }
+ }
+</style>
diff --git a/uni_modules/uview-ui/components/u-album/props.js b/uni_modules/uview-ui/components/u-album/props.js
new file mode 100644
index 0000000..75cdb37
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-album/props.js
@@ -0,0 +1,59 @@
+export default {
+ props: {
+ // ���������������Array<String>|Array<Object>������
+ urls: {
+ type: Array,
+ default: uni.$u.props.album.urls
+ },
+ // ���������������������������������������������������������������������
+ keyName: {
+ type: String,
+ default: uni.$u.props.album.keyName
+ },
+ // ���������������������������������
+ singleSize: {
+ type: [String, Number],
+ default: uni.$u.props.album.singleSize
+ },
+ // ������������������������
+ multipleSize: {
+ type: [String, Number],
+ default: uni.$u.props.album.multipleSize
+ },
+ // ������������������������������������������������
+ space: {
+ type: [String, Number],
+ default: uni.$u.props.album.space
+ },
+ // ���������������������������������������
+ singleMode: {
+ type: String,
+ default: uni.$u.props.album.singleMode
+ },
+ // ���������������������������������������
+ multipleMode: {
+ type: String,
+ default: uni.$u.props.album.multipleMode
+ },
+ // ���������������������������������������������������������������������������������������
+ maxCount: {
+ type: [String, Number],
+ default: uni.$u.props.album.maxCount
+ },
+ // ������������������������
+ previewFullImage: {
+ type: Boolean,
+ default: uni.$u.props.album.previewFullImage
+ },
+ // ���������������������������������������singleSize���multipleSize������������
+ rowCount: {
+ type: [String, Number],
+ default: uni.$u.props.album.rowCount
+ },
+ // ������maxCount������������������������������������
+ showMore: {
+ type: Boolean,
+ default: uni.$u.props.album.showMore
+ }
+ }
+}
diff --git a/uni_modules/uview-ui/components/u-album/u-album.vue b/uni_modules/uview-ui/components/u-album/u-album.vue
new file mode 100644
index 0000000..687e2d5
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-album/u-album.vue
@@ -0,0 +1,259 @@
+<template>
+ <view class="u-album">
+ <view
+ class="u-album__row"
+ ref="u-album__row"
+ v-for="(arr, index) in showUrls"
+ :forComputedUse="albumWidth"
+ :key="index"
+ >
+ <view
+ class="u-album__row__wrapper"
+ v-for="(item, index1) in arr"
+ :key="index1"
+ :style="[imageStyle(index + 1, index1 + 1)]"
+ @tap="previewFullImage ? onPreviewTap(getSrc(item)) : ''"
+ >
+ <image
+ :src="getSrc(item)"
+ :mode="
+ urls.length === 1
+ ? imageHeight > 0
+ ? singleMode
+ : 'widthFix'
+ : multipleMode
+ "
+ :style="[
+ {
+ width: imageWidth,
+ height: imageHeight
+ }
+ ]"
+ ></image>
+ <view
+ v-if="
+ showMore &&
+ urls.length > rowCount * showUrls.length &&
+ index === showUrls.length - 1 &&
+ index1 === showUrls[showUrls.length - 1].length - 1
+ "
+ class="u-album__row__wrapper__text"
+ >
+ <u--text
+ :text="`+${urls.length - maxCount}`"
+ color="#fff"
+ :size="multipleSize * 0.3"
+ align="center"
+ customStyle="justify-content: center"
+ ></u--text>
+ </view>
+ </view>
+ </view>
+ </view>
+</template>
+
+<script>
+import props from './props.js'
+// #ifdef APP-NVUE
+// ������weex������������KPI���������������������������������������������������������������������������dom���������������������
+const dom = uni.requireNativePlugin('dom')
+// #endif
+
+/**
+ * Album ������
+ * @description ���������������������������������������������������������������������������������������������������������������������
+ * @tutorial https://www.uviewui.com/components/album.html
+ *
+ * @property {Array} urls ������������������ Array<String>|Array<Object>������
+ * @property {String} keyName ���������������������������������������������������������������������
+ * @property {String | Number} singleSize ��������������������������������� ��������� 180 ���
+ * @property {String | Number} multipleSize ������������������������ ��������� 70 ���
+ * @property {String | Number} space ������������������������������������������������ ��������� 6 ���
+ * @property {String} singleMode ��������������������������������������� ��������� 'scaleToFill' ���
+ * @property {String} multipleMode ��������������������������������������� ��������� 'aspectFill' ���
+ * @property {String | Number} maxCount ��������������������������� ��������� 9 ���
+ * @property {Boolean} previewFullImage ������������������������ ��������� true ���
+ * @property {String | Number} rowCount ���������������������������������������singleSize���multipleSize������������ ��������� 3 ���
+ * @property {Boolean} showMore ������maxCount������������������������������������ ��������� true ���
+ *
+ * @event {Function} albumWidth ������������������������������������������������������������������������������������������������������ ��������������� width ���
+ * @example <u-album :urls="urls2" @albumWidth="width => albumWidth = width" multipleSize="68" ></u-album>
+ */
+export default {
+ name: 'u-album',
+ mixins: [uni.$u.mpMixin, uni.$u.mixin, props],
+ data() {
+ return {
+ // ���������������
+ singleWidth: 0,
+ // ���������������
+ singleHeight: 0,
+ // ������������������������������������������������������������������������������������������������������
+ singlePercent: 0.6
+ }
+ },
+ watch: {
+ urls: {
+ immediate: true,
+ handler(newVal) {
+ if (newVal.length === 1) {
+ this.getImageRect()
+ }
+ }
+ }
+ },
+ computed: {
+ imageStyle() {
+ return (index1, index2) => {
+ const { space, rowCount, multipleSize, urls } = this,
+ { addUnit, addStyle } = uni.$u,
+ rowLen = this.showUrls.length,
+ allLen = this.urls.length
+ const style = {
+ marginRight: addUnit(space),
+ marginBottom: addUnit(space)
+ }
+ // ���������������������������������������������������������
+ if (index1 === rowLen) style.marginBottom = 0
+ // ������������������������������������������������������������������
+ if (
+ index2 === rowCount ||
+ (index1 === rowLen &&
+ index2 === this.showUrls[index1 - 1].length)
+ )
+ style.marginRight = 0
+ return style
+ }
+ },
+ // ������������������������������
+ showUrls() {
+ const arr = []
+ this.urls.map((item, index) => {
+ // ������������������������
+ if (index + 1 <= this.maxCount) {
+ // ������������������������������������
+ const itemIndex = Math.floor(index / this.rowCount)
+ // ���������������������������������
+ if (!arr[itemIndex]) {
+ arr[itemIndex] = []
+ }
+ arr[itemIndex].push(item)
+ }
+ })
+ return arr
+ },
+ imageWidth() {
+ return uni.$u.addUnit(
+ this.urls.length === 1 ? this.singleWidth : this.multipleSize
+ )
+ },
+ imageHeight() {
+ return uni.$u.addUnit(
+ this.urls.length === 1 ? this.singleHeight : this.multipleSize
+ )
+ },
+ // ������������������������������������������������computed������������������urls������������������������������������������������
+ // ���������������������������������������������������������������������������������������������������������������������������
+ albumWidth() {
+ let width = 0
+ if (this.urls.length === 1) {
+ width = this.singleWidth
+ } else {
+ width =
+ this.showUrls[0].length * this.multipleSize +
+ this.space * (this.showUrls[0].length - 1)
+ }
+ this.$emit('albumWidth', width)
+ return width
+ }
+ },
+ methods: {
+ // ������������
+ onPreviewTap(url) {
+ const urls = this.urls.map((item) => {
+ return this.getSrc(item)
+ })
+ uni.previewImage({
+ current: url,
+ urls
+ })
+ },
+ // ���������������������
+ getSrc(item) {
+ return uni.$u.test.object(item)
+ ? (this.keyName && item[this.keyName]) || item.src
+ : item
+ },
+ // ���������������������������������
+ // ������������������������������������������������������������������������download���������������������������
+ // ���������������������������������������������������������������������������(singlePercent)
+ getImageRect() {
+ const src = this.getSrc(this.urls[0])
+ uni.getImageInfo({
+ src,
+ success: (res) => {
+ // ������������������������������������������
+ const isHorizotal = res.width >= res.height
+ this.singleWidth = isHorizotal
+ ? this.singleSize
+ : (res.width / res.height) * this.singleSize
+ this.singleHeight = !isHorizotal
+ ? this.singleSize
+ : (res.height / res.width) * this.singleWidth
+ },
+ fail: () => {
+ this.getComponentWidth()
+ }
+ })
+ },
+ // ���������������������
+ async getComponentWidth() {
+ // ������������������������������dom������
+ await uni.$u.sleep(30)
+ // #ifndef APP-NVUE
+ this.$uGetRect('.u-album__row').then((size) => {
+ this.singleWidth = size.width * this.singlePercent
+ })
+ // #endif
+
+ // #ifdef APP-NVUE
+ // ������ref="u-album__row"������������������������for���������������������this.$refs['u-album__row']���������������
+ const ref = this.$refs['u-album__row'][0]
+ ref &&
+ dom.getComponentRect(ref, (res) => {
+ this.singleWidth = res.size.width * this.singlePercent
+ })
+ // #endif
+ }
+ }
+}
+</script>
+
+<style lang="scss" scoped>
+@import '../../libs/css/components.scss';
+
+.u-album {
+ @include flex(column);
+
+ &__row {
+ @include flex(row);
+ flex-wrap: wrap;
+
+ &__wrapper {
+ position: relative;
+
+ &__text {
+ position: absolute;
+ top: 0;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ background-color: rgba(0, 0, 0, 0.3);
+ @include flex(row);
+ justify-content: center;
+ align-items: center;
+ }
+ }
+ }
+}
+</style>
\ No newline at end of file
diff --git a/uni_modules/uview-ui/components/u-alert/props.js b/uni_modules/uview-ui/components/u-alert/props.js
new file mode 100644
index 0000000..4297e2c
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-alert/props.js
@@ -0,0 +1,44 @@
+export default {
+ props: {
+ // ������������
+ title: {
+ type: String,
+ default: uni.$u.props.alert.title
+ },
+ // ���������success/warning/info/error
+ type: {
+ type: String,
+ default: uni.$u.props.alert.type
+ },
+ // ���������������
+ description: {
+ type: String,
+ default: uni.$u.props.alert.description
+ },
+ // ���������������
+ closable: {
+ type: Boolean,
+ default: uni.$u.props.alert.closable
+ },
+ // ������������������
+ showIcon: {
+ type: Boolean,
+ default: uni.$u.props.alert.showIcon
+ },
+ // ������������������light-���������dark-������
+ effect: {
+ type: String,
+ default: uni.$u.props.alert.effect
+ },
+ // ������������������
+ center: {
+ type: Boolean,
+ default: uni.$u.props.alert.center
+ },
+ // ������������
+ fontSize: {
+ type: [String, Number],
+ default: uni.$u.props.alert.fontSize
+ }
+ }
+}
diff --git a/uni_modules/uview-ui/components/u-alert/u-alert.vue b/uni_modules/uview-ui/components/u-alert/u-alert.vue
new file mode 100644
index 0000000..81f7d43
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-alert/u-alert.vue
@@ -0,0 +1,243 @@
+<template>
+ <u-transition
+ mode="fade"
+ :show="show"
+ >
+ <view
+ class="u-alert"
+ :class="[`u-alert--${type}--${effect}`]"
+ @tap.stop="clickHandler"
+ :style="[$u.addStyle(customStyle)]"
+ >
+ <view
+ class="u-alert__icon"
+ v-if="showIcon"
+ >
+ <u-icon
+ :name="iconName"
+ size="18"
+ :color="iconColor"
+ ></u-icon>
+ </view>
+ <view
+ class="u-alert__content"
+ :style="[{
+ paddingRight: closable ? '20px' : 0
+ }]"
+ >
+ <text
+ class="u-alert__content__title"
+ v-if="title"
+ :style="[{
+ fontSize: $u.addUnit(fontSize),
+ textAlign: center ? 'center' : 'left'
+ }]"
+ :class="[effect === 'dark' ? 'u-alert__text--dark' : `u-alert__text--${type}--light`]"
+ >{{ title }}</text>
+ <text
+ class="u-alert__content__desc"
+ v-if="description"
+ :style="[{
+ fontSize: $u.addUnit(fontSize),
+ textAlign: center ? 'center' : 'left'
+ }]"
+ :class="[effect === 'dark' ? 'u-alert__text--dark' : `u-alert__text--${type}--light`]"
+ >{{ description }}</text>
+ </view>
+ <view
+ class="u-alert__close"
+ v-if="closable"
+ @tap.stop="closeHandler"
+ >
+ <u-icon
+ name="close"
+ :color="iconColor"
+ size="15"
+ ></u-icon>
+ </view>
+ </view>
+ </u-transition>
+</template>
+
+<script>
+ import props from './props.js';
+ /**
+ * Alert ������������
+ * @description ���������������������������������������������
+ * @tutorial https://www.uviewui.com/components/alertTips.html
+ *
+ * @property {String} title ���������������
+ * @property {String} type ��������������������� ��������� 'warning' ���
+ * @property {String} description ���������������������������title���������������������������������������
+ * @property {Boolean} closable ������������(���������������icon������) ��������� false ���
+ * @property {Boolean} showIcon ��������������������������������� ��� ������ false ���
+ * @property {String} effect ��������������������������������������� ��������� 'light' ���
+ * @property {Boolean} center ������������������ ��������� false ���
+ * @property {String | Number} fontSize ������������ ��������� 14 ���
+ * @property {Object} customStyle ���������������������������������
+ * @event {Function} click ���������������������
+ * @example <u-alert :title="title" type = "warning" :closable="closable" :description = "description"></u-alert>
+ */
+ export default {
+ name: 'u-alert',
+ mixins: [uni.$u.mpMixin, uni.$u.mixin, props],
+ data() {
+ return {
+ show: true
+ }
+ },
+ computed: {
+ iconColor() {
+ return this.effect === 'light' ? this.type : '#fff'
+ },
+ // ���������������������������������
+ iconName() {
+ switch (this.type) {
+ case 'success':
+ return 'checkmark-circle-fill';
+ break;
+ case 'error':
+ return 'close-circle-fill';
+ break;
+ case 'warning':
+ return 'error-circle-fill';
+ break;
+ case 'info':
+ return 'info-circle-fill';
+ break;
+ case 'primary':
+ return 'more-circle-fill';
+ break;
+ default:
+ return 'error-circle-fill';
+ }
+ }
+ },
+ methods: {
+ // ������������
+ clickHandler() {
+ this.$emit('click')
+ },
+ // ������������������
+ closeHandler() {
+ this.show = false
+ }
+ }
+ }
+</script>
+
+<style lang="scss" scoped>
+ @import "../../libs/css/components.scss";
+
+ .u-alert {
+ position: relative;
+ background-color: $u-primary;
+ padding: 8px 10px;
+ @include flex(row);
+ align-items: center;
+ border-top-left-radius: 4px;
+ border-top-right-radius: 4px;
+ border-bottom-left-radius: 4px;
+ border-bottom-right-radius: 4px;
+
+ &--primary--dark {
+ background-color: $u-primary;
+ }
+
+ &--primary--light {
+ background-color: #ecf5ff;
+ }
+
+ &--error--dark {
+ background-color: $u-error;
+ }
+
+ &--error--light {
+ background-color: #FEF0F0;
+ }
+
+ &--success--dark {
+ background-color: $u-success;
+ }
+
+ &--success--light {
+ background-color: #f5fff0;
+ }
+
+ &--warning--dark {
+ background-color: $u-warning;
+ }
+
+ &--warning--light {
+ background-color: #FDF6EC;
+ }
+
+ &--info--dark {
+ background-color: $u-info;
+ }
+
+ &--info--light {
+ background-color: #f4f4f5;
+ }
+
+ &__icon {
+ margin-right: 5px;
+ }
+
+ &__content {
+ @include flex(column);
+ flex: 1;
+
+ &__title {
+ color: $u-main-color;
+ font-size: 14px;
+ font-weight: bold;
+ color: #fff;
+ margin-bottom: 2px;
+ }
+
+ &__desc {
+ color: $u-main-color;
+ font-size: 14px;
+ flex-wrap: wrap;
+ color: #fff;
+ }
+ }
+
+ &__title--dark,
+ &__desc--dark {
+ color: #FFFFFF;
+ }
+
+ &__text--primary--light,
+ &__text--primary--light {
+ color: $u-primary;
+ }
+
+ &__text--success--light,
+ &__text--success--light {
+ color: $u-success;
+ }
+
+ &__text--warning--light,
+ &__text--warning--light {
+ color: $u-warning;
+ }
+
+ &__text--error--light,
+ &__text--error--light {
+ color: $u-error;
+ }
+
+ &__text--info--light,
+ &__text--info--light {
+ color: $u-info;
+ }
+
+ &__close {
+ position: absolute;
+ top: 11px;
+ right: 10px;
+ }
+ }
+</style>
diff --git a/uni_modules/uview-ui/components/u-avatar-group/props.js b/uni_modules/uview-ui/components/u-avatar-group/props.js
new file mode 100644
index 0000000..58b42ac
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-avatar-group/props.js
@@ -0,0 +1,52 @@
+export default {
+ props: {
+ // ���������������
+ urls: {
+ type: Array,
+ default: uni.$u.props.avatarGroup.urls
+ },
+ // ���������������������������
+ maxCount: {
+ type: [String, Number],
+ default: uni.$u.props.avatarGroup.maxCount
+ },
+ // ������������
+ shape: {
+ type: String,
+ default: uni.$u.props.avatarGroup.shape
+ },
+ // ������������������
+ mode: {
+ type: String,
+ default: uni.$u.props.avatarGroup.mode
+ },
+ // ������maxCount������������������������������������
+ showMore: {
+ type: Boolean,
+ default: uni.$u.props.avatarGroup.showMore
+ },
+ // ������������
+ size: {
+ type: [String, Number],
+ default: uni.$u.props.avatarGroup.size
+ },
+ // ���������������������������������������������������������������������
+ keyName: {
+ type: String,
+ default: uni.$u.props.avatarGroup.keyName
+ },
+ // ���������������������������
+ gap: {
+ type: [String, Number],
+ validator(value) {
+ return value >= 0 && value <= 1
+ },
+ default: uni.$u.props.avatarGroup.gap
+ },
+ // ���������������������
+ extraValue: {
+ type: [Number, String],
+ default: uni.$u.props.avatarGroup.extraValue
+ }
+ }
+}
diff --git a/uni_modules/uview-ui/components/u-avatar-group/u-avatar-group.vue b/uni_modules/uview-ui/components/u-avatar-group/u-avatar-group.vue
new file mode 100644
index 0000000..7e996d7
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-avatar-group/u-avatar-group.vue
@@ -0,0 +1,103 @@
+<template>
+ <view class="u-avatar-group">
+ <view
+ class="u-avatar-group__item"
+ v-for="(item, index) in showUrl"
+ :key="index"
+ :style="{
+ marginLeft: index === 0 ? 0 : $u.addUnit(-size * gap)
+ }"
+ >
+ <u-avatar
+ :size="size"
+ :shape="shape"
+ :mode="mode"
+ :src="$u.test.object(item) ? keyName && item[keyName] || item.url : item"
+ ></u-avatar>
+ <view
+ class="u-avatar-group__item__show-more"
+ v-if="showMore && index === showUrl.length - 1 && (urls.length > maxCount || extraValue > 0)"
+ @tap="clickHandler"
+ >
+ <u--text
+ color="#ffffff"
+ :size="size * 0.4"
+ :text="`+${extraValue || urls.length - showUrl.length}`"
+ align="center"
+ customStyle="justify-content: center"
+ ></u--text>
+ </view>
+ </view>
+ </view>
+</template>
+
+<script>
+ import props from './props.js';
+ /**
+ * AvatarGroup ���������
+ * @description ���������������������������������������������������������������������������������������������������������������������
+ * @tutorial https://www.uviewui.com/components/avatar.html
+ *
+ * @property {Array} urls ��������������� ��������� [] ���
+ * @property {String | Number} maxCount ��������������������������� ��� ������ 5 ���
+ * @property {String} shape ��������������� 'circle' (������) | 'square' ���
+ * @property {String} mode ��������������������������� 'scaleToFill' ���
+ * @property {Boolean} showMore ������maxCount������������������������������������ ��������� true ���
+ * @property {String | Number} size ������������ ��������� 40 ���
+ * @property {String} keyName ���������������������������������������������������������������������
+ * @property {String | Number} gap ������������������������������0.4������������40%��� ��������� 0.5 ���
+ * @property {String | Number} extraValue ���������������������
+ * @event {Function} showMore ���������������������
+ * @example <u-avatar-group:urls="urls" size="35" gap="0.4" ></u-avatar-group:urls=>
+ */
+ export default {
+ name: 'u-avatar-group',
+ mixins: [uni.$u.mpMixin, uni.$u.mixin, props],
+ data() {
+ return {
+
+ }
+ },
+ computed: {
+ showUrl() {
+ return this.urls.slice(0, this.maxCount)
+ }
+ },
+ methods: {
+ clickHandler() {
+ this.$emit('showMore')
+ }
+ },
+ }
+</script>
+
+<style lang="scss" scoped>
+ @import "../../libs/css/components.scss";
+
+ .u-avatar-group {
+ @include flex;
+
+ &__item {
+ margin-left: -10px;
+ position: relative;
+
+ &--no-indent {
+ // ������������������������������������:first-child������������������������������nvue���������
+ margin-left: 0;
+ }
+
+ &__show-more {
+ position: absolute;
+ top: 0;
+ bottom: 0;
+ left: 0;
+ right: 0;
+ background-color: rgba(0, 0, 0, 0.3);
+ @include flex;
+ align-items: center;
+ justify-content: center;
+ border-radius: 100px;
+ }
+ }
+ }
+</style>
diff --git a/uni_modules/uview-ui/components/u-avatar/props.js b/uni_modules/uview-ui/components/u-avatar/props.js
new file mode 100644
index 0000000..34ca0f2
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-avatar/props.js
@@ -0,0 +1,78 @@
+export default {
+ props: {
+ // ������������������(���������������������)
+ src: {
+ type: String,
+ default: uni.$u.props.avatar.src
+ },
+ // ���������������circle-���������square-������
+ shape: {
+ type: String,
+ default: uni.$u.props.avatar.shape
+ },
+ // ������������
+ size: {
+ type: [String, Number],
+ default: uni.$u.props.avatar.size
+ },
+ // ������������
+ mode: {
+ type: String,
+ default: uni.$u.props.avatar.mode
+ },
+ // ���������������
+ text: {
+ type: String,
+ default: uni.$u.props.avatar.text
+ },
+ // ���������
+ bgColor: {
+ type: String,
+ default: uni.$u.props.avatar.bgColor
+ },
+ // ������������
+ color: {
+ type: String,
+ default: uni.$u.props.avatar.color
+ },
+ // ������������
+ fontSize: {
+ type: [String, Number],
+ default: uni.$u.props.avatar.fontSize
+ },
+ // ���������������
+ icon: {
+ type: String,
+ default: uni.$u.props.avatar.icon
+ },
+ // ������������������������������������������������QQ���������������
+ mpAvatar: {
+ type: Boolean,
+ default: uni.$u.props.avatar.mpAvatar
+ },
+ // ���������������������������
+ randomBgColor: {
+ type: Boolean,
+ default: uni.$u.props.avatar.randomBgColor
+ },
+ // ���������������������������(���������������������������)
+ defaultUrl: {
+ type: String,
+ default: uni.$u.props.avatar.defaultUrl
+ },
+ // ���������������randomBgColor���true������������������������������������������������������������������������������������������������0-19������
+ colorIndex: {
+ type: [String, Number],
+ // ������������������������������0-19������
+ validator(n) {
+ return uni.$u.test.range(n, [0, 19]) || n === ''
+ },
+ default: uni.$u.props.avatar.colorIndex
+ },
+ // ���������������
+ name: {
+ type: String,
+ default: uni.$u.props.avatar.name
+ }
+ }
+}
diff --git a/uni_modules/uview-ui/components/u-avatar/u-avatar.vue b/uni_modules/uview-ui/components/u-avatar/u-avatar.vue
new file mode 100644
index 0000000..3319be5
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-avatar/u-avatar.vue
@@ -0,0 +1,172 @@
+<template>
+ <view
+ class="u-avatar"
+ :class="[`u-avatar--${shape}`]"
+ :style="[{
+ backgroundColor: (text || icon) ? (randomBgColor ? colors[colorIndex !== '' ? colorIndex : $u.random(0, 19)] : bgColor) : 'transparent',
+ width: $u.addUnit(size),
+ height: $u.addUnit(size),
+ }, $u.addStyle(customStyle)]"
+ @tap="clickHandler"
+ >
+ <slot>
+ <!-- #ifdef MP-WEIXIN || MP-QQ || MP-BAIDU -->
+ <open-data
+ v-if="mpAvatar && allowMp"
+ type="userAvatarUrl"
+ :style="[{
+ width: $u.addUnit(size),
+ height: $u.addUnit(size)
+ }]"
+ />
+ <!-- #endif -->
+ <!-- #ifndef MP-WEIXIN && MP-QQ && MP-BAIDU -->
+ <template v-if="mpAvatar && allowMp"></template>
+ <!-- #endif -->
+ <u-icon
+ v-else-if="icon"
+ :name="icon"
+ :size="fontSize"
+ :color="color"
+ ></u-icon>
+ <u--text
+ v-else-if="text"
+ :text="text"
+ :size="fontSize"
+ :color="color"
+ align="center"
+ customStyle="justify-content: center"
+ ></u--text>
+ <image
+ class="u-avatar__image"
+ v-else
+ :class="[`u-avatar__image--${shape}`]"
+ :src="avatarUrl || defaultUrl"
+ :mode="mode"
+ @error="errorHandler"
+ :style="[{
+ width: $u.addUnit(size),
+ height: $u.addUnit(size)
+ }]"
+ ></image>
+ </slot>
+ </view>
+</template>
+
+<script>
+ import props from './props.js';
+ const base64Avatar =
+ "data:image/jpg;base64,/9j/4QAYRXhpZgAASUkqAAgAAAAAAAAAAAAAAP/sABFEdWNreQABAAQAAAA8AAD/4QMraHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLwA8P3hwYWNrZXQgYmVnaW49Iu+7vyIgaWQ9Ilc1TTBNcENlaGlIenJlU3pOVGN6a2M5ZCI/PiA8eDp4bXBtZXRhIHhtbG5zOng9ImFkb2JlOm5zOm1ldGEvIiB4OnhtcHRrPSJBZG9iZSBYTVAgQ29yZSA1LjMtYzAxMSA2Ni4xNDU2NjEsIDIwMTIvMDIvMDYtMTQ6NTY6MjcgICAgICAgICI+IDxyZGY6UkRGIHhtbG5zOnJkZj0iaHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zIyI+IDxyZGY6RGVzY3JpcHRpb24gcmRmOmFib3V0PSIiIHhtbG5zOnhtcD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLyIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bXA6Q3JlYXRvclRvb2w9IkFkb2JlIFBob3Rvc2hvcCBDUzYgKFdpbmRvd3MpIiB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOjREMEQwRkY0RjgwNDExRUE5OTY2RDgxODY3NkJFODMxIiB4bXBNTTpEb2N1bWVudElEPSJ4bXAuZGlkOjREMEQwRkY1RjgwNDExRUE5OTY2RDgxODY3NkJFODMxIj4gPHhtcE1NOkRlcml2ZWRGcm9tIHN0UmVmOmluc3RhbmNlSUQ9InhtcC5paWQ6NEQwRDBGRjJGODA0MTFFQTk5NjZEODE4Njc2QkU4MzEiIHN0UmVmOmRvY3VtZW50SUQ9InhtcC5kaWQ6NEQwRDBGRjNGODA0MTFFQTk5NjZEODE4Njc2QkU4MzEiLz4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+IDw/eHBhY2tldCBlbmQ9InIiPz7/7gAOQWRvYmUAZMAAAAAB/9sAhAAGBAQEBQQGBQUGCQYFBgkLCAYGCAsMCgoLCgoMEAwMDAwMDBAMDg8QDw4MExMUFBMTHBsbGxwfHx8fHx8fHx8fAQcHBw0MDRgQEBgaFREVGh8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx//wAARCADIAMgDAREAAhEBAxEB/8QAcQABAQEAAwEBAAAAAAAAAAAAAAUEAQMGAgcBAQAAAAAAAAAAAAAAAAAAAAAQAAIBAwICBgkDBQAAAAAAAAABAhEDBCEFMVFBYXGREiKBscHRMkJSEyOh4XLxYjNDFBEBAAAAAAAAAAAAAAAAAAAAAP/aAAwDAQACEQMRAD8A/fAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHbHFyZ/Dam+yLA+Z2L0Pjtyj2poD4AAAAAAAAAAAAAAAAAAAAAAAAKWFs9y6lcvvwQeqj8z9wFaziY1n/HbUX9XF97A7QAGXI23EvJ1goyfzR0YEfN269jeZ+a03pNe0DIAAAAAAAAAAAAAAAAAAAACvtO3RcVkXlWutuL9YFYAAAAAOJRjKLjJVi9GmB5/csH/mu1h/in8PU+QGMAAAAAAAAAAAAAAAAAAaMDG/6MmMH8C80+xAelSSVFolwQAAAAAAAHVlWI37ErUulaPk+hgeYnCUJuElSUXRrrQHAAAAAAAAAAAAAAAAABa2Oz4bM7r4zdF2ICmAAAAAAAAAg7zZ8GX41wuJP0rRgYAAAAAAAAAAAAAAAAAD0m2R8ODaXU33tsDSAAAAAAAAAlb9HyWZcnJd9PcBHAAAAAAAAAAAAAAAAAPS7e64Vn+KA0AAAAAAAAAJm+v8Ftf3ewCKAAAAAAAAAAAAAAAAAX9muqeGo9NttP06+0DcAAAAAAAAAjb7dTu2ra+VOT9P8AQCWAAAAAAAAAAAAAAAAAUNmyPt5Ltv4bui/kuAF0AAAAAAADiUlGLlJ0SVW+oDzOXfd/Ind6JPRdS0QHSAAAAAAAAAAAAAAAAAE2nVaNcGB6Lbs6OTao9LsF51z60BrAAAAAABJ3jOVHjW3r/sa9QEgAAAAAAAAAAAAAAAAAAAPu1duWriuW34ZR4MC9hbnZyEoy8l36XwfYBsAAADaSq9EuLAlZ+7xSdrGdW9Hc5dgEdtt1erfFgAAAAAAAAAAAAAAAAADVjbblX6NR8MH80tEBRs7HYivyzlN8lovaBPzduvY0m6eK10TXtAyAarO55lpJK54orolr+4GqO/Xaea1FvqbXvA+Z77kNeW3GPbV+4DJfzcm/pcm3H6Vou5AdAFLC2ed2Pjv1txa8sV8T6wOL+yZEKu1JXFy4MDBOE4ScZxcZLinoB8gAAAAAAAAAAAB242LeyJ+C3GvN9C7QLmJtePYpKS+5c+p8F2IDYAANJqj1T4oCfk7Nj3G5Wn9qXJax7gJ93Z82D8sVNc4v30A6Xg5i42Z+iLfqARwcyT0sz9MWvWBps7LlTf5Grce9/oBTxdtxseklHxT+uWr9AGoAB138ezfj4bsFJdD6V2MCPm7RdtJzs1uW1xXzL3gTgAAAAAAAAADRhYc8q74I6RWs5ckB6GxYtWLat21SK731sDsAAAAAAAAAAAAAAAASt021NO/YjrxuQXT1oCOAAAAAAABzGLlJRSq26JAelwsWONYjbXxcZvmwO8AAAAAAAAAAAAAAAAAAef3TEWPkVivx3NY9T6UBiAAAAAABo2+VmGXblddIJ8eivRUD0oAAAAAAAAAAAAAAAAAAAYt4tKeFKVNYNSXfRgefAAAAAAAAr7VuSSWPedKaW5v1MCsAAAAAAAAAAAAAAAAAAIe6bj96Ts2n+JPzSXzP3ATgAAAAAAAAFbbt1UUrOQ9FpC4/UwK6aaqtU+DAAAAAAAAAAAAAAA4lKMIuUmoxWrb4ARNx3R3q2rLpa4Sl0y/YCcAAAAAAAAAAANmFud7G8r89r6X0dgFvGzLGRGtuWvTF6NAdwAAAAAAAAAAAy5W442PVN+K59EePp5ARMvOv5MvO6QXCC4AZwAAAAAAAAAAAAAcxlKLUotprg1owN+PvORborq+7Hnwl3gUbO74VzRydt8pKn68ANcJwmqwkpLmnUDkAAAAfNy9atqtyagut0AxXt5xIV8Fbj6lRd7Am5G65V6qUvtwfyx94GMAAAAAAAAAAAAAAAAAAAOU2nVOj5gdsc3LiqRvTpyqwOxbnnrhdfpSfrQB7pnv/AGvuS9gHXPMy5/Fem1yq0v0A6W29XqwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAf//Z";
+ /**
+ * Avatar ������
+ * @description ���������������������������������������������������������������������������������������������������������������������
+ * @tutorial https://www.uviewui.com/components/avatar.html
+ *
+ * @property {String} src ���������������������������������������������������������(���������������������)
+ * @property {String} shape ������������ ��� circle (������) | square���
+ * @property {String | Number} size ���������������������������������������(large, default, mini)��������������� ��������� 40 ���
+ * @property {String} mode ���������������������������������uni���image���������mode������������������������������������������������������widthFix��� ��������� 'scaleToFill' ���
+ * @property {String} text ���������������������������������������src
+ * @property {String} bgColor ��������������������������������������� ��������� '#c0c4cc' ���
+ * @property {String} color ������������ ��������� '#ffffff' ���
+ * @property {String | Number} fontSize ������������ ��������� 18 ���
+ * @property {String} icon ���������������
+ * @property {Boolean} mpAvatar ������������������������������������������������QQ��������������� ��������� false ���
+ * @property {Boolean} randomBgColor ��������������������������� ��������� false ���
+ * @property {String} defaultUrl ���������������������������(���������������������������)
+ * @property {String | Number} colorIndex ���������������randomBgColor���true������������������������������������������������������������������������������������������������0-19������
+ * @property {String} name ��������������� ��������� 'level' ���
+ * @property {Object} customStyle ���������������������������������
+ *
+ * @event {Function} click ��������������������� index: ������������������������
+ * @example <u-avatar :src="src" mode="square"></u-avatar>
+ */
+ export default {
+ name: 'u-avatar',
+ mixins: [uni.$u.mpMixin, uni.$u.mixin, props],
+ data() {
+ return {
+ // ������������randomBgColor���������true������������������������������������������������������������������������������������������
+ colors: ['#ffb34b', '#f2bba9', '#f7a196', '#f18080', '#88a867', '#bfbf39', '#89c152', '#94d554', '#f19ec2',
+ '#afaae4', '#e1b0df', '#c38cc1', '#72dcdc', '#9acdcb', '#77b1cc', '#448aca', '#86cefa', '#98d1ee',
+ '#73d1f1',
+ '#80a7dc'
+ ],
+ avatarUrl: this.src,
+ allowMp: false
+ }
+ },
+ watch: {
+ // ������������src������������������������������avatarUrl������������������������������������������������������������src������������
+ // ���������������������������������props���������������������������������������
+ src: {
+ immediate: true,
+ handler(newVal) {
+ this.avatarUrl = newVal
+ // ���������������src������������������error���������������������������������������������src���''������������������������������������������
+ if(!newVal) {
+ this.errorHandler()
+ }
+ }
+ }
+ },
+ computed: {
+ imageStyle() {
+ const style = {}
+ return style
+ }
+ },
+ created() {
+ this.init()
+ },
+ methods: {
+ init() {
+ // ������������������������������������������open-data������
+ // ������������������������uni.getUserInfo���������������������������������������������������(������)������������������������
+ // ������������������������������������������������������������
+ // #ifdef MP-WEIXIN || MP-QQ || MP-BAIDU
+ this.allowMp = true
+ // #endif
+ },
+ // ���������������name������������������������������������������"/"������������������������
+ isImg() {
+ return this.src.indexOf('/') !== -1
+ },
+ // ������������������������������
+ errorHandler() {
+ this.avatarUrl = this.defaultUrl || base64Avatar
+ },
+ clickHandler() {
+ this.$emit('click', this.name)
+ }
+ }
+ }
+</script>
+
+<style lang="scss" scoped>
+ @import "../../libs/css/components.scss";
+
+ .u-avatar {
+ @include flex;
+ align-items: center;
+ justify-content: center;
+
+ &--circle {
+ border-radius: 100px;
+ }
+
+ &--square {
+ border-radius: 4px;
+ }
+
+ &__image {
+ &--circle {
+ border-radius: 100px;
+ }
+
+ &--square {
+ border-radius: 4px;
+ }
+ }
+ }
+</style>
diff --git a/uni_modules/uview-ui/components/u-back-top/props.js b/uni_modules/uview-ui/components/u-back-top/props.js
new file mode 100644
index 0000000..6c702c2
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-back-top/props.js
@@ -0,0 +1,54 @@
+export default {
+ props: {
+ // ������������������������circle-���������square-������
+ mode: {
+ type: String,
+ default: uni.$u.props.backtop.mode
+ },
+ // ���������������
+ icon: {
+ type: String,
+ default: uni.$u.props.backtop.icon
+ },
+ // ������������
+ text: {
+ type: String,
+ default: uni.$u.props.backtop.text
+ },
+ // ������������������������
+ duration: {
+ type: [String, Number],
+ default: uni.$u.props.backtop.duration
+ },
+ // ������������
+ scrollTop: {
+ type: [String, Number],
+ default: uni.$u.props.backtop.scrollTop
+ },
+ // ���������������������������������������px
+ top: {
+ type: [String, Number],
+ default: uni.$u.props.backtop.top
+ },
+ // ���������������������������������������������px
+ bottom: {
+ type: [String, Number],
+ default: uni.$u.props.backtop.bottom
+ },
+ // ���������������������������������������������px
+ right: {
+ type: [String, Number],
+ default: uni.$u.props.backtop.right
+ },
+ // ������
+ zIndex: {
+ type: [String, Number],
+ default: uni.$u.props.backtop.zIndex
+ },
+ // ������������������������������
+ iconStyle: {
+ type: Object,
+ default: uni.$u.props.backtop.iconStyle
+ }
+ }
+}
diff --git a/uni_modules/uview-ui/components/u-back-top/u-back-top.vue b/uni_modules/uview-ui/components/u-back-top/u-back-top.vue
new file mode 100644
index 0000000..2d07566
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-back-top/u-back-top.vue
@@ -0,0 +1,129 @@
+<template>
+ <u-transition
+ mode="fade"
+ :customStyle="backTopStyle"
+ :show="show"
+ >
+ <view
+ class="u-back-top"
+ :style="[contentStyle]"
+ v-if="!$slots.default && !$slots.$default"
+ @click="backToTop"
+ >
+ <u-icon
+ :name="icon"
+ :custom-style="iconStyle"
+ ></u-icon>
+ <text
+ v-if="text"
+ class="u-back-top__text"
+ >{{text}}</text>
+ </view>
+ <slot v-else />
+ </u-transition>
+</template>
+
+<script>
+ import props from './props.js';
+ // #ifdef APP-NVUE
+ const dom = weex.requireModule('dom')
+ // #endif
+ /**
+ * backTop ������������
+ * @description ������������������������������������������������������������������������������������������������������������������������
+ * @tutorial https://uviewui.com/components/backTop.html
+ *
+ * @property {String} mode ������������������������circle-���������square-������ ��������� 'circle' ���
+ * @property {String} icon ��������������� ��������� 'arrow-upward' ��� ���������������������
+ * @property {String} text ������������
+ * @property {String | Number} duration ������������������������ ��������� 100���
+ * @property {String | Number} scrollTop ������������ ��������� 0 ���
+ * @property {String | Number} top ���������������������������������������px ��������� 400 ���
+ * @property {String | Number} bottom ���������������������������������������������px ��������� 100 ���
+ * @property {String | Number} right ���������������������������������������������px ��������� 20 ���
+ * @property {String | Number} zIndex ������ ��������� 9 ���
+ * @property {Object<Object>} iconStyle ������������������������������ ��������� {color: '#909399',fontSize: '19px'}���
+ * @property {Object} customStyle ���������������������������������
+ *
+ * @example <u-back-top :scrollTop="scrollTop"></u-back-top>
+ */
+ export default {
+ name: 'u-back-top',
+ mixins: [uni.$u.mpMixin, uni.$u.mixin,props],
+ computed: {
+ backTopStyle() {
+ // ������������������
+ const style = {
+ bottom: uni.$u.addUnit(this.bottom),
+ right: uni.$u.addUnit(this.right),
+ width: '40px',
+ height: '40px',
+ position: 'fixed',
+ zIndex: 10,
+ }
+ return style
+ },
+ show() {
+ return uni.$u.getPx(this.scrollTop) > uni.$u.getPx(this.top)
+ },
+ contentStyle() {
+ const style = {}
+ let radius = 0
+ // ������������
+ if(this.mode === 'circle') {
+ radius = '100px'
+ } else {
+ radius = '4px'
+ }
+ // ������������������nvue������������������������
+ style.borderTopLeftRadius = radius
+ style.borderTopRightRadius = radius
+ style.borderBottomLeftRadius = radius
+ style.borderBottomRightRadius = radius
+ return uni.$u.deepMerge(style, uni.$u.addStyle(this.customStyle))
+ }
+ },
+ methods: {
+ backToTop() {
+ // #ifdef APP-NVUE
+ if (!this.$parent.$refs['u-back-top']) {
+ uni.$u.error(`nvue������������������������������������������"ref='u-back-top'`)
+ }
+ dom.scrollToElement(this.$parent.$refs['u-back-top'], {
+ offset: 0
+ })
+ // #endif
+
+ // #ifndef APP-NVUE
+ uni.pageScrollTo({
+ scrollTop: 0,
+ duration: this.duration
+ });
+ // #endif
+ this.$emit('click')
+ }
+ }
+ }
+</script>
+
+<style lang="scss" scoped>
+ @import '../../libs/css/components.scss';
+ $u-back-top-flex:1 !default;
+ $u-back-top-height:100% !default;
+ $u-back-top-background-color:#E1E1E1 !default;
+ $u-back-top-tips-font-size:12px !default;
+ .u-back-top {
+ @include flex;
+ flex-direction: column;
+ align-items: center;
+ flex:$u-back-top-flex;
+ height: $u-back-top-height;
+ justify-content: center;
+ background-color: $u-back-top-background-color;
+
+ &__tips {
+ font-size:$u-back-top-tips-font-size;
+ transform: scale(0.8);
+ }
+ }
+</style>
diff --git a/uni_modules/uview-ui/components/u-badge/props.js b/uni_modules/uview-ui/components/u-badge/props.js
new file mode 100644
index 0000000..74c032c
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-badge/props.js
@@ -0,0 +1,72 @@
+export default {
+ props: {
+ // ������������������
+ isDot: {
+ type: Boolean,
+ default: uni.$u.props.badge.isDot
+ },
+ // ���������������
+ value: {
+ type: [Number, String],
+ default: uni.$u.props.badge.value
+ },
+ // ������������
+ show: {
+ type: Boolean,
+ default: uni.$u.props.badge.show
+ },
+ // ������������������������������������ '{max}+'
+ max: {
+ type: [Number, String],
+ default: uni.$u.props.badge.max
+ },
+ // ���������������error|warning|success|primary
+ type: {
+ type: String,
+ default: uni.$u.props.badge.type
+ },
+ // ������������ 0 ������������������ Badge
+ showZero: {
+ type: Boolean,
+ default: uni.$u.props.badge.showZero
+ },
+ // ���������������������������type������������������type���������������
+ bgColor: {
+ type: [String, null],
+ default: uni.$u.props.badge.bgColor
+ },
+ // ������������
+ color: {
+ type: [String, null],
+ default: uni.$u.props.badge.color
+ },
+ // ���������������circle-���������������������horn-������������������
+ shape: {
+ type: String,
+ default: uni.$u.props.badge.shape
+ },
+ // ������������������������������overflow|ellipsis|limit
+ // overflow���������max���������������������������`${max}+`
+ // ellipsis���������max���������������������`${max}...`
+ // limit���������1000���������������������������1000���������`${value/1000}K`���������2.2k���3.34w���������������2���������
+ numberType: {
+ type: String,
+ default: uni.$u.props.badge.numberType
+ },
+ // ������badge��������������������������� [x, y]���������������������top���right���������absolute���true���������
+ offset: {
+ type: Array,
+ default: uni.$u.props.badge.offset
+ },
+ // ���������������������������������
+ inverted: {
+ type: Boolean,
+ default: uni.$u.props.badge.inverted
+ },
+ // ������������������
+ absolute: {
+ type: Boolean,
+ default: uni.$u.props.badge.absolute
+ }
+ }
+}
diff --git a/uni_modules/uview-ui/components/u-badge/u-badge.vue b/uni_modules/uview-ui/components/u-badge/u-badge.vue
new file mode 100644
index 0000000..53cfc81
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-badge/u-badge.vue
@@ -0,0 +1,171 @@
+<template>
+ <text
+ v-if="show && ((Number(value) === 0 ? showZero : true) || isDot)"
+ :class="[isDot ? 'u-badge--dot' : 'u-badge--not-dot', inverted && 'u-badge--inverted', shape === 'horn' && 'u-badge--horn', `u-badge--${type}${inverted ? '--inverted' : ''}`]"
+ :style="[$u.addStyle(customStyle), badgeStyle]"
+ class="u-badge"
+ >{{ isDot ? '' :showValue }}</text>
+</template>
+
+<script>
+ import props from './props.js';
+ /**
+ * badge ���������
+ * @description ���������������������������������������������������������������������������������������������������������������������������������
+ * @tutorial https://uviewui.com/components/badge.html
+ *
+ * @property {Boolean} isDot ������������������ ��������� false ���
+ * @property {String | Number} value ���������������
+ * @property {Boolean} show ������������ ��������� true ���
+ * @property {String | Number} max ������������������������������������ '{max}+' ���������999���
+ * @property {String} type ���������������error|warning|success|primary ��������� 'error' ���
+ * @property {Boolean} showZero ������������ 0 ������������������ Badge ��������� false ���
+ * @property {String} bgColor ���������������������������type������������������type���������������
+ * @property {String} color ������������ ��������� '#ffffff' ���
+ * @property {String} shape ���������������circle-���������������������horn-������������������ ��������� 'circle' ���
+ * @property {String} numberType ������������������������������overflow|ellipsis|limit ��������� 'overflow' ���
+ * @property {Array}} offset ������badge��������������������������� [x, y]���������������������top���right���������absolute���true���������
+ * @property {Boolean} inverted ������������������������������������������ false ���
+ * @property {Boolean} absolute ��������������������������� false ���
+ * @property {Object} customStyle ���������������������������������
+ * @example <u-badge :type="type" :count="count"></u-badge>
+ */
+ export default {
+ name: 'u-badge',
+ mixins: [uni.$u.mpMixin, props, uni.$u.mixin],
+ computed: {
+ // ���������badge���������������������������������
+ boxStyle() {
+ let style = {};
+ return style;
+ },
+ // ���������������������
+ badgeStyle() {
+ const style = {}
+ if(this.color) {
+ style.color = this.color
+ }
+ if (this.bgColor && !this.inverted) {
+ style.backgroundColor = this.bgColor
+ }
+ if (this.absolute) {
+ style.position = 'absolute'
+ // ���������������offset������
+ if(this.offset.length) {
+ // top���right���������offset������������������������������������������������������������right������top
+ const top = this.offset[0]
+ const right = this.offset[1] || top
+ style.top = uni.$u.addUnit(top)
+ style.right = uni.$u.addUnit(right)
+ }
+ }
+ return style
+ },
+ showValue() {
+ switch (this.numberType) {
+ case "overflow":
+ return Number(this.value) > Number(this.max) ? this.max + "+" : this.value
+ break;
+ case "ellipsis":
+ return Number(this.value) > Number(this.max) ? "..." : this.value
+ break;
+ case "limit":
+ return Number(this.value) > 999 ? Number(this.value) >= 9999 ?
+ Math.floor(this.value / 1e4 * 100) / 100 + "w" : Math.floor(this.value /
+ 1e3 * 100) / 100 + "k" : this.value
+ break;
+ default:
+ return Number(this.value)
+ }
+ },
+ }
+ }
+</script>
+
+<style lang="scss" scoped>
+ @import "../../libs/css/components.scss";
+
+ $u-badge-primary: $u-primary !default;
+ $u-badge-error: $u-error !default;
+ $u-badge-success: $u-success !default;
+ $u-badge-info: $u-info !default;
+ $u-badge-warning: $u-warning !default;
+ $u-badge-dot-radius: 100px !default;
+ $u-badge-dot-size: 8px !default;
+ $u-badge-dot-right: 4px !default;
+ $u-badge-dot-top: 0 !default;
+ $u-badge-text-font-size: 11px !default;
+ $u-badge-text-right: 10px !default;
+ $u-badge-text-padding: 2px 5px !default;
+ $u-badge-text-align: center !default;
+ $u-badge-text-color: #FFFFFF !default;
+
+ .u-badge {
+ border-top-right-radius: $u-badge-dot-radius;
+ border-top-left-radius: $u-badge-dot-radius;
+ border-bottom-left-radius: $u-badge-dot-radius;
+ border-bottom-right-radius: $u-badge-dot-radius;
+ @include flex;
+ line-height: $u-badge-text-font-size;
+ text-align: $u-badge-text-align;
+ font-size: $u-badge-text-font-size;
+ color: $u-badge-text-color;
+
+ &--dot {
+ height: $u-badge-dot-size;
+ width: $u-badge-dot-size;
+ }
+
+ &--inverted {
+ font-size: 13px;
+ }
+
+ &--not-dot {
+ padding: $u-badge-text-padding;
+ }
+
+ &--horn {
+ border-bottom-left-radius: 0;
+ }
+
+ &--primary {
+ background-color: $u-badge-primary;
+ }
+
+ &--primary--inverted {
+ color: $u-badge-primary;
+ }
+
+ &--error {
+ background-color: $u-badge-error;
+ }
+
+ &--error--inverted {
+ color: $u-badge-error;
+ }
+
+ &--success {
+ background-color: $u-badge-success;
+ }
+
+ &--success--inverted {
+ color: $u-badge-success;
+ }
+
+ &--info {
+ background-color: $u-badge-info;
+ }
+
+ &--info--inverted {
+ color: $u-badge-info;
+ }
+
+ &--warning {
+ background-color: $u-badge-warning;
+ }
+
+ &--warning--inverted {
+ color: $u-badge-warning;
+ }
+ }
+</style>
diff --git a/uni_modules/uview-ui/components/u-button/nvue.scss b/uni_modules/uview-ui/components/u-button/nvue.scss
new file mode 100644
index 0000000..490db7d
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-button/nvue.scss
@@ -0,0 +1,46 @@
+$u-button-active-opacity:0.75 !default;
+$u-button-loading-text-margin-left:4px !default;
+$u-button-text-color: #FFFFFF !default;
+$u-button-text-plain-error-color:$u-error !default;
+$u-button-text-plain-warning-color:$u-warning !default;
+$u-button-text-plain-success-color:$u-success !default;
+$u-button-text-plain-info-color:$u-info !default;
+$u-button-text-plain-primary-color:$u-primary !default;
+.u-button {
+ &--active {
+ opacity: $u-button-active-opacity;
+ }
+
+ &--active--plain {
+ background-color: rgb(217, 217, 217);
+ }
+
+ &__loading-text {
+ margin-left:$u-button-loading-text-margin-left;
+ }
+
+ &__text,
+ &__loading-text {
+ color:$u-button-text-color;
+ }
+
+ &__text--plain--error {
+ color:$u-button-text-plain-error-color;
+ }
+
+ &__text--plain--warning {
+ color:$u-button-text-plain-warning-color;
+ }
+
+ &__text--plain--success{
+ color:$u-button-text-plain-success-color;
+ }
+
+ &__text--plain--info {
+ color:$u-button-text-plain-info-color;
+ }
+
+ &__text--plain--primary {
+ color:$u-button-text-plain-primary-color;
+ }
+}
\ No newline at end of file
diff --git a/uni_modules/uview-ui/components/u-button/props.js b/uni_modules/uview-ui/components/u-button/props.js
new file mode 100644
index 0000000..07fd844
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-button/props.js
@@ -0,0 +1,161 @@
+/*
+ * @Author : LQ
+ * @Description :
+ * @version : 1.0
+ * @Date : 2021-08-16 10:04:04
+ * @LastAuthor : LQ
+ * @lastTime : 2021-08-16 10:04:24
+ * @FilePath : /u-view2.0/uview-ui/components/u-button/props.js
+ */
+export default {
+ props: {
+ // ���������������
+ hairline: {
+ type: Boolean,
+ default: uni.$u.props.button.hairline
+ },
+ // ������������������������info���primary���error���warning���success
+ type: {
+ type: String,
+ default: uni.$u.props.button.type
+ },
+ // ���������������large���normal���small���mini
+ size: {
+ type: String,
+ default: uni.$u.props.button.size
+ },
+ // ���������������circle������������������������square���������������
+ shape: {
+ type: String,
+ default: uni.$u.props.button.shape
+ },
+ // ������������������
+ plain: {
+ type: Boolean,
+ default: uni.$u.props.button.plain
+ },
+ // ������������������
+ disabled: {
+ type: Boolean,
+ default: uni.$u.props.button.disabled
+ },
+ // ���������������
+ loading: {
+ type: Boolean,
+ default: uni.$u.props.button.loading
+ },
+ // ���������������������
+ loadingText: {
+ type: [String, Number],
+ default: uni.$u.props.button.loadingText
+ },
+ // ������������������������
+ loadingMode: {
+ type: String,
+ default: uni.$u.props.button.loadingMode
+ },
+ // ������������������
+ loadingSize: {
+ type: [String, Number],
+ default: uni.$u.props.button.loadingSize
+ },
+ // ���������������������������uniapp������������button������������������
+ // https://uniapp.dcloud.io/component/button
+ openType: {
+ type: String,
+ default: uni.$u.props.button.openType
+ },
+ // ������ <form> ������������������������������ <form> ��������� submit/reset ������
+ // ���������submit���������������������reset������������������
+ formType: {
+ type: String,
+ default: uni.$u.props.button.formType
+ },
+ // ������ APP ��������� APP ������������������open-type=launchApp���������
+ // ���������������������QQ���������������
+ appParameter: {
+ type: String,
+ default: uni.$u.props.button.appParameter
+ },
+ // ���������������������������������������������������������������������������������
+ hoverStopPropagation: {
+ type: Boolean,
+ default: uni.$u.props.button.hoverStopPropagation
+ },
+ // ������������������������������������zh_CN ���������������zh_TW ���������������en ���������������������������������
+ lang: {
+ type: String,
+ default: uni.$u.props.button.lang
+ },
+ // ���������������open-type="contact"������������������������������������
+ sessionFrom: {
+ type: String,
+ default: uni.$u.props.button.sessionFrom
+ },
+ // ������������������������������open-type="contact"���������
+ // ���������������������������������������������
+ sendMessageTitle: {
+ type: String,
+ default: uni.$u.props.button.sendMessageTitle
+ },
+ // ���������������������������������������������������open-type="contact"���������
+ // ���������������������������������������������������
+ sendMessagePath: {
+ type: String,
+ default: uni.$u.props.button.sendMessagePath
+ },
+ // ������������������������������open-type="contact"���������
+ // ���������������������������������������������������
+ sendMessageImg: {
+ type: String,
+ default: uni.$u.props.button.sendMessageImg
+ },
+ // ������������������������������������������������������ true������������������������������������������������"���������������������������"���������
+ // ���������������������������������������������������open-type="contact"���������
+ showMessageCard: {
+ type: Boolean,
+ default: uni.$u.props.button.showMessageCard
+ },
+ // ���������������������������������������data-xxx���������������target.dataset.name������
+ dataName: {
+ type: String,
+ default: uni.$u.props.button.dataName
+ },
+ // ������������������������������������������
+ throttleTime: {
+ type: [String, Number],
+ default: uni.$u.props.button.throttleTime
+ },
+ // ���������������������������������������������
+ hoverStartTime: {
+ type: [String, Number],
+ default: uni.$u.props.button.hoverStartTime
+ },
+ // ���������������������������������������������������
+ hoverStayTime: {
+ type: [String, Number],
+ default: uni.$u.props.button.hoverStayTime
+ },
+ // ������������������������������props������������������slot������������
+ // nvue������������������������������
+ text: {
+ type: [String, Number],
+ default: uni.$u.props.button.text
+ },
+ // ������������
+ icon: {
+ type: String,
+ default: uni.$u.props.button.icon
+ },
+ // ������������
+ iconColor: {
+ type: String,
+ default: uni.$u.props.button.icon
+ },
+ // ���������������������������linear-gradient���������
+ color: {
+ type: String,
+ default: uni.$u.props.button.color
+ }
+ }
+}
diff --git a/uni_modules/uview-ui/components/u-button/u-button.vue b/uni_modules/uview-ui/components/u-button/u-button.vue
new file mode 100644
index 0000000..5494351
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-button/u-button.vue
@@ -0,0 +1,490 @@
+<template>
+ <!-- #ifndef APP-NVUE -->
+ <button
+ :hover-start-time="Number(hoverStartTime)"
+ :hover-stay-time="Number(hoverStayTime)"
+ :form-type="formType"
+ :open-type="openType"
+ :app-parameter="appParameter"
+ :hover-stop-propagation="hoverStopPropagation"
+ :send-message-title="sendMessageTitle"
+ :send-message-path="sendMessagePath"
+ :lang="lang"
+ :data-name="dataName"
+ :session-from="sessionFrom"
+ :send-message-img="sendMessageImg"
+ :show-message-card="showMessageCard"
+ @getphonenumber="getphonenumber"
+ @getuserinfo="getuserinfo"
+ @error="error"
+ @opensetting="opensetting"
+ @launchapp="launchapp"
+ :hover-class="!disabled && !loading ? 'u-button--active' : ''"
+ class="u-button u-reset-button"
+ :style="[baseColor, $u.addStyle(customStyle)]"
+ @tap="clickHandler"
+ :class="bemClass"
+ >
+ <template v-if="loading">
+ <u-loading-icon
+ :mode="loadingMode"
+ :size="loadingSize * 1.15"
+ :color="loadingColor"
+ ></u-loading-icon>
+ <text
+ class="u-button__loading-text"
+ :style="[{ fontSize: textSize + 'px' }]"
+ >{{ loadingText || text }}</text
+ >
+ </template>
+ <template v-else>
+ <u-icon
+ v-if="icon"
+ :name="icon"
+ :color="iconColorCom"
+ :size="textSize * 1.35"
+ :customStyle="{ marginRight: '2px' }"
+ ></u-icon>
+ <slot>
+ <text
+ class="u-button__text"
+ :style="[{ fontSize: textSize + 'px' }]"
+ >{{ text }}</text
+ >
+ </slot>
+ </template>
+ </button>
+ <!-- #endif -->
+
+ <!-- #ifdef APP-NVUE -->
+ <view
+ :hover-start-time="Number(hoverStartTime)"
+ :hover-stay-time="Number(hoverStayTime)"
+ class="u-button"
+ :hover-class="
+ !disabled && !loading && !color && (plain || type === 'info')
+ ? 'u-button--active--plain'
+ : !disabled && !loading && !plain
+ ? 'u-button--active'
+ : ''
+ "
+ @tap="clickHandler"
+ :class="bemClass"
+ :style="[baseColor, $u.addStyle(customStyle)]"
+ >
+ <template v-if="loading">
+ <u-loading-icon
+ :mode="loadingMode"
+ :size="loadingSize * 1.15"
+ :color="loadingColor"
+ ></u-loading-icon>
+ <text
+ class="u-button__loading-text"
+ :style="[nvueTextStyle]"
+ :class="[plain && `u-button__text--plain--${type}`]"
+ >{{ loadingText || text }}</text
+ >
+ </template>
+ <template v-else>
+ <u-icon
+ v-if="icon"
+ :name="icon"
+ :color="iconColorCom"
+ :size="textSize * 1.35"
+ ></u-icon>
+ <text
+ class="u-button__text"
+ :style="[
+ {
+ marginLeft: icon ? '2px' : 0,
+ },
+ nvueTextStyle,
+ ]"
+ :class="[plain && `u-button__text--plain--${type}`]"
+ >{{ text }}</text
+ >
+ </template>
+ </view>
+ <!-- #endif -->
+</template>
+
+<script>
+import button from "../../libs/mixin/button.js";
+import openType from "../../libs/mixin/openType.js";
+import props from "./props.js";
+/**
+ * button ������
+ * @description Button ������
+ * @tutorial https://www.uviewui.com/components/button.html
+ *
+ * @property {Boolean} hairline ������������������������������ (������ true )
+ * @property {String} type ������������������������info���primary���error���warning���success (������ 'info' )
+ * @property {String} size ���������������large���normal���mini ��������� normal���
+ * @property {String} shape ���������������circle������������������������square��������������� ��������� 'square' ���
+ * @property {Boolean} plain ������������������������������������ ��������� false���
+ * @property {Boolean} disabled ������������ ��������� false���
+ * @property {Boolean} loading ������������������������ loading ������(App-nvue ������������ ios ���������������Android������������) ��������� false���
+ * @property {String | Number} loadingText ���������������������
+ * @property {String} loadingMode ������������������������ ��������� 'spinner' ���
+ * @property {String | Number} loadingSize ������������������ ��������� 15 ���
+ * @property {String} openType ���������������������������uniapp������������button������������������
+ * @property {String} formType ������ <form> ������������������������������ <form> ��������� submit/reset ������
+ * @property {String} appParameter ������ APP ��������� APP ������������������open-type=launchApp��������� ������������������������������QQ������������������
+ * @property {Boolean} hoverStopPropagation ������������������������������������������������������������������������������������������ true ���
+ * @property {String} lang ������������������������������������zh_CN ���������������zh_TW ���������������en ��������������� en ���
+ * @property {String} sessionFrom ���������������openType="contact"���������
+ * @property {String} sendMessageTitle ������������������������������openType="contact"���������
+ * @property {String} sendMessagePath ���������������������������������������������������openType="contact"���������
+ * @property {String} sendMessageImg ������������������������������openType="contact"���������
+ * @property {Boolean} showMessageCard ������������������������������������������������������ true������������������������������������������������"���������������������������"������������������������������������������������������������openType="contact"������������������false���
+ * @property {String} dataName ���������������������������������������data-xxx���������������target.dataset.name������
+ * @property {String | Number} throttleTime ������������������������������������������ ��������� 0 )
+ * @property {String | Number} hoverStartTime ��������������������������������������������� ��������� 0 )
+ * @property {String | Number} hoverStayTime ��������������������������������������������������� ��������� 200 )
+ * @property {String | Number} text ������������������������������props������������������slot���������������������nvue���������������������������������
+ * @property {String} icon ������������
+ * @property {String} iconColor ������������������
+ * @property {String} color ���������������������������linear-gradient���������
+ * @property {Object} customStyle ���������������������������������
+ *
+ * @event {Function} click ������������������������������������������
+ * @event {Function} getphonenumber open-type="getPhoneNumber"���������
+ * @event {Function} getuserinfo ���������������������������������������������������������������������������������detail���������������������uni.getUserInfo
+ * @event {Function} error ������������������������������������������������
+ * @event {Function} opensetting ������������������������������������������
+ * @event {Function} launchapp ������ APP ���������������
+ * @example <u-button>������</u-button>
+ */
+export default {
+ name: "u-button",
+ // #ifdef MP
+ mixins: [uni.$u.mpMixin, uni.$u.mixin, button, openType, props],
+ // #endif
+ // #ifndef MP
+ mixins: [uni.$u.mpMixin, uni.$u.mixin, props],
+ // #endif
+ data() {
+ return {};
+ },
+ computed: {
+ // ������bem���������������
+ bemClass() {
+ // this.bem���������computed������������mixin���
+ if (!this.color) {
+ return this.bem(
+ "button",
+ ["type", "shape", "size"],
+ ["disabled", "plain", "hairline"]
+ );
+ } else {
+ // ������nvue������������������color���������������������������type������������������type���������������������������������������
+ return this.bem(
+ "button",
+ ["shape", "size"],
+ ["disabled", "plain", "hairline"]
+ );
+ }
+ },
+ loadingColor() {
+ if (this.plain) {
+ // ���������������color������������color������������������type������������
+ return this.color
+ ? this.color
+ : uni.$u.config.color[`u-${this.type}`];
+ }
+ if (this.type === "info") {
+ return "#c9c9c9";
+ }
+ return "rgb(200, 200, 200)";
+ },
+ iconColorCom() {
+ // ���������������������������������color������color���������������������������������
+ // u-icon���color���������������������������������
+ if (this.iconColor) return this.iconColor;
+ if (this.plain) {
+ return this.color ? this.color : this.type;
+ } else {
+ return this.type === "info" ? "#000000" : "#ffffff";
+ }
+ },
+ baseColor() {
+ let style = {};
+ if (this.color) {
+ // ������������������color���������������������������������������������������������������
+ style.color = this.plain ? this.color : "white";
+ if (!this.plain) {
+ // ���������������������������������������������
+ style["background-color"] = this.color;
+ }
+ if (this.color.indexOf("gradient") !== -1) {
+ // ���������������������������������������������������������������������backgroundImage���������������
+ // weex���������������������borderWidth���������������������������������������������
+ // ������weex������������������������������������������������������������������������������������������������
+ style.borderTopWidth = 0;
+ style.borderRightWidth = 0;
+ style.borderBottomWidth = 0;
+ style.borderLeftWidth = 0;
+ if (!this.plain) {
+ style.backgroundImage = this.color;
+ }
+ } else {
+ // ���������������������������������������������
+ style.borderColor = this.color;
+ style.borderWidth = "1px";
+ style.borderStyle = "solid";
+ }
+ }
+ return style;
+ },
+ // nvue������������������������������������������������������������������������text���������������������������
+ nvueTextStyle() {
+ let style = {};
+ // ������������������color���������������������������������������������������������������
+ if (this.type === "info") {
+ style.color = "#323233";
+ }
+ if (this.color) {
+ style.color = this.plain ? this.color : "white";
+ }
+ style.fontSize = this.textSize + "px";
+ return style;
+ },
+ // ������������
+ textSize() {
+ let fontSize = 14,
+ { size } = this;
+ if (size === "large") fontSize = 16;
+ if (size === "normal") fontSize = 14;
+ if (size === "small") fontSize = 12;
+ if (size === "mini") fontSize = 10;
+ return fontSize;
+ },
+ },
+ methods: {
+ clickHandler() {
+ // ������������������������������������������
+ if (!this.disabled && !this.loading) {
+ // ������������������������this.throttle���������������������������������
+ uni.$u.throttle(() => {
+ this.$emit("click");
+ }, this.throttleTime);
+ }
+ },
+ // ���������������uniapp���������������������������������������������
+ getphonenumber(res) {
+ this.$emit("getphonenumber", res);
+ },
+ getuserinfo(res) {
+ this.$emit("getuserinfo", res);
+ },
+ error(res) {
+ this.$emit("error", res);
+ },
+ opensetting(res) {
+ this.$emit("opensetting", res);
+ },
+ launchapp(res) {
+ this.$emit("launchapp", res);
+ },
+ },
+};
+</script>
+
+<style lang="scss" scoped>
+@import "../../libs/css/components.scss";
+
+/* #ifndef APP-NVUE */
+@import "./vue.scss";
+/* #endif */
+
+/* #ifdef APP-NVUE */
+@import "./nvue.scss";
+/* #endif */
+
+$u-button-u-button-height: 40px !default;
+$u-button-text-font-size: 15px !default;
+$u-button-loading-text-font-size: 15px !default;
+$u-button-loading-text-margin-left: 4px !default;
+$u-button-large-width: 100% !default;
+$u-button-large-height: 50px !default;
+$u-button-normal-padding: 0 12px !default;
+$u-button-large-padding: 0 15px !default;
+$u-button-normal-font-size: 14px !default;
+$u-button-small-min-width: 60px !default;
+$u-button-small-height: 30px !default;
+$u-button-small-padding: 0px 8px !default;
+$u-button-mini-padding: 0px 8px !default;
+$u-button-small-font-size: 12px !default;
+$u-button-mini-height: 22px !default;
+$u-button-mini-font-size: 10px !default;
+$u-button-mini-min-width: 50px !default;
+$u-button-disabled-opacity: 0.5 !default;
+$u-button-info-color: #323233 !default;
+$u-button-info-background-color: #fff !default;
+$u-button-info-border-color: #ebedf0 !default;
+$u-button-info-border-width: 1px !default;
+$u-button-info-border-style: solid !default;
+$u-button-success-color: #fff !default;
+$u-button-success-background-color: $u-success !default;
+$u-button-success-border-color: $u-button-success-background-color !default;
+$u-button-success-border-width: 1px !default;
+$u-button-success-border-style: solid !default;
+$u-button-primary-color: #fff !default;
+$u-button-primary-background-color: $u-primary !default;
+$u-button-primary-border-color: $u-button-primary-background-color !default;
+$u-button-primary-border-width: 1px !default;
+$u-button-primary-border-style: solid !default;
+$u-button-error-color: #fff !default;
+$u-button-error-background-color: $u-error !default;
+$u-button-error-border-color: $u-button-error-background-color !default;
+$u-button-error-border-width: 1px !default;
+$u-button-error-border-style: solid !default;
+$u-button-warning-color: #fff !default;
+$u-button-warning-background-color: $u-warning !default;
+$u-button-warning-border-color: $u-button-warning-background-color !default;
+$u-button-warning-border-width: 1px !default;
+$u-button-warning-border-style: solid !default;
+$u-button-block-width: 100% !default;
+$u-button-circle-border-top-right-radius: 100px !default;
+$u-button-circle-border-top-left-radius: 100px !default;
+$u-button-circle-border-bottom-left-radius: 100px !default;
+$u-button-circle-border-bottom-right-radius: 100px !default;
+$u-button-square-border-top-right-radius: 3px !default;
+$u-button-square-border-top-left-radius: 3px !default;
+$u-button-square-border-bottom-left-radius: 3px !default;
+$u-button-square-border-bottom-right-radius: 3px !default;
+$u-button-icon-min-width: 1em !default;
+$u-button-plain-background-color: #fff !default;
+$u-button-hairline-border-width: 0.5px !default;
+
+.u-button {
+ height: $u-button-u-button-height;
+ position: relative;
+ align-items: center;
+ justify-content: center;
+ @include flex;
+ /* #ifndef APP-NVUE */
+ box-sizing: border-box;
+ /* #endif */
+ flex-direction: row;
+
+ &__text {
+ font-size: $u-button-text-font-size;
+ }
+
+ &__loading-text {
+ font-size: $u-button-loading-text-font-size;
+ margin-left: $u-button-loading-text-margin-left;
+ }
+
+ &--large {
+ /* #ifndef APP-NVUE */
+ width: $u-button-large-width;
+ /* #endif */
+ height: $u-button-large-height;
+ padding: $u-button-large-padding;
+ }
+
+ &--normal {
+ padding: $u-button-normal-padding;
+ font-size: $u-button-normal-font-size;
+ }
+
+ &--small {
+ /* #ifndef APP-NVUE */
+ min-width: $u-button-small-min-width;
+ /* #endif */
+ height: $u-button-small-height;
+ padding: $u-button-small-padding;
+ font-size: $u-button-small-font-size;
+ }
+
+ &--mini {
+ height: $u-button-mini-height;
+ font-size: $u-button-mini-font-size;
+ /* #ifndef APP-NVUE */
+ min-width: $u-button-mini-min-width;
+ /* #endif */
+ padding: $u-button-mini-padding;
+ }
+
+ &--disabled {
+ opacity: $u-button-disabled-opacity;
+ }
+
+ &--info {
+ color: $u-button-info-color;
+ background-color: $u-button-info-background-color;
+ border-color: $u-button-info-border-color;
+ border-width: $u-button-info-border-width;
+ border-style: $u-button-info-border-style;
+ }
+
+ &--success {
+ color: $u-button-success-color;
+ background-color: $u-button-success-background-color;
+ border-color: $u-button-success-border-color;
+ border-width: $u-button-success-border-width;
+ border-style: $u-button-success-border-style;
+ }
+
+ &--primary {
+ color: $u-button-primary-color;
+ background-color: $u-button-primary-background-color;
+ border-color: $u-button-primary-border-color;
+ border-width: $u-button-primary-border-width;
+ border-style: $u-button-primary-border-style;
+ }
+
+ &--error {
+ color: $u-button-error-color;
+ background-color: $u-button-error-background-color;
+ border-color: $u-button-error-border-color;
+ border-width: $u-button-error-border-width;
+ border-style: $u-button-error-border-style;
+ }
+
+ &--warning {
+ color: $u-button-warning-color;
+ background-color: $u-button-warning-background-color;
+ border-color: $u-button-warning-border-color;
+ border-width: $u-button-warning-border-width;
+ border-style: $u-button-warning-border-style;
+ }
+
+ &--block {
+ @include flex;
+ width: $u-button-block-width;
+ }
+
+ &--circle {
+ border-top-right-radius: $u-button-circle-border-top-right-radius;
+ border-top-left-radius: $u-button-circle-border-top-left-radius;
+ border-bottom-left-radius: $u-button-circle-border-bottom-left-radius;
+ border-bottom-right-radius: $u-button-circle-border-bottom-right-radius;
+ }
+
+ &--square {
+ border-bottom-left-radius: $u-button-square-border-top-right-radius;
+ border-bottom-right-radius: $u-button-square-border-top-left-radius;
+ border-top-left-radius: $u-button-square-border-bottom-left-radius;
+ border-top-right-radius: $u-button-square-border-bottom-right-radius;
+ }
+
+ &__icon {
+ /* #ifndef APP-NVUE */
+ min-width: $u-button-icon-min-width;
+ line-height: inherit !important;
+ vertical-align: top;
+ /* #endif */
+ }
+
+ &--plain {
+ background-color: $u-button-plain-background-color;
+ }
+
+ &--hairline {
+ border-width: $u-button-hairline-border-width !important;
+ }
+}
+</style>
diff --git a/uni_modules/uview-ui/components/u-button/vue.scss b/uni_modules/uview-ui/components/u-button/vue.scss
new file mode 100644
index 0000000..32019b2
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-button/vue.scss
@@ -0,0 +1,80 @@
+// nvue���hover-class������
+$u-button-before-top:50% !default;
+$u-button-before-left:50% !default;
+$u-button-before-width:100% !default;
+$u-button-before-height:100% !default;
+$u-button-before-transform:translate(-50%, -50%) !default;
+$u-button-before-opacity:0 !default;
+$u-button-before-background-color:#000 !default;
+$u-button-before-border-color:#000 !default;
+$u-button-active-before-opacity:.15 !default;
+$u-button-icon-margin-left:4px !default;
+$u-button-plain-u-button-info-color:$u-info;
+$u-button-plain-u-button-success-color:$u-success;
+$u-button-plain-u-button-error-color:$u-error;
+$u-button-plain-u-button-warning-color:$u-error;
+
+.u-button {
+ width: 100%;
+
+ &__text {
+ white-space: nowrap;
+ line-height: 1;
+ }
+
+ &:before {
+ position: absolute;
+ top:$u-button-before-top;
+ left:$u-button-before-left;
+ width:$u-button-before-width;
+ height:$u-button-before-height;
+ border: inherit;
+ border-radius: inherit;
+ transform:$u-button-before-transform;
+ opacity:$u-button-before-opacity;
+ content: " ";
+ background-color:$u-button-before-background-color;
+ border-color:$u-button-before-border-color;
+ }
+
+ &--active {
+ &:before {
+ opacity: .15
+ }
+ }
+
+ &__icon+&__text:not(:empty),
+ &__loading-text {
+ margin-left:$u-button-icon-margin-left;
+ }
+
+ &--plain {
+ &.u-button--primary {
+ color: $u-primary;
+ }
+ }
+
+ &--plain {
+ &.u-button--info {
+ color:$u-button-plain-u-button-info-color;
+ }
+ }
+
+ &--plain {
+ &.u-button--success {
+ color:$u-button-plain-u-button-success-color;
+ }
+ }
+
+ &--plain {
+ &.u-button--error {
+ color:$u-button-plain-u-button-error-color;
+ }
+ }
+
+ &--plain {
+ &.u-button--warning {
+ color:$u-button-plain-u-button-warning-color;
+ }
+ }
+}
diff --git a/uni_modules/uview-ui/components/u-calendar/header.vue b/uni_modules/uview-ui/components/u-calendar/header.vue
new file mode 100644
index 0000000..dc4f7d0
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-calendar/header.vue
@@ -0,0 +1,99 @@
+<template>
+ <view class="u-calendar-header u-border-bottom">
+ <text
+ class="u-calendar-header__title"
+ v-if="showTitle"
+ >{{ title }}</text>
+ <text
+ class="u-calendar-header__subtitle"
+ v-if="showSubtitle"
+ >{{ subtitle }}</text>
+ <view class="u-calendar-header__weekdays">
+ <text class="u-calendar-header__weekdays__weekday">���</text>
+ <text class="u-calendar-header__weekdays__weekday">���</text>
+ <text class="u-calendar-header__weekdays__weekday">���</text>
+ <text class="u-calendar-header__weekdays__weekday">���</text>
+ <text class="u-calendar-header__weekdays__weekday">���</text>
+ <text class="u-calendar-header__weekdays__weekday">���</text>
+ <text class="u-calendar-header__weekdays__weekday">���</text>
+ </view>
+ </view>
+</template>
+
+<script>
+ export default {
+ name: 'u-calendar-header',
+ mixins: [uni.$u.mpMixin, uni.$u.mixin],
+ props: {
+ // ������
+ title: {
+ type: String,
+ default: ''
+ },
+ // ���������
+ subtitle: {
+ type: String,
+ default: ''
+ },
+ // ������������������
+ showTitle: {
+ type: Boolean,
+ default: true
+ },
+ // ���������������������
+ showSubtitle: {
+ type: Boolean,
+ default: true
+ },
+ },
+ data() {
+ return {
+
+ }
+ },
+ methods: {
+ name() {
+
+ }
+ },
+ }
+</script>
+
+<style lang="scss" scoped>
+ @import "../../libs/css/components.scss";
+
+ .u-calendar-header {
+ padding-bottom: 4px;
+
+ &__title {
+ font-size: 16px;
+ color: $u-main-color;
+ text-align: center;
+ height: 42px;
+ line-height: 42px;
+ font-weight: bold;
+ }
+
+ &__subtitle {
+ font-size: 14px;
+ color: $u-main-color;
+ height: 40px;
+ text-align: center;
+ line-height: 40px;
+ font-weight: bold;
+ }
+
+ &__weekdays {
+ @include flex;
+ justify-content: space-between;
+
+ &__weekday {
+ font-size: 13px;
+ color: $u-main-color;
+ line-height: 30px;
+ flex: 1;
+ text-align: center;
+ }
+ }
+ }
+</style>
diff --git a/uni_modules/uview-ui/components/u-calendar/month.vue b/uni_modules/uview-ui/components/u-calendar/month.vue
new file mode 100644
index 0000000..c20937f
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-calendar/month.vue
@@ -0,0 +1,579 @@
+<template>
+ <view class="u-calendar-month-wrapper" ref="u-calendar-month-wrapper">
+ <view v-for="(item, index) in months" :key="index" :class="[`u-calendar-month-${index}`]"
+ :ref="`u-calendar-month-${index}`" :id="`month-${index}`">
+ <text v-if="index !== 0" class="u-calendar-month__title">{{ item.year }}���{{ item.month }}���</text>
+ <view class="u-calendar-month__days">
+ <view v-if="showMark" class="u-calendar-month__days__month-mark-wrapper">
+ <text class="u-calendar-month__days__month-mark-wrapper__text">{{ item.month }}</text>
+ </view>
+ <view class="u-calendar-month__days__day" v-for="(item1, index1) in item.date" :key="index1"
+ :style="[dayStyle(index, index1, item1)]" @tap="clickHandler(index, index1, item1)"
+ :class="[item1.selected && 'u-calendar-month__days__day__select--selected']">
+ <view class="u-calendar-month__days__day__select" :style="[daySelectStyle(index, index1, item1)]">
+ <text class="u-calendar-month__days__day__select__info"
+ :class="[item1.disabled && 'u-calendar-month__days__day__select__info--disabled']"
+ :style="[textStyle(item1)]">{{ item1.day }}</text>
+ <text v-if="getBottomInfo(index, index1, item1)"
+ class="u-calendar-month__days__day__select__buttom-info"
+ :class="[item1.disabled && 'u-calendar-month__days__day__select__buttom-info--disabled']"
+ :style="[textStyle(item1)]">{{ getBottomInfo(index, index1, item1) }}</text>
+ <text v-if="item1.dot" class="u-calendar-month__days__day__select__dot"></text>
+ </view>
+ </view>
+ </view>
+ </view>
+ </view>
+</template>
+
+<script>
+ // #ifdef APP-NVUE
+ // ������nvue���������������������������������������������������������������������������
+ const dom = uni.requireNativePlugin('dom')
+ // #endif
+ import dayjs from '../../libs/util/dayjs.js';
+ export default {
+ name: 'u-calendar-month',
+ mixins: [uni.$u.mpMixin, uni.$u.mixin],
+ props: {
+ // ���������������������������
+ showMark: {
+ type: Boolean,
+ default: true
+ },
+ // ������������������������������������������������
+ color: {
+ type: String,
+ default: '#3c9cff'
+ },
+ // ������������
+ months: {
+ type: Array,
+ default: () => []
+ },
+ // ������������������
+ mode: {
+ type: String,
+ default: 'single'
+ },
+ // ������������
+ rowHeight: {
+ type: [String, Number],
+ default: 58
+ },
+ // mode=multiple���������������������������������
+ maxCount: {
+ type: [String, Number],
+ default: Infinity
+ },
+ // mode=range������������������������������������������
+ startText: {
+ type: String,
+ default: '������'
+ },
+ // mode=range���������������������������������������������
+ endText: {
+ type: String,
+ default: '������'
+ },
+ // ������������������������mode���multiple���range������������������������
+ defaultDate: {
+ type: [Array, String, Date],
+ default: null
+ },
+ // ���������������������
+ minDate: {
+ type: [String, Number],
+ default: 0
+ },
+ // ������������������
+ maxDate: {
+ type: [String, Number],
+ default: 0
+ },
+ // ������������������maxDate���������������������������
+ maxMonth: {
+ type: [String, Number],
+ default: 2
+ },
+ // ���������������������������������������������������������
+ readonly: {
+ type: Boolean,
+ default: uni.$u.props.calendar.readonly
+ },
+ // ���������������������������������������������������mode = range���������
+ maxRange: {
+ type: [Number, String],
+ default: Infinity
+ },
+ // ���������������������������������������������������������mode = range���������
+ rangePrompt: {
+ type: String,
+ default: ''
+ },
+ // ���������������������������������������������������������������������mode = range���������
+ showRangePrompt: {
+ type: Boolean,
+ default: true
+ },
+ // ������������������������������������������������������mode = range���������
+ allowSameDay: {
+ type: Boolean,
+ default: false
+ }
+ },
+ data() {
+ return {
+ // ���������������������
+ width: 0,
+ // ���������������������item
+ item: {},
+ selected: []
+ }
+ },
+ watch: {
+ selectedChange: {
+ immediate: true,
+ handler(n) {
+ this.setDefaultDate()
+ }
+ }
+ },
+ computed: {
+ // ���������������������������������������������������������������������������������
+ selectedChange() {
+ return [this.minDate, this.maxDate, this.defaultDate]
+ },
+ dayStyle(index1, index2, item) {
+ return (index1, index2, item) => {
+ const style = {}
+ let week = item.week
+ // ������������������������������������2���������
+ const dayWidth = Number(parseFloat(this.width / 7).toFixed(3).slice(0, -1))
+ // ���������������������������
+ // #ifdef APP-NVUE
+ style.width = uni.$u.addUnit(dayWidth)
+ // #endif
+ style.height = uni.$u.addUnit(this.rowHeight)
+ if (index2 === 0) {
+ // ������������������������������������0������������������������������������������������������������������������item������
+ week = (week === 0 ? 7 : week) - 1
+ style.marginLeft = uni.$u.addUnit(week * dayWidth)
+ }
+ if (this.mode === 'range') {
+ // ������������������������������������DCloud���������iOS������������������������������������������bug
+ style.paddingLeft = 0
+ style.paddingRight = 0
+ style.paddingBottom = 0
+ style.paddingTop = 0
+ }
+ return style
+ }
+ },
+ daySelectStyle() {
+ return (index1, index2, item) => {
+ let date = dayjs(item.date).format("YYYY-MM-DD"),
+ style = {}
+ // ������date���������selected������������������������������������������0���������������dateSame���������������������������includes������
+ if (this.selected.some(item => this.dateSame(item, date))) {
+ style.backgroundColor = this.color
+ }
+ if (this.mode === 'single') {
+ if (date === this.selected[0]) {
+ // ���������������nvue������������������������������������������������������������������������������
+ style.borderTopLeftRadius = '3px'
+ style.borderBottomLeftRadius = '3px'
+ style.borderTopRightRadius = '3px'
+ style.borderBottomRightRadius = '3px'
+ }
+ } else if (this.mode === 'range') {
+ if (this.selected.length >= 2) {
+ const len = this.selected.length - 1
+ // ���������������������������������������������������
+ if (this.dateSame(date, this.selected[0])) {
+ style.borderTopLeftRadius = '3px'
+ style.borderBottomLeftRadius = '3px'
+ }
+ // ������������������������������������������������������
+ if (this.dateSame(date, this.selected[len])) {
+ style.borderTopRightRadius = '3px'
+ style.borderBottomRightRadius = '3px'
+ }
+ // ���������������������������������������������������������������������������������������������������������������������������������������
+ if (dayjs(date).isAfter(dayjs(this.selected[0])) && dayjs(date).isBefore(dayjs(this
+ .selected[len]))) {
+ style.backgroundColor = uni.$u.colorGradient(this.color, '#ffffff', 100)[90]
+ // ������������������������������������������������������������������������mark������������
+ style.opacity = 0.7
+ }
+ } else if (this.selected.length === 1) {
+ // ������������������������������������DCloud���������iOS������������������������������������������bug
+ // ������������������������������nvue���iOS���uni-app���bug���������������������������
+ style.borderTopLeftRadius = '3px'
+ style.borderBottomLeftRadius = '3px'
+ }
+ } else {
+ if (this.selected.some(item => this.dateSame(item, date))) {
+ style.borderTopLeftRadius = '3px'
+ style.borderBottomLeftRadius = '3px'
+ style.borderTopRightRadius = '3px'
+ style.borderBottomRightRadius = '3px'
+ }
+ }
+ return style
+ }
+ },
+ // ���������������������������
+ textStyle() {
+ return (item) => {
+ const date = dayjs(item.date).format("YYYY-MM-DD"),
+ style = {}
+ // ������������������������������������������
+ if (this.selected.some(item => this.dateSame(item, date))) {
+ style.color = '#ffffff'
+ }
+ if (this.mode === 'range') {
+ const len = this.selected.length - 1
+ // ���������������������������������������������������������������������������������������������������������������
+ if (dayjs(date).isAfter(dayjs(this.selected[0])) && dayjs(date).isBefore(dayjs(this
+ .selected[len]))) {
+ style.color = this.color
+ }
+ }
+ return style
+ }
+ },
+ // ���������������������������
+ getBottomInfo() {
+ return (index1, index2, item) => {
+ const date = dayjs(item.date).format("YYYY-MM-DD")
+ const bottomInfo = item.bottomInfo
+ // ������������������������������������������������������������0���
+ if (this.mode === 'range' && this.selected.length > 0) {
+ if (this.selected.length === 1) {
+ // ������������������������������������������������������������������������������������������������������������������
+ if (this.dateSame(date, this.selected[0])) return this.startText
+ else return bottomInfo
+ } else {
+ const len = this.selected.length - 1
+ // ������������������������������2���������������������������������������������������������������
+ if (this.dateSame(date, this.selected[0]) && this.dateSame(date, this.selected[1]) &&
+ len === 1) {
+ // ���������������2������������������������������������������������������������������item���
+ return `${this.startText}/${this.endText}`
+ } else if (this.dateSame(date, this.selected[0])) {
+ return this.startText
+ } else if (this.dateSame(date, this.selected[len])) {
+ return this.endText
+ } else {
+ return bottomInfo
+ }
+ }
+ } else {
+ return bottomInfo
+ }
+ }
+ }
+ },
+ mounted() {
+ this.init()
+ },
+ methods: {
+ init() {
+ // ���������������������
+ this.$emit('monthSelected', this.selected)
+ this.$nextTick(() => {
+ // ������������������������������������������������������������������������������������������������������������������������������������
+ // ������nvue������$nextTick���������100%���������
+ uni.$u.sleep(10).then(() => {
+ this.getWrapperWidth()
+ this.getMonthRect()
+ })
+ })
+ },
+ // ������������������������������
+ dateSame(date1, date2) {
+ return dayjs(date1).isSame(dayjs(date2))
+ },
+ // ������������������������������������������nvue���������������������������������������css������������������item���������
+ getWrapperWidth() {
+ // #ifdef APP-NVUE
+ dom.getComponentRect(this.$refs['u-calendar-month-wrapper'], res => {
+ this.width = res.size.width
+ })
+ // #endif
+ // #ifndef APP-NVUE
+ this.$uGetRect('.u-calendar-month-wrapper').then(size => {
+ this.width = size.width
+ })
+ // #endif
+ },
+ getMonthRect() {
+ // ������������������������������������������������������scroll-view���������������������������������������������������������
+ const promiseAllArr = this.months.map((item, index) => this.getMonthRectByPromise(
+ `u-calendar-month-${index}`))
+ // ���������������
+ Promise.all(promiseAllArr).then(
+ sizes => {
+ let height = 1
+ const topArr = []
+ for (let i = 0; i < this.months.length; i++) {
+ // ���������months���������������scroll-view���������������������������������������������������
+ topArr[i] = height
+ height += sizes[i].height
+ }
+ // ������������������������������this.months[i].top���������(������������)���������������������month���top������������������������������������������
+ this.$emit('updateMonthTop', topArr)
+ })
+ },
+ // ���������������������������������
+ getMonthRectByPromise(el) {
+ // #ifndef APP-NVUE
+ // $uGetRect���uView���������������������������������������������������������https://www.uviewui.com/js/getRect.html
+ // ���������������������this.$uGetRect���������������uni.$u.getRect������������������������������������
+ return new Promise(resolve => {
+ this.$uGetRect(`.${el}`).then(size => {
+ resolve(size)
+ })
+ })
+ // #endif
+
+ // #ifdef APP-NVUE
+ // nvue������������dom������������������������
+ // ������������promise���������������������������������������then������
+ return new Promise(resolve => {
+ dom.getComponentRect(this.$refs[el][0], res => {
+ resolve(res.size)
+ })
+ })
+ // #endif
+ },
+ // ���������������������
+ clickHandler(index1, index2, item) {
+ if (this.readonly) {
+ return;
+ }
+ this.item = item
+ const date = dayjs(item.date).format("YYYY-MM-DD")
+ if (item.disabled) return
+ // ���������������������������������������������������
+ let selected = uni.$u.deepClone(this.selected)
+ if (this.mode === 'single') {
+ // ���������������������������������������������������������������
+ selected = [date]
+ } else if (this.mode === 'multiple') {
+ if (selected.some(item => this.dateSame(item, date))) {
+ // ���������������������������������������������������������������������������������������������
+ const itemIndex = selected.findIndex(item => item === date)
+ selected.splice(itemIndex, 1)
+ } else {
+ // ������������������������������������������������������������������������������������������������������������
+ if (selected.length < this.maxCount) selected.push(date)
+ }
+ } else {
+ // ������������������
+ if (selected.length === 0 || selected.length >= 2) {
+ // ������������������0������������2���������������������������������������������������������
+ selected = [date]
+ } else if (selected.length === 1) {
+ // ���������������������������������
+ const existsDate = selected[0]
+ // ������������������������������������������������������������������������������������������������
+ if (dayjs(date).isBefore(existsDate)) {
+ selected = [date]
+ } else if (dayjs(date).isAfter(existsDate)) {
+ // ������������������������������������������������������������������������������������������
+ if(dayjs(dayjs(date).subtract(this.maxRange, 'day')).isAfter(dayjs(selected[0])) && this.showRangePrompt) {
+ if(this.rangePrompt) {
+ uni.$u.toast(this.rangePrompt)
+ } else {
+ uni.$u.toast(`������������������������ ${this.maxRange} ���`)
+ }
+ return
+ }
+ // ������������������������������������������������������������������������
+ selected.push(date)
+ const startDate = selected[0]
+ const endDate = selected[1]
+ const arr = []
+ let i = 0
+ do {
+ // ���������������������������������������������������������
+ arr.push(dayjs(startDate).add(i, 'day').format("YYYY-MM-DD"))
+ i++
+ // ���������������������������������������������������������������
+ } while (dayjs(startDate).add(i, 'day').isBefore(dayjs(endDate)))
+ // ������������������������������������computed������������������������������arr������������������������������������������������������������������������
+ arr.push(endDate)
+ selected = arr
+ } else {
+ // ���������������������������������������������������������������������������������������������������������������������
+ if (selected[0] === date && !this.allowSameDay) return
+ selected.push(date)
+ }
+ }
+ }
+ this.setSelected(selected)
+ },
+ // ������������������
+ setDefaultDate() {
+ if (!this.defaultDate) {
+ // ���������������������������������������������������������������������������������
+ const selected = [dayjs().format("YYYY-MM-DD")]
+ return this.setSelected(selected, false)
+ }
+ let defaultDate = []
+ const minDate = this.minDate || dayjs().format("YYYY-MM-DD")
+ const maxDate = this.maxDate || dayjs(minDate).add(this.maxMonth - 1, 'month').format("YYYY-MM-DD")
+ if (this.mode === 'single') {
+ // ���������������������������������������������Date���������
+ if (!uni.$u.test.array(this.defaultDate)) {
+ defaultDate = [dayjs(this.defaultDate).format("YYYY-MM-DD")]
+ } else {
+ defaultDate = [this.defaultDate[0]]
+ }
+ } else {
+ // ���������������������������������
+ if (!uni.$u.test.array(this.defaultDate)) return
+ defaultDate = this.defaultDate
+ }
+ // ���������������������������������������������������������������������������������������������
+ defaultDate = defaultDate.filter(item => {
+ return dayjs(item).isAfter(dayjs(minDate).subtract(1, 'day')) && dayjs(item).isBefore(dayjs(
+ maxDate).add(1, 'day'))
+ })
+ this.setSelected(defaultDate, false)
+ },
+ setSelected(selected, event = true) {
+ this.selected = selected
+ event && this.$emit('monthSelected', this.selected)
+ }
+ }
+ }
+</script>
+
+<style lang="scss" scoped>
+ @import "../../libs/css/components.scss";
+
+ .u-calendar-month-wrapper {
+ margin-top: 4px;
+ }
+
+ .u-calendar-month {
+
+ &__title {
+ font-size: 14px;
+ line-height: 42px;
+ height: 42px;
+ color: $u-main-color;
+ text-align: center;
+ font-weight: bold;
+ }
+
+ &__days {
+ position: relative;
+ @include flex;
+ flex-wrap: wrap;
+
+ &__month-mark-wrapper {
+ position: absolute;
+ top: 0;
+ bottom: 0;
+ left: 0;
+ right: 0;
+ @include flex;
+ justify-content: center;
+ align-items: center;
+
+ &__text {
+ font-size: 155px;
+ color: rgba(231, 232, 234, 0.83);
+ }
+ }
+
+ &__day {
+ @include flex;
+ padding: 2px;
+ /* #ifndef APP-NVUE */
+ // vue���������css���������������������������������������������������������js������������������������������������������������������
+ width: calc(100% / 7);
+ box-sizing: border-box;
+ /* #endif */
+
+ &__select {
+ flex: 1;
+ @include flex;
+ align-items: center;
+ justify-content: center;
+ position: relative;
+
+ &__dot {
+ width: 7px;
+ height: 7px;
+ border-radius: 100px;
+ background-color: $u-error;
+ position: absolute;
+ top: 12px;
+ right: 7px;
+ }
+
+ &__buttom-info {
+ color: $u-content-color;
+ text-align: center;
+ position: absolute;
+ bottom: 5px;
+ font-size: 10px;
+ text-align: center;
+ left: 0;
+ right: 0;
+
+ &--selected {
+ color: #ffffff;
+ }
+
+ &--disabled {
+ color: #cacbcd;
+ }
+ }
+
+ &__info {
+ text-align: center;
+ font-size: 16px;
+
+ &--selected {
+ color: #ffffff;
+ }
+
+ &--disabled {
+ color: #cacbcd;
+ }
+ }
+
+ &--selected {
+ background-color: $u-primary;
+ @include flex;
+ justify-content: center;
+ align-items: center;
+ flex: 1;
+ border-radius: 3px;
+ }
+
+ &--range-selected {
+ opacity: 0.3;
+ border-radius: 0;
+ }
+
+ &--range-start-selected {
+ border-top-right-radius: 0;
+ border-bottom-right-radius: 0;
+ }
+
+ &--range-end-selected {
+ border-top-left-radius: 0;
+ border-bottom-left-radius: 0;
+ }
+ }
+ }
+ }
+ }
+</style>
diff --git a/uni_modules/uview-ui/components/u-calendar/props.js b/uni_modules/uview-ui/components/u-calendar/props.js
new file mode 100644
index 0000000..2ad7bc7
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-calendar/props.js
@@ -0,0 +1,144 @@
+export default {
+ props: {
+ // ������������������
+ title: {
+ type: String,
+ default: uni.$u.props.calendar.title
+ },
+ // ������������������
+ showTitle: {
+ type: Boolean,
+ default: uni.$u.props.calendar.showTitle
+ },
+ // ���������������������
+ showSubtitle: {
+ type: Boolean,
+ default: uni.$u.props.calendar.showSubtitle
+ },
+ // ���������������������single-���������������������multiple-���������������������������range-������������������
+ mode: {
+ type: String,
+ default: uni.$u.props.calendar.mode
+ },
+ // mode=range������������������������������������������
+ startText: {
+ type: String,
+ default: uni.$u.props.calendar.startText
+ },
+ // mode=range���������������������������������������������
+ endText: {
+ type: String,
+ default: uni.$u.props.calendar.endText
+ },
+ // ���������������
+ customList: {
+ type: Array,
+ default: uni.$u.props.calendar.customList
+ },
+ // ������������������������������������������������
+ color: {
+ type: String,
+ default: uni.$u.props.calendar.color
+ },
+ // ���������������������
+ minDate: {
+ type: [String, Number],
+ default: uni.$u.props.calendar.minDate
+ },
+ // ������������������
+ maxDate: {
+ type: [String, Number],
+ default: uni.$u.props.calendar.maxDate
+ },
+ // ������������������������mode���multiple���range������������������������
+ defaultDate: {
+ type: [Array, String, Date, null],
+ default: uni.$u.props.calendar.defaultDate
+ },
+ // mode=multiple���������������������������������
+ maxCount: {
+ type: [String, Number],
+ default: uni.$u.props.calendar.maxCount
+ },
+ // ������������
+ rowHeight: {
+ type: [String, Number],
+ default: uni.$u.props.calendar.rowHeight
+ },
+ // ���������������������
+ formatter: {
+ type: [Function, null],
+ default: uni.$u.props.calendar.formatter
+ },
+ // ������������������
+ showLunar: {
+ type: Boolean,
+ default: uni.$u.props.calendar.showLunar
+ },
+ // ���������������������������
+ showMark: {
+ type: Boolean,
+ default: uni.$u.props.calendar.showMark
+ },
+ // ���������������������
+ confirmText: {
+ type: String,
+ default: uni.$u.props.calendar.confirmText
+ },
+ // ������������������������������������������
+ confirmDisabledText: {
+ type: String,
+ default: uni.$u.props.calendar.confirmDisabledText
+ },
+ // ������������������������
+ show: {
+ type: Boolean,
+ default: uni.$u.props.calendar.show
+ },
+ // ������������������������������������
+ closeOnClickOverlay: {
+ type: Boolean,
+ default: uni.$u.props.calendar.closeOnClickOverlay
+ },
+ // ���������������������������������������������������������
+ readonly: {
+ type: Boolean,
+ default: uni.$u.props.calendar.readonly
+ },
+ // ������������������������
+ showConfirm: {
+ type: Boolean,
+ default: uni.$u.props.calendar.showConfirm
+ },
+ // ���������������������������������������������������mode = range���������
+ maxRange: {
+ type: [Number, String],
+ default: uni.$u.props.calendar.maxRange
+ },
+ // ���������������������������������������������������������mode = range���������
+ rangePrompt: {
+ type: String,
+ default: uni.$u.props.calendar.rangePrompt
+ },
+ // ���������������������������������������������������������������������mode = range���������
+ showRangePrompt: {
+ type: Boolean,
+ default: uni.$u.props.calendar.showRangePrompt
+ },
+ // ������������������������������������������������������mode = range���������
+ allowSameDay: {
+ type: Boolean,
+ default: uni.$u.props.calendar.allowSameDay
+ },
+ // ���������
+ round: {
+ type: [Boolean, String, Number],
+ default: uni.$u.props.calendar.round
+ },
+ // ������������������������
+ monthNum: {
+ type: [Number, String],
+ default: 3
+ }
+ }
+}
diff --git a/uni_modules/uview-ui/components/u-calendar/u-calendar.vue b/uni_modules/uview-ui/components/u-calendar/u-calendar.vue
new file mode 100644
index 0000000..511f993
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-calendar/u-calendar.vue
@@ -0,0 +1,384 @@
+<template>
+ <u-popup
+ :show="show"
+ mode="bottom"
+ closeable
+ @close="close"
+ :round="round"
+ :closeOnClickOverlay="closeOnClickOverlay"
+ >
+ <view class="u-calendar">
+ <uHeader
+ :title="title"
+ :subtitle="subtitle"
+ :showSubtitle="showSubtitle"
+ :showTitle="showTitle"
+ ></uHeader>
+ <scroll-view
+ :style="{
+ height: $u.addUnit(listHeight)
+ }"
+ scroll-y
+ @scroll="onScroll"
+ :scroll-top="scrollTop"
+ :scrollIntoView="scrollIntoView"
+ >
+ <uMonth
+ :color="color"
+ :rowHeight="rowHeight"
+ :showMark="showMark"
+ :months="months"
+ :mode="mode"
+ :maxCount="maxCount"
+ :startText="startText"
+ :endText="endText"
+ :defaultDate="defaultDate"
+ :minDate="innerMinDate"
+ :maxDate="innerMaxDate"
+ :maxMonth="monthNum"
+ :readonly="readonly"
+ :maxRange="maxRange"
+ :rangePrompt="rangePrompt"
+ :showRangePrompt="showRangePrompt"
+ :allowSameDay="allowSameDay"
+ ref="month"
+ @monthSelected="monthSelected"
+ @updateMonthTop="updateMonthTop"
+ ></uMonth>
+ </scroll-view>
+ <slot name="footer" v-if="showConfirm">
+ <view class="u-calendar__confirm">
+ <u-button
+ shape="circle"
+ :text="
+ buttonDisabled ? confirmDisabledText : confirmText
+ "
+ :color="color"
+ @click="confirm"
+ :disabled="buttonDisabled"
+ ></u-button>
+ </view>
+ </slot>
+ </view>
+ </u-popup>
+</template>
+
+<script>
+import uHeader from './header.vue'
+import uMonth from './month.vue'
+import props from './props.js'
+import util from './util.js'
+import dayjs from '../../libs/util/dayjs.js'
+import Calendar from '../../libs/util/calendar.js'
+/**
+ * Calendar ������
+ * @description ������������������������������������������������������������������������������������������������������.
+ * @tutorial https://www.uviewui.com/components/calendar.html
+ *
+ * @property {String} title ������������ (������ ������������ )
+ * @property {Boolean} showTitle ������������������ (������ true )
+ * @property {Boolean} showSubtitle ��������������������� (������ true )
+ * @property {String} mode ������������������ single-���������������������multiple-���������������������������range-������������������ ��� ������ 'single' )
+ * @property {String} startText mode=range������������������������������������������ (������ '������' )
+ * @property {String} endText mode=range��������������������������������������������� (������ '������' )
+ * @property {Array} customList ���������������
+ * @property {String} color ������������������������������������������������ (������ ���#3c9cff' )
+ * @property {String | Number} minDate ��������������������� (������ 0 )
+ * @property {String | Number} maxDate ������������������ (������ 0 )
+ * @property {Array | String| Date} defaultDate ������������������������mode���multiple���range������������������������
+ * @property {String | Number} maxCount mode=multiple��������������������������������� (������ Number.MAX_SAFE_INTEGER )
+ * @property {String | Number} rowHeight ������������ (������ 56 )
+ * @property {Function} formatter ���������������������
+ * @property {Boolean} showLunar ������������������ (������ false )
+ * @property {Boolean} showMark ��������������������������� (������ true )
+ * @property {String} confirmText ��������������������� (������ '������' )
+ * @property {String} confirmDisabledText ������������������������������������������ (������ '������' )
+ * @property {Boolean} show ������������������������ (������ false )
+ * @property {Boolean} closeOnClickOverlay ������������������������������������ (������ false )
+ * @property {Boolean} readonly ��������������������������������������������������������� (������ false )
+ * @property {String | Number} maxRange ���������������������������������������������������mode = range���������
+ * @property {String} rangePrompt ���������������������������������������������������������mode = range���������
+ * @property {Boolean} showRangePrompt ���������������������������������������������������������������������mode = range��������� (������ true )
+ * @property {Boolean} allowSameDay ������������������������������������������������������mode = range��������� (������ false )
+ * @property {Number|String} round ��������������������������� (������ 0 )
+ * @property {Number|String} monthNum ��������������������������� (������ 3 )
+ *
+ * @event {Function()} confirm ��������������������������� ���������������������������������
+ * @event {Function()} close ��������������������� ���������������������������������������
+ * @example <u-calendar :defaultDate="defaultDateMultiple" :show="show" mode="multiple" @confirm="confirm">
+ </u-calendar>
+ * */
+export default {
+ name: 'u-calendar',
+ mixins: [uni.$u.mpMixin, uni.$u.mixin, props],
+ components: {
+ uHeader,
+ uMonth
+ },
+ data() {
+ return {
+ // ������������������������������
+ months: [],
+ // ���������������������������������������������������index������
+ monthIndex: 0,
+ // ���������������������������
+ listHeight: 0,
+ // month������������������������������
+ selected: [],
+ scrollIntoView: '',
+ scrollTop:0,
+ // ������������������
+ innerFormatter: (value) => value
+ }
+ },
+ watch: {
+ selectedChange: {
+ immediate: true,
+ handler(n) {
+ this.setMonth()
+ }
+ },
+ // ������������������������������������
+ show: {
+ immediate: true,
+ handler(n) {
+ this.setMonth()
+ }
+ }
+ },
+ computed: {
+ // ������maxDate���minDate������������������(2021-10-10)���������������(���������)���������dayjs������������������������������������������������������������������������
+ innerMaxDate() {
+ return uni.$u.test.number(this.maxDate)
+ ? Number(this.maxDate)
+ : this.maxDate
+ },
+ innerMinDate() {
+ return uni.$u.test.number(this.minDate)
+ ? Number(this.minDate)
+ : this.minDate
+ },
+ // ���������������������������������������������������������������������������������
+ selectedChange() {
+ return [this.innerMinDate, this.innerMaxDate, this.defaultDate]
+ },
+ subtitle() {
+ // ���������������this.months���������������������������������������������
+ if (this.months.length) {
+ return `${this.months[this.monthIndex].year}���${
+ this.months[this.monthIndex].month
+ }���`
+ } else {
+ return ''
+ }
+ },
+ buttonDisabled() {
+ // ���������range���������������������������������������1���������������������������������disabled������
+ if (this.mode === 'range') {
+ if (this.selected.length <= 1) {
+ return true
+ } else {
+ return false
+ }
+ } else {
+ return false
+ }
+ }
+ },
+ mounted() {
+ this.start = Date.now()
+ this.init()
+ },
+ methods: {
+ // ������������������������������������������������props������������������������ref������������
+ setFormatter(e) {
+ this.innerFormatter = e
+ },
+ // month������������������������������������������������������������
+ monthSelected(e) {
+ this.selected = e
+ if (!this.showConfirm) {
+ // ������������������������������������������������������������������������������������������������2������������������������
+ if (
+ this.mode === 'multiple' ||
+ this.mode === 'single' ||
+ (this.mode === 'range' && this.selected.length >= 2)
+ ) {
+ this.$emit('confirm', this.selected)
+ }
+ }
+ },
+ init() {
+ // ������maxDate���������������minDate
+ if (
+ this.innerMaxDate &&
+ this.innerMinDate &&
+ new Date(this.innerMaxDate).getTime() < new Date(this.innerMinDate).getTime()
+ ) {
+ return uni.$u.error('maxDate������������minDate')
+ }
+ // ���������������������
+ this.listHeight = this.rowHeight * 5 + 30
+ this.setMonth()
+ },
+ close() {
+ this.$emit('close')
+ },
+ // ������������������
+ confirm() {
+ if (!this.buttonDisabled) {
+ this.$emit('confirm', this.selected)
+ }
+ },
+ // ������������������������������������
+ getMonths(minDate, maxDate) {
+ const minYear = dayjs(minDate).year()
+ const minMonth = dayjs(minDate).month() + 1
+ const maxYear = dayjs(maxDate).year()
+ const maxMonth = dayjs(maxDate).month() + 1
+ return (maxYear - minYear) * 12 + (maxMonth - minMonth) + 1
+ },
+ // ������������������
+ setMonth() {
+ // ������������������������
+ const minDate = this.innerMinDate || dayjs().valueOf()
+ // ���������������������������������������������3������
+ const maxDate =
+ this.innerMaxDate ||
+ dayjs(minDate)
+ .add(this.monthNum - 1, 'month')
+ .valueOf()
+ // ���������������������������������������������������
+ const months = uni.$u.range(
+ 1,
+ this.monthNum,
+ this.getMonths(minDate, maxDate)
+ )
+ // ���������������
+ this.months = []
+ for (let i = 0; i < months; i++) {
+ this.months.push({
+ date: new Array(
+ dayjs(minDate).add(i, 'month').daysInMonth()
+ )
+ .fill(1)
+ .map((item, index) => {
+ // ���������������1-31
+ let day = index + 1
+ // ���������0-6���0���������
+ const week = dayjs(minDate)
+ .add(i, 'month')
+ .date(day)
+ .day()
+ const date = dayjs(minDate)
+ .add(i, 'month')
+ .date(day)
+ .format('YYYY-MM-DD')
+ let bottomInfo = ''
+ if (this.showLunar) {
+ // ���������������������������
+ const lunar = Calendar.solar2lunar(
+ dayjs(date).year(),
+ dayjs(date).month() + 1,
+ dayjs(date).date()
+ )
+ bottomInfo = lunar.IDayCn
+ }
+ let config = {
+ day,
+ week,
+ // ������������������������������������������������������������������������disabled������
+ disabled:
+ dayjs(date).isBefore(
+ dayjs(minDate).format('YYYY-MM-DD')
+ ) ||
+ dayjs(date).isAfter(
+ dayjs(maxDate).format('YYYY-MM-DD')
+ ),
+ // ���������������������������������������formatter������������������������������������������������������������
+ date: new Date(date),
+ bottomInfo,
+ dot: false,
+ month:
+ dayjs(minDate).add(i, 'month').month() + 1
+ }
+ const formatter =
+ this.formatter || this.innerFormatter
+ return formatter(config)
+ }),
+ // ���������������������
+ month: dayjs(minDate).add(i, 'month').month() + 1,
+ // ������������
+ year: dayjs(minDate).add(i, 'month').year()
+ })
+ }
+
+ },
+ // ������������������������������
+ scrollIntoDefaultMonth(selected) {
+ // ������������������������������������������
+ const _index = this.months.findIndex(({
+ year,
+ month
+ }) => {
+ month = uni.$u.padZero(month)
+ return `${year}-${month}` === selected
+ })
+ if (_index !== -1) {
+ // #ifndef MP-WEIXIN
+ this.$nextTick(() => {
+ this.scrollIntoView = `month-${_index}`
+ })
+ // #endif
+ // #ifdef MP-WEIXIN
+ this.scrollTop = this.months[_index].top || 0;
+ // #endif
+ }
+ },
+ // scroll-view������������
+ onScroll(event) {
+ // ���������������0���������������������scroll-view���������������������������������������������
+ const scrollTop = Math.max(0, event.detail.scrollTop)
+ // ���������������������������������������������������������������������������������������������������������������
+ for (let i = 0; i < this.months.length; i++) {
+ if (scrollTop >= (this.months[i].top || this.listHeight)) {
+ this.monthIndex = i
+ }
+ }
+ },
+ // ���������������top���
+ updateMonthTop(topArr = []) {
+ // ���������������������top������������onScroll������������������
+ topArr.map((item, index) => {
+ this.months[index].top = item
+ })
+
+ // ���������������������������
+ if (!this.defaultDate) {
+ // ���������������������������������������������������������������������������������
+ const selected = dayjs().format("YYYY-MM")
+ this.scrollIntoDefaultMonth(selected)
+ return
+ }
+ let selected = dayjs().format("YYYY-MM");
+ // ���������������������������������������������Date���������
+ if (!uni.$u.test.array(this.defaultDate)) {
+ selected = dayjs(this.defaultDate).format("YYYY-MM")
+ } else {
+ selected = dayjs(this.defaultDate[0]).format("YYYY-MM");
+ }
+ this.scrollIntoDefaultMonth(selected)
+ }
+ }
+}
+</script>
+
+<style lang="scss" scoped>
+@import '../../libs/css/components.scss';
+
+.u-calendar {
+ &__confirm {
+ padding: 7px 18px;
+ }
+}
+</style>
diff --git a/uni_modules/uview-ui/components/u-calendar/util.js b/uni_modules/uview-ui/components/u-calendar/util.js
new file mode 100644
index 0000000..ca4736b
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-calendar/util.js
@@ -0,0 +1,85 @@
+export default {
+ methods: {
+ // ������������������
+ setMonth() {
+ // ���������������
+ const day = dayjs(this.date).date(1).day()
+ const start = day == 0 ? 6 : day - 1
+
+ // ������������
+ const days = dayjs(this.date).endOf('month').format('D')
+
+ // ���������������
+ const prevDays = dayjs(this.date).endOf('month').subtract(1, 'month').format('D')
+
+ // ������������
+ const arr = []
+ // ������������
+ this.month = []
+
+ // ������������������
+ arr.push(
+ ...new Array(start).fill(1).map((e, i) => {
+ const day = prevDays - start + i + 1
+
+ return {
+ value: day,
+ disabled: true,
+ date: dayjs(this.date).subtract(1, 'month').date(day).format('YYYY-MM-DD')
+ }
+ })
+ )
+
+ // ������������������
+ arr.push(
+ ...new Array(days - 0).fill(1).map((e, i) => {
+ const day = i + 1
+
+ return {
+ value: day,
+ date: dayjs(this.date).date(day).format('YYYY-MM-DD')
+ }
+ })
+ )
+
+ // ���������������
+ arr.push(
+ ...new Array(42 - days - start).fill(1).map((e, i) => {
+ const day = i + 1
+
+ return {
+ value: day,
+ disabled: true,
+ date: dayjs(this.date).add(1, 'month').date(day).format('YYYY-MM-DD')
+ }
+ })
+ )
+
+ // ������������
+ for (let n = 0; n < arr.length; n += 7) {
+ this.month.push(
+ arr.slice(n, n + 7).map((e, i) => {
+ e.index = i + n
+
+ // ���������������
+ const custom = this.customList.find((c) => c.date == e.date)
+
+ // ������
+ if (this.lunar) {
+ const {
+ IDayCn,
+ IMonthCn
+ } = this.getLunar(e.date)
+ e.lunar = IDayCn == '������' ? IMonthCn : IDayCn
+ }
+
+ return {
+ ...e,
+ ...custom
+ }
+ })
+ )
+ }
+ }
+ }
+}
diff --git a/uni_modules/uview-ui/components/u-car-keyboard/props.js b/uni_modules/uview-ui/components/u-car-keyboard/props.js
new file mode 100644
index 0000000..3553647
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-car-keyboard/props.js
@@ -0,0 +1,14 @@
+export default {
+ props: {
+ // ���������������������������������
+ random: {
+ type: Boolean,
+ default: false
+ },
+ // ���������������������������������������������������
+ autoChange: {
+ type: Boolean,
+ default: false
+ }
+ }
+}
diff --git a/uni_modules/uview-ui/components/u-car-keyboard/u-car-keyboard.vue b/uni_modules/uview-ui/components/u-car-keyboard/u-car-keyboard.vue
new file mode 100644
index 0000000..51175b5
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-car-keyboard/u-car-keyboard.vue
@@ -0,0 +1,311 @@
+<template>
+ <view
+ class="u-keyboard"
+ @touchmove.stop.prevent="noop"
+ >
+ <view
+ v-for="(group, i) in abc ? engKeyBoardList : areaList"
+ :key="i"
+ class="u-keyboard__button"
+ :index="i"
+ :class="[i + 1 === 4 && 'u-keyboard__button--center']"
+ >
+ <view
+ v-if="i === 3"
+ class="u-keyboard__button__inner-wrapper"
+ >
+ <view
+ class="u-keyboard__button__inner-wrapper__left"
+ hover-class="u-hover-class"
+ :hover-stay-time="200"
+ @tap="changeCarInputMode"
+ >
+ <text
+ class="u-keyboard__button__inner-wrapper__left__lang"
+ :class="[!abc && 'u-keyboard__button__inner-wrapper__left__lang--active']"
+ >���</text>
+ <text class="u-keyboard__button__inner-wrapper__left__line">/</text>
+ <text
+ class="u-keyboard__button__inner-wrapper__left__lang"
+ :class="[abc && 'u-keyboard__button__inner-wrapper__left__lang--active']"
+ >���</text>
+ </view>
+ </view>
+ <view
+ class="u-keyboard__button__inner-wrapper"
+ v-for="(item, j) in group"
+ :key="j"
+ >
+ <view
+ class="u-keyboard__button__inner-wrapper__inner"
+ :hover-stay-time="200"
+ @tap="carInputClick(i, j)"
+ hover-class="u-hover-class"
+ >
+ <text class="u-keyboard__button__inner-wrapper__inner__text">{{ item }}</text>
+ </view>
+ </view>
+ <view
+ v-if="i === 3"
+ @touchstart="backspaceClick"
+ @touchend="clearTimer"
+ class="u-keyboard__button__inner-wrapper"
+ >
+ <view
+ class="u-keyboard__button__inner-wrapper__right"
+ hover-class="u-hover-class"
+ :hover-stay-time="200"
+ >
+ <u-icon
+ size="28"
+ name="backspace"
+ color="#303133"
+ ></u-icon>
+ </view>
+ </view>
+ </view>
+ </view>
+</template>
+
+<script>
+ import props from './props.js';
+ /**
+ * keyboard ������������
+ * @description ������uView������������������������������������������������������������������������������������3������������������������������������������������������
+ * @tutorial https://uviewui.com/components/keyboard.html
+ * @property {Boolean} random ���������������������������
+ * @event {Function} change ������������������
+ * @event {Function} backspace ���������������������
+ * @example <u-keyboard ref="uKeyboard" mode="car" v-model="show"></u-keyboard>
+ */
+ export default {
+ name: "u-keyboard",
+ mixins: [uni.$u.mpMixin, uni.$u.mixin, props],
+ data() {
+ return {
+ // ������������������abc=true������������������������bac=false���������������������������
+ abc: false
+ };
+ },
+ computed: {
+ areaList() {
+ let data = [
+ '���',
+ '���',
+ '���',
+ '���',
+ '���',
+ '���',
+ '���',
+ '���',
+ '���',
+ '���',
+ '���',
+ '���',
+ '���',
+ '���',
+ '���',
+ '���',
+ '���',
+ '���',
+ '���',
+ '���',
+ '���',
+ '���',
+ '���',
+ '���',
+ '���',
+ '���',
+ '���',
+ '���',
+ '���',
+ '���',
+ '���',
+ '���',
+ '���',
+ '���',
+ '���',
+ '���'
+ ];
+ let tmp = [];
+ // ������������
+ if (this.random) data = uni.$u.randomArray(data);
+ // ���������������������
+ tmp[0] = data.slice(0, 10);
+ tmp[1] = data.slice(10, 20);
+ tmp[2] = data.slice(20, 30);
+ tmp[3] = data.slice(30, 36);
+ return tmp;
+ },
+ engKeyBoardList() {
+ let data = [
+ 1,
+ 2,
+ 3,
+ 4,
+ 5,
+ 6,
+ 7,
+ 8,
+ 9,
+ 0,
+ 'Q',
+ 'W',
+ 'E',
+ 'R',
+ 'T',
+ 'Y',
+ 'U',
+ 'I',
+ 'O',
+ 'P',
+ 'A',
+ 'S',
+ 'D',
+ 'F',
+ 'G',
+ 'H',
+ 'J',
+ 'K',
+ 'L',
+ 'Z',
+ 'X',
+ 'C',
+ 'V',
+ 'B',
+ 'N',
+ 'M'
+ ];
+ let tmp = [];
+ if (this.random) data = uni.$u.randomArray(data);
+ tmp[0] = data.slice(0, 10);
+ tmp[1] = data.slice(10, 20);
+ tmp[2] = data.slice(20, 30);
+ tmp[3] = data.slice(30, 36);
+ return tmp;
+ }
+ },
+ methods: {
+ // ������������������
+ carInputClick(i, j) {
+ let value = '';
+ // ���������������������������������������
+ if (this.abc) value = this.engKeyBoardList[i][j];
+ else value = this.areaList[i][j];
+ // ������������������������������������������������������������
+ if (!this.abc && this.autoChange) uni.$u.sleep(200).then(() => this.abc = true)
+ this.$emit('change', value);
+ },
+ // ���������������������������������������������|������
+ changeCarInputMode() {
+ this.abc = !this.abc;
+ },
+ // ���������������
+ backspaceClick() {
+ this.$emit('backspace');
+ clearInterval(this.timer); //���������������������������������������������������
+ this.timer = null;
+ this.timer = setInterval(() => {
+ this.$emit('backspace');
+ }, 250);
+ },
+ clearTimer() {
+ clearInterval(this.timer);
+ this.timer = null;
+ },
+ }
+ };
+</script>
+
+<style lang="scss" scoped>
+ @import "../../libs/css/components.scss";
+ $u-car-keyboard-background-color: rgb(224, 228, 230) !default;
+ $u-car-keyboard-padding:6px 0 6px !default;
+ $u-car-keyboard-button-inner-width:64rpx !default;
+ $u-car-keyboard-button-inner-background-color:#FFFFFF !default;
+ $u-car-keyboard-button-height:80rpx !default;
+ $u-car-keyboard-button-inner-box-shadow:0 1px 0px #999992 !default;
+ $u-car-keyboard-button-border-radius:4px !default;
+ $u-car-keyboard-button-inner-margin:8rpx 5rpx !default;
+ $u-car-keyboard-button-text-font-size:16px !default;
+ $u-car-keyboard-button-text-color:$u-main-color !default;
+ $u-car-keyboard-center-inner-margin: 0 4rpx !default;
+ $u-car-keyboard-special-button-width:134rpx !default;
+ $u-car-keyboard-lang-font-size:16px !default;
+ $u-car-keyboard-lang-color:$u-main-color !default;
+ $u-car-keyboard-active-color:$u-primary !default;
+ $u-car-keyboard-line-font-size:15px !default;
+ $u-car-keyboard-line-color:$u-main-color !default;
+ $u-car-keyboard-line-margin:0 1px !default;
+ $u-car-keyboard-u-hover-class-background-color:#BBBCC6 !default;
+
+ .u-keyboard {
+ @include flex(column);
+ justify-content: space-around;
+ background-color: $u-car-keyboard-background-color;
+ align-items: stretch;
+ padding: $u-car-keyboard-padding;
+
+ &__button {
+ @include flex;
+ justify-content: center;
+ flex: 1;
+ /* #ifndef APP-NVUE */
+ /* #endif */
+
+ &__inner-wrapper {
+ box-shadow: $u-car-keyboard-button-inner-box-shadow;
+ margin: $u-car-keyboard-button-inner-margin;
+ border-radius: $u-car-keyboard-button-border-radius;
+
+ &__inner {
+ @include flex;
+ justify-content: center;
+ align-items: center;
+ width: $u-car-keyboard-button-inner-width;
+ background-color: $u-car-keyboard-button-inner-background-color;
+ height: $u-car-keyboard-button-height;
+ border-radius: $u-car-keyboard-button-border-radius;
+
+ &__text {
+ font-size: $u-car-keyboard-button-text-font-size;
+ color: $u-car-keyboard-button-text-color;
+ }
+ }
+
+ &__left,
+ &__right {
+ border-radius: $u-car-keyboard-button-border-radius;
+ width: $u-car-keyboard-special-button-width;
+ height: $u-car-keyboard-button-height;
+ background-color: $u-car-keyboard-u-hover-class-background-color;
+ @include flex;
+ justify-content: center;
+ align-items: center;
+ box-shadow: $u-car-keyboard-button-inner-box-shadow;
+ }
+
+ &__left {
+ &__line {
+ font-size: $u-car-keyboard-line-font-size;
+ color: $u-car-keyboard-line-color;
+ margin: $u-car-keyboard-line-margin;
+ }
+
+ &__lang {
+ font-size: $u-car-keyboard-lang-font-size;
+ color: $u-car-keyboard-lang-color;
+
+ &--active {
+ color: $u-car-keyboard-active-color;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ .u-hover-class {
+ background-color: $u-car-keyboard-u-hover-class-background-color;
+ }
+</style>
diff --git a/uni_modules/uview-ui/components/u-cell-group/props.js b/uni_modules/uview-ui/components/u-cell-group/props.js
new file mode 100644
index 0000000..350ef40
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-cell-group/props.js
@@ -0,0 +1,14 @@
+export default {
+ props: {
+ // ������������
+ title: {
+ type: String,
+ default: uni.$u.props.cellGroup.title
+ },
+ // ���������������������
+ border: {
+ type: Boolean,
+ default: uni.$u.props.cellGroup.border
+ }
+ }
+}
diff --git a/uni_modules/uview-ui/components/u-cell-group/u-cell-group.vue b/uni_modules/uview-ui/components/u-cell-group/u-cell-group.vue
new file mode 100644
index 0000000..a9508c0
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-cell-group/u-cell-group.vue
@@ -0,0 +1,61 @@
+<template>
+ <view :style="[$u.addStyle(customStyle)]" :class="[customClass]" class="u-cell-group">
+ <view v-if="title" class="u-cell-group__title">
+ <slot name="title">
+ <text class="u-cell-group__title__text">{{ title }}</text>
+ </slot>
+ </view>
+ <view class="u-cell-group__wrapper">
+ <u-line v-if="border"></u-line>
+ <slot />
+ </view>
+ </view>
+</template>
+
+<script>
+ import props from './props.js';
+ /**
+ * cellGroup ���������
+ * @description cell������������������������������������������������������������������������������������
+ * @tutorial https://uviewui.com/components/cell.html
+ *
+ * @property {String} title ������������
+ * @property {Boolean} border ��������������������� (������ true )
+ * @property {Object} customStyle ���������������������������������
+ *
+ * @event {Function} click ������cell���������������
+ * @example <u-cell-group title="������������">
+ */
+ export default {
+ name: 'u-cell-group',
+ mixins: [uni.$u.mpMixin, uni.$u.mixin,props],
+ }
+</script>
+
+<style lang="scss" scoped>
+ @import "../../libs/css/components.scss";
+
+ $u-cell-group-title-padding: 16px 16px 8px !default;
+ $u-cell-group-title-font-size: 15px !default;
+ $u-cell-group-title-line-height: 16px !default;
+ $u-cell-group-title-color: $u-main-color !default;
+
+ .u-cell-group {
+ flex: 1;
+
+ &__title {
+ padding: $u-cell-group-title-padding;
+
+ &__text {
+ font-size: $u-cell-group-title-font-size;
+ line-height: $u-cell-group-title-line-height;
+ color: $u-cell-group-title-color;
+ }
+ }
+
+ &__wrapper {
+ position: relative;
+ }
+ }
+</style>
+
diff --git a/uni_modules/uview-ui/components/u-cell/props.js b/uni_modules/uview-ui/components/u-cell/props.js
new file mode 100644
index 0000000..da03330
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-cell/props.js
@@ -0,0 +1,110 @@
+export default {
+ props: {
+ // ������
+ title: {
+ type: [String, Number],
+ default: uni.$u.props.cell.title
+ },
+ // ���������������������������
+ label: {
+ type: [String, Number],
+ default: uni.$u.props.cell.label
+ },
+ // ���������������
+ value: {
+ type: [String, Number],
+ default: uni.$u.props.cell.value
+ },
+ // ���������������������������������������(������������������������������������)
+ icon: {
+ type: String,
+ default: uni.$u.props.cell.icon
+ },
+ // ������������cell
+ disabled: {
+ type: Boolean,
+ default: uni.$u.props.cell.disabled
+ },
+ // ���������������������
+ border: {
+ type: Boolean,
+ default: uni.$u.props.cell.border
+ },
+ // ������������������������(������������������������value������)
+ center: {
+ type: Boolean,
+ default: uni.$u.props.cell.center
+ },
+ // ������������������URL������
+ url: {
+ type: String,
+ default: uni.$u.props.cell.url
+ },
+ // ������������������������������������������uView���������route������������������������������������
+ linkType: {
+ type: String,
+ default: uni.$u.props.cell.linkType
+ },
+ // ������������������������(������������������������������������)
+ clickable: {
+ type: Boolean,
+ default: uni.$u.props.cell.clickable
+ },
+ // ���������������������������������������������
+ isLink: {
+ type: Boolean,
+ default: uni.$u.props.cell.isLink
+ },
+ // ������������������������������������������(���������������������������input������)
+ required: {
+ type: Boolean,
+ default: uni.$u.props.cell.required
+ },
+ // ���������������������
+ rightIcon: {
+ type: String,
+ default: uni.$u.props.cell.rightIcon
+ },
+ // ���������������������������������������left���up���down
+ arrowDirection: {
+ type: String,
+ default: uni.$u.props.cell.arrowDirection
+ },
+ // ������������������
+ iconStyle: {
+ type: [Object, String],
+ default: () => {
+ return uni.$u.props.cell.iconStyle
+ }
+ },
+ // ���������������������������
+ rightIconStyle: {
+ type: [Object, String],
+ default: () => {
+ return uni.$u.props.cell.rightIconStyle
+ }
+ },
+ // ���������������
+ titleStyle: {
+ type: [Object, String],
+ default: () => {
+ return uni.$u.props.cell.titleStyle
+ }
+ },
+ // ���������������������������������large
+ size: {
+ type: String,
+ default: uni.$u.props.cell.size
+ },
+ // ������cell������������������������
+ stop: {
+ type: Boolean,
+ default: uni.$u.props.cell.stop
+ },
+ // ������������cell������������������
+ name: {
+ type: [Number, String],
+ default: uni.$u.props.cell.name
+ }
+ }
+}
diff --git a/uni_modules/uview-ui/components/u-cell/u-cell.vue b/uni_modules/uview-ui/components/u-cell/u-cell.vue
new file mode 100644
index 0000000..b099c90
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-cell/u-cell.vue
@@ -0,0 +1,229 @@
+<template>
+ <view class="u-cell" :class="[customClass]" :style="[$u.addStyle(customStyle)]"
+ :hover-class="(!disabled && (clickable || isLink)) ? 'u-cell--clickable' : ''" :hover-stay-time="250"
+ @tap="clickHandler">
+ <view class="u-cell__body" :class="[ center && 'u-cell--center', size === 'large' && 'u-cell__body--large']">
+ <view class="u-cell__body__content">
+ <view class="u-cell__left-icon-wrap" v-if="$slots.icon || icon">
+ <slot name="icon" v-if="$slots.icon">
+ </slot>
+ <u-icon v-else :name="icon" :custom-style="iconStyle" :size="size === 'large' ? 22 : 18"></u-icon>
+ </view>
+ <view class="u-cell__title">
+ <slot name="title">
+ <text v-if="title" class="u-cell__title-text" :style="[titleTextStyle]"
+ :class="[disabled && 'u-cell--disabled', size === 'large' && 'u-cell__title-text--large']">{{ title }}</text>
+ </slot>
+ <slot name="label">
+ <text class="u-cell__label" v-if="label"
+ :class="[disabled && 'u-cell--disabled', size === 'large' && 'u-cell__label--large']">{{ label }}</text>
+ </slot>
+ </view>
+ </view>
+ <slot name="value">
+ <text class="u-cell__value"
+ :class="[disabled && 'u-cell--disabled', size === 'large' && 'u-cell__value--large']"
+ v-if="!$u.test.empty(value)">{{ value }}</text>
+ </slot>
+ <view class="u-cell__right-icon-wrap" v-if="$slots['right-icon'] || isLink"
+ :class="[`u-cell__right-icon-wrap--${arrowDirection}`]">
+ <slot name="right-icon" v-if="$slots['right-icon']">
+ </slot>
+ <u-icon v-else :name="rightIcon" :custom-style="rightIconStyle" :color="disabled ? '#c8c9cc' : 'info'"
+ :size="size === 'large' ? 18 : 16"></u-icon>
+ </view>
+ </view>
+ <u-line v-if="border"></u-line>
+ </view>
+</template>
+
+<script>
+ import props from './props.js';
+ /**
+ * cell ���������
+ * @description cell������������������������������������������������������������������������������������
+ * @tutorial https://uviewui.com/components/cell.html
+ * @property {String | Number} title ������
+ * @property {String | Number} label ���������������������������
+ * @property {String | Number} value ���������������
+ * @property {String} icon ���������������������������������������(������������������������������������)
+ * @property {Boolean} disabled ������������cell
+ * @property {Boolean} border ��������������������� (������ true )
+ * @property {Boolean} center ������������������������(������������������������value������) (������ false )
+ * @property {String} url ������������������URL������
+ * @property {String} linkType ������������������������������������������uView���������route������������������������������������ (������ 'navigateTo' )
+ * @property {Boolean} clickable ������������������������(������������������������������������) ��������� false ���
+ * @property {Boolean} isLink ��������������������������������������������� ��������� false ���
+ * @property {Boolean} required ������������������������������������������(���������������������������input������) ��������� false ���
+ * @property {String} rightIcon ��������������������� ��������� 'arrow-right'���
+ * @property {String} arrowDirection ���������������������������������������left���up���down
+ * @property {Object | String} rightIconStyle ���������������������������
+ * @property {Object | String} titleStyle ���������������
+ * @property {Object | String} iconStyle ������������������
+ * @property {String} size ��������������������������������� large���normal���mini
+ * @property {Boolean} stop ������cell������������������������ (������ true )
+ * @property {Object} customStyle ���������������������������������
+ *
+ * @event {Function} click ������cell���������������
+ * @example ���������������������cell-group������������������������������������
+ */
+ export default {
+ name: 'u-cell',
+ data() {
+ return {
+
+ }
+ },
+ mixins: [uni.$u.mpMixin, uni.$u.mixin, props],
+ computed: {
+ titleTextStyle() {
+ return uni.$u.addStyle(this.titleStyle)
+ }
+ },
+ methods: {
+ // ������cell
+ clickHandler(e) {
+ if (this.disabled) return
+ this.$emit('click', {
+ name: this.name
+ })
+ // ���������������url(���props������������mixin������)���������������������
+ this.openPage()
+ // ������������������������
+ this.stop && this.preventEvent(e)
+ },
+ }
+ }
+</script>
+
+<style lang="scss" scoped>
+ @import "../../libs/css/components.scss";
+
+ $u-cell-padding: 10px 15px !default;
+ $u-cell-font-size: 15px !default;
+ $u-cell-line-height: 24px !default;
+ $u-cell-color: $u-main-color !default;
+ $u-cell-icon-size: 16px !default;
+ $u-cell-title-font-size: 15px !default;
+ $u-cell-title-line-height: 22px !default;
+ $u-cell-title-color: $u-main-color !default;
+ $u-cell-label-font-size: 12px !default;
+ $u-cell-label-color: $u-tips-color !default;
+ $u-cell-label-line-height: 18px !default;
+ $u-cell-value-font-size: 14px !default;
+ $u-cell-value-color: $u-content-color !default;
+ $u-cell-clickable-color: $u-bg-color !default;
+ $u-cell-disabled-color: #c8c9cc !default;
+ $u-cell-padding-top-large: 13px !default;
+ $u-cell-padding-bottom-large: 13px !default;
+ $u-cell-value-font-size-large: 15px !default;
+ $u-cell-label-font-size-large: 14px !default;
+ $u-cell-title-font-size-large: 16px !default;
+ $u-cell-left-icon-wrap-margin-right: 4px !default;
+ $u-cell-right-icon-wrap-margin-left: 4px !default;
+ $u-cell-title-flex:1 !default;
+ $u-cell-label-margin-top:5px !default;
+
+
+ .u-cell {
+ &__body {
+ @include flex();
+ /* #ifndef APP-NVUE */
+ box-sizing: border-box;
+ /* #endif */
+ padding: $u-cell-padding;
+ font-size: $u-cell-font-size;
+ color: $u-cell-color;
+ // line-height: $u-cell-line-height;
+ align-items: center;
+
+ &__content {
+ @include flex(row);
+ align-items: center;
+ flex: 1;
+ }
+
+ &--large {
+ padding-top: $u-cell-padding-top-large;
+ padding-bottom: $u-cell-padding-bottom-large;
+ }
+ }
+
+ &__left-icon-wrap,
+ &__right-icon-wrap {
+ @include flex();
+ align-items: center;
+ // height: $u-cell-line-height;
+ font-size: $u-cell-icon-size;
+ }
+
+ &__left-icon-wrap {
+ margin-right: $u-cell-left-icon-wrap-margin-right;
+ }
+
+ &__right-icon-wrap {
+ margin-left: $u-cell-right-icon-wrap-margin-left;
+ transition: transform 0.3s;
+
+ &--up {
+ transform: rotate(-90deg);
+ }
+
+ &--down {
+ transform: rotate(90deg);
+ }
+ }
+
+ &__title {
+ flex: $u-cell-title-flex;
+
+ &-text {
+ font-size: $u-cell-title-font-size;
+ line-height: $u-cell-title-line-height;
+ color: $u-cell-title-color;
+
+ &--large {
+ font-size: $u-cell-title-font-size-large;
+ }
+ }
+
+ }
+
+ &__label {
+ margin-top: $u-cell-label-margin-top;
+ font-size: $u-cell-label-font-size;
+ color: $u-cell-label-color;
+ line-height: $u-cell-label-line-height;
+
+ &--large {
+ font-size: $u-cell-label-font-size-large;
+ }
+ }
+
+ &__value {
+ text-align: right;
+ font-size: $u-cell-value-font-size;
+ line-height: $u-cell-line-height;
+ color: $u-cell-value-color;
+
+ &--large {
+ font-size: $u-cell-value-font-size-large;
+ }
+ }
+
+ &--clickable {
+ background-color: $u-cell-clickable-color;
+ }
+
+ &--disabled {
+ color: $u-cell-disabled-color;
+ /* #ifndef APP-NVUE */
+ cursor: not-allowed;
+ /* #endif */
+ }
+
+ &--center {
+ align-items: center;
+ }
+ }
+</style>
diff --git a/uni_modules/uview-ui/components/u-checkbox-group/props.js b/uni_modules/uview-ui/components/u-checkbox-group/props.js
new file mode 100644
index 0000000..2f818a1
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-checkbox-group/props.js
@@ -0,0 +1,82 @@
+export default {
+ props: {
+ // ���������
+ name: {
+ type: String,
+ default: uni.$u.props.checkboxGroup.name
+ },
+ // ������������
+ value: {
+ type: Array,
+ default: uni.$u.props.checkboxGroup.value
+ },
+ // ���������circle-���������square-������
+ shape: {
+ type: String,
+ default: uni.$u.props.checkboxGroup.shape
+ },
+ // ������������������checkbox
+ disabled: {
+ type: Boolean,
+ default: uni.$u.props.checkboxGroup.disabled
+ },
+
+ // ���������������������������������������������������������parent���activeColor���
+ activeColor: {
+ type: String,
+ default: uni.$u.props.checkboxGroup.activeColor
+ },
+ // ������������������
+ inactiveColor: {
+ type: String,
+ default: uni.$u.props.checkboxGroup.inactiveColor
+ },
+
+ // ������������������������������px
+ size: {
+ type: [String, Number],
+ default: uni.$u.props.checkboxGroup.size
+ },
+ // ���������������row-���������column-������
+ placement: {
+ type: String,
+ default: uni.$u.props.checkboxGroup.placement
+ },
+ // label������������������px������
+ labelSize: {
+ type: [String, Number],
+ default: uni.$u.props.checkboxGroup.labelSize
+ },
+ // label���������������
+ labelColor: {
+ type: [String],
+ default: uni.$u.props.checkboxGroup.labelColor
+ },
+ // ������������������������������
+ labelDisabled: {
+ type: Boolean,
+ default: uni.$u.props.checkboxGroup.labelDisabled
+ },
+ // ������������
+ iconColor: {
+ type: String,
+ default: uni.$u.props.checkboxGroup.iconColor
+ },
+ // ������������������������px
+ iconSize: {
+ type: [String, Number],
+ default: uni.$u.props.checkboxGroup.iconSize
+ },
+ // ������������������������������left-���������right-������
+ iconPlacement: {
+ type: String,
+ default: uni.$u.props.checkboxGroup.iconPlacement
+ },
+ // ���������������������������������������
+ borderBottom: {
+ type: Boolean,
+ default: uni.$u.props.checkboxGroup.borderBottom
+ }
+
+ }
+}
diff --git a/uni_modules/uview-ui/components/u-checkbox-group/u-checkbox-group.vue b/uni_modules/uview-ui/components/u-checkbox-group/u-checkbox-group.vue
new file mode 100644
index 0000000..7a6b4fa
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-checkbox-group/u-checkbox-group.vue
@@ -0,0 +1,103 @@
+<template>
+ <view
+ class="u-checkbox-group"
+ :class="bemClass"
+ >
+ <slot></slot>
+ </view>
+</template>
+
+<script>
+ import props from './props.js';
+ /**
+ * checkboxGroup ������������
+ * @description ���������������������������������������������������������������������������������������������
+ * @tutorial https://www.uviewui.com/components/checkbox.html
+ * @property {String} name ���������
+ * @property {Array} value ������������
+ * @property {String} shape ���������circle-���������square-������ ��������� 'square' ���
+ * @property {Boolean} disabled ������������������checkbox ��������� false ���
+ * @property {String} activeColor ���������������������������������������������������������parent���activeColor��� ��������� '#2979ff' ���
+ * @property {String} inactiveColor ������������������ ��������� '#c8c9cc' ���
+ * @property {String | Number} size ��������������������� ������px ��������� 18 ���
+ * @property {String} placement ���������������row-���������column-������ ��������� 'row' ���
+ * @property {String | Number} labelSize label������������������px������ ��������� 14 ���
+ * @property {String} labelColor label��������������� ��������� '#303133' ���
+ * @property {Boolean} labelDisabled ������������������������������ (������ false )
+ * @property {String} iconColor ������������ ��������� '#ffffff' ���
+ * @property {String | Number} iconSize ������������������������px ��������� 12 ���
+ * @property {String} iconPlacement ������������������������������left-���������right-������ ��������� 'left' ���
+ * @property {Boolean} borderBottom placement���row��������������������������� ��������� false ���
+ * @event {Function} change ���������checkbox���������������������������������������������������
+ * @event {Function} input ������������v-model���������������������������������������������
+ * @example <u-checkbox-group></u-checkbox-group>
+ */
+ export default {
+ name: 'u-checkbox-group',
+ mixins: [uni.$u.mpMixin, uni.$u.mixin,props],
+ computed: {
+ // ������computed���������������������������u-checkbox���������������������������������������������������������������������������������������������������������������
+ // ������������������������������������������������������parentData������������watch���������������������������������������������������������������(u-checkbox-group)
+ // ���������������������������������������
+ parentData() {
+ return [this.value, this.disabled, this.inactiveColor, this.activeColor, this.size, this.labelDisabled, this.shape,
+ this.iconSize, this.borderBottom, this.placement
+ ]
+ },
+ bemClass() {
+ // this.bem���������computed������������mixin���
+ return this.bem('checkbox-group', ['placement'])
+ },
+ },
+ watch: {
+ // ���������������������������������������������������������������������������������������
+ parentData() {
+ if (this.children.length) {
+ this.children.map(child => {
+ // ���������������(u-checkbox)���������init���������������������������(������������������������������������������������������������������)
+ typeof(child.init) === 'function' && child.init()
+ })
+ }
+ },
+ },
+ data() {
+ return {
+
+ }
+ },
+ created() {
+ this.children = []
+ },
+ methods: {
+ // ������������checkbox���������������������������
+ unCheckedOther(childInstance) {
+ const values = []
+ this.children.map(child => {
+ // ���������������checkbox������������������������
+ if (child.isChecked) {
+ values.push(child.name)
+ }
+ })
+ // ������������
+ this.$emit('change', values)
+ // ������������v-model������������
+ this.$emit('input', values)
+ },
+ }
+ }
+</script>
+
+<style lang="scss" scoped>
+ @import "../../libs/css/components.scss";
+
+ .u-checkbox-group {
+
+ &--row {
+ @include flex;
+ }
+
+ &--column {
+ @include flex(column);
+ }
+ }
+</style>
diff --git a/uni_modules/uview-ui/components/u-checkbox/props.js b/uni_modules/uview-ui/components/u-checkbox/props.js
new file mode 100644
index 0000000..93f4fd9
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-checkbox/props.js
@@ -0,0 +1,69 @@
+export default {
+ props: {
+ // checkbox���������
+ name: {
+ type: [String, Number, Boolean],
+ default: uni.$u.props.checkbox.name
+ },
+ // ���������square������������circle���������
+ shape: {
+ type: String,
+ default: uni.$u.props.checkbox.shape
+ },
+ // ���������������
+ size: {
+ type: [String, Number],
+ default: uni.$u.props.checkbox.size
+ },
+ // ������������������
+ checked: {
+ type: Boolean,
+ default: uni.$u.props.checkbox.checked
+ },
+ // ������������
+ disabled: {
+ type: [String, Boolean],
+ default: uni.$u.props.checkbox.disabled
+ },
+ // ���������������������������������������������������������parent���activeColor���
+ activeColor: {
+ type: String,
+ default: uni.$u.props.checkbox.activeColor
+ },
+ // ������������������
+ inactiveColor: {
+ type: String,
+ default: uni.$u.props.checkbox.inactiveColor
+ },
+ // ������������������������px
+ iconSize: {
+ type: [String, Number],
+ default: uni.$u.props.checkbox.iconSize
+ },
+ // ������������
+ iconColor: {
+ type: String,
+ default: uni.$u.props.checkbox.iconColor
+ },
+ // label���������������������nvue������������slot������������������������������������������������������������
+ label: {
+ type: [String, Number],
+ default: uni.$u.props.checkbox.label
+ },
+ // label������������������px������
+ labelSize: {
+ type: [String, Number],
+ default: uni.$u.props.checkbox.labelSize
+ },
+ // label���������
+ labelColor: {
+ type: String,
+ default: uni.$u.props.checkbox.labelColor
+ },
+ // ������������������������������������������
+ labelDisabled: {
+ type: [String, Boolean],
+ default: uni.$u.props.checkbox.labelDisabled
+ }
+ }
+}
diff --git a/uni_modules/uview-ui/components/u-checkbox/u-checkbox.vue b/uni_modules/uview-ui/components/u-checkbox/u-checkbox.vue
new file mode 100644
index 0000000..6429cca
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-checkbox/u-checkbox.vue
@@ -0,0 +1,344 @@
+<template>
+ <view
+ class="u-checkbox"
+ :style="[checkboxStyle]"
+ @tap.stop="wrapperClickHandler"
+ :class="[`u-checkbox-label--${parentData.iconPlacement}`, parentData.borderBottom && parentData.placement === 'column' && 'u-border-bottom']"
+ >
+ <view
+ class="u-checkbox__icon-wrap"
+ @tap.stop="iconClickHandler"
+ :class="iconClasses"
+ :style="[iconWrapStyle]"
+ >
+ <slot name="icon">
+ <u-icon
+ class="u-checkbox__icon-wrap__icon"
+ name="checkbox-mark"
+ :size="elIconSize"
+ :color="elIconColor"
+ />
+ </slot>
+ </view>
+ <text
+ @tap.stop="labelClickHandler"
+ :style="{
+ color: elDisabled ? elInactiveColor : elLabelColor,
+ fontSize: elLabelSize,
+ lineHeight: elLabelSize
+ }"
+ >{{label}}</text>
+ </view>
+</template>
+
+<script>
+ import props from './props.js';
+ /**
+ * checkbox ���������
+ * @description ���������������������������������������������������������������������������������������������
+ * @tutorial https://uviewui.com/components/checkbox.html
+ * @property {String | Number | Boolean} name checkbox������������������
+ * @property {String} shape ���������square������������circle���������
+ * @property {String | Number} size ���������������
+ * @property {Boolean} checked ������������������
+ * @property {String | Boolean} disabled ������������
+ * @property {String} activeColor ���������������������������������������������������������parent���activeColor���
+ * @property {String} inactiveColor ������������������
+ * @property {String | Number} iconSize ������������������������px
+ * @property {String} iconColor ������������
+ * @property {String | Number} label label���������������������nvue������������slot������������������������������������������������������������
+ * @property {String} labelColor label���������
+ * @property {String | Number} labelSize label������������������px������
+ * @property {String | Boolean} labelDisabled ������������������������������������������
+ * @property {Object} customStyle ���������������������������������
+ *
+ * @event {Function} change ���������checkbox���������������������������������������������������
+ * @example <u-checkbox v-model="checked" :disabled="false">������</u-checkbox>
+ */
+ export default {
+ name: "u-checkbox",
+ mixins: [uni.$u.mpMixin, uni.$u.mixin,props],
+ data() {
+ return {
+ isChecked: false,
+ // ���������������������������������������������������������computed���������this.parent.shape���������
+ // ���������������������������
+ parentData: {
+ iconSize: 12,
+ labelDisabled: null,
+ disabled: null,
+ shape: 'square',
+ activeColor: null,
+ inactiveColor: null,
+ size: 18,
+ value: null,
+ iconColor: null,
+ placement: 'row',
+ borderBottom: false,
+ iconPlacement: 'left'
+ }
+ }
+ },
+ computed: {
+ // ������������������������������u-raios-group���������������������������������������������
+ elDisabled() {
+ return this.disabled !== '' ? this.disabled : this.parentData.disabled !== null ? this.parentData.disabled : false;
+ },
+ // ������������label������
+ elLabelDisabled() {
+ return this.labelDisabled !== '' ? this.labelDisabled : this.parentData.labelDisabled !== null ? this.parentData.labelDisabled :
+ false;
+ },
+ // ���������������������size���������������������21px
+ elSize() {
+ return this.size ? this.size : (this.parentData.size ? this.parentData.size : 21);
+ },
+ // ���������������������������������������12px
+ elIconSize() {
+ return this.iconSize ? this.iconSize : (this.parentData.iconSize ? this.parentData.iconSize : 12);
+ },
+ // ������������������������������
+ elActiveColor() {
+ return this.activeColor ? this.activeColor : (this.parentData.activeColor ? this.parentData.activeColor : '#2979ff');
+ },
+ // ���������������������������������
+ elInactiveColor() {
+ return this.inactiveColor ? this.inactiveColor : (this.parentData.inactiveColor ? this.parentData.inactiveColor :
+ '#c8c9cc');
+ },
+ // label���������
+ elLabelColor() {
+ return this.labelColor ? this.labelColor : (this.parentData.labelColor ? this.parentData.labelColor : '#606266')
+ },
+ // ���������������
+ elShape() {
+ return this.shape ? this.shape : (this.parentData.shape ? this.parentData.shape : 'circle');
+ },
+ // label������
+ elLabelSize() {
+ return uni.$u.addUnit(this.labelSize ? this.labelSize : (this.parentData.labelSize ? this.parentData.labelSize :
+ '15'))
+ },
+ elIconColor() {
+ const iconColor = this.iconColor ? this.iconColor : (this.parentData.iconColor ? this.parentData.iconColor :
+ '#ffffff');
+ // ���������������
+ if (this.elDisabled) {
+ // disabled������������������������checkbox������������elInactiveColor
+ return this.isChecked ? this.elInactiveColor : 'transparent'
+ } else {
+ return this.isChecked ? iconColor : 'transparent'
+ }
+ },
+ iconClasses() {
+ let classes = []
+ // ���������������
+ classes.push('u-checkbox__icon-wrap--' + this.elShape)
+ if (this.elDisabled) {
+ classes.push('u-checkbox__icon-wrap--disabled')
+ }
+ if (this.isChecked && this.elDisabled) {
+ classes.push('u-checkbox__icon-wrap--disabled--checked')
+ }
+ // ������������������������������������������������������������������������������������������������������","������������������
+ // #ifdef MP-ALIPAY || MP-TOUTIAO
+ classes = classes.join(' ')
+ // #endif
+ return classes
+ },
+ iconWrapStyle() {
+ // checkbox���������������
+ const style = {}
+ style.backgroundColor = this.isChecked && !this.elDisabled ? this.elActiveColor : '#ffffff'
+ style.borderColor = this.isChecked && !this.elDisabled ? this.elActiveColor : this.elInactiveColor
+ style.width = uni.$u.addUnit(this.elSize)
+ style.height = uni.$u.addUnit(this.elSize)
+ // ������������������������������������������������������
+ if (this.parentData.iconPlacement === 'right') {
+ style.marginRight = 0
+ }
+ return style
+ },
+ checkboxStyle() {
+ const style = {}
+ if (this.parentData.borderBottom && this.parentData.placement === 'row') {
+ uni.$u.error('���������������borderBottom���������true������������������u-checkbox-group���placement���������column���������')
+ }
+ // ���������������������������������������������������������������������������������������������������������������
+ if (this.parentData.borderBottom && this.parentData.placement === 'column') {
+ style.paddingBottom = '8px'
+ }
+ return uni.$u.deepMerge(style, uni.$u.addStyle(this.customStyle))
+ }
+ },
+ mounted() {
+ this.init()
+ },
+ methods: {
+ init() {
+ // ���������������������������provide/inject������������������������������������������������������created���������������������������
+ this.updateParentData()
+ if (!this.parent) {
+ uni.$u.error('u-checkbox������������u-checkbox-group������������')
+ }
+ // ������������������������������������������������������������u-checkbox-group���value���������array���������������������
+ if (this.checked) {
+ this.isChecked = true
+ } else if (uni.$u.test.array(this.parentData.value)) {
+ // ���������������������������this.name���������
+ this.isChecked = this.parentData.value.some(item => {
+ return item === this.name
+ })
+ }
+ },
+ updateParentData() {
+ this.getParentData('u-checkbox-group')
+ },
+ // ������������������������������������������������������������
+ wrapperClickHandler(e) {
+ this.parentData.iconPlacement === 'right' && this.iconClickHandler(e)
+ },
+ // ������������
+ iconClickHandler(e) {
+ this.preventEvent(e)
+ // ������������������������������������������
+ if (!this.elDisabled) {
+ this.setRadioCheckedStatus()
+ }
+ },
+ // ������label
+ labelClickHandler(e) {
+ this.preventEvent(e)
+ // ���������������������������������label������������������������������������������������
+ if (!this.elLabelDisabled && !this.elDisabled) {
+ this.setRadioCheckedStatus()
+ }
+ },
+ emitEvent() {
+ this.$emit('change', this.isChecked)
+ // ������������u-form������������������������������������������������������������������������������������
+ this.$nextTick(() => {
+ uni.$u.formValidate(this, 'change')
+ })
+ },
+ // ������������������������
+ // ������������������������������������������������checked������true������������������������������������u-checkbox������
+ // ������������������������u-checkbox���checked������������false(������������������������)���������������������������������������
+ setRadioCheckedStatus() {
+ // ���������������������������������������������
+ this.isChecked = !this.isChecked
+ this.emitEvent()
+ typeof this.parent.unCheckedOther === 'function' && this.parent.unCheckedOther(this)
+ }
+ },
+ watch:{
+ checked(){
+ this.isChecked = this.checked
+ }
+ }
+ }
+</script>
+
+<style lang="scss" scoped>
+ @import "../../libs/css/components.scss";
+ $u-checkbox-icon-wrap-margin-right:6px !default;
+ $u-checkbox-icon-wrap-font-size:6px !default;
+ $u-checkbox-icon-wrap-border-width:1px !default;
+ $u-checkbox-icon-wrap-border-color:#c8c9cc !default;
+ $u-checkbox-icon-wrap-icon-line-height:0 !default;
+ $u-checkbox-icon-wrap-circle-border-radius:100% !default;
+ $u-checkbox-icon-wrap-square-border-radius:3px !default;
+ $u-checkbox-icon-wrap-checked-color:#fff !default;
+ $u-checkbox-icon-wrap-checked-background-color:red !default;
+ $u-checkbox-icon-wrap-checked-border-color:#2979ff !default;
+ $u-checkbox-icon-wrap-disabled-background-color:#ebedf0 !default;
+ $u-checkbox-icon-wrap-disabled-checked-color:#c8c9cc !default;
+ $u-checkbox-label-margin-left:5px !default;
+ $u-checkbox-label-margin-right:12px !default;
+ $u-checkbox-label-color:$u-content-color !default;
+ $u-checkbox-label-font-size:15px !default;
+ $u-checkbox-label-disabled-color:#c8c9cc !default;
+
+ .u-checkbox {
+ /* #ifndef APP-NVUE */
+ @include flex(row);
+ /* #endif */
+ overflow: hidden;
+ flex-direction: row;
+ align-items: center;
+
+ &-label--left {
+ flex-direction: row
+ }
+
+ &-label--right {
+ flex-direction: row-reverse;
+ justify-content: space-between
+ }
+
+ &__icon-wrap {
+ /* #ifndef APP-NVUE */
+ box-sizing: border-box;
+ // nvue������border-color���������������
+ transition-property: border-color, background-color, color;
+ transition-duration: 0.2s;
+ /* #endif */
+ color: $u-content-color;
+ @include flex;
+ align-items: center;
+ justify-content: center;
+ color: transparent;
+ text-align: center;
+ margin-right: $u-checkbox-icon-wrap-margin-right;
+
+ font-size: $u-checkbox-icon-wrap-font-size;
+ border-width: $u-checkbox-icon-wrap-border-width;
+ border-color: $u-checkbox-icon-wrap-border-color;
+ border-style: solid;
+
+ /* #ifdef MP-TOUTIAO */
+ // ������������������������������������������������������0���������������������
+ &__icon {
+ line-height: $u-checkbox-icon-wrap-icon-line-height;
+ }
+
+ /* #endif */
+
+ &--circle {
+ border-radius: $u-checkbox-icon-wrap-circle-border-radius;
+ }
+
+ &--square {
+ border-radius: $u-checkbox-icon-wrap-square-border-radius;
+ }
+
+ &--checked {
+ color: $u-checkbox-icon-wrap-checked-color;
+ background-color: $u-checkbox-icon-wrap-checked-background-color;
+ border-color: $u-checkbox-icon-wrap-checked-border-color;
+ }
+
+ &--disabled {
+ background-color: $u-checkbox-icon-wrap-disabled-background-color !important;
+ }
+
+ &--disabled--checked {
+ color: $u-checkbox-icon-wrap-disabled-checked-color !important;
+ }
+ }
+
+ &__label {
+ /* #ifndef APP-NVUE */
+ word-wrap: break-word;
+ /* #endif */
+ margin-left: $u-checkbox-label-margin-left;
+ margin-right: $u-checkbox-label-margin-right;
+ color: $u-checkbox-label-color;
+ font-size: $u-checkbox-label-font-size;
+
+ &--disabled {
+ color: $u-checkbox-label-disabled-color;
+ }
+ }
+ }
+</style>
diff --git a/uni_modules/uview-ui/components/u-circle-progress/props.js b/uni_modules/uview-ui/components/u-circle-progress/props.js
new file mode 100644
index 0000000..d776cfb
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-circle-progress/props.js
@@ -0,0 +1,8 @@
+export default {
+ props: {
+ percentage: {
+ type: [String, Number],
+ default: uni.$u.props.circleProgress.percentage
+ }
+ }
+}
diff --git a/uni_modules/uview-ui/components/u-circle-progress/u-circle-progress.vue b/uni_modules/uview-ui/components/u-circle-progress/u-circle-progress.vue
new file mode 100644
index 0000000..d1ee286
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-circle-progress/u-circle-progress.vue
@@ -0,0 +1,198 @@
+<template>
+ <view class="u-circle-progress">
+ <view class="u-circle-progress__left">
+ <view
+ class="u-circle-progress__left__circle"
+ :style="[leftSyle]"
+ ref="left-circle"
+ >
+
+ </view>
+ </view>
+ <view
+ class="u-circle-progress__right"
+ >
+ <view
+ class="u-circle-progress__right__circle"
+ ref="right-circle"
+ :style="[rightSyle]"
+ >
+
+ </view>
+ </view>
+ <view class="u-circle-progress__circle">
+
+ </view>
+ </view>
+</template>
+
+<script>
+ import props from './props.js';
+ // #ifdef APP-NVUE
+ const animation = uni.requireNativePlugin('animation')
+ // #endif
+ /**
+ * CircleProgress ��������������� TODO: ���������
+ * @description ������������������������������������������������������������������������������������������
+ * @tutorial https://www.uviewui.com/components/circleProgress.html
+ * @property {String | Number} percentage ���������������������������������������������0-100 (������ 30 )
+ * @example
+ */
+ export default {
+ name: 'u-circle-progress',
+ mixins: [uni.$u.mpMixin, uni.$u.mixin,props],
+ data() {
+ return {
+ leftBorderColor: 'rgb(200, 200, 200)',
+ rightBorderColor: 'rgb(200, 200, 200)',
+ }
+ },
+ computed: {
+ leftSyle() {
+ const style = {}
+ style.borderTopColor = this.leftBorderColor
+ style.borderRightColor = this.leftBorderColor
+ return style
+ },
+ rightSyle() {
+ const style = {}
+ style.borderLeftColor = this.rightBorderColor
+ style.borderBottomColor = this.rightBorderColor
+ return style
+ }
+ },
+ mounted() {
+ uni.$u.sleep().then(() => {
+ this.rightBorderColor = 'rgb(66, 185, 131)'
+ // this.init()
+ })
+ },
+ methods: {
+ init() {
+ animation.transition(this.$refs['right-circle'].ref, {
+ styles: {
+ transform: 'rotate(45deg)',
+ transformOrigin: 'center center'
+ },
+ }, () => {
+ this.rightBorderColor = 'rgb(66, 185, 131)'
+ // animation.transition(this.$refs['right-circle'].ref, {
+ // styles: {
+ // transform: 'rotate(225deg)',
+ // transformOrigin: 'center center'
+ // },
+ // duration: 3000,
+ // }, () => {
+ // animation.transition(this.$refs['left-circle'].ref, {
+ // styles: {
+ // transform: 'rotate(45deg)',
+ // transformOrigin: 'center center'
+ // },
+ // }, () => {
+ // this.leftBorderColor = 'rgb(66, 185, 131)'
+ // animation.transition(this.$refs['left-circle'].ref, {
+ // styles: {
+ // transform: 'rotate(225deg)',
+ // transformOrigin: 'center center'
+ // },
+ // duration: 1500,
+ // }, () => {
+
+ // })
+ // })
+ // })
+ })
+
+ }
+ },
+ }
+</script>
+
+<style lang="scss" scoped>
+ @import "../../libs/css/components.scss";
+
+ .u-circle-progress {
+ @include flex(row);
+ position: relative;
+ border-radius: 100px;
+ height: 100px;
+ width: 100px;
+ // transform: rotate(0deg);
+ // background-color: rgb(66, 185, 131);
+ background-color: rgb(200, 200, 200);
+ overflow: hidden;
+ justify-content: space-between;
+
+ &__circle {
+ border-radius: 100px;
+ height: 90px;
+ width: 90px;
+ transform: translate(-50%, -50%);
+ background-color: rgb(255, 255, 255);
+ left: 50px;
+ top: 50px;
+ position: absolute;
+ }
+
+ &__left {
+ position: absolute;
+ left: 0;
+ width: 50px;
+ height: 100px;
+ overflow: hidden;
+ box-sizing: border-box;
+ // background-color: rgb(66, 185, 131);
+ // background-color: rgb(200, 200, 200);
+ // transform-origin: left center;
+
+ &__circle {
+ box-sizing: border-box;
+ // background-color: red;
+ border-left-color: transparent;
+ border-bottom-color: transparent;
+ border-top-left-radius: 50px;
+ border-top-right-radius: 50px;
+ border-bottom-right-radius: 50px;
+ // border-left-color: rgb(66, 185, 131);
+ // border-bottom-color: rgb(66, 185, 131);
+ border-top-color: rgb(66, 185, 131);
+ border-right-color: rgb(66, 185, 131);
+ border-width: 5px;
+ width: 100px;
+ height: 100px;
+ transform: rotate(225deg);
+ // border-radius: 100px;
+ }
+ }
+
+ &__right {
+ position: absolute;
+ right: 0;
+ width: 50px;
+ height: 100px;
+ overflow: hidden;
+
+ &__circle {
+ position: absolute;
+ right: 0;
+ box-sizing: border-box;
+ // background-color: red;
+ border-top-color: transparent;
+ border-right-color: transparent;
+ border-top-left-radius: 50px;
+ border-bottom-left-radius: 50px;
+ border-bottom-right-radius: 50px;
+ // border-left-color: rgb(66, 185, 131);
+ // border-bottom-color: rgb(66, 185, 131);
+ border-left-color: rgb(200, 200, 200);
+ border-bottom-color: rgb(200, 200, 200);
+ border-width: 5px;
+ width: 100px;
+ height: 100px;
+ transform: rotate(45deg);
+ transform-origin: center center;
+ // border-radius: 100px;
+ }
+ }
+ }
+</style>
diff --git a/uni_modules/uview-ui/components/u-code-input/props.js b/uni_modules/uview-ui/components/u-code-input/props.js
new file mode 100644
index 0000000..0f016ee
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-code-input/props.js
@@ -0,0 +1,79 @@
+export default {
+ props: {
+ // ������������������������������������������
+ adjustPosition: {
+ type: Boolean,
+ default: uni.$u.props.codeInput.adjustPosition
+ },
+ // ������������������
+ maxlength: {
+ type: [String, Number],
+ default: uni.$u.props.codeInput.maxlength
+ },
+ // ���������������������
+ dot: {
+ type: Boolean,
+ default: uni.$u.props.codeInput.dot
+ },
+ // ���������������box-���������������line-������������������
+ mode: {
+ type: String,
+ default: uni.$u.props.codeInput.mode
+ },
+ // ���������������
+ hairline: {
+ type: Boolean,
+ default: uni.$u.props.codeInput.hairline
+ },
+ // ������������������
+ space: {
+ type: [String, Number],
+ default: uni.$u.props.codeInput.space
+ },
+ // ���������
+ value: {
+ type: [String, Number],
+ default: uni.$u.props.codeInput.value
+ },
+ // ������������������������
+ focus: {
+ type: Boolean,
+ default: uni.$u.props.codeInput.focus
+ },
+ // ������������������
+ bold: {
+ type: Boolean,
+ default: uni.$u.props.codeInput.bold
+ },
+ // ������������
+ color: {
+ type: String,
+ default: uni.$u.props.codeInput.color
+ },
+ // ������������
+ fontSize: {
+ type: [String, Number],
+ default: uni.$u.props.codeInput.fontSize
+ },
+ // ���������������������������������
+ size: {
+ type: [String, Number],
+ default: uni.$u.props.codeInput.size
+ },
+ // ������������������������������������������������������������������������������������true
+ disabledKeyboard: {
+ type: Boolean,
+ default: uni.$u.props.codeInput.disabledKeyboard
+ },
+ // ���������������������
+ borderColor: {
+ type: String,
+ default: uni.$u.props.codeInput.borderColor
+ },
+ // ������������������"."������
+ disabledDot: {
+ type: Boolean,
+ default: uni.$u.props.codeInput.disabledDot
+ }
+ }
+}
diff --git a/uni_modules/uview-ui/components/u-code-input/u-code-input.vue b/uni_modules/uview-ui/components/u-code-input/u-code-input.vue
new file mode 100644
index 0000000..96241cf
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-code-input/u-code-input.vue
@@ -0,0 +1,252 @@
+<template>
+ <view class="u-code-input">
+ <view
+ class="u-code-input__item"
+ :style="[itemStyle(index)]"
+ v-for="(item, index) in codeLength"
+ :key="index"
+ >
+ <view
+ class="u-code-input__item__dot"
+ v-if="dot && codeArray.length > index"
+ ></view>
+ <text
+ v-else
+ :style="{
+ fontSize: $u.addUnit(fontSize),
+ fontWeight: bold ? 'bold' : 'normal',
+ color: color
+ }"
+ >{{codeArray[index]}}</text>
+ <view
+ class="u-code-input__item__line"
+ v-if="mode === 'line'"
+ :style="[lineStyle]"
+ ></view>
+ <!-- #ifndef APP-PLUS -->
+ <view v-if="isFocus && codeArray.length === index" :style="{backgroundColor: color}" class="u-code-input__item__cursor"></view>
+ <!-- #endif -->
+ </view>
+ <input
+ :disabled="disabledKeyboard"
+ type="number"
+ :focus="focus"
+ :value="inputValue"
+ :maxlength="maxlength"
+ :adjustPosition="adjustPosition"
+ class="u-code-input__input"
+ @input="inputHandler"
+ :style="{
+ height: $u.addUnit(size)
+ }"
+ @focus="isFocus = true"
+ @blur="isFocus = false"
+ />
+ </view>
+</template>
+
+<script>
+ import props from './props.js';
+ /**
+ * CodeInput ���������������
+ * @description ���������������������������������������������������������������������������uView���������������������
+ * @tutorial https://www.uviewui.com/components/codeInput.html
+ * @property {String | Number} maxlength ������������������ ��������� 6 ���
+ * @property {Boolean} dot ��������������������� ��������� false ���
+ * @property {String} mode ���������������box-���������������line-������������������ ��������� 'box' ���
+ * @property {Boolean} hairline ��������������� ��������� false ���
+ * @property {String | Number} space ������������������ ��������� 10 ���
+ * @property {String | Number} value ���������
+ * @property {Boolean} focus ������������������������ ��������� false ���
+ * @property {Boolean} bold ��������������������������������� ��������� false ���
+ * @property {String} color ������������ ��������� '#606266' ���
+ * @property {String | Number} fontSize ���������������������px ��������� 18 ���
+ * @property {String | Number} size ��������������������������������� ��������� 35 ���
+ * @property {Boolean} disabledKeyboard ������������������������������������������������������������������������������������true ��������� false ���
+ * @property {String} borderColor ��������������������� ��������� '#c9cacc' ���
+ * @property {Boolean} disabledDot ������������������"."������ ��������� true ���
+ *
+ * @event {Function} change ��������������������������������������������������������� value���������������������
+ * @event {Function} finish ���������������������maxlength������������������������������ value���������������������
+ * @example <u-code-input v-model="value4" :focus="true"></u-code-input>
+ */
+ export default {
+ name: 'u-code-input',
+ mixins: [uni.$u.mpMixin, uni.$u.mixin, props],
+ data() {
+ return {
+ inputValue: '',
+ isFocus: this.focus
+ }
+ },
+ watch: {
+ value: {
+ immediate: true,
+ handler(val) {
+ // ������������������������������������
+ this.inputValue = String(val).substring(0, this.maxlength)
+ }
+ },
+ },
+ computed: {
+ // ���������������������������������������������������������������������������������v-for
+ codeLength() {
+ return new Array(Number(this.maxlength))
+ },
+ // ������item���������
+ itemStyle() {
+ return index => {
+ const addUnit = uni.$u.addUnit
+ const style = {
+ width: addUnit(this.size),
+ height: addUnit(this.size)
+ }
+ // ������������������������������������������
+ if (this.mode === 'box') {
+ // ���������������������������������������������������������0.5px������
+ style.border = `${this.hairline ? 0.5 : 1}px solid ${this.borderColor}`
+ // ���������������������0������
+ if (uni.$u.getPx(this.space) === 0) {
+ // ������������������������������������������
+ if (index === 0) {
+ style.borderTopLeftRadius = '3px'
+ style.borderBottomLeftRadius = '3px'
+ }
+ if (index === this.codeLength.length - 1) {
+ style.borderTopRightRadius = '3px'
+ style.borderBottomRightRadius = '3px'
+ }
+ // ������������������������������������������
+ if (index !== this.codeLength.length - 1) {
+ style.borderRight = 'none'
+ }
+ }
+ }
+ if (index !== this.codeLength.length - 1) {
+ // ���������������������������������������������margin-right���������������������������������������������
+ style.marginRight = addUnit(this.space)
+ } else {
+ // ������������������������������������������
+ style.marginRight = 0
+ }
+
+ return style
+ }
+ },
+ // ������������������������������������item������������������������������������������������������
+ codeArray() {
+ return String(this.inputValue).split('')
+ },
+ // ������������������������������������
+ lineStyle() {
+ const style = {}
+ style.height = this.hairline ? '2px' : '4px'
+ style.width = uni.$u.addUnit(this.size)
+ // ���������������������������������������������
+ style.backgroundColor = this.borderColor
+ return style
+ }
+ },
+ methods: {
+ // ���������������������������������
+ inputHandler(e) {
+ const value = e.detail.value
+ this.inputValue = value
+ // ���������������������.���������
+ if(this.disabledDot) {
+ this.$nextTick(() => {
+ this.inputValue = value.replace('.', '')
+ })
+ }
+ // ���������maxlength���������������change������������������������finish������
+ this.$emit('change', value)
+ // ������������v-model������������������
+ this.$emit('input', value)
+ // ������������������������������������������������������
+ if (String(value).length >= Number(this.maxlength)) {
+ this.$emit('finish', value)
+ }
+ }
+ }
+ }
+</script>
+
+<style lang="scss" scoped>
+ @import "../../libs/css/components.scss";
+ $u-code-input-cursor-width: 1px;
+ $u-code-input-cursor-height: 40%;
+ $u-code-input-cursor-animation-duration: 1s;
+ $u-code-input-cursor-animation-name: u-cursor-flicker;
+
+ .u-code-input {
+ @include flex;
+ position: relative;
+ overflow: hidden;
+
+ &__item {
+ @include flex;
+ justify-content: center;
+ align-items: center;
+ position: relative;
+
+ &__text {
+ font-size: 15px;
+ color: $u-content-color;
+ }
+
+ &__dot {
+ width: 7px;
+ height: 7px;
+ border-radius: 100px;
+ background-color: $u-content-color;
+ }
+
+ &__line {
+ position: absolute;
+ bottom: 0;
+ height: 4px;
+ border-radius: 100px;
+ width: 40px;
+ background-color: $u-content-color;
+ }
+ /* #ifndef APP-PLUS */
+ &__cursor {
+ position: absolute;
+ top: 50%;
+ left: 50%;
+ transform: translate(-50%,-50%);
+ width: $u-code-input-cursor-width;
+ height: $u-code-input-cursor-height;
+ animation: $u-code-input-cursor-animation-duration u-cursor-flicker infinite;
+ }
+ /* #endif */
+
+ }
+
+ &__input {
+ // ���������������input���������������������������������������������
+ // ������������������������������������������������������������������������������������������������������������������������
+ position: absolute;
+ left: -750rpx;
+ width: 1500rpx;
+ top: 0;
+ background-color: transparent;
+ text-align: left;
+ }
+ }
+
+ /* #ifndef APP-PLUS */
+ @keyframes u-cursor-flicker {
+ 0% {
+ opacity: 0;
+ }
+ 50% {
+ opacity: 1;
+ }
+ 100% {
+ opacity: 0;
+ }
+ }
+ /* #endif */
+
+</style>
diff --git a/uni_modules/uview-ui/components/u-code/props.js b/uni_modules/uview-ui/components/u-code/props.js
new file mode 100644
index 0000000..eaf80d0
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-code/props.js
@@ -0,0 +1,34 @@
+export default {
+ props: {
+ // ������������������
+ seconds: {
+ type: [String, Number],
+ default: uni.$u.props.code.seconds
+ },
+ // ���������������������
+ startText: {
+ type: String,
+ default: uni.$u.props.code.startText
+ },
+ // ���������������������������
+ changeText: {
+ type: String,
+ default: uni.$u.props.code.changeText
+ },
+ // ���������������������������
+ endText: {
+ type: String,
+ default: uni.$u.props.code.endText
+ },
+ // ���������H5������������������������������������������������
+ keepRunning: {
+ type: Boolean,
+ default: uni.$u.props.code.keepRunning
+ },
+ // ������������������������������������������������������������������������������������������������������
+ uniqueKey: {
+ type: String,
+ default: uni.$u.props.code.uniqueKey
+ }
+ }
+}
diff --git a/uni_modules/uview-ui/components/u-code/u-code.vue b/uni_modules/uview-ui/components/u-code/u-code.vue
new file mode 100644
index 0000000..f79a09a
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-code/u-code.vue
@@ -0,0 +1,129 @@
+<template>
+ <view class="u-code">
+ <!-- ������������������js������������������html������ -->
+ </view>
+</template>
+
+<script>
+ import props from './props.js';
+ /**
+ * Code ������������������
+ * @description ������������������������������������������������������������������������������������������������������������������������������������������ ������������������������������������������������������������������������������������������
+ * @tutorial https://www.uviewui.com/components/code.html
+ * @property {String | Number} seconds ��������������������������������� 60 ���
+ * @property {String} startText ������������������������������������������������ '���������������' ���
+ * @property {String} changeText ������������������������������������������������"x"��������������������������� 'X���������������' ���
+ * @property {String} endText ��������������������������������������������������� '������������' ���
+ * @property {Boolean} keepRunning ���������H5��������������������������������������������������� ������false ���
+ * @property {String} uniqueKey ������������������������������������������������������������������������������������������������������
+ *
+ * @event {Function} change ������������������������������������
+ * @event {Function} start ���������������������
+ * @event {Function} end ���������������������
+ * @example <u-code ref="uCode" @change="codeChange" seconds="20"></u-code>
+ */
+ export default {
+ name: "u-code",
+ mixins: [uni.$u.mpMixin, uni.$u.mixin,props],
+ data() {
+ return {
+ secNum: this.seconds,
+ timer: null,
+ canGetCode: true, // ���������������������������������
+ }
+ },
+ mounted() {
+ this.checkKeepRunning()
+ },
+ watch: {
+ seconds: {
+ immediate: true,
+ handler(n) {
+ this.secNum = n
+ }
+ }
+ },
+ methods: {
+ checkKeepRunning() {
+ // ���������������������������(H5���������������)������������������������������������������������������������������
+ let lastTimestamp = Number(uni.getStorageSync(this.uniqueKey + '_$uCountDownTimestamp'))
+ if(!lastTimestamp) return this.changeEvent(this.startText)
+ // ���������������������
+ let nowTimestamp = Math.floor((+ new Date()) / 1000)
+ // ������������������������������������������������������������������������������������������������������
+ if(this.keepRunning && lastTimestamp && lastTimestamp > nowTimestamp) {
+ // ������������������������������������
+ this.secNum = lastTimestamp - nowTimestamp
+ // ���������������������������
+ uni.removeStorageSync(this.uniqueKey + '_$uCountDownTimestamp')
+ // ���������������
+ this.start()
+ } else {
+ // ������������������������������������������������������������������������
+ this.changeEvent(this.startText)
+ }
+ },
+ // ���������������
+ start() {
+ // ������������������������������������������������������������������������������������������
+ if(this.timer) {
+ clearInterval(this.timer)
+ this.timer = null
+ }
+ this.$emit('start')
+ this.canGetCode = false
+ // ���������������������������������������������������������������setInterval���1���������������������
+ this.changeEvent(this.changeText.replace(/x|X/, this.secNum))
+ this.timer = setInterval(() => {
+ if (--this.secNum) {
+ // ������������������������������������������������������"x"������
+ this.changeEvent(this.changeText.replace(/x|X/, this.secNum))
+ } else {
+ clearInterval(this.timer)
+ this.timer = null
+ this.changeEvent(this.endText)
+ this.secNum = this.seconds
+ this.$emit('end')
+ this.canGetCode = true
+ }
+ }, 1000)
+ this.setTimeToStorage()
+ },
+ // ���������������������������������������������
+ reset() {
+ this.canGetCode = true
+ clearInterval(this.timer)
+ this.secNum = this.seconds
+ this.changeEvent(this.endText)
+ },
+ changeEvent(text) {
+ this.$emit('change', text)
+ },
+ // ������������������������������������������������������H5������������������������������������������������������
+ setTimeToStorage() {
+ if(!this.keepRunning || !this.timer) return
+ // ������������������������������������������������������������������������������������������������������
+ // ������������������������������������0���������������������������������������������������������������������������������������������������������������������
+ if(this.secNum > 0 && this.secNum <= this.seconds) {
+ // ���������������������(+ new Date()���������������)���������1000���������������������������������
+ let nowTimestamp = Math.floor((+ new Date()) / 1000)
+ // ��������������������������������������������� => ��������������� + ���������������
+ uni.setStorage({
+ key: this.uniqueKey + '_$uCountDownTimestamp',
+ data: nowTimestamp + Number(this.secNum)
+ })
+ }
+ }
+ },
+ // ���������������������������������������������������������������������������������������������������
+ beforeDestroy() {
+ this.setTimeToStorage()
+ clearTimeout(this.timer)
+ this.timer = null
+ }
+ }
+</script>
+
+<style lang="scss" scoped>
+ @import "../../libs/css/components.scss";
+</style>
diff --git a/uni_modules/uview-ui/components/u-col/props.js b/uni_modules/uview-ui/components/u-col/props.js
new file mode 100644
index 0000000..0622251
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-col/props.js
@@ -0,0 +1,29 @@
+export default {
+ props: {
+ // ���������������������������������������������12���
+ span: {
+ type: [String, Number],
+ default: uni.$u.props.col.span
+ },
+ // ������������������������������(���12���)
+ offset: {
+ type: [String, Number],
+ default: uni.$u.props.col.offset
+ },
+ // ���������������������������������`start`(���`flex-start`)���`end`(���`flex-end`)���`center`���`around`(���`space-around`)���`between`(���`space-between`)
+ justify: {
+ type: String,
+ default: uni.$u.props.col.justify
+ },
+ // ���������������������������������top���center���bottom���stretch
+ align: {
+ type: String,
+ default: uni.$u.props.col.align
+ },
+ // ������������������
+ textAlign: {
+ type: String,
+ default: uni.$u.props.col.textAlign
+ }
+ }
+}
diff --git a/uni_modules/uview-ui/components/u-col/u-col.vue b/uni_modules/uview-ui/components/u-col/u-col.vue
new file mode 100644
index 0000000..8be1517
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-col/u-col.vue
@@ -0,0 +1,162 @@
+<template>
+ <view
+ class="u-col"
+ ref="u-col"
+ :class="[
+ 'u-col-' + span
+ ]"
+ :style="[colStyle]"
+ @tap="clickHandler"
+ >
+ <slot></slot>
+ </view>
+</template>
+
+<script>
+ import props from './props.js';
+ /**
+ * CodeInput ������������������
+ * @description ���������������������Layout ������ ��������������� 12 ������������������������������������
+ * @tutorial https://www.uviewui.com/components/Layout.html
+ * @property {String | Number} span ���������������������������12������ (������ 12 )
+ * @property {String | Number} offset ������������������������������������span������ (������ 0 )
+ * @property {String} justify ���������������������������������`start`(���`flex-start`)���`end`(���`flex-end`)���`center`���`around`(���`space-around`)���`between`(���`space-between`) (������ 'start' )
+ * @property {String} align ���������������������������������top���center���bottom���stretch (������ 'stretch' )
+ * @property {String} textAlign ������������������������ (������ 'left' )
+ * @property {Object} customStyle ���������������������������������
+ * @event {Function} click col������������������������������������row
+ * @example <u-col span="3" offset="3" > <view class="demo-layout bg-purple"></view> </u-col>
+ */
+ export default {
+ name: 'u-col',
+ mixins: [uni.$u.mpMixin, uni.$u.mixin, props],
+ data() {
+ return {
+ width: 0,
+ parentData: {
+ gutter: 0
+ },
+ gridNum: 12
+ }
+ },
+ computed: {
+ uJustify() {
+ if (this.justify == 'end' || this.justify == 'start') return 'flex-' + this.justify
+ else if (this.justify == 'around' || this.justify == 'between') return 'space-' + this.justify
+ else return this.justify
+ },
+ uAlignItem() {
+ if (this.align == 'top') return 'flex-start'
+ if (this.align == 'bottom') return 'flex-end'
+ else return this.align
+ },
+ colStyle() {
+ const style = {
+ // ������������"padding: 0 10px"������������������nvue���������
+ paddingLeft: uni.$u.addUnit(uni.$u.getPx(this.parentData.gutter)/2),
+ paddingRight: uni.$u.addUnit(uni.$u.getPx(this.parentData.gutter)/2),
+ alignItems: this.uAlignItem,
+ justifyContent: this.uJustify,
+ textAlign: this.textAlign,
+ // #ifndef APP-NVUE
+ // ������nvue���������������������������
+ flex: `0 0 ${100 / this.gridNum * this.span}%`,
+ marginLeft: 100 / 12 * this.offset + '%',
+ // #endif
+ // #ifdef APP-NVUE
+ // ���nvue������������������������������������������������������������������������������������������������������������������������������
+ width: uni.$u.addUnit(Math.floor(this.width / this.gridNum * Number(this.span))),
+ marginLeft: uni.$u.addUnit(Math.floor(this.width / this.gridNum * Number(this.offset))),
+ // #endif
+ }
+ return uni.$u.deepMerge(style, uni.$u.addStyle(this.customStyle))
+ }
+ },
+ mounted() {
+ this.init()
+ },
+ methods: {
+ async init() {
+ // ���������������������������provide/inject������������������������������������������������������created���������������������������
+ this.updateParentData()
+ this.width = await this.parent.getComponentWidth()
+ },
+ updateParentData() {
+ this.getParentData('u-row')
+ },
+ clickHandler(e) {
+ this.$emit('click');
+ }
+ },
+ }
+</script>
+
+<style lang="scss" scoped>
+ @import "../../libs/css/components.scss";
+
+ .u-col {
+ padding: 0;
+ /* #ifndef APP-NVUE */
+ box-sizing:border-box;
+ /* #endif */
+ /* #ifdef MP */
+ display: block;
+ /* #endif */
+ }
+
+ // nvue������������������
+ /* #ifndef APP-NVUE */
+ .u-col-0 {
+ width: 0;
+ }
+
+ .u-col-1 {
+ width: calc(100%/12);
+ }
+
+ .u-col-2 {
+ width: calc(100%/12 * 2);
+ }
+
+ .u-col-3 {
+ width: calc(100%/12 * 3);
+ }
+
+ .u-col-4 {
+ width: calc(100%/12 * 4);
+ }
+
+ .u-col-5 {
+ width: calc(100%/12 * 5);
+ }
+
+ .u-col-6 {
+ width: calc(100%/12 * 6);
+ }
+
+ .u-col-7 {
+ width: calc(100%/12 * 7);
+ }
+
+ .u-col-8 {
+ width: calc(100%/12 * 8);
+ }
+
+ .u-col-9 {
+ width: calc(100%/12 * 9);
+ }
+
+ .u-col-10 {
+ width: calc(100%/12 * 10);
+ }
+
+ .u-col-11 {
+ width: calc(100%/12 * 11);
+ }
+
+ .u-col-12 {
+ width: calc(100%/12 * 12);
+ }
+
+ /* #endif */
+</style>
diff --git a/uni_modules/uview-ui/components/u-collapse-item/props.js b/uni_modules/uview-ui/components/u-collapse-item/props.js
new file mode 100644
index 0000000..bd5749b
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-collapse-item/props.js
@@ -0,0 +1,59 @@
+export default {
+ props: {
+ // ������
+ title: {
+ type: String,
+ default: uni.$u.props.collapseItem.title
+ },
+ // ������������������
+ value: {
+ type: String,
+ default: uni.$u.props.collapseItem.value
+ },
+ // ���������������������������
+ label: {
+ type: String,
+ default: uni.$u.props.collapseItem.label
+ },
+ // ������������������������
+ disabled: {
+ type: Boolean,
+ default: uni.$u.props.collapseItem.disabled
+ },
+ // ���������������������������������������������
+ isLink: {
+ type: Boolean,
+ default: uni.$u.props.collapseItem.isLink
+ },
+ // ������������������������
+ clickable: {
+ type: Boolean,
+ default: uni.$u.props.collapseItem.clickable
+ },
+ // ���������������������
+ border: {
+ type: Boolean,
+ default: uni.$u.props.collapseItem.border
+ },
+ // ���������������������
+ align: {
+ type: String,
+ default: uni.$u.props.collapseItem.align
+ },
+ // ���������������
+ name: {
+ type: [String, Number],
+ default: uni.$u.props.collapseItem.name
+ },
+ // ���������������������������������������������������������������
+ icon: {
+ type: String,
+ default: uni.$u.props.collapseItem.icon
+ },
+ // ������������������������������������������ms
+ duration: {
+ type: Number,
+ default: uni.$u.props.collapseItem.duration
+ }
+ }
+}
diff --git a/uni_modules/uview-ui/components/u-collapse-item/u-collapse-item.vue b/uni_modules/uview-ui/components/u-collapse-item/u-collapse-item.vue
new file mode 100644
index 0000000..0e1b703
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-collapse-item/u-collapse-item.vue
@@ -0,0 +1,225 @@
+<template>
+ <view class="u-collapse-item">
+ <u-cell
+ :title="title"
+ :value="value"
+ :label="label"
+ :icon="icon"
+ :isLink="isLink"
+ :clickable="clickable"
+ :border="parentData.border && showBorder"
+ @click="clickHandler"
+ :arrowDirection="expanded ? 'up' : 'down'"
+ :disabled="disabled"
+ >
+ <!-- #ifndef MP-WEIXIN -->
+ <!-- ��������������������������������������������������� <slot name="title" slot="title" />��������� -->
+ <template slot="title">
+ <slot name="title"></slot>
+ </template>
+ <template slot="icon">
+ <slot name="icon"></slot>
+ </template>
+ <template slot="value">
+ <slot name="value"></slot>
+ </template>
+ <template slot="right-icon">
+ <slot name="right-icon"></slot>
+ </template>
+ <!-- #endif -->
+ </u-cell>
+ <view
+ class="u-collapse-item__content"
+ :animation="animationData"
+ ref="animation"
+ >
+ <view
+ class="u-collapse-item__content__text content-class"
+ :id="elId"
+ :ref="elId"
+ ><slot /></view>
+ </view>
+ <u-line v-if="parentData.border"></u-line>
+ </view>
+</template>
+
+<script>
+ import props from './props.js';
+ // #ifdef APP-NVUE
+ const animation = uni.requireNativePlugin('animation')
+ const dom = uni.requireNativePlugin('dom')
+ // #endif
+ /**
+ * collapseItem ������������Item
+ * @description ���������������������������������������������u-collapse���������
+ * @tutorial https://www.uviewui.com/components/collapse.html
+ * @property {String} title ������
+ * @property {String} value ������������������
+ * @property {String} label ���������������������������
+ * @property {Boolean} disbled ������������������������ ( ������ false )
+ * @property {Boolean} isLink ��������������������������������������������� ( ������ true )
+ * @property {Boolean} clickable ������������������������ ( ������ true )
+ * @property {Boolean} border ��������������������� ( ������ true )
+ * @property {String} align ��������������������� ( ������ 'left' )
+ * @property {String | Number} name ���������������
+ * @property {String} icon ���������������������������������������������������������������
+ * @event {Function} change ������item������������������������������
+ * @example <u-collapse-item :title="item.head" v-for="(item, index) in itemList" :key="index">{{item.body}}</u-collapse-item>
+ */
+ export default {
+ name: "u-collapse-item",
+ mixins: [uni.$u.mpMixin, uni.$u.mixin, props],
+ data() {
+ return {
+ elId: uni.$u.guid(),
+ // uni.createAnimation���������������
+ animationData: {},
+ // ������������������
+ expanded: false,
+ // ������expanded������������������border���������������������������cell���������������������������������������������������������������
+ showBorder: false,
+ // ���������������������������������������������������������
+ animating: false,
+ // ���������u-collapse���������
+ parentData: {
+ accordion: false,
+ border: false
+ }
+ };
+ },
+ watch: {
+ expanded(n) {
+ clearTimeout(this.timer)
+ this.timer = null
+ // ������������expanded������������������������������������������cell���������������������������������
+ this.timer = setTimeout(() => {
+ this.showBorder = n
+ }, n ? 10 : 290)
+ }
+ },
+ mounted() {
+ this.init()
+ },
+ methods: {
+ // ���������������������������������������������������������������������������
+ init() {
+ // ���������������
+ this.updateParentData()
+ if (!this.parent) {
+ return uni.$u.error('u-collapse-item���������������u-collapse������������')
+ }
+ const {
+ value,
+ accordion,
+ children = []
+ } = this.parent
+
+ if (accordion) {
+ if (uni.$u.test.array(value)) {
+ return uni.$u.error('���������������������u-collapse���������value���������������������')
+ }
+ this.expanded = this.name == value
+ } else {
+ if (!uni.$u.test.array(value) && value !== null) {
+ return uni.$u.error('������������������������u-collapse���������value���������������������')
+ }
+ this.expanded = (value || []).some(item => item == this.name)
+ }
+ // ������������������������������������
+ this.$nextTick(function() {
+ this.setContentAnimate()
+ })
+ },
+ updateParentData() {
+ // ������������mixin���
+ this.getParentData('u-collapse')
+ },
+ async setContentAnimate() {
+ // ���������������������������������������������������������
+ // ���������������������������������������������������������������������������������������������������
+ const rect = await this.queryRect()
+ const height = this.expanded ? rect.height : 0
+ this.animating = true
+ // #ifdef APP-NVUE
+ const ref = this.$refs['animation'].ref
+ animation.transition(ref, {
+ styles: {
+ height: height + 'px'
+ },
+ duration: this.duration,
+ // ���������������true���������������������������������������������������������������������������������������������
+ needLayout: true,
+ timingFunction: 'ease-in-out',
+ }, () => {
+ this.animating = false
+ })
+ // #endif
+
+ // #ifndef APP-NVUE
+ const animation = uni.createAnimation({
+ timingFunction: 'ease-in-out',
+ });
+ animation
+ .height(height)
+ .step({
+ duration: this.duration,
+ })
+ .step()
+ // ������������������������������animationData���
+ this.animationData = animation.export()
+ // ������������������
+ uni.$u.sleep(this.duration).then(() => {
+ this.animating = false
+ })
+ // #endif
+ },
+ // ������collapsehead������
+ clickHandler() {
+ if (this.disabled && this.animating) return
+ // ���������������������������������
+ this.parent && this.parent.onChange(this)
+ },
+ // ������������������
+ queryRect() {
+ // #ifndef APP-NVUE
+ // $uGetRect���uView���������������������������������������������������������https://www.uviewui.com/js/getRect.html
+ // ���������������������this.$uGetRect���������������uni.$u.getRect������������������������������������
+ return new Promise(resolve => {
+ this.$uGetRect(`#${this.elId}`).then(size => {
+ resolve(size)
+ })
+ })
+ // #endif
+
+ // #ifdef APP-NVUE
+ // nvue������������dom������������������������
+ // ������������promise���������������������������������������then������
+ return new Promise(resolve => {
+ dom.getComponentRect(this.$refs[this.elId], res => {
+ resolve(res.size)
+ })
+ })
+ // #endif
+ }
+ },
+ };
+</script>
+
+<style lang="scss" scoped>
+ @import "../../libs/css/components.scss";
+
+ .u-collapse-item {
+
+ &__content {
+ overflow: hidden;
+ height: 0;
+
+ &__text {
+ padding: 12px 15px;
+ color: $u-content-color;
+ font-size: 14px;
+ line-height: 18px;
+ }
+ }
+ }
+</style>
diff --git a/uni_modules/uview-ui/components/u-collapse/props.js b/uni_modules/uview-ui/components/u-collapse/props.js
new file mode 100644
index 0000000..7ee6d31
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-collapse/props.js
@@ -0,0 +1,19 @@
+export default {
+ props: {
+ // ���������������������name������������������������[<string | number>]���������������������string | number
+ value: {
+ type: [String, Number, Array, null],
+ default: uni.$u.props.collapse.value
+ },
+ // ���������������������
+ accordion: {
+ type: Boolean,
+ default: uni.$u.props.collapse.accordion
+ },
+ // ���������������������
+ border: {
+ type: Boolean,
+ default: uni.$u.props.collapse.border
+ }
+ }
+}
diff --git a/uni_modules/uview-ui/components/u-collapse/u-collapse.vue b/uni_modules/uview-ui/components/u-collapse/u-collapse.vue
new file mode 100644
index 0000000..fc188a2
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-collapse/u-collapse.vue
@@ -0,0 +1,90 @@
+<template>
+ <view class="u-collapse">
+ <u-line v-if="border"></u-line>
+ <slot />
+ </view>
+</template>
+
+<script>
+ import props from './props.js';
+ /**
+ * collapse ������������
+ * @description ������������������������������������
+ * @tutorial https://www.uviewui.com/components/collapse.html
+ * @property {String | Number | Array} value ���������������������name������������������������[<string | number>]���������������������string | number
+ * @property {Boolean} accordion ������������������������ ������ false ���
+ * @property {Boolean} border ��������������������� ( ������ true ���
+ * @event {Function} change ���������������������������������(���������������������������������activeNames���������String������������Array)
+ * @example <u-collapse></u-collapse>
+ */
+ export default {
+ name: "u-collapse",
+ mixins: [uni.$u.mpMixin, uni.$u.mixin,props],
+ watch: {
+ needInit() {
+ this.init()
+ }
+ },
+ created() {
+ this.children = []
+ },
+ computed: {
+ needInit() {
+ // ������computed���������������accordion���value������������
+ // ���������watch���������init()������������������������������������
+ return [this.accordion, this.value]
+ }
+ },
+ watch: {
+ // ���������������������������������������������������������������������������������������
+ parentData() {
+ if (this.children.length) {
+ this.children.map(child => {
+ // ���������������(u-checkbox)���������updateParentData���������������������������(������������������������������������������������������������������)
+ typeof(child.updateParentData) === 'function' && child.updateParentData()
+ })
+ }
+ },
+ },
+ methods: {
+ // ���������������������������������������������
+ init() {
+ this.children.map(child => {
+ child.init()
+ })
+ },
+ /**
+ * collapse-item������������������������collapse���������������������������������
+ * @param {Object} target ���������������������������
+ */
+ onChange(target) {
+ let changeArr = []
+ this.children.map((child, index) => {
+ // ������������������������������������������������������������
+ if (this.accordion) {
+ child.expanded = child === target ? !target.expanded : false
+ child.setContentAnimate()
+ } else {
+ if(child === target) {
+ child.expanded = !child.expanded
+ child.setContentAnimate()
+ }
+ }
+ // ������change���������������������������������
+ changeArr.push({
+ // ������������������name���������������������������������index������
+ name: child.name || index,
+ status: child.expanded ? 'open' : 'close'
+ })
+ })
+
+ this.$emit('change', changeArr)
+ this.$emit(target.expanded ? 'open' : 'close', target.name)
+ }
+ }
+ }
+</script>
+
+<style lang="scss" scoped>
+ @import "../../libs/css/components.scss";
+</style>
diff --git a/uni_modules/uview-ui/components/u-column-notice/props.js b/uni_modules/uview-ui/components/u-column-notice/props.js
new file mode 100644
index 0000000..4809154
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-column-notice/props.js
@@ -0,0 +1,55 @@
+export default {
+ props: {
+ // ���������������������������
+ text: {
+ type: [Array],
+ default: uni.$u.props.columnNotice.text
+ },
+ // ���������������������������������
+ icon: {
+ type: String,
+ default: uni.$u.props.columnNotice.icon
+ },
+ // ���������������link-������������������closable-������������������������
+ mode: {
+ type: String,
+ default: uni.$u.props.columnNotice.mode
+ },
+ // ������������������������������������������������
+ color: {
+ type: String,
+ default: uni.$u.props.columnNotice.color
+ },
+ // ������������
+ bgColor: {
+ type: String,
+ default: uni.$u.props.columnNotice.bgColor
+ },
+ // ���������������������px
+ fontSize: {
+ type: [String, Number],
+ default: uni.$u.props.columnNotice.fontSize
+ },
+ // ������������������������������������������������������px(px)���������������������������������������������������������������������������
+ speed: {
+ type: [String, Number],
+ default: uni.$u.props.columnNotice.speed
+ },
+ // direction = row������������������������������������
+ step: {
+ type: Boolean,
+ default: uni.$u.props.columnNotice.step
+ },
+ // ���������������������������������������ms
+ duration: {
+ type: [String, Number],
+ default: uni.$u.props.columnNotice.duration
+ },
+ // ������������������������������
+ // ������HX2.6.11������������App 2.5.5+���H5 2.5.5+���������������������������������������������
+ disableTouch: {
+ type: Boolean,
+ default: uni.$u.props.columnNotice.disableTouch
+ }
+ }
+}
diff --git a/uni_modules/uview-ui/components/u-column-notice/u-column-notice.vue b/uni_modules/uview-ui/components/u-column-notice/u-column-notice.vue
new file mode 100644
index 0000000..fc39532
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-column-notice/u-column-notice.vue
@@ -0,0 +1,160 @@
+<template>
+ <view
+ class="u-notice"
+ @tap="clickHandler"
+ >
+ <slot name="icon">
+ <view
+ class="u-notice__left-icon"
+ v-if="icon"
+ >
+ <u-icon
+ :name="icon"
+ :color="color"
+ size="19"
+ ></u-icon>
+ </view>
+ </slot>
+ <swiper
+ :disable-touch="disableTouch"
+ :vertical="step ? false : true"
+ circular
+ :interval="duration"
+ :autoplay="true"
+ class="u-notice__swiper"
+ @change="noticeChange"
+ >
+ <swiper-item
+ v-for="(item, index) in text"
+ :key="index"
+ class="u-notice__swiper__item"
+ >
+ <text
+ class="u-notice__swiper__item__text u-line-1"
+ :style="[textStyle]"
+ >{{ item }}</text>
+ </swiper-item>
+ </swiper>
+ <view
+ class="u-notice__right-icon"
+ v-if="['link', 'closable'].includes(mode)"
+ >
+ <u-icon
+ v-if="mode === 'link'"
+ name="arrow-right"
+ :size="17"
+ :color="color"
+ ></u-icon>
+ <u-icon
+ v-if="mode === 'closable'"
+ name="close"
+ :size="16"
+ :color="color"
+ @click="close"
+ ></u-icon>
+ </view>
+ </view>
+</template>
+
+<script>
+ import props from './props.js';
+ /**
+ * ColumnNotice ������������������������������ ������������
+ * @description ������������������������������������������������������������������
+ * @tutorial https://www.uviewui.com/components/noticeBar.html
+ * @property {Array} text ���������������������������
+ * @property {String} icon ��������������������������������� ��� ������ 'volume' ���
+ * @property {String} mode ���������������link-������������������closable-������������������������
+ * @property {String} color ������������������������������������������������ ��� ������ '#f9ae3d' ���
+ * @property {String} bgColor ������������ ��� ������ '#fdf6ec' ���
+ * @property {String | Number} fontSize ���������������������px ��� ������ 14 ���
+ * @property {String | Number} speed ������������������������������������������������������px(rpx)��������������������������������������������������������������������������� ��� ������ 80 ���
+ * @property {Boolean} step direction = row������������������������������������ ��� ������ false ���
+ * @property {String | Number} duration ���������������������������������������ms ��� ������ 1500 ���
+ * @property {Boolean} disableTouch ������������������������������ ������HX2.6.11������������App 2.5.5+���H5 2.5.5+��������������������������������������������� ��� ������ true ���
+ * @example
+ */
+ export default {
+ mixins: [uni.$u.mpMixin, uni.$u.mixin,props],
+ watch: {
+ text: {
+ immediate: true,
+ handler(newValue, oldValue) {
+ if(!uni.$u.test.array(newValue)) {
+ uni.$u.error('noticebar������direction���column������������text���������������������')
+ }
+ }
+ }
+ },
+ computed: {
+ // ���������������������
+ textStyle() {
+ let style = {}
+ style.color = this.color
+ style.fontSize = uni.$u.addUnit(this.fontSize)
+ return style
+ },
+ // ������������������������
+ vertical() {
+ if (this.mode == 'horizontal') return false
+ else return true
+ },
+ },
+ data() {
+ return {
+ index:0
+ }
+ },
+ methods: {
+ noticeChange(e){
+ this.index = e.detail.current
+ },
+ // ���������������
+ clickHandler() {
+ this.$emit('click', this.index)
+ },
+ // ������������������
+ close() {
+ this.$emit('close')
+ }
+ }
+ };
+</script>
+
+<style lang="scss" scoped>
+ @import "../../libs/css/components.scss";
+
+ .u-notice {
+ @include flex;
+ align-items: center;
+ justify-content: space-between;
+
+ &__left-icon {
+ align-items: center;
+ margin-right: 5px;
+ }
+
+ &__right-icon {
+ margin-left: 5px;
+ align-items: center;
+ }
+
+ &__swiper {
+ height: 16px;
+ @include flex;
+ align-items: center;
+ flex: 1;
+
+ &__item {
+ @include flex;
+ align-items: center;
+ overflow: hidden;
+
+ &__text {
+ font-size: 14px;
+ color: $u-warning;
+ }
+ }
+ }
+ }
+</style>
diff --git a/uni_modules/uview-ui/components/u-count-down/props.js b/uni_modules/uview-ui/components/u-count-down/props.js
new file mode 100644
index 0000000..d62f025
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-count-down/props.js
@@ -0,0 +1,24 @@
+export default {
+ props: {
+ // ������������������������ms
+ time: {
+ type: [String, Number],
+ default: uni.$u.props.countDown.time
+ },
+ // ���������������DD-������HH-������mm-������ss-������SSS-������
+ format: {
+ type: String,
+ default: uni.$u.props.countDown.format
+ },
+ // ���������������������������
+ autoStart: {
+ type: Boolean,
+ default: uni.$u.props.countDown.autoStart
+ },
+ // ���������������������������
+ millisecond: {
+ type: Boolean,
+ default: uni.$u.props.countDown.millisecond
+ }
+ }
+}
diff --git a/uni_modules/uview-ui/components/u-count-down/u-count-down.vue b/uni_modules/uview-ui/components/u-count-down/u-count-down.vue
new file mode 100644
index 0000000..b5e85a6
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-count-down/u-count-down.vue
@@ -0,0 +1,163 @@
+<template>
+ <view class="u-count-down">
+ <slot>
+ <text class="u-count-down__text">{{ formattedTime }}</text>
+ </slot>
+ </view>
+</template>
+
+<script>
+ import props from './props.js';
+ import {
+ isSameSecond,
+ parseFormat,
+ parseTimeData
+ } from './utils';
+ /**
+ * u-count-down ���������
+ * @description ������������������������������������������������������������������������������������������������������������������������������������������������������������
+ * @tutorial https://uviewui.com/components/countDown.html
+ * @property {String | Number} time ������������������������ms ��������� 0 ���
+ * @property {String} format ���������������DD-������HH-������mm-������ss-������SSS-������ ��������� 'HH:mm:ss' ���
+ * @property {Boolean} autoStart ��������������������������� ��������� true ���
+ * @property {Boolean} millisecond ��������������������������� ��������� false ���
+ * @event {Function} finish ������������������������
+ * @event {Function} change ������������������������
+ * @event {Function} start ���������������
+ * @event {Function} pause ���������������
+ * @event {Function} reset ��������������������� auto-start ��� true������������������������������������
+ * @example <u-count-down :time="time"></u-count-down>
+ */
+ export default {
+ name: 'u-count-down',
+ mixins: [uni.$u.mpMixin, uni.$u.mixin, props],
+ data() {
+ return {
+ timer: null,
+ // ���������(������������������)������������
+ timeData: parseTimeData(0),
+ // ���������������������������"03:23:21"
+ formattedTime: '0',
+ // ������������������������������
+ runing: false,
+ endTime: 0, // ������������������������
+ remainTime: 0, // ���������������������
+ }
+ },
+ watch: {
+ time(n) {
+ this.reset()
+ }
+ },
+ mounted() {
+ this.init()
+ },
+ methods: {
+ init() {
+ this.reset()
+ },
+ // ���������������
+ start() {
+ if (this.runing) return
+ // ������������������
+ this.runing = true
+ // ��������������� = ��������������� + ���������������
+ this.endTime = Date.now() + this.remainTime
+ this.toTick()
+ },
+ // ���������������������������������������������������
+ toTick() {
+ if (this.millisecond) {
+ this.microTick()
+ } else {
+ this.macroTick()
+ }
+ },
+ macroTick() {
+ this.clearTimeout()
+ // ������������������������������������������������
+ // ���������������������������������������������������������
+ this.timer = setTimeout(() => {
+ // ������������������
+ const remain = this.getRemainTime()
+ // ������������������
+ if (!isSameSecond(remain, this.remainTime) || remain === 0) {
+ this.setRemainTime(remain)
+ }
+ // ������������������������0���������������������������������
+ if (this.remainTime !== 0) {
+ this.macroTick()
+ }
+ }, 30)
+ },
+ microTick() {
+ this.clearTimeout()
+ this.timer = setTimeout(() => {
+ this.setRemainTime(this.getRemainTime())
+ if (this.remainTime !== 0) {
+ this.microTick()
+ }
+ }, 50)
+ },
+ // ���������������������
+ getRemainTime() {
+ // ���������������������������������0������������������
+ return Math.max(this.endTime - Date.now(), 0)
+ },
+ // ���������������������
+ setRemainTime(remain) {
+ this.remainTime = remain
+ // ���������������������������������������������������������������������������������������������
+ const timeData = parseTimeData(remain)
+ this.$emit('change', timeData)
+ // ���������������������������
+ this.formattedTime = parseFormat(this.format, timeData)
+ // ������������������������������������
+ if (remain <= 0) {
+ this.pause()
+ this.$emit('finish')
+ }
+ },
+ // ���������������
+ reset() {
+ this.pause()
+ this.remainTime = this.time
+ this.setRemainTime(this.remainTime)
+ if (this.autoStart) {
+ this.start()
+ }
+ },
+ // ���������������
+ pause() {
+ this.runing = false;
+ this.clearTimeout()
+ },
+ // ���������������
+ clearTimeout() {
+ clearTimeout(this.timer)
+ this.timer = null
+ }
+ },
+ beforeDestroy() {
+ this.clearTimeout()
+ }
+ }
+</script>
+
+<style
+ lang="scss"
+ scoped
+>
+ @import "../../libs/css/components.scss";
+ $u-count-down-text-color:$u-content-color !default;
+ $u-count-down-text-font-size:15px !default;
+ $u-count-down-text-line-height:22px !default;
+
+ .u-count-down {
+ &__text {
+ color: $u-count-down-text-color;
+ font-size: $u-count-down-text-font-size;
+ line-height: $u-count-down-text-line-height;
+ }
+ }
+</style>
diff --git a/uni_modules/uview-ui/components/u-count-down/utils.js b/uni_modules/uview-ui/components/u-count-down/utils.js
new file mode 100644
index 0000000..8c75005
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-count-down/utils.js
@@ -0,0 +1,62 @@
+// ���0������1 -> 01
+function padZero(num, targetLength = 2) {
+ let str = `${num}`
+ while (str.length < targetLength) {
+ str = `0${str}`
+ }
+ return str
+}
+const SECOND = 1000
+const MINUTE = 60 * SECOND
+const HOUR = 60 * MINUTE
+const DAY = 24 * HOUR
+export function parseTimeData(time) {
+ const days = Math.floor(time / DAY)
+ const hours = Math.floor((time % DAY) / HOUR)
+ const minutes = Math.floor((time % HOUR) / MINUTE)
+ const seconds = Math.floor((time % MINUTE) / SECOND)
+ const milliseconds = Math.floor(time % SECOND)
+ return {
+ days,
+ hours,
+ minutes,
+ seconds,
+ milliseconds
+ }
+}
+export function parseFormat(format, timeData) {
+ let {
+ days,
+ hours,
+ minutes,
+ seconds,
+ milliseconds
+ } = timeData
+ // ������������������������������������DD(���)���������������������������������������
+ if (format.indexOf('DD') === -1) {
+ hours += days * 24
+ } else {
+ // ���������0
+ format = format.replace('DD', padZero(days))
+ }
+ // ���������������DD������������������������
+ if (format.indexOf('HH') === -1) {
+ minutes += hours * 60
+ } else {
+ format = format.replace('HH', padZero(hours))
+ }
+ if (format.indexOf('mm') === -1) {
+ seconds += minutes * 60
+ } else {
+ format = format.replace('mm', padZero(minutes))
+ }
+ if (format.indexOf('ss') === -1) {
+ milliseconds += seconds * 1000
+ } else {
+ format = format.replace('ss', padZero(seconds))
+ }
+ return format.replace('SSS', padZero(milliseconds, 3))
+}
+export function isSameSecond(time1, time2) {
+ return Math.floor(time1 / 1000) === Math.floor(time2 / 1000)
+}
diff --git a/uni_modules/uview-ui/components/u-count-to/props.js b/uni_modules/uview-ui/components/u-count-to/props.js
new file mode 100644
index 0000000..86873c1
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-count-to/props.js
@@ -0,0 +1,59 @@
+export default {
+ props: {
+ // ���������������������������0���������������������
+ startVal: {
+ type: [String, Number],
+ default: uni.$u.props.countTo.startVal
+ },
+ // ���������������������������������
+ endVal: {
+ type: [String, Number],
+ default: uni.$u.props.countTo.endVal
+ },
+ // ���������������������������������������������������������������ms���
+ duration: {
+ type: [String, Number],
+ default: uni.$u.props.countTo.duration
+ },
+ // ���������������������������������������
+ autoplay: {
+ type: Boolean,
+ default: uni.$u.props.countTo.autoplay
+ },
+ // ������������������������
+ decimals: {
+ type: [String, Number],
+ default: uni.$u.props.countTo.decimals
+ },
+ // ������������������������������������������������������������������������
+ useEasing: {
+ type: Boolean,
+ default: uni.$u.props.countTo.useEasing
+ },
+ // ���������������
+ decimal: {
+ type: [String, Number],
+ default: uni.$u.props.countTo.decimal
+ },
+ // ������������
+ color: {
+ type: String,
+ default: uni.$u.props.countTo.color
+ },
+ // ������������
+ fontSize: {
+ type: [String, Number],
+ default: uni.$u.props.countTo.fontSize
+ },
+ // ������������������
+ bold: {
+ type: Boolean,
+ default: uni.$u.props.countTo.bold
+ },
+ // ���������������������������������������(���23,321.05������",")
+ separator: {
+ type: String,
+ default: uni.$u.props.countTo.separator
+ }
+ }
+}
diff --git a/uni_modules/uview-ui/components/u-count-to/u-count-to.vue b/uni_modules/uview-ui/components/u-count-to/u-count-to.vue
new file mode 100644
index 0000000..417b732
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-count-to/u-count-to.vue
@@ -0,0 +1,184 @@
+<template>
+ <text
+ class="u-count-num"
+ :style="{
+ fontSize: $u.addUnit(fontSize),
+ fontWeight: bold ? 'bold' : 'normal',
+ color: color
+ }"
+ >{{ displayValue }}</text>
+</template>
+
+<script>
+ import props from './props.js';
+/**
+ * countTo ������������
+ * @description ������������������������������������������������������������������������������������������������������
+ * @tutorial https://www.uviewui.com/components/countTo.html
+ * @property {String | Number} startVal ���������������������������0������������������������������ 0 ���
+ * @property {String | Number} endVal ��������������������������������� ��������� 0 ���
+ * @property {String | Number} duration ���������������������������������������������������������������ms��� ��������� 2000 ���
+ * @property {Boolean} autoplay ��������������������������������������� ��������� true ���
+ * @property {String | Number} decimals ��������������������������������������������������� 0 ���
+ * @property {Boolean} useEasing ��������������������������������������������������������������� true ���
+ * @property {String} decimal ��������������� ��� ������ "." ���
+ * @property {String} color ��������������� ������ '#606266' )
+ * @property {String | Number} fontSize ���������������������px��� ������ 22 ���
+ * @property {Boolean} bold ��������������������������� false ���
+ * @property {String} separator ���������������������������������
+ * @event {Function} end ���������������������������������
+ * @example <u-count-to ref="uCountTo" :end-val="endVal" :autoplay="autoplay"></u-count-to>
+ */
+export default {
+ name: 'u-count-to',
+ data() {
+ return {
+ localStartVal: this.startVal,
+ displayValue: this.formatNumber(this.startVal),
+ printVal: null,
+ paused: false, // ������������
+ localDuration: Number(this.duration),
+ startTime: null, // ���������������
+ timestamp: null, // ���������
+ remaining: null, // ���������������
+ rAF: null,
+ lastTime: 0 // ������������������
+ };
+ },
+ mixins: [uni.$u.mpMixin, uni.$u.mixin,props],
+ computed: {
+ countDown() {
+ return this.startVal > this.endVal;
+ }
+ },
+ watch: {
+ startVal() {
+ this.autoplay && this.start();
+ },
+ endVal() {
+ this.autoplay && this.start();
+ }
+ },
+ mounted() {
+ this.autoplay && this.start();
+ },
+ methods: {
+ easingFn(t, b, c, d) {
+ return (c * (-Math.pow(2, (-10 * t) / d) + 1) * 1024) / 1023 + b;
+ },
+ requestAnimationFrame(callback) {
+ const currTime = new Date().getTime();
+ // ���������setTimteout���������������������������60������������
+ const timeToCall = Math.max(0, 16 - (currTime - this.lastTime));
+ const id = setTimeout(() => {
+ callback(currTime + timeToCall);
+ }, timeToCall);
+ this.lastTime = currTime + timeToCall;
+ return id;
+ },
+ cancelAnimationFrame(id) {
+ clearTimeout(id);
+ },
+ // ������������������
+ start() {
+ this.localStartVal = this.startVal;
+ this.startTime = null;
+ this.localDuration = this.duration;
+ this.paused = false;
+ this.rAF = this.requestAnimationFrame(this.count);
+ },
+ // ���������������������������������������������������������������������
+ reStart() {
+ if (this.paused) {
+ this.resume();
+ this.paused = false;
+ } else {
+ this.stop();
+ this.paused = true;
+ }
+ },
+ // ������
+ stop() {
+ this.cancelAnimationFrame(this.rAF);
+ },
+ // ������������(������������������)
+ resume() {
+ if (!this.remaining) return
+ this.startTime = 0;
+ this.localDuration = this.remaining;
+ this.localStartVal = this.printVal;
+ this.requestAnimationFrame(this.count);
+ },
+ // ������
+ reset() {
+ this.startTime = null;
+ this.cancelAnimationFrame(this.rAF);
+ this.displayValue = this.formatNumber(this.startVal);
+ },
+ count(timestamp) {
+ if (!this.startTime) this.startTime = timestamp;
+ this.timestamp = timestamp;
+ const progress = timestamp - this.startTime;
+ this.remaining = this.localDuration - progress;
+ if (this.useEasing) {
+ if (this.countDown) {
+ this.printVal = this.localStartVal - this.easingFn(progress, 0, this.localStartVal - this.endVal, this.localDuration);
+ } else {
+ this.printVal = this.easingFn(progress, this.localStartVal, this.endVal - this.localStartVal, this.localDuration);
+ }
+ } else {
+ if (this.countDown) {
+ this.printVal = this.localStartVal - (this.localStartVal - this.endVal) * (progress / this.localDuration);
+ } else {
+ this.printVal = this.localStartVal + (this.endVal - this.localStartVal) * (progress / this.localDuration);
+ }
+ }
+ if (this.countDown) {
+ this.printVal = this.printVal < this.endVal ? this.endVal : this.printVal;
+ } else {
+ this.printVal = this.printVal > this.endVal ? this.endVal : this.printVal;
+ }
+ this.displayValue = this.formatNumber(this.printVal) || 0;
+ if (progress < this.localDuration) {
+ this.rAF = this.requestAnimationFrame(this.count);
+ } else {
+ this.$emit('end');
+ }
+ },
+ // ������������������
+ isNumber(val) {
+ return !isNaN(parseFloat(val));
+ },
+ formatNumber(num) {
+ // ���num������Number������������������������������������������������������toFixed���������
+ num = Number(num);
+ num = num.toFixed(Number(this.decimals));
+ num += '';
+ const x = num.split('.');
+ let x1 = x[0];
+ const x2 = x.length > 1 ? this.decimal + x[1] : '';
+ const rgx = /(\d+)(\d{3})/;
+ if (this.separator && !this.isNumber(this.separator)) {
+ while (rgx.test(x1)) {
+ x1 = x1.replace(rgx, '$1' + this.separator + '$2');
+ }
+ }
+ return x1 + x2;
+ },
+ destroyed() {
+ this.cancelAnimationFrame(this.rAF);
+ }
+ }
+};
+</script>
+
+<style lang="scss" scoped>
+@import "../../libs/css/components.scss";
+
+.u-count-num {
+ /* #ifndef APP-NVUE */
+ display: inline-flex;
+ /* #endif */
+ text-align: center;
+}
+</style>
diff --git a/uni_modules/uview-ui/components/u-datetime-picker/props.js b/uni_modules/uview-ui/components/u-datetime-picker/props.js
new file mode 100644
index 0000000..f44c0f9
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-datetime-picker/props.js
@@ -0,0 +1,116 @@
+export default {
+ props: {
+ // ������������������
+ show: {
+ type: Boolean,
+ default: uni.$u.props.datetimePicker.show
+ },
+ // ������������������������������
+ showToolbar: {
+ type: Boolean,
+ default: uni.$u.props.datetimePicker.showToolbar
+ },
+ // ���������
+ value: {
+ type: [String, Number],
+ default: uni.$u.props.datetimePicker.value
+ },
+ // ������������
+ title: {
+ type: String,
+ default: uni.$u.props.datetimePicker.title
+ },
+ // ���������������mode=date������������������mode=time������������������mode=year-month������������������mode=datetime���������������������
+ mode: {
+ type: String,
+ default: uni.$u.props.datetimePicker.mode
+ },
+ // ���������������������
+ maxDate: {
+ type: Number,
+ // ���������������������10���
+ default: uni.$u.props.datetimePicker.maxDate
+ },
+ // ���������������������
+ minDate: {
+ type: Number,
+ // ���������������������10���
+ default: uni.$u.props.datetimePicker.minDate
+ },
+ // ���������������������������mode=time������
+ minHour: {
+ type: Number,
+ default: uni.$u.props.datetimePicker.minHour
+ },
+ // ���������������������������mode=time������
+ maxHour: {
+ type: Number,
+ default: uni.$u.props.datetimePicker.maxHour
+ },
+ // ���������������������������mode=time������
+ minMinute: {
+ type: Number,
+ default: uni.$u.props.datetimePicker.minMinute
+ },
+ // ���������������������������mode=time������
+ maxMinute: {
+ type: Number,
+ default: uni.$u.props.datetimePicker.maxMinute
+ },
+ // ������������������
+ filter: {
+ type: [Function, null],
+ default: uni.$u.props.datetimePicker.filter
+ },
+ // ���������������������
+ formatter: {
+ type: [Function, null],
+ default: uni.$u.props.datetimePicker.formatter
+ },
+ // ���������������������������
+ loading: {
+ type: Boolean,
+ default: uni.$u.props.datetimePicker.loading
+ },
+ // ���������������������������������
+ itemHeight: {
+ type: [String, Number],
+ default: uni.$u.props.datetimePicker.itemHeight
+ },
+ // ���������������������
+ cancelText: {
+ type: String,
+ default: uni.$u.props.datetimePicker.cancelText
+ },
+ // ���������������������
+ confirmText: {
+ type: String,
+ default: uni.$u.props.datetimePicker.confirmText
+ },
+ // ���������������������
+ cancelColor: {
+ type: String,
+ default: uni.$u.props.datetimePicker.cancelColor
+ },
+ // ���������������������
+ confirmColor: {
+ type: String,
+ default: uni.$u.props.datetimePicker.confirmColor
+ },
+ // ������������������������������
+ visibleItemCount: {
+ type: [String, Number],
+ default: uni.$u.props.datetimePicker.visibleItemCount
+ },
+ // ���������������������������������������
+ closeOnClickOverlay: {
+ type: Boolean,
+ default: uni.$u.props.datetimePicker.closeOnClickOverlay
+ },
+ // ���������������������
+ defaultIndex: {
+ type: Array,
+ default: uni.$u.props.datetimePicker.defaultIndex
+ }
+ }
+}
diff --git a/uni_modules/uview-ui/components/u-datetime-picker/u-datetime-picker.vue b/uni_modules/uview-ui/components/u-datetime-picker/u-datetime-picker.vue
new file mode 100644
index 0000000..18d8dcc
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-datetime-picker/u-datetime-picker.vue
@@ -0,0 +1,360 @@
+<template>
+ <u-picker
+ ref="picker"
+ :show="show"
+ :closeOnClickOverlay="closeOnClickOverlay"
+ :columns="columns"
+ :title="title"
+ :itemHeight="itemHeight"
+ :showToolbar="showToolbar"
+ :visibleItemCount="visibleItemCount"
+ :defaultIndex="innerDefaultIndex"
+ :cancelText="cancelText"
+ :confirmText="confirmText"
+ :cancelColor="cancelColor"
+ :confirmColor="confirmColor"
+ @close="close"
+ @cancel="cancel"
+ @confirm="confirm"
+ @change="change"
+ >
+ </u-picker>
+</template>
+
+<script>
+ function times(n, iteratee) {
+ let index = -1
+ const result = Array(n < 0 ? 0 : n)
+ while (++index < n) {
+ result[index] = iteratee(index)
+ }
+ return result
+ }
+ import props from './props.js';
+ import dayjs from '../../libs/util/dayjs.js';
+ /**
+ * DatetimePicker ���������������������
+ * @description ������������������������������
+ * @tutorial https://www.uviewui.com/components/datetimePicker.html
+ * @property {Boolean} show ��������������������������������������� ( ������ false )
+ * @property {Boolean} showToolbar ������������������������������ ( ������ true )
+ * @property {String | Number} value ���������
+ * @property {String} title ������������
+ * @property {String} mode ������������ mode=date������������������mode=time������������������mode=year-month������������������mode=datetime��������������������� ( ������ ���datetime )
+ * @property {Number} maxDate ��������������������� ���������������10���
+ * @property {Number} minDate ��������������������� ���������������10���
+ * @property {Number} minHour ���������������������������mode=time������ ( ������ 0 )
+ * @property {Number} maxHour ���������������������������mode=time������ ( ������ 23 )
+ * @property {Number} minMinute ���������������������������mode=time������ ( ������ 0 )
+ * @property {Number} maxMinute ���������������������������mode=time������ ( ������ 59 )
+ * @property {Function} filter ������������������
+ * @property {Function} formatter ���������������������
+ * @property {Boolean} loading ��������������������������� ( ������ false )
+ * @property {String | Number} itemHeight ��������������������������������� ( ������ 44 )
+ * @property {String} cancelText ��������������������� ( ������ '������' )
+ * @property {String} confirmText ��������������������� ( ������ '������' )
+ * @property {String} cancelColor ��������������������� ( ������ '#909193' )
+ * @property {String} confirmColor ��������������������� ( ������ '#3c9cff' )
+ * @property {String | Number} visibleItemCount ������������������������������ ( ������ 5 )
+ * @property {Boolean} closeOnClickOverlay ��������������������������������������� ( ������ false )
+ * @property {Array} defaultIndex ���������������������
+ * @event {Function} close ������������������������
+ * @event {Function} confirm ���������������������������������������������
+ * @event {Function} change ���������������������������
+ * @event {Function} cancel ������������������
+ * @example <u-datetime-picker :show="show" :value="value1" mode="datetime" ></u-datetime-picker>
+ */
+ export default {
+ name: 'datetime-picker',
+ mixins: [uni.$u.mpMixin, uni.$u.mixin, props],
+ data() {
+ return {
+ columns: [],
+ innerDefaultIndex: [],
+ innerFormatter: (type, value) => value
+ }
+ },
+ watch: {
+ show(newValue, oldValue) {
+ if (newValue) {
+ this.updateColumnValue(this.innerValue)
+ }
+ },
+ propsChange() {
+ this.init()
+ }
+ },
+ computed: {
+ // ������������������������������������������������������������������������������������
+ propsChange() {
+ return [this.mode, this.maxDate, this.minDate, this.minHour, this.maxHour, this.minMinute, this.maxMinute, this.filter, ]
+ }
+ },
+ mounted() {
+ this.init()
+ },
+ methods: {
+ init() {
+ this.innerValue = this.correctValue(this.value)
+ this.updateColumnValue(this.innerValue)
+ },
+ // ������������������������������������������������props������������������������ref������������
+ setFormatter(e) {
+ this.innerFormatter = e
+ },
+ // ���������������
+ close() {
+ if (this.closeOnClickOverlay) {
+ this.$emit('close')
+ }
+ },
+ // ������������������������������
+ cancel() {
+ this.$emit('cancel')
+ },
+ // ������������������������������
+ confirm() {
+ this.$emit('confirm', {
+ value: this.innerValue,
+ mode: this.mode
+ })
+ this.$emit('input', this.innerValue)
+ },
+ //������������������������,������������������������,������������
+ intercept(e,type){
+ let judge = e.match(/\d+/g)
+ //������������������������
+ if(judge.length>1){
+ uni.$u.error("������������������������������������������������")
+ return 0
+ }else if(type&&judge[0].length==4){//���������������������
+ return judge[0]
+ }else if(judge[0].length>2){
+ uni.$u.error("������������������������������������������������")
+ return 0
+ }else{
+ return judge[0]
+ }
+ },
+ // ������������������������
+ change(e) {
+ const { indexs, values } = e
+ let selectValue = ''
+ if(this.mode === 'time') {
+ // ������value������������������������������������������������������������������
+ selectValue = `${this.intercept(values[0][indexs[0]])}:${this.intercept(values[1][indexs[1]])}`
+ } else {
+ // ������������������������������������'03'���������������3���'2019'���������������2019
+ const year = parseInt(this.intercept(values[0][indexs[0]],'year'))
+ const month = parseInt(this.intercept(values[1][indexs[1]]))
+ let date = parseInt(values[2] ? this.intercept(values[2][indexs[2]]) : 1)
+ let hour = 0, minute = 0
+ // ������������������������
+ const maxDate = dayjs(`${year}-${month}`).daysInMonth()
+ // year-month������������date���������������������������������1������������������������������1���������
+ if (this.mode === 'year-month') {
+ date = 1
+ }
+ // ���������������maxDate���
+ date = Math.min(maxDate, date)
+ if (this.mode === 'datetime') {
+ hour = parseInt(this.intercept(values[3][indexs[3]]))
+ minute = parseInt(this.intercept(values[4][indexs[4]]))
+ }
+ // ������������������
+ selectValue = Number(new Date(year, month - 1, date, hour, minute))
+ }
+ // ������������������������������������������������������
+ selectValue = this.correctValue(selectValue)
+ this.innerValue = selectValue
+ this.updateColumnValue(selectValue)
+ // ������change���������value���������������������������
+ this.$emit('change', {
+ value: selectValue,
+ // #ifndef MP-WEIXIN
+ // ���������������������������this���������������������������������������
+ picker: this.$refs.picker,
+ // #endif
+ mode: this.mode
+ })
+ },
+ // ������������������������������0���������������������
+ updateColumnValue(value) {
+ this.innerValue = value
+ this.updateColumns()
+ this.updateIndexs(value)
+ },
+ // ������������
+ updateIndexs(value) {
+ let values = []
+ const formatter = this.formatter || this.innerFormatter
+ const padZero = uni.$u.padZero
+ if (this.mode === 'time') {
+ // ���time������������������:���������������
+ const timeArr = value.split(':')
+ // ������formatter���������������������������������
+ values = [formatter('hour', timeArr[0]), formatter('minute', timeArr[1])]
+ } else {
+ const date = new Date(value)
+ values = [
+ formatter('year', `${dayjs(value).year()}`),
+ // ���������0
+ formatter('month', padZero(dayjs(value).month() + 1))
+ ]
+ if (this.mode === 'date') {
+ // date���������������������������
+ values.push(formatter('day', padZero(dayjs(value).date())))
+ }
+ if (this.mode === 'datetime') {
+ // ���������push���������������������������������
+ values.push(formatter('day', padZero(dayjs(value).date())), formatter('hour', padZero(dayjs(value).hour())), formatter('minute', padZero(dayjs(value).minute())))
+ }
+ }
+
+ // ������������������������������������������������������������������������������������������
+ const indexs = this.columns.map((column, index) => {
+ // ������������������������������������������������������������-1������
+ return Math.max(0, column.findIndex(item => item === values[index]))
+ })
+ this.innerDefaultIndex = indexs
+ },
+ // ������������������
+ updateColumns() {
+ const formatter = this.formatter || this.innerFormatter
+ // ���������������������������map������������������������������������0������
+ const results = this.getOriginColumns().map((column) => column.values.map((value) => formatter(column.type, value)))
+ this.columns = results
+ },
+ getOriginColumns() {
+ // ������������������
+ const results = this.getRanges().map(({ type, range }) => {
+ let values = times(range[1] - range[0] + 1, (index) => {
+ let value = range[0] + index
+ value = type === 'year' ? `${value}` : uni.$u.padZero(value)
+ return value
+ })
+ // ������������
+ if (this.filter) {
+ values = this.filter(type, values)
+ }
+ return { type, values }
+ })
+ return results
+ },
+ // ���������������������������������������
+ generateArray(start, end) {
+ return Array.from(new Array(end + 1).keys()).slice(start)
+ },
+ // ���������������������
+ correctValue(value) {
+ const isDateMode = this.mode !== 'time'
+ if (isDateMode && !uni.$u.test.date(value)) {
+ // ������������������������������������������������������������������������������������������������������������
+ value = this.minDate
+ } else if (!isDateMode && !value) {
+ // ������������������������������������������������������������������������
+ value = `${uni.$u.padZero(this.minHour)}:${uni.$u.padZero(this.minMinute)}`
+ }
+ // ������������
+ if (!isDateMode) {
+ if (String(value).indexOf(':') === -1) return uni.$u.error('���������������������������12:24���������')
+ let [hour, minute] = value.split(':')
+ // ������������������������������������������������������������
+ hour = uni.$u.padZero(uni.$u.range(this.minHour, this.maxHour, Number(hour)))
+ minute = uni.$u.padZero(uni.$u.range(this.minMinute, this.maxMinute, Number(minute)))
+ return `${ hour }:${ minute }`
+ } else {
+ // ������������������������������������������������������������������
+ value = dayjs(value).isBefore(dayjs(this.minDate)) ? this.minDate : value
+ value = dayjs(value).isAfter(dayjs(this.maxDate)) ? this.maxDate : value
+ return value
+ }
+ },
+ // ���������������������������������
+ getRanges() {
+ if (this.mode === 'time') {
+ return [
+ {
+ type: 'hour',
+ range: [this.minHour, this.maxHour],
+ },
+ {
+ type: 'minute',
+ range: [this.minMinute, this.maxMinute],
+ },
+ ];
+ }
+ const { maxYear, maxDate, maxMonth, maxHour, maxMinute, } = this.getBoundary('max', this.innerValue);
+ const { minYear, minDate, minMonth, minHour, minMinute, } = this.getBoundary('min', this.innerValue);
+ const result = [
+ {
+ type: 'year',
+ range: [minYear, maxYear],
+ },
+ {
+ type: 'month',
+ range: [minMonth, maxMonth],
+ },
+ {
+ type: 'day',
+ range: [minDate, maxDate],
+ },
+ {
+ type: 'hour',
+ range: [minHour, maxHour],
+ },
+ {
+ type: 'minute',
+ range: [minMinute, maxMinute],
+ },
+ ];
+ if (this.mode === 'date')
+ result.splice(3, 2);
+ if (this.mode === 'year-month')
+ result.splice(2, 3);
+ return result;
+ },
+ // ������minDate���maxDate���minHour���maxHour������������������������������������������������������
+ getBoundary(type, innerValue) {
+ const value = new Date(innerValue)
+ const boundary = new Date(this[`${type}Date`])
+ const year = dayjs(boundary).year()
+ let month = 1
+ let date = 1
+ let hour = 0
+ let minute = 0
+ if (type === 'max') {
+ month = 12
+ // ���������������
+ date = dayjs(value).daysInMonth()
+ hour = 23
+ minute = 59
+ }
+ // ������������������������������������������������������(������������������)���������������������������������������������������������
+ if (dayjs(value).year() === year) {
+ month = dayjs(boundary).month() + 1
+ if (dayjs(value).month() + 1 === month) {
+ date = dayjs(boundary).date()
+ if (dayjs(value).date() === date) {
+ hour = dayjs(boundary).hour()
+ if (dayjs(value).hour() === hour) {
+ minute = dayjs(boundary).minute()
+ }
+ }
+ }
+ }
+ return {
+ [`${type}Year`]: year,
+ [`${type}Month`]: month,
+ [`${type}Date`]: date,
+ [`${type}Hour`]: hour,
+ [`${type}Minute`]: minute
+ }
+ },
+ },
+ }
+</script>
+
+<style lang="scss" scoped>
+ @import '../../libs/css/components.scss';
+</style>
diff --git a/uni_modules/uview-ui/components/u-divider/props.js b/uni_modules/uview-ui/components/u-divider/props.js
new file mode 100644
index 0000000..1fa8359
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-divider/props.js
@@ -0,0 +1,44 @@
+export default {
+ props: {
+ // ������������
+ dashed: {
+ type: Boolean,
+ default: uni.$u.props.divider.dashed
+ },
+ // ������������
+ hairline: {
+ type: Boolean,
+ default: uni.$u.props.divider.hairline
+ },
+ // ������������������������������������text���������������
+ dot: {
+ type: Boolean,
+ default: uni.$u.props.divider.dot
+ },
+ // ������������������������left-���������center-���������right-������
+ textPosition: {
+ type: String,
+ default: uni.$u.props.divider.textPosition
+ },
+ // ������������
+ text: {
+ type: [String, Number],
+ default: uni.$u.props.divider.text
+ },
+ // ������������
+ textSize: {
+ type: [String, Number],
+ default: uni.$u.props.divider.textSize
+ },
+ // ������������
+ textColor: {
+ type: String,
+ default: uni.$u.props.divider.textColor
+ },
+ // ������������
+ lineColor: {
+ type: String,
+ default: uni.$u.props.divider.lineColor
+ }
+ }
+}
diff --git a/uni_modules/uview-ui/components/u-divider/u-divider.vue b/uni_modules/uview-ui/components/u-divider/u-divider.vue
new file mode 100644
index 0000000..b629da6
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-divider/u-divider.vue
@@ -0,0 +1,116 @@
+<template>
+ <view
+ class="u-divider"
+ :style="[$u.addStyle(customStyle)]"
+ @tap="click"
+ >
+ <u-line
+ :color="lineColor"
+ :customStyle="leftLineStyle"
+ :hairline="hairline"
+ :dashed="dashed"
+ ></u-line>
+ <text
+ v-if="dot"
+ class="u-divider__dot"
+ >���</text>
+ <text
+ v-else-if="text"
+ class="u-divider__text"
+ :style="[textStyle]"
+ >{{text}}</text>
+ <u-line
+ :color="lineColor"
+ :customStyle="rightLineStyle"
+ :hairline="hairline"
+ :dashed="dashed"
+ ></u-line>
+ </view>
+</template>
+
+<script>
+ import props from './props.js';
+ /**
+ * divider ���������
+ * @description ���������������������������������������������������"������������"������������
+ * @tutorial https://www.uviewui.com/components/divider.html
+ * @property {Boolean} dashed ������������ ��������� false ���
+ * @property {Boolean} hairline ������������ ��������� true ���
+ * @property {Boolean} dot ������������������������������������text��������������� ��������� false ���
+ * @property {String} textPosition ������������������������left-���������center-���������right-������ ��������� 'center' ���
+ * @property {String | Number} text ������������
+ * @property {String | Number} textSize ������������ ��������� 14���
+ * @property {String} textColor ������������ ��������� '#909399' ���
+ * @property {String} lineColor ������������ ��������� '#dcdfe6' ���
+ * @property {Object} customStyle ���������������������������������
+ *
+ * @event {Function} click divider������������������������
+ * @example <u-divider :color="color">���������������������</u-divider>
+ */
+ export default {
+ name:'u-divider',
+ mixins: [uni.$u.mpMixin, uni.$u.mixin,props],
+ computed: {
+ textStyle() {
+ const style = {}
+ style.fontSize = uni.$u.addUnit(this.textSize)
+ style.color = this.textColor
+ return style
+ },
+ // ������������������������
+ leftLineStyle() {
+ const style = {}
+ // ������������������������������������������������������
+ if (this.textPosition === 'left') {
+ style.width = '80rpx'
+ } else {
+ style.flex = 1
+ }
+ return style
+ },
+ // ������������������������
+ rightLineStyle() {
+ const style = {}
+ // ������������������������������������������������������
+ if (this.textPosition === 'right') {
+ style.width = '80rpx'
+ } else {
+ style.flex = 1
+ }
+ return style
+ }
+ },
+ methods: {
+ // divider������������������������
+ click() {
+ this.$emit('click');
+ }
+ }
+ }
+</script>
+
+<style lang="scss" scoped>
+ @import '../../libs/css/components.scss';
+ $u-divider-margin:15px 0 !default;
+ $u-divider-text-margin:0 15px !default;
+ $u-divider-dot-font-size:12px !default;
+ $u-divider-dot-margin:0 12px !default;
+ $u-divider-dot-color: #c0c4cc !default;
+
+ .u-divider {
+ @include flex;
+ flex-direction: row;
+ align-items: center;
+ margin: $u-divider-margin;
+
+ &__text {
+ margin: $u-divider-text-margin;
+ }
+
+ &__dot {
+ font-size: $u-divider-dot-font-size;
+ margin: $u-divider-dot-margin;
+ color: $u-divider-dot-color;
+ }
+ }
+</style>
diff --git a/uni_modules/uview-ui/components/u-dropdown-item/props.js b/uni_modules/uview-ui/components/u-dropdown-item/props.js
new file mode 100644
index 0000000..501a1f0
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-dropdown-item/props.js
@@ -0,0 +1,36 @@
+export default {
+ props: {
+ // ������������������value���
+ value: {
+ type: [Number, String, Array],
+ default: ''
+ },
+ // ���������������
+ title: {
+ type: [String, Number],
+ default: ''
+ },
+ // ������������������������������������slot������������������
+ options: {
+ type: Array,
+ default() {
+ return []
+ }
+ },
+ // ������������������������
+ disabled: {
+ type: Boolean,
+ default: false
+ },
+ // ���������������������
+ height: {
+ type: [Number, String],
+ default: 'auto'
+ },
+ // ������������������������������������
+ closeOnClickOverlay: {
+ type: Boolean,
+ default: true
+ }
+ }
+}
diff --git a/uni_modules/uview-ui/components/u-dropdown-item/u-dropdown-item.vue b/uni_modules/uview-ui/components/u-dropdown-item/u-dropdown-item.vue
new file mode 100644
index 0000000..f830291
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-dropdown-item/u-dropdown-item.vue
@@ -0,0 +1,127 @@
+<template>
+ <view class="u-drawdown">
+ <view
+ class="u-dropdown__menu"
+ :style="{
+ height: $u.addUnit(height)
+ }"
+ ref="u-dropdown__menu"
+ >
+ <view
+ class="u-dropdown__menu__item"
+ v-for="(item, index) in menuList"
+ :key="index"
+ @tap.stop="clickHandler(item, index)"
+ >
+ <view class="u-dropdown__menu__item__content">
+ <text
+ class="u-dropdown__menu__item__content__text"
+ :style="[index === current ? activeStyle : inactiveStyle]"
+ >{{item.title}}</text>
+ <view
+ class="u-dropdown__menu__item__content__arrow"
+ :class="[index === current && 'u-dropdown__menu__item__content__arrow--rotate']"
+ >
+ <u-icon
+ :name="menuIcon"
+ :size="$u.addUnit(menuIconSize)"
+ ></u-icon>
+ </view>
+ </view>
+ </view>
+ </view>
+ <view class="u-dropdown__content">
+ <slot />
+ </view>
+ </view>
+</template>
+
+<script>
+import props from './props.js';
+/**
+ * Dropdown
+ * @description
+ * @tutorial url
+ * @property {String}
+ * @event {Function}
+ * @example
+ */
+export default {
+ name: 'u-dropdown',
+ mixins: [uni.$u.mixin, props],
+ data() {
+ return {
+ // ��������������������
+ menuList: [],
+ current: 0
+ }
+ },
+ computed: {
+
+ },
+ created() {
+ // ���������������������������������������(u-dropdown-item)������this������������������������data��������������������������������������������������������������������������������������������������������������������������
+ this.children = [];
+ },
+ methods: {
+ clickHandler(item, index) {
+ this.children.map(child => {
+ if(child.title === item.title) {
+ // this.queryRect('u-dropdown__menu').then(size => {
+ child.$emit('click')
+ child.setContentAnimate(child.show ? 0 : 300)
+ child.show = !child.show
+ // })
+ } else {
+ child.show = false
+ child.setContentAnimate(0)
+ }
+ })
+ },
+ // ����������������������������������
+ queryRect(el) {
+ // #ifndef APP-NVUE
+ // $uGetRect��uView����������������������������������������������������������������������������https://www.uviewui.com/js/getRect.html
+ // �������������������������������this.$uGetRect�����������������������this.$u.getRect����������������������������������������������������
+ return new Promise(resolve => {
+ this.$uGetRect(`.${el}`).then(size => {
+ resolve(size)
+ })
+ })
+ // #endif
+
+ // #ifdef APP-NVUE
+ // nvue����������������dom�������������������������
+ // ��������������������promise��������������������������������������������������������������then��������
+ return new Promise(resolve => {
+ dom.getComponentRect(this.$refs[el], res => {
+ resolve(res.size)
+ })
+ })
+ // #endif
+ },
+ },
+}
+</script>
+
+<style lang="scss">
+@import '../../libs/css/components.scss';
+
+.u-dropdown {
+
+ &__menu {
+ @include flex;
+
+ &__item {
+ flex: 1;
+ @include flex;
+ justify-content: center;
+
+ &__content {
+ @include flex;
+ align-items: center;
+ }
+ }
+ }
+}
+</style>
diff --git a/uni_modules/uview-ui/components/u-dropdown/props.js b/uni_modules/uview-ui/components/u-dropdown/props.js
new file mode 100644
index 0000000..5f8465e
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-dropdown/props.js
@@ -0,0 +1,65 @@
+export default {
+ props: {
+ // ������������������������
+ activeStyle: {
+ type: [String, Object],
+ default: () => ({
+ color: '#2979ff',
+ fontSize: '14px'
+ })
+ },
+ // ���������������������������
+ inactiveStyle: {
+ type: [String, Object],
+ default: () => ({
+ color: '#606266',
+ fontSize: '14px'
+ })
+ },
+ // ������������������������������
+ closeOnClickMask: {
+ type: Boolean,
+ default: true
+ },
+ // ���������������������������������������������
+ closeOnClickSelf: {
+ type: Boolean,
+ default: true
+ },
+ // ������������
+ duration: {
+ type: [Number, String],
+ default: 300
+ },
+ // ���������������������
+ height: {
+ type: [Number, String],
+ default: 40
+ },
+ // ���������������������
+ borderBottom: {
+ type: Boolean,
+ default: false
+ },
+ // ���������������������
+ titleSize: {
+ type: [Number, String],
+ default: 14
+ },
+ // ���������������������������������������
+ borderRadius: {
+ type: [Number, String],
+ default: 0
+ },
+ // ���������������icon������
+ menuIcon: {
+ type: String,
+ default: 'arrow-down'
+ },
+ // ���������������������������
+ menuIconSize: {
+ type: [Number, String],
+ default: 14
+ }
+ }
+}
diff --git a/uni_modules/uview-ui/components/u-dropdown/u-dropdown.vue b/uni_modules/uview-ui/components/u-dropdown/u-dropdown.vue
new file mode 100644
index 0000000..f830291
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-dropdown/u-dropdown.vue
@@ -0,0 +1,127 @@
+<template>
+ <view class="u-drawdown">
+ <view
+ class="u-dropdown__menu"
+ :style="{
+ height: $u.addUnit(height)
+ }"
+ ref="u-dropdown__menu"
+ >
+ <view
+ class="u-dropdown__menu__item"
+ v-for="(item, index) in menuList"
+ :key="index"
+ @tap.stop="clickHandler(item, index)"
+ >
+ <view class="u-dropdown__menu__item__content">
+ <text
+ class="u-dropdown__menu__item__content__text"
+ :style="[index === current ? activeStyle : inactiveStyle]"
+ >{{item.title}}</text>
+ <view
+ class="u-dropdown__menu__item__content__arrow"
+ :class="[index === current && 'u-dropdown__menu__item__content__arrow--rotate']"
+ >
+ <u-icon
+ :name="menuIcon"
+ :size="$u.addUnit(menuIconSize)"
+ ></u-icon>
+ </view>
+ </view>
+ </view>
+ </view>
+ <view class="u-dropdown__content">
+ <slot />
+ </view>
+ </view>
+</template>
+
+<script>
+import props from './props.js';
+/**
+ * Dropdown
+ * @description
+ * @tutorial url
+ * @property {String}
+ * @event {Function}
+ * @example
+ */
+export default {
+ name: 'u-dropdown',
+ mixins: [uni.$u.mixin, props],
+ data() {
+ return {
+ // ��������������������
+ menuList: [],
+ current: 0
+ }
+ },
+ computed: {
+
+ },
+ created() {
+ // ���������������������������������������(u-dropdown-item)������this������������������������data��������������������������������������������������������������������������������������������������������������������������
+ this.children = [];
+ },
+ methods: {
+ clickHandler(item, index) {
+ this.children.map(child => {
+ if(child.title === item.title) {
+ // this.queryRect('u-dropdown__menu').then(size => {
+ child.$emit('click')
+ child.setContentAnimate(child.show ? 0 : 300)
+ child.show = !child.show
+ // })
+ } else {
+ child.show = false
+ child.setContentAnimate(0)
+ }
+ })
+ },
+ // ����������������������������������
+ queryRect(el) {
+ // #ifndef APP-NVUE
+ // $uGetRect��uView����������������������������������������������������������������������������https://www.uviewui.com/js/getRect.html
+ // �������������������������������this.$uGetRect�����������������������this.$u.getRect����������������������������������������������������
+ return new Promise(resolve => {
+ this.$uGetRect(`.${el}`).then(size => {
+ resolve(size)
+ })
+ })
+ // #endif
+
+ // #ifdef APP-NVUE
+ // nvue����������������dom�������������������������
+ // ��������������������promise��������������������������������������������������������������then��������
+ return new Promise(resolve => {
+ dom.getComponentRect(this.$refs[el], res => {
+ resolve(res.size)
+ })
+ })
+ // #endif
+ },
+ },
+}
+</script>
+
+<style lang="scss">
+@import '../../libs/css/components.scss';
+
+.u-dropdown {
+
+ &__menu {
+ @include flex;
+
+ &__item {
+ flex: 1;
+ @include flex;
+ justify-content: center;
+
+ &__content {
+ @include flex;
+ align-items: center;
+ }
+ }
+ }
+}
+</style>
diff --git a/uni_modules/uview-ui/components/u-empty/props.js b/uni_modules/uview-ui/components/u-empty/props.js
new file mode 100644
index 0000000..78662f8
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-empty/props.js
@@ -0,0 +1,59 @@
+export default {
+ props: {
+ // ���������������������������������������������������������
+ icon: {
+ type: String,
+ default: uni.$u.props.empty.icon
+ },
+ // ������������
+ text: {
+ type: String,
+ default: uni.$u.props.empty.text
+ },
+ // ������������
+ textColor: {
+ type: String,
+ default: uni.$u.props.empty.textColor
+ },
+ // ������������
+ textSize: {
+ type: [String, Number],
+ default: uni.$u.props.empty.textSize
+ },
+ // ���������������
+ iconColor: {
+ type: String,
+ default: uni.$u.props.empty.iconColor
+ },
+ // ���������������
+ iconSize: {
+ type: [String, Number],
+ default: uni.$u.props.empty.iconSize
+ },
+ // ���������������������������
+ mode: {
+ type: String,
+ default: uni.$u.props.empty.mode
+ },
+ // ���������������������px
+ width: {
+ type: [String, Number],
+ default: uni.$u.props.empty.width
+ },
+ // ���������������������px
+ height: {
+ type: [String, Number],
+ default: uni.$u.props.empty.height
+ },
+ // ������������������
+ show: {
+ type: Boolean,
+ default: uni.$u.props.empty.show
+ },
+ // ���������������������������������������������������px������
+ marginTop: {
+ type: [String, Number],
+ default: uni.$u.props.empty.marginTop
+ }
+ }
+}
diff --git a/uni_modules/uview-ui/components/u-empty/u-empty.vue b/uni_modules/uview-ui/components/u-empty/u-empty.vue
new file mode 100644
index 0000000..03d6a27
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-empty/u-empty.vue
@@ -0,0 +1,128 @@
+<template>
+ <view
+ class="u-empty"
+ :style="[emptyStyle]"
+ v-if="show"
+ >
+ <u-icon
+ v-if="!isSrc"
+ :name="mode === 'message' ? 'chat' : `empty-${mode}`"
+ :size="iconSize"
+ :color="iconColor"
+ margin-top="14"
+ ></u-icon>
+ <image
+ v-else
+ :style="{
+ width: $u.addUnit(width),
+ height: $u.addUnit(height),
+ }"
+ :src="icon"
+ mode="widthFix"
+ ></image>
+ <text
+ class="u-empty__text"
+ :style="[textStyle]"
+ >{{text ? text : icons[mode]}}</text>
+ <view class="u-empty__wrap" v-if="$slots.default || $slots.$default">
+ <slot />
+ </view>
+ </view>
+</template>
+
+<script>
+ import props from './props.js';
+
+ /**
+ * empty ������������
+ * @description ������������������������������������������������������������������������������������������"������������"������������ ������������������������������������������������������������������
+ * @tutorial https://www.uviewui.com/components/empty.html
+ * @property {String} icon ���������������������������������������������������������
+ * @property {String} text ������������
+ * @property {String} textColor ������������ (������ '#c0c4cc' )
+ * @property {String | Number} textSize ������������ ��������� 14 ���
+ * @property {String} iconColor ��������������� ��������� '#c0c4cc' ���
+ * @property {String | Number} iconSize ��������������� ��������� 90 ���
+ * @property {String} mode ��������������������������� ��������� 'data' ���
+ * @property {String | Number} width ���������������������px ��������� 160 ���
+ * @property {String | Number} height ���������������������px ��������� 160 ���
+ * @property {Boolean} show ������������������ ��������� true ���
+ * @property {String | Number} marginTop ���������������������������������������������������px������ ��������� 0 ���
+ * @property {Object} customStyle ���������������������������������
+ *
+ * @event {Function} click ���������������������
+ * @event {Function} close ���������������������������
+ * @example <u-empty text="���������������������������" mode="list"></u-empty>
+ */
+ export default {
+ name: "u-empty",
+ mixins: [uni.$u.mpMixin, uni.$u.mixin, props],
+ data() {
+ return {
+ icons: {
+ car: '���������������',
+ page: '���������������',
+ search: '������������������',
+ address: '������������������',
+ wifi: '������WiFi',
+ order: '������������',
+ coupon: '���������������',
+ favor: '������������',
+ permission: '���������',
+ history: '���������������',
+ news: '���������������',
+ message: '������������������',
+ list: '������������',
+ data: '������������',
+ comment: '������������',
+ }
+ }
+ },
+ computed: {
+ // ������������
+ emptyStyle() {
+ const style = {}
+ style.marginTop = uni.$u.addUnit(this.marginTop)
+ // ������customStyle������������������������mixin������props������
+ return uni.$u.deepMerge(uni.$u.addStyle(this.customStyle), style)
+ },
+ // ������������
+ textStyle() {
+ const style = {}
+ style.color = this.textColor
+ style.fontSize = uni.$u.addUnit(this.textSize)
+ return style
+ },
+ // ������icon������������������
+ isSrc() {
+ return this.icon.indexOf('/') >= 0
+ }
+ }
+ }
+</script>
+
+<style lang="scss" scoped>
+ @import '../../libs/css/components.scss';
+ $u-empty-text-margin-top:20rpx !default;
+ $u-empty-slot-margin-top:20rpx !default;
+
+ .u-empty {
+ @include flex;
+ flex-direction: column;
+ justify-content: center;
+ align-items: center;
+
+ &__text {
+ @include flex;
+ justify-content: center;
+ align-items: center;
+ margin-top: $u-empty-text-margin-top;
+ }
+ }
+ .u-slot-wrap {
+ @include flex;
+ justify-content: center;
+ align-items: center;
+ margin-top:$u-empty-slot-margin-top;
+ }
+</style>
diff --git a/uni_modules/uview-ui/components/u-form-item/props.js b/uni_modules/uview-ui/components/u-form-item/props.js
new file mode 100644
index 0000000..7b16655
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-form-item/props.js
@@ -0,0 +1,48 @@
+export default {
+ props: {
+ // input���label���������
+ label: {
+ type: String,
+ default: uni.$u.props.formItem.label
+ },
+ // ������������
+ prop: {
+ type: String,
+ default: uni.$u.props.formItem.prop
+ },
+ // ���������������������������������������
+ borderBottom: {
+ type: [String, Boolean],
+ default: uni.$u.props.formItem.borderBottom
+ },
+ // label������������left-���������top-������
+ labelPosition: {
+ type: String,
+ default: uni.$u.props.formItem.labelPosition
+ },
+ // label������������������px
+ labelWidth: {
+ type: [String, Number],
+ default: uni.$u.props.formItem.labelWidth
+ },
+ // ������������
+ rightIcon: {
+ type: String,
+ default: uni.$u.props.formItem.rightIcon
+ },
+ // ������������
+ leftIcon: {
+ type: String,
+ default: uni.$u.props.formItem.leftIcon
+ },
+ // ������������������������������������������������������������������������������������������rules���������
+ required: {
+ type: Boolean,
+ default: uni.$u.props.formItem.required
+ },
+ leftIconStyle: {
+ type: [String, Object],
+ default: uni.$u.props.formItem.leftIconStyle,
+ }
+ }
+}
diff --git a/uni_modules/uview-ui/components/u-form-item/u-form-item.vue b/uni_modules/uview-ui/components/u-form-item/u-form-item.vue
new file mode 100644
index 0000000..6aa8d69
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-form-item/u-form-item.vue
@@ -0,0 +1,235 @@
+<template>
+ <view class="u-form-item">
+ <view
+ class="u-form-item__body"
+ @tap="clickHandler"
+ :style="[$u.addStyle(customStyle), {
+ flexDirection: (labelPosition || parentData.labelPosition) === 'left' ? 'row' : 'column'
+ }]"
+ >
+ <!-- ���������������������������������������������������������������������������������"true" -->
+ <slot name="label">
+ <!-- {{required}} -->
+ <view
+ class="u-form-item__body__left"
+ v-if="required || leftIcon || label"
+ :style="{
+ width: $u.addUnit(labelWidth || parentData.labelWidth),
+ marginBottom: parentData.labelPosition === 'left' ? 0 : '5px',
+ }"
+ >
+ <!-- ��������������� -->
+ <view class="u-form-item__body__left__content">
+ <!-- nvue������������������before -->
+ <text
+ v-if="required"
+ class="u-form-item__body__left__content__required"
+ >*</text>
+ <view
+ class="u-form-item__body__left__content__icon"
+ v-if="leftIcon"
+ >
+ <u-icon
+ :name="leftIcon"
+ :custom-style="leftIconStyle"
+ ></u-icon>
+ </view>
+ <text
+ class="u-form-item__body__left__content__label"
+ :style="[parentData.labelStyle, {
+ justifyContent: parentData.labelAlign === 'left' ? 'flex-start' : parentData.labelAlign === 'center' ? 'center' : 'flex-end'
+ }]"
+ >{{ label }}</text>
+ </view>
+ </view>
+ </slot>
+ <view class="u-form-item__body__right">
+ <view class="u-form-item__body__right__content">
+ <view class="u-form-item__body__right__content__slot">
+ <slot />
+ </view>
+ <view
+ class="item__body__right__content__icon"
+ v-if="$slots.right"
+ >
+ <slot name="right" />
+ </view>
+ </view>
+ </view>
+ </view>
+ <slot name="error">
+ <text
+ v-if="!!message && parentData.errorType === 'message'"
+ class="u-form-item__body__right__message"
+ :style="{
+ marginLeft: $u.addUnit(parentData.labelPosition === 'top' ? 0 : (labelWidth || parentData.labelWidth))
+ }"
+ >{{ message }}</text>
+ </slot>
+ <u-line
+ v-if="borderBottom"
+ :color="message && parentData.errorType === 'border-bottom' ? $u.color.error : propsLine.color"
+ :customStyle="`margin-top: ${message && parentData.errorType === 'message' ? '5px' : 0}`"
+ ></u-line>
+ </view>
+</template>
+
+<script>
+ import props from './props.js';
+ /**
+ * Form ������
+ * @description ������������������������������������������������Input������������Select������������������������������������
+ * @tutorial https://www.uviewui.com/components/form.html
+ * @property {String} label input���label���������
+ * @property {String} prop ������������
+ * @property {String | Boolean} borderBottom ���������������������������������������
+ * @property {String | Number} labelWidth label������������������px
+ * @property {String} rightIcon ������������
+ * @property {String} leftIcon ������������
+ * @property {String | Object} leftIconStyle ���������������������
+ * @property {Boolean} required ������������������������������������������������������������������������������������������rules��������� (������ false )
+ *
+ * @example <u-form-item label="������" prop="userInfo.name" borderBottom ref="item1"></u-form-item>
+ */
+ export default {
+ name: 'u-form-item',
+ mixins: [uni.$u.mpMixin, uni.$u.mixin, props],
+ data() {
+ return {
+ // ���������������
+ message: '',
+ parentData: {
+ // ���������������������
+ labelPosition: 'left',
+ // ������������������������
+ labelAlign: 'left',
+ // ���������������������
+ labelStyle: {},
+ // ���������������������
+ labelWidth: 45,
+ // ������������������
+ errorType: 'message'
+ }
+ }
+ },
+ // ������������������������������������������������u-form���
+ computed: {
+ propsLine() {
+ return uni.$u.props.line
+ }
+ },
+ mounted() {
+ this.init()
+ },
+ methods: {
+ init() {
+ // ������������������
+ this.updateParentData()
+ if (!this.parent) {
+ uni.$u.error('u-form-item������������u-form������������')
+ }
+ },
+ // ������������������������
+ updateParentData() {
+ // ���������������mixin���
+ this.getParentData('u-form');
+ },
+ // ������u-form-item���������������
+ clearValidate() {
+ this.message = null
+ },
+ // ������������������������������������������������������������
+ resetField() {
+ // ���������������
+ const value = uni.$u.getProperty(this.parent.originalModel, this.prop)
+ // ���u-form���model���prop������������������������
+ uni.$u.setProperty(this.parent.model, this.prop, value)
+ // ������������������
+ this.message = null
+ },
+ // ������������
+ clickHandler() {
+ this.$emit('click')
+ }
+ },
+ }
+</script>
+
+<style lang="scss" scoped>
+ @import "../../libs/css/components.scss";
+
+ .u-form-item {
+ @include flex(column);
+ font-size: 14px;
+ color: $u-main-color;
+
+ &__body {
+ @include flex;
+ padding: 10px 0;
+
+ &__left {
+ @include flex;
+ align-items: center;
+
+ &__content {
+ position: relative;
+ @include flex;
+ align-items: center;
+ padding-right: 10rpx;
+ flex: 1;
+
+ &__icon {
+ margin-right: 8rpx;
+ }
+
+ &__required {
+ position: absolute;
+ left: -9px;
+ color: $u-error;
+ line-height: 20px;
+ font-size: 20px;
+ top: 3px;
+ }
+
+ &__label {
+ @include flex;
+ align-items: center;
+ flex: 1;
+ color: $u-main-color;
+ font-size: 15px;
+ }
+ }
+ }
+
+ &__right {
+ flex: 1;
+
+ &__content {
+ @include flex;
+ align-items: center;
+ flex: 1;
+
+ &__slot {
+ flex: 1;
+ /* #ifndef MP */
+ @include flex;
+ align-items: center;
+ /* #endif */
+ }
+
+ &__icon {
+ margin-left: 10rpx;
+ color: $u-light-color;
+ font-size: 30rpx;
+ }
+ }
+
+ &__message {
+ font-size: 12px;
+ line-height: 12px;
+ color: $u-error;
+ }
+ }
+ }
+ }
+</style>
diff --git a/uni_modules/uview-ui/components/u-form/props.js b/uni_modules/uview-ui/components/u-form/props.js
new file mode 100644
index 0000000..f2a629c
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-form/props.js
@@ -0,0 +1,45 @@
+export default {
+ props: {
+ // ������form������������������������������
+ model: {
+ type: Object,
+ default: uni.$u.props.form.model
+ },
+ // ������������
+ rules: {
+ type: [Object, Function, Array],
+ default: uni.$u.props.form.rules
+ },
+ // ������������������������������message-���������������toast-������toast������
+ // border-bottom-������������������������none-���������
+ errorType: {
+ type: String,
+ default: uni.$u.props.form.errorType
+ },
+ // ���������������������������������������
+ borderBottom: {
+ type: Boolean,
+ default: uni.$u.props.form.borderBottom
+ },
+ // label������������left-���������top-������
+ labelPosition: {
+ type: String,
+ default: uni.$u.props.form.labelPosition
+ },
+ // label������������������px
+ labelWidth: {
+ type: [String, Number],
+ default: uni.$u.props.form.labelWidth
+ },
+ // lable���������������������
+ labelAlign: {
+ type: String,
+ default: uni.$u.props.form.labelAlign
+ },
+ // lable������������������������
+ labelStyle: {
+ type: Object,
+ default: uni.$u.props.form.labelStyle
+ }
+ }
+}
diff --git a/uni_modules/uview-ui/components/u-form/u-form.vue b/uni_modules/uview-ui/components/u-form/u-form.vue
new file mode 100644
index 0000000..fe2dde2
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-form/u-form.vue
@@ -0,0 +1,214 @@
+<template>
+ <view class="u-form">
+ <slot />
+ </view>
+</template>
+
+<script>
+ import props from "./props.js";
+ import Schema from "../../libs/util/async-validator";
+ // ������������������
+ Schema.warning = function() {};
+ /**
+ * Form ������
+ * @description ������������������������������������������������Input������������Select������������������������������������
+ * @tutorial https://www.uviewui.com/components/form.html
+ * @property {Object} model ������form������������������������������
+ * @property {Object | Function | Array} rules ������������
+ * @property {String} errorType ��������������������������������������� ( ������ message )
+ * @property {Boolean} borderBottom ��������������������������������������� ( ������ true ���
+ * @property {String} labelPosition ���������������������������������left-���������top-������ ( ������ 'left' ���
+ * @property {String | Number} labelWidth ������������������������������px ( ������ 45 ���
+ * @property {String} labelAlign lable��������������������� ( ������ ���left' ���
+ * @property {Object} labelStyle lable������������������������
+ * @example <u--formlabelPosition="left" :model="model1" :rules="rules" ref="form1"></u--form>
+ */
+ export default {
+ name: "u-form",
+ mixins: [uni.$u.mpMixin, uni.$u.mixin, props],
+ provide() {
+ return {
+ uForm: this,
+ };
+ },
+ data() {
+ return {
+ formRules: {},
+ // ���������������
+ validator: {},
+ // ���������model���������������resetFields���������������������������
+ originalModel: null,
+ };
+ },
+ watch: {
+ // ���������������������
+ rules: {
+ immediate: true,
+ handler(n) {
+ this.setRules(n);
+ },
+ },
+ // ���������������������������������������u-form-item������������������
+ propsChange(n) {
+ if (this.children?.length) {
+ this.children.map((child) => {
+ // ���������������(u-form-item)���������updateParentData���������������������������(������������������������������������������������������������������)
+ typeof child.updateParentData == "function" &&
+ child.updateParentData();
+ });
+ }
+ },
+ // ������model���������������������������������������
+ model: {
+ immediate: true,
+ handler(n) {
+ if (!this.originalModel) {
+ this.originalModel = uni.$u.deepClone(n);
+ }
+ },
+ },
+ },
+ computed: {
+ propsChange() {
+ return [
+ this.errorType,
+ this.borderBottom,
+ this.labelPosition,
+ this.labelWidth,
+ this.labelAlign,
+ this.labelStyle,
+ ];
+ },
+ },
+ created() {
+ // ������������form������������u-form-item���������
+ // ���������������data���������������������������������������������������������
+ this.children = [];
+ },
+ methods: {
+ // ������������������������������������������������������������������������������������������������������������������������������������
+ setRules(rules) {
+ // ���������������������
+ if (Object.keys(rules).length === 0) return;
+ if (process.env.NODE_ENV === 'development' && Object.keys(this.model).length === 0) {
+ uni.$u.error('������rules���model������������������������������������������������������');
+ return;
+ };
+ this.formRules = rules;
+ // ���������������������Validator
+ this.validator = new Schema(rules);
+ },
+ // ������������u-form-item���������������������������������������u-form-item������������resetField()������
+ resetFields() {
+ this.resetModel();
+ },
+ // ������model���������������������
+ resetModel(obj) {
+ // ������������u-form-item������������prop���������������model���������������
+ this.children.map((child) => {
+ const prop = child?.prop;
+ const value = uni.$u.getProperty(this.originalModel, prop);
+ uni.$u.setProperty(this.model, prop, value);
+ });
+ },
+ // ������������������
+ clearValidate(props) {
+ props = [].concat(props);
+ this.children.map((child) => {
+ // ������u-form-item���prop���props������������������������������������������������
+ if (props[0] === undefined || props.includes(child.prop)) {
+ child.message = null;
+ }
+ });
+ },
+ // ���������������������������������
+ async validateField(value, callback, event = null) {
+ // $nextTick���������������������model������������������������������������������������
+ this.$nextTick(() => {
+ // ���������������������������������������������������������������form-item���������������
+ const errorsRes = [];
+ // ���������������������������������
+ value = [].concat(value);
+ // ������children���������form-item
+ this.children.map((child) => {
+ // ������������form-item���������������
+ const childErrors = [];
+ if (value.includes(child.prop)) {
+ // ������������������������������������'a.b.c'���������
+ const propertyVal = uni.$u.getProperty(
+ this.model,
+ child.prop
+ );
+ // ���������������
+ const propertyChain = child.prop.split(".");
+ const propertyName =
+ propertyChain[propertyChain.length - 1];
+
+ const rule = this.formRules[child.prop];
+ // ������������������������������������������������������������������������
+ if (!rule) return;
+ // rule���������������������������������������������������������������������������
+ const rules = [].concat(rule);
+
+ // ���rules������������������
+ for (let i = 0; i < rules.length; i++) {
+ const ruleItem = rules[i];
+ // ���u-form-item������������������������������
+ const trigger = [].concat(ruleItem?.trigger);
+ // ������������������������������������������form-item���������������������������������������������������������
+ if (event && !trigger.includes(event)) continue;
+ // ������������������������������������������
+ const validator = new Schema({
+ [propertyName]: ruleItem,
+ });
+ validator.validate({
+ [propertyName]: propertyVal,
+ },
+ (errors, fields) => {
+ if (uni.$u.test.array(errors)) {
+ errorsRes.push(...errors);
+ childErrors.push(...errors);
+ }
+ child.message =
+ childErrors[0]?.message ?? null;
+ }
+ );
+ }
+ }
+ });
+ // ������������������
+ typeof callback === "function" && callback(errorsRes);
+ });
+ },
+ // ������������������
+ validate(callback) {
+ // ������������������������������������������������
+ if (process.env.NODE_ENV === 'development' && Object.keys(this.formRules).length === 0) {
+ uni.$u.error('���������rules���������������������������������������������������������������');
+ return;
+ }
+ return new Promise((resolve, reject) => {
+ // $nextTick���������������������model������������������������������validate������
+ this.$nextTick(() => {
+ // ������������form-item���prop���������validateField������������������
+ const formItemProps = this.children.map(
+ (item) => item.prop
+ );
+ this.validateField(formItemProps, (errors) => {
+ if(errors.length) {
+ // ���������������������������toast������������������
+ this.errorType === 'toast' && uni.$u.toast(errors[0].message)
+ reject(errors)
+ } else {
+ resolve(true)
+ }
+ });
+ });
+ });
+ },
+ },
+ };
+</script>
+
+<style lang="scss" scoped>
+</style>
diff --git a/uni_modules/uview-ui/components/u-gap/props.js b/uni_modules/uview-ui/components/u-gap/props.js
new file mode 100644
index 0000000..89953e3
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-gap/props.js
@@ -0,0 +1,24 @@
+export default {
+ props: {
+ // ���������������������transparent���
+ bgColor: {
+ type: String,
+ default: uni.$u.props.gap.bgColor
+ },
+ // ������������������������px���������30���
+ height: {
+ type: [String, Number],
+ default: uni.$u.props.gap.height
+ },
+ // ���������������������������
+ marginTop: {
+ type: [String, Number],
+ default: uni.$u.props.gap.marginTop
+ },
+ // ���������������������������
+ marginBottom: {
+ type: [String, Number],
+ default: uni.$u.props.gap.marginBottom
+ }
+ }
+}
diff --git a/uni_modules/uview-ui/components/u-gap/u-gap.vue b/uni_modules/uview-ui/components/u-gap/u-gap.vue
new file mode 100644
index 0000000..e4429f0
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-gap/u-gap.vue
@@ -0,0 +1,38 @@
+<template>
+ <view class="u-gap" :style="[gapStyle]"></view>
+</template>
+
+<script>
+ import props from './props.js';
+ /**
+ * gap ���������
+ * @description ���������������������������������������������������������������������������������������������������������������������
+ * @tutorial https://www.uviewui.com/components/gap.html
+ * @property {String} bgColor ������������ ��������� 'transparent' ���
+ * @property {String | Number} height ������������������������px ��������� 20 ���
+ * @property {String | Number} marginTop ������������������������������������px��� ������ 0 ���
+ * @property {String | Number} marginBottom ������������������������������������px ��������� 0 ���
+ * @property {Object} customStyle ���������������������������������
+ *
+ * @example <u-gap height="80" bg-color="#bbb"></u-gap>
+ */
+ export default {
+ name: "u-gap",
+ mixins: [uni.$u.mpMixin, uni.$u.mixin,props],
+ computed: {
+ gapStyle() {
+ const style = {
+ backgroundColor: this.bgColor,
+ height: uni.$u.addUnit(this.height),
+ marginTop: uni.$u.addUnit(this.marginTop),
+ marginBottom: uni.$u.addUnit(this.marginBottom),
+ }
+ return uni.$u.deepMerge(style, uni.$u.addStyle(this.customStyle))
+ }
+ }
+ };
+</script>
+
+<style lang="scss" scoped>
+ @import "../../libs/css/components.scss";
+</style>
diff --git a/uni_modules/uview-ui/components/u-grid-item/props.js b/uni_modules/uview-ui/components/u-grid-item/props.js
new file mode 100644
index 0000000..06c3c66
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-grid-item/props.js
@@ -0,0 +1,14 @@
+export default {
+ props: {
+ // ���������name
+ name: {
+ type: [String, Number, null],
+ default: uni.$u.props.gridItem.name
+ },
+ // ������������
+ bgColor: {
+ type: String,
+ default: uni.$u.props.gridItem.bgColor
+ }
+ }
+}
diff --git a/uni_modules/uview-ui/components/u-grid-item/u-grid-item.vue b/uni_modules/uview-ui/components/u-grid-item/u-grid-item.vue
new file mode 100644
index 0000000..fc0c7cf
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-grid-item/u-grid-item.vue
@@ -0,0 +1,209 @@
+<template>
+ <!-- #ifndef APP-NVUE -->
+ <view
+ class="u-grid-item"
+ hover-class="u-grid-item--hover-class"
+ :hover-stay-time="200"
+ @tap="clickHandler"
+ :class="classes"
+ :style="[itemStyle]"
+ >
+ <slot />
+ </view>
+ <!-- #endif -->
+ <!-- #ifdef APP-NVUE -->
+ <view
+ class="u-grid-item"
+ :hover-stay-time="200"
+ @tap="clickHandler"
+ :class="classes"
+ :style="[itemStyle]"
+ >
+ <slot />
+ </view>
+ <!-- #endif -->
+</template>
+
+<script>
+ import props from './props.js';
+ /**
+ * gridItem ������
+ * @description ������������������������������������������������������������������������������������������������������������(badge)���������������������������������������������������������������������������u-grid������
+ * @tutorial https://www.uviewui.com/components/grid.html
+ * @property {String | Number} name ���������name ( ������ null )
+ * @property {String} bgColor ��������������������� ��������� 'transparent' ���
+ * @property {Object} customStyle ������������������������������
+ * @event {Function} click ������������������
+ * @example <u-grid-item></u-grid-item>
+ */
+ export default {
+ name: "u-grid-item",
+ mixins: [uni.$u.mpMixin, uni.$u.mixin,props],
+ data() {
+ return {
+ parentData: {
+ col: 3, // ���������������������������
+ border: true, // ������������������������������������������
+ },
+ // #ifdef APP-NVUE
+ width: 0, // nvue���������������������vue���������computed���������������������������������������
+ // #endif
+ classes: [], // ���������������������������������������������������������
+ };
+ },
+ mounted() {
+ this.init()
+ },
+ computed: {
+ // #ifndef APP-NVUE
+ // vue���������computed���������������������������������������
+ width() {
+ return 100 / Number(this.parentData.col) + '%'
+ },
+ // #endif
+ itemStyle() {
+ const style = {
+ background: this.bgColor,
+ width: this.width
+ }
+ return uni.$u.deepMerge(style, uni.$u.addStyle(this.customStyle))
+ }
+ },
+ methods: {
+ init() {
+ // ������������������u-grid���children������������������������������
+ // ������������item���������
+ uni.$on('$uGridItem', () => {
+ this.gridItemClasses()
+ })
+ // ������������������
+ this.updateParentData()
+ // #ifdef APP-NVUE
+ // ������������������������������nvue���������������������
+ this.$nextTick(function(){
+ this.getItemWidth()
+ })
+ // #endif
+ // ������������������������������grid-item������������������������������
+ uni.$emit('$uGridItem')
+ this.gridItemClasses()
+ },
+ // ������������������������
+ updateParentData() {
+ // ���������������mixin���
+ this.getParentData('u-grid');
+ },
+ clickHandler() {
+ let name = this.name
+ // ������������������name���������������������������children������������������������������������������������this������������������������������������
+ const children = this.parent?.children
+ if(children && this.name === null) {
+ name = children.findIndex(child => child === this)
+ }
+ // ������������������������������������
+ this.parent && this.parent.childClick(name)
+ this.$emit('click', name)
+ },
+ async getItemWidth() {
+ // ���������nvue���������������������������������������������������
+ let width = 0
+ if(this.parent) {
+ // ���������������������������������������������������������item���������
+ const parentWidth = await this.getParentWidth()
+ width = parentWidth / Number(this.parentData.col) + 'px'
+ }
+ this.width = width
+ },
+ // ������������������������
+ getParentWidth() {
+ // #ifdef APP-NVUE
+ // ������������promise������������������������await������������
+ const dom = uni.requireNativePlugin('dom')
+ return new Promise(resolve => {
+ // ������������������ref
+ dom.getComponentRect(this.parent.$refs['u-grid'], res => {
+ resolve(res.size.width)
+ })
+ })
+ // #endif
+ },
+ gridItemClasses() {
+ if(this.parentData.border) {
+ const classes = []
+ this.parent.children.map((child, index) =>{
+ if(this === child) {
+ const len = this.parent.children.length
+ // ���������������������������child������������������������������������������2���������������������������������
+ if((index + 1) % this.parentData.col !== 0 && index + 1 !== len) {
+ classes.push('u-border-right')
+ }
+ // ���������������������������������������
+ // ������������������������0������������������������������������������������������������������
+ const lessNum = len % this.parentData.col === 0 ? this.parentData.col : len % this.parentData.col
+ // ������������������child������������������
+ if(index < len - lessNum) {
+ classes.push('u-border-bottom')
+ }
+ }
+ })
+ // ������������������������������������������������������������������������������������������������������","������������������
+ // #ifdef MP-ALIPAY || MP-TOUTIAO
+ classes = classes.join(' ')
+ // #endif
+ this.classes = classes
+ }
+ }
+ },
+ beforeDestroy() {
+ // ���������������������������������
+ uni.$off('$uGridItem')
+ }
+ };
+</script>
+
+<style lang="scss" scoped>
+ @import "../../libs/css/components.scss";
+ $u-grid-item-hover-class-opcatiy:.5 !default;
+ $u-grid-item-margin-top:1rpx !default;
+ $u-grid-item-border-right-width:0.5px !default;
+ $u-grid-item-border-bottom-width:0.5px !default;
+ $u-grid-item-border-right-color:$u-border-color !default;
+ $u-grid-item-border-bottom-color:$u-border-color !default;
+ .u-grid-item {
+ align-items: center;
+ justify-content: center;
+ position: relative;
+ flex-direction: column;
+ /* #ifndef APP-NVUE */
+ box-sizing: border-box;
+ display: flex;
+ /* #endif */
+
+ /* #ifdef MP */
+ position: relative;
+ float: left;
+ /* #endif */
+
+ /* #ifdef MP-WEIXIN */
+ margin-top:$u-grid-item-margin-top;
+ /* #endif */
+
+ &--hover-class {
+ opacity:$u-grid-item-hover-class-opcatiy;
+ }
+ }
+
+ /* #ifdef APP-NVUE */
+ // ������nvue������������������������app.vue������������������������������������������������
+ .u-border-right {
+ border-right-width:$u-grid-item-border-right-width;
+ border-color: $u-grid-item-border-right-color;
+ }
+
+ .u-border-bottom {
+ border-bottom-width:$u-grid-item-border-bottom-width;
+ border-color:$u-grid-item-border-bottom-color;
+ }
+
+ /* #endif */
+</style>
diff --git a/uni_modules/uview-ui/components/u-grid/props.js b/uni_modules/uview-ui/components/u-grid/props.js
new file mode 100644
index 0000000..87b0f6a
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-grid/props.js
@@ -0,0 +1,19 @@
+export default {
+ props: {
+ // ������������
+ col: {
+ type: [String, Number],
+ default: uni.$u.props.grid.col
+ },
+ // ������������������
+ border: {
+ type: Boolean,
+ default: uni.$u.props.grid.border
+ },
+ // ���������������������������������������������������������������������������������
+ align: {
+ type: String,
+ default: uni.$u.props.grid.align
+ }
+ }
+}
diff --git a/uni_modules/uview-ui/components/u-grid/u-grid.vue b/uni_modules/uview-ui/components/u-grid/u-grid.vue
new file mode 100644
index 0000000..b43cc27
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-grid/u-grid.vue
@@ -0,0 +1,97 @@
+<template>
+ <view
+ class="u-grid"
+ ref='u-grid'
+ :style="[gridStyle]"
+ >
+ <slot />
+ </view>
+</template>
+
+<script>
+ import props from './props.js';
+ /**
+ * grid ������������
+ * @description ������������������������������������������������������������������������������������������������������������(badge)���������������������������������������������������������������������
+ * @tutorial https://www.uviewui.com/components/grid.html
+ * @property {String | Number} col ������������������������ 3 ���
+ * @property {Boolean} border ������������������������������������ false ���
+ * @property {String} align ��������������������������������������������������������������������������������� ��������� 'left' ���
+ * @property {Object} customStyle ���������������������������������
+ * @event {Function} click ������������������
+ * @example <u-grid :col="3" @click="click"></u-grid>
+ */
+ export default {
+ name: 'u-grid',
+ mixins: [uni.$u.mpMixin, uni.$u.mixin,props],
+ data() {
+ return {
+ index: 0,
+ width: 0
+ }
+ },
+ watch: {
+ // ���������������������������������������������������������������������������������������
+ parentData() {
+ if (this.children.length) {
+ this.children.map(child => {
+ // ���������������(u-radio)���������updateParentData���������������������������(������������������������������������������������������������������)
+ typeof(child.updateParentData) == 'function' && child.updateParentData();
+ })
+ }
+ },
+ },
+ created() {
+ // ���������children���������data������������������������������������������������������
+ this.children = []
+ },
+ computed: {
+ // ���������������������������������������
+ parentData() {
+ return [this.hoverClass, this.col, this.size, this.border];
+ },
+ // ������������������
+ gridStyle() {
+ let style = {};
+ switch (this.align) {
+ case 'left':
+ style.justifyContent = 'flex-start';
+ break;
+ case 'center':
+ style.justifyContent = 'center';
+ break;
+ case 'right':
+ style.justifyContent = 'flex-end';
+ break;
+ default:
+ style.justifyContent = 'flex-start';
+ };
+ return uni.$u.deepMerge(style, uni.$u.addStyle(this.customStyle));
+ }
+ },
+ methods: {
+ // ������������u-grid-item������������������u-grid������������
+ childClick(name) {
+ this.$emit('click', name)
+ }
+ }
+ };
+</script>
+
+<style lang="scss" scoped>
+ @import "../../libs/css/components.scss";
+ $u-grid-width:100% !default;
+ .u-grid {
+ /* #ifdef MP */
+ width: $u-grid-width;
+ position: relative;
+ box-sizing: border-box;
+ overflow: hidden;
+ display: block;
+ /* #endif */
+ justify-content: center;
+ @include flex;
+ flex-wrap: wrap;
+ align-items: center;
+ }
+</style>
diff --git a/uni_modules/uview-ui/components/u-icon/icons.js b/uni_modules/uview-ui/components/u-icon/icons.js
new file mode 100644
index 0000000..f4d0fe2
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-icon/icons.js
@@ -0,0 +1,214 @@
+export default {
+ 'uicon-level': '\ue693',
+ 'uicon-column-line': '\ue68e',
+ 'uicon-checkbox-mark': '\ue807',
+ 'uicon-folder': '\ue7f5',
+ 'uicon-movie': '\ue7f6',
+ 'uicon-star-fill': '\ue669',
+ 'uicon-star': '\ue65f',
+ 'uicon-phone-fill': '\ue64f',
+ 'uicon-phone': '\ue622',
+ 'uicon-apple-fill': '\ue881',
+ 'uicon-chrome-circle-fill': '\ue885',
+ 'uicon-backspace': '\ue67b',
+ 'uicon-attach': '\ue632',
+ 'uicon-cut': '\ue948',
+ 'uicon-empty-car': '\ue602',
+ 'uicon-empty-coupon': '\ue682',
+ 'uicon-empty-address': '\ue646',
+ 'uicon-empty-favor': '\ue67c',
+ 'uicon-empty-permission': '\ue686',
+ 'uicon-empty-news': '\ue687',
+ 'uicon-empty-search': '\ue664',
+ 'uicon-github-circle-fill': '\ue887',
+ 'uicon-rmb': '\ue608',
+ 'uicon-person-delete-fill': '\ue66a',
+ 'uicon-reload': '\ue788',
+ 'uicon-order': '\ue68f',
+ 'uicon-server-man': '\ue6bc',
+ 'uicon-search': '\ue62a',
+ 'uicon-fingerprint': '\ue955',
+ 'uicon-more-dot-fill': '\ue630',
+ 'uicon-scan': '\ue662',
+ 'uicon-share-square': '\ue60b',
+ 'uicon-map': '\ue61d',
+ 'uicon-map-fill': '\ue64e',
+ 'uicon-tags': '\ue629',
+ 'uicon-tags-fill': '\ue651',
+ 'uicon-bookmark-fill': '\ue63b',
+ 'uicon-bookmark': '\ue60a',
+ 'uicon-eye': '\ue613',
+ 'uicon-eye-fill': '\ue641',
+ 'uicon-mic': '\ue64a',
+ 'uicon-mic-off': '\ue649',
+ 'uicon-calendar': '\ue66e',
+ 'uicon-calendar-fill': '\ue634',
+ 'uicon-trash': '\ue623',
+ 'uicon-trash-fill': '\ue658',
+ 'uicon-play-left': '\ue66d',
+ 'uicon-play-right': '\ue610',
+ 'uicon-minus': '\ue618',
+ 'uicon-plus': '\ue62d',
+ 'uicon-info': '\ue653',
+ 'uicon-info-circle': '\ue7d2',
+ 'uicon-info-circle-fill': '\ue64b',
+ 'uicon-question': '\ue715',
+ 'uicon-error': '\ue6d3',
+ 'uicon-close': '\ue685',
+ 'uicon-checkmark': '\ue6a8',
+ 'uicon-android-circle-fill': '\ue67e',
+ 'uicon-android-fill': '\ue67d',
+ 'uicon-ie': '\ue87b',
+ 'uicon-IE-circle-fill': '\ue889',
+ 'uicon-google': '\ue87a',
+ 'uicon-google-circle-fill': '\ue88a',
+ 'uicon-setting-fill': '\ue872',
+ 'uicon-setting': '\ue61f',
+ 'uicon-minus-square-fill': '\ue855',
+ 'uicon-plus-square-fill': '\ue856',
+ 'uicon-heart': '\ue7df',
+ 'uicon-heart-fill': '\ue851',
+ 'uicon-camera': '\ue7d7',
+ 'uicon-camera-fill': '\ue870',
+ 'uicon-more-circle': '\ue63e',
+ 'uicon-more-circle-fill': '\ue645',
+ 'uicon-chat': '\ue620',
+ 'uicon-chat-fill': '\ue61e',
+ 'uicon-bag-fill': '\ue617',
+ 'uicon-bag': '\ue619',
+ 'uicon-error-circle-fill': '\ue62c',
+ 'uicon-error-circle': '\ue624',
+ 'uicon-close-circle': '\ue63f',
+ 'uicon-close-circle-fill': '\ue637',
+ 'uicon-checkmark-circle': '\ue63d',
+ 'uicon-checkmark-circle-fill': '\ue635',
+ 'uicon-question-circle-fill': '\ue666',
+ 'uicon-question-circle': '\ue625',
+ 'uicon-share': '\ue631',
+ 'uicon-share-fill': '\ue65e',
+ 'uicon-shopping-cart': '\ue621',
+ 'uicon-shopping-cart-fill': '\ue65d',
+ 'uicon-bell': '\ue609',
+ 'uicon-bell-fill': '\ue640',
+ 'uicon-list': '\ue650',
+ 'uicon-list-dot': '\ue616',
+ 'uicon-zhihu': '\ue6ba',
+ 'uicon-zhihu-circle-fill': '\ue709',
+ 'uicon-zhifubao': '\ue6b9',
+ 'uicon-zhifubao-circle-fill': '\ue6b8',
+ 'uicon-weixin-circle-fill': '\ue6b1',
+ 'uicon-weixin-fill': '\ue6b2',
+ 'uicon-twitter-circle-fill': '\ue6ab',
+ 'uicon-twitter': '\ue6aa',
+ 'uicon-taobao-circle-fill': '\ue6a7',
+ 'uicon-taobao': '\ue6a6',
+ 'uicon-weibo-circle-fill': '\ue6a5',
+ 'uicon-weibo': '\ue6a4',
+ 'uicon-qq-fill': '\ue6a1',
+ 'uicon-qq-circle-fill': '\ue6a0',
+ 'uicon-moments-circel-fill': '\ue69a',
+ 'uicon-moments': '\ue69b',
+ 'uicon-qzone': '\ue695',
+ 'uicon-qzone-circle-fill': '\ue696',
+ 'uicon-baidu-circle-fill': '\ue680',
+ 'uicon-baidu': '\ue681',
+ 'uicon-facebook-circle-fill': '\ue68a',
+ 'uicon-facebook': '\ue689',
+ 'uicon-car': '\ue60c',
+ 'uicon-car-fill': '\ue636',
+ 'uicon-warning-fill': '\ue64d',
+ 'uicon-warning': '\ue694',
+ 'uicon-clock-fill': '\ue638',
+ 'uicon-clock': '\ue60f',
+ 'uicon-edit-pen': '\ue612',
+ 'uicon-edit-pen-fill': '\ue66b',
+ 'uicon-email': '\ue611',
+ 'uicon-email-fill': '\ue642',
+ 'uicon-minus-circle': '\ue61b',
+ 'uicon-minus-circle-fill': '\ue652',
+ 'uicon-plus-circle': '\ue62e',
+ 'uicon-plus-circle-fill': '\ue661',
+ 'uicon-file-text': '\ue663',
+ 'uicon-file-text-fill': '\ue665',
+ 'uicon-pushpin': '\ue7e3',
+ 'uicon-pushpin-fill': '\ue86e',
+ 'uicon-grid': '\ue673',
+ 'uicon-grid-fill': '\ue678',
+ 'uicon-play-circle': '\ue647',
+ 'uicon-play-circle-fill': '\ue655',
+ 'uicon-pause-circle-fill': '\ue654',
+ 'uicon-pause': '\ue8fa',
+ 'uicon-pause-circle': '\ue643',
+ 'uicon-eye-off': '\ue648',
+ 'uicon-eye-off-outline': '\ue62b',
+ 'uicon-gift-fill': '\ue65c',
+ 'uicon-gift': '\ue65b',
+ 'uicon-rmb-circle-fill': '\ue657',
+ 'uicon-rmb-circle': '\ue677',
+ 'uicon-kefu-ermai': '\ue656',
+ 'uicon-server-fill': '\ue751',
+ 'uicon-coupon-fill': '\ue8c4',
+ 'uicon-coupon': '\ue8ae',
+ 'uicon-integral': '\ue704',
+ 'uicon-integral-fill': '\ue703',
+ 'uicon-home-fill': '\ue964',
+ 'uicon-home': '\ue965',
+ 'uicon-hourglass-half-fill': '\ue966',
+ 'uicon-hourglass': '\ue967',
+ 'uicon-account': '\ue628',
+ 'uicon-plus-people-fill': '\ue626',
+ 'uicon-minus-people-fill': '\ue615',
+ 'uicon-account-fill': '\ue614',
+ 'uicon-thumb-down-fill': '\ue726',
+ 'uicon-thumb-down': '\ue727',
+ 'uicon-thumb-up': '\ue733',
+ 'uicon-thumb-up-fill': '\ue72f',
+ 'uicon-lock-fill': '\ue979',
+ 'uicon-lock-open': '\ue973',
+ 'uicon-lock-opened-fill': '\ue974',
+ 'uicon-lock': '\ue97a',
+ 'uicon-red-packet-fill': '\ue690',
+ 'uicon-photo-fill': '\ue98b',
+ 'uicon-photo': '\ue98d',
+ 'uicon-volume-off-fill': '\ue659',
+ 'uicon-volume-off': '\ue644',
+ 'uicon-volume-fill': '\ue670',
+ 'uicon-volume': '\ue633',
+ 'uicon-red-packet': '\ue691',
+ 'uicon-download': '\ue63c',
+ 'uicon-arrow-up-fill': '\ue6b0',
+ 'uicon-arrow-down-fill': '\ue600',
+ 'uicon-play-left-fill': '\ue675',
+ 'uicon-play-right-fill': '\ue676',
+ 'uicon-rewind-left-fill': '\ue679',
+ 'uicon-rewind-right-fill': '\ue67a',
+ 'uicon-arrow-downward': '\ue604',
+ 'uicon-arrow-leftward': '\ue601',
+ 'uicon-arrow-rightward': '\ue603',
+ 'uicon-arrow-upward': '\ue607',
+ 'uicon-arrow-down': '\ue60d',
+ 'uicon-arrow-right': '\ue605',
+ 'uicon-arrow-left': '\ue60e',
+ 'uicon-arrow-up': '\ue606',
+ 'uicon-skip-back-left': '\ue674',
+ 'uicon-skip-forward-right': '\ue672',
+ 'uicon-rewind-right': '\ue66f',
+ 'uicon-rewind-left': '\ue671',
+ 'uicon-arrow-right-double': '\ue68d',
+ 'uicon-arrow-left-double': '\ue68c',
+ 'uicon-wifi-off': '\ue668',
+ 'uicon-wifi': '\ue667',
+ 'uicon-empty-data': '\ue62f',
+ 'uicon-empty-history': '\ue684',
+ 'uicon-empty-list': '\ue68b',
+ 'uicon-empty-page': '\ue627',
+ 'uicon-empty-order': '\ue639',
+ 'uicon-man': '\ue697',
+ 'uicon-woman': '\ue69c',
+ 'uicon-man-add': '\ue61c',
+ 'uicon-man-add-fill': '\ue64c',
+ 'uicon-man-delete': '\ue61a',
+ 'uicon-man-delete-fill': '\ue66a',
+ 'uicon-zh': '\ue70a',
+ 'uicon-en': '\ue692'
+}
diff --git a/uni_modules/uview-ui/components/u-icon/props.js b/uni_modules/uview-ui/components/u-icon/props.js
new file mode 100644
index 0000000..71845b7
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-icon/props.js
@@ -0,0 +1,89 @@
+export default {
+ props: {
+ // ������������
+ name: {
+ type: String,
+ default: uni.$u.props.icon.name
+ },
+ // ���������������������������������
+ color: {
+ type: String,
+ default: uni.$u.props.icon.color
+ },
+ // ���������������������px
+ size: {
+ type: [String, Number],
+ default: uni.$u.props.icon.size
+ },
+ // ������������������
+ bold: {
+ type: Boolean,
+ default: uni.$u.props.icon.bold
+ },
+ // ������������������������������������������index������������������������������������
+ index: {
+ type: [String, Number],
+ default: uni.$u.props.icon.index
+ },
+ // ������������������������
+ hoverClass: {
+ type: String,
+ default: uni.$u.props.icon.hoverClass
+ },
+ // ������������������������������������������������������������
+ customPrefix: {
+ type: String,
+ default: uni.$u.props.icon.customPrefix
+ },
+ // ���������������������������������
+ label: {
+ type: [String, Number],
+ default: uni.$u.props.icon.label
+ },
+ // label������������������������������������
+ labelPos: {
+ type: String,
+ default: uni.$u.props.icon.labelPos
+ },
+ // label���������
+ labelSize: {
+ type: [String, Number],
+ default: uni.$u.props.icon.labelSize
+ },
+ // label���������
+ labelColor: {
+ type: String,
+ default: uni.$u.props.icon.labelColor
+ },
+ // label������������������
+ space: {
+ type: [String, Number],
+ default: uni.$u.props.icon.space
+ },
+ // ���������mode
+ imgMode: {
+ type: String,
+ default: uni.$u.props.icon.imgMode
+ },
+ // ������������������������������������������������
+ width: {
+ type: [String, Number],
+ default: uni.$u.props.icon.width
+ },
+ // ������������������������������������������������
+ height: {
+ type: [String, Number],
+ default: uni.$u.props.icon.height
+ },
+ // ������������������������������������������������������������
+ top: {
+ type: [String, Number],
+ default: uni.$u.props.icon.top
+ },
+ // ������������������������
+ stop: {
+ type: Boolean,
+ default: uni.$u.props.icon.stop
+ }
+ }
+}
diff --git a/uni_modules/uview-ui/components/u-icon/u-icon.vue b/uni_modules/uview-ui/components/u-icon/u-icon.vue
new file mode 100644
index 0000000..9340328
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-icon/u-icon.vue
@@ -0,0 +1,234 @@
+<template>
+ <view
+ class="u-icon"
+ @tap="clickHandler"
+ :class="['u-icon--' + labelPos]"
+ >
+ <image
+ class="u-icon__img"
+ v-if="isImg"
+ :src="name"
+ :mode="imgMode"
+ :style="[imgStyle, $u.addStyle(customStyle)]"
+ ></image>
+ <text
+ v-else
+ class="u-icon__icon"
+ :class="uClasses"
+ :style="[iconStyle, $u.addStyle(customStyle)]"
+ :hover-class="hoverClass"
+ >{{icon}}</text>
+ <!-- ������������������������������������������������v-if="label"������������������������0��������������������������������� -->
+ <text
+ v-if="label !== ''"
+ class="u-icon__label"
+ :style="{
+ color: labelColor,
+ fontSize: $u.addUnit(labelSize),
+ marginLeft: labelPos == 'right' ? $u.addUnit(space) : 0,
+ marginTop: labelPos == 'bottom' ? $u.addUnit(space) : 0,
+ marginRight: labelPos == 'left' ? $u.addUnit(space) : 0,
+ marginBottom: labelPos == 'top' ? $u.addUnit(space) : 0,
+ }"
+ >{{ label }}</text>
+ </view>
+</template>
+
+<script>
+ // #ifdef APP-NVUE
+ // nvue������weex���dom������������������������������������������������
+ // https://weex.apache.org/zh/docs/modules/dom.html#addrule
+ const fontUrl = 'https://at.alicdn.com/t/font_2225171_8kdcwk4po24.ttf'
+ const domModule = weex.requireModule('dom')
+ domModule.addRule('fontFace', {
+ 'fontFamily': "uicon-iconfont",
+ 'src': `url('${fontUrl}')`
+ })
+ // #endif
+
+ // ������������������������������������unicode
+ import icons from './icons'
+
+ import props from './props.js';;
+
+ /**
+ * icon ������
+ * @description ���������������������������������������������������������������������
+ * @tutorial https://www.uviewui.com/components/icon.html
+ * @property {String} name ���������������������������������
+ * @property {String} color ������������,������������������ ��������� color['u-content-color'] ���
+ * @property {String | Number} size ���������������������������px ��������� '16px' ���
+ * @property {Boolean} bold ������������������ ��������� false ���
+ * @property {String | Number} index ������������������������������������������index������������������������������������
+ * @property {String} hoverClass ���������������������������������������uni���view���������hoverClass������������������������
+ * @property {String} customPrefix ������������������������������������������������������������ ��������� 'uicon' ���
+ * @property {String | Number} label ���������������label������
+ * @property {String} labelPos label���������������������������������right���bottom ��������� 'right' ���
+ * @property {String | Number} labelSize label���������������������px ��������� '15px' ���
+ * @property {String} labelColor ���������������label������������ ��� ������ color['u-content-color'] ���
+ * @property {String | Number} space label���������������������������px ��������� '3px' ���
+ * @property {String} imgMode ���������mode
+ * @property {String | Number} width ���������������������������������
+ * @property {String | Number} height ���������������������������������
+ * @property {String | Number} top ��������������������������������� ������������������������������������������������������������ ��������� 0 ���
+ * @property {Boolean} stop ������������������������ ��������� false ���
+ * @property {Object} customStyle icon������������������������
+ * @event {Function} click ���������������������
+ * @event {Function} touchstart ���������������������
+ * @example <u-icon name="photo" color="#2979ff" size="28"></u-icon>
+ */
+ export default {
+ name: 'u-icon',
+ data() {
+ return {
+
+ }
+ },
+ mixins: [uni.$u.mpMixin, uni.$u.mixin,props],
+ computed: {
+ uClasses() {
+ let classes = []
+ classes.push(this.customPrefix + '-' + this.name)
+ // // uView���������������������������u-iconfont
+ // if (this.customPrefix == 'uicon') {
+ // classes.push('u-iconfont')
+ // } else {
+ // classes.push(this.customPrefix)
+ // }
+ // ���������������������������
+ if (this.color && uni.$u.config.type.includes(this.color)) classes.push('u-icon__icon--' + this.color)
+ // ���������������������������������������������������������������������������������[a, b, c]������������������������������
+ // ���������������������������������������������������������������������������
+ //#ifdef MP-ALIPAY || MP-TOUTIAO || MP-BAIDU
+ classes = classes.join(' ')
+ //#endif
+ return classes
+ },
+ iconStyle() {
+ let style = {}
+ style = {
+ fontSize: uni.$u.addUnit(this.size),
+ lineHeight: uni.$u.addUnit(this.size),
+ fontWeight: this.bold ? 'bold' : 'normal',
+ // ������������������������������������������������������������������������������������
+ top: uni.$u.addUnit(this.top)
+ }
+ // ���������������������������������������
+ if (this.color && !uni.$u.config.type.includes(this.color)) style.color = this.color
+
+ return style
+ },
+ // ���������������name������������������������������������������"/"������������������������
+ isImg() {
+ return this.name.indexOf('/') !== -1
+ },
+ imgStyle() {
+ let style = {}
+ // ������������width���height���������������������������������������size������
+ style.width = this.width ? uni.$u.addUnit(this.width) : uni.$u.addUnit(this.size)
+ style.height = this.height ? uni.$u.addUnit(this.height) : uni.$u.addUnit(this.size)
+ return style
+ },
+ // ���������������������������������������
+ icon() {
+ // ������������������������������������������������������������������name������������������������������������unicode������
+ return icons['uicon-' + this.name] || this.name
+ }
+ },
+ methods: {
+ clickHandler(e) {
+ this.$emit('click', this.index)
+ // ������������������������
+ this.stop && this.preventEvent(e)
+ }
+ }
+ }
+</script>
+
+<style lang="scss" scoped>
+ @import "../../libs/css/components.scss";
+
+ // ������������
+ $u-icon-primary: $u-primary !default;
+ $u-icon-success: $u-success !default;
+ $u-icon-info: $u-info !default;
+ $u-icon-warning: $u-warning !default;
+ $u-icon-error: $u-error !default;
+ $u-icon-label-line-height:1 !default;
+
+ /* #ifndef APP-NVUE */
+ // ���nvue���������������
+ @font-face {
+ font-family: 'uicon-iconfont';
+ src: url('https://at.alicdn.com/t/font_2225171_8kdcwk4po24.ttf') format('truetype');
+ }
+
+ /* #endif */
+
+ .u-icon {
+ /* #ifndef APP-NVUE */
+ display: flex;
+ /* #endif */
+ align-items: center;
+
+ &--left {
+ flex-direction: row-reverse;
+ align-items: center;
+ }
+
+ &--right {
+ flex-direction: row;
+ align-items: center;
+ }
+
+ &--top {
+ flex-direction: column-reverse;
+ justify-content: center;
+ }
+
+ &--bottom {
+ flex-direction: column;
+ justify-content: center;
+ }
+
+ &__icon {
+ font-family: uicon-iconfont;
+ position: relative;
+ @include flex;
+ align-items: center;
+
+ &--primary {
+ color: $u-icon-primary;
+ }
+
+ &--success {
+ color: $u-icon-success;
+ }
+
+ &--error {
+ color: $u-icon-error;
+ }
+
+ &--warning {
+ color: $u-icon-warning;
+ }
+
+ &--info {
+ color: $u-icon-info;
+ }
+ }
+
+ &__img {
+ /* #ifndef APP-NVUE */
+ height: auto;
+ will-change: transform;
+ /* #endif */
+ }
+
+ &__label {
+ /* #ifndef APP-NVUE */
+ line-height: $u-icon-label-line-height;
+ /* #endif */
+ }
+ }
+</style>
diff --git a/uni_modules/uview-ui/components/u-image/props.js b/uni_modules/uview-ui/components/u-image/props.js
new file mode 100644
index 0000000..2eabb74
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-image/props.js
@@ -0,0 +1,84 @@
+export default {
+ props: {
+ // ������������
+ src: {
+ type: String,
+ default: uni.$u.props.image.src
+ },
+ // ������������
+ mode: {
+ type: String,
+ default: uni.$u.props.image.mode
+ },
+ // ���������������������
+ width: {
+ type: [String, Number],
+ default: uni.$u.props.image.width
+ },
+ // ���������������������
+ height: {
+ type: [String, Number],
+ default: uni.$u.props.image.height
+ },
+ // ���������������circle-���������square-������
+ shape: {
+ type: String,
+ default: uni.$u.props.image.shape
+ },
+ // ���������������������
+ radius: {
+ type: [String, Number],
+ default: uni.$u.props.image.radius
+ },
+ // ������������������������������������App������������������������������������������
+ lazyLoad: {
+ type: Boolean,
+ default: uni.$u.props.image.lazyLoad
+ },
+ // ������������������������������������������������������
+ showMenuByLongpress: {
+ type: Boolean,
+ default: uni.$u.props.image.showMenuByLongpress
+ },
+ // ������������������������������������
+ loadingIcon: {
+ type: String,
+ default: uni.$u.props.image.loadingIcon
+ },
+ // ���������������������������������������
+ errorIcon: {
+ type: String,
+ default: uni.$u.props.image.errorIcon
+ },
+ // ������������������������������������������������slot
+ showLoading: {
+ type: Boolean,
+ default: uni.$u.props.image.showLoading
+ },
+ // ���������������������������������������������������slot
+ showError: {
+ type: Boolean,
+ default: uni.$u.props.image.showError
+ },
+ // ������������������������
+ fade: {
+ type: Boolean,
+ default: uni.$u.props.image.fade
+ },
+ // ���������������������������������������������������
+ webp: {
+ type: Boolean,
+ default: uni.$u.props.image.webp
+ },
+ // ���������������������ms
+ duration: {
+ type: [String, Number],
+ default: uni.$u.props.image.duration
+ },
+ // ���������������������������������������������������������������������������
+ bgColor: {
+ type: String,
+ default: uni.$u.props.image.bgColor
+ }
+ }
+}
diff --git a/uni_modules/uview-ui/components/u-image/u-image.vue b/uni_modules/uview-ui/components/u-image/u-image.vue
new file mode 100644
index 0000000..473e35b
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-image/u-image.vue
@@ -0,0 +1,232 @@
+<template>
+ <u-transition
+ mode="fade"
+ :show="show"
+ :duration="fade ? 1000 : 0"
+ >
+ <view
+ class="u-image"
+ @tap="onClick"
+ :style="[wrapStyle, backgroundStyle]"
+ >
+ <image
+ v-if="!isError"
+ :src="src"
+ :mode="mode"
+ @error="onErrorHandler"
+ @load="onLoadHandler"
+ :show-menu-by-longpress="showMenuByLongpress"
+ :lazy-load="lazyLoad"
+ class="u-image__image"
+ :style="{
+ borderRadius: shape == 'circle' ? '10000px' : $u.addUnit(radius),
+ width: $u.addUnit(width),
+ height: $u.addUnit(height)
+ }"
+ ></image>
+ <view
+ v-if="showLoading && loading"
+ class="u-image__loading"
+ :style="{
+ borderRadius: shape == 'circle' ? '50%' : $u.addUnit(radius),
+ backgroundColor: this.bgColor,
+ width: $u.addUnit(width),
+ height: $u.addUnit(height)
+ }"
+ >
+ <slot name="loading">
+ <u-icon
+ :name="loadingIcon"
+ :width="width"
+ :height="height"
+ ></u-icon>
+ </slot>
+ </view>
+ <view
+ v-if="showError && isError && !loading"
+ class="u-image__error"
+ :style="{
+ borderRadius: shape == 'circle' ? '50%' : $u.addUnit(radius),
+ width: $u.addUnit(width),
+ height: $u.addUnit(height)
+ }"
+ >
+ <slot name="error">
+ <u-icon
+ :name="errorIcon"
+ :width="width"
+ :height="height"
+ ></u-icon>
+ </slot>
+ </view>
+ </view>
+ </u-transition>
+</template>
+
+<script>
+ import props from './props.js';
+ /**
+ * Image ������
+ * @description ������������uni-app���image������������������������������������������������������������������������������������������������������������������������������������
+ * @tutorial https://uviewui.com/components/image.html
+ * @property {String} src ������������
+ * @property {String} mode ������������������������������ ��������� 'aspectFill' ���
+ * @property {String | Number} width ������������������������������������������������px������ ��������� '300' ���
+ * @property {String | Number} height ������������������������������������������������px������ ��������� '225' ���
+ * @property {String} shape ���������������circle-���������square-������ ��������� 'square' ���
+ * @property {String | Number} radius ���������������������������������������������������px������ ��������� 0 ���
+ * @property {Boolean} lazyLoad ���������������������������������������App������������������������������������������������ ��������� true ���
+ * @property {Boolean} showMenuByLongpress ��������������������������������������������������������������������������������� ��������� true ���
+ * @property {String} loadingIcon ������������������������������������ ��������� 'photo' ���
+ * @property {String} errorIcon ��������������������������������������� ��������� 'error-circle' ���
+ * @property {Boolean} showLoading ������������������������������������������������slot ��������� true ���
+ * @property {Boolean} showError ���������������������������������������������������slot ��������� true ���
+ * @property {Boolean} fade ������������������������ ��������� true ���
+ * @property {Boolean} webp ��������������������������������������������������� ��������� false ���
+ * @property {String | Number} duration ������fade������������������������������ms ��������� 500 ���
+ * @property {String} bgColor ��������������������������������������������������������������������������� (������ '#f3f4f6' )
+ * @property {Object} customStyle ���������������������������������
+ * @event {Function} click ���������������������
+ * @event {Function} error ���������������������������
+ * @event {Function} load ���������������������������
+ * @example <u-image width="100%" height="300px" :src="src"></u-image>
+ */
+ export default {
+ name: 'u-image',
+ mixins: [uni.$u.mpMixin, uni.$u.mixin, props],
+ data() {
+ return {
+ // ���������������������������������������������������������������
+ isError: false,
+ // ���������������������������������������������
+ loading: true,
+ // ������������������������������������������������
+ opacity: 1,
+ // ���������������������props���������������������������������������������
+ durationTime: this.duration,
+ // ������������������������������������������������������������png������������������������������������
+ backgroundStyle: {},
+ // ������fade���������������������������������
+ show: false
+ };
+ },
+ watch: {
+ src: {
+ immediate: true,
+ handler(n) {
+ if (!n) {
+ // ������������null������''���������false���������undefined������������������������
+ this.isError = true
+
+ } else {
+ this.isError = false;
+ this.loading = true;
+ }
+ }
+ }
+ },
+ computed: {
+ wrapStyle() {
+ let style = {};
+ // ������������addUnit()������������������������������������������px���������������������������������������������������������������rpx������
+ style.width = this.$u.addUnit(this.width);
+ style.height = this.$u.addUnit(this.height);
+ // ������������������������������������������������������������
+ style.borderRadius = this.shape == 'circle' ? '10000px' : uni.$u.addUnit(this.radius)
+ // ���������������������������������hidden���������������������������
+ style.overflow = this.borderRadius > 0 ? 'hidden' : 'visible'
+ // if (this.fade) {
+ // style.opacity = this.opacity
+ // // nvue���������������������������������������
+ // style.transitionDuration = `${this.durationTime}ms`
+ // style.transitionTimingFunction = 'ease-in-out'
+ // style.transitionProperty = 'opacity'
+ // }
+ return uni.$u.deepMerge(style, uni.$u.addStyle(this.customStyle));
+
+ }
+ },
+ mounted() {
+ this.show = true
+ },
+ methods: {
+ // ������������
+ onClick() {
+ this.$emit('click')
+ },
+ // ������������������
+ onErrorHandler(err) {
+ this.loading = false
+ this.isError = true
+ this.$emit('error', err)
+ },
+ // ���������������������������loading������
+ onLoadHandler(event) {
+ this.loading = false
+ this.isError = false
+ this.$emit('load', event)
+ this.removeBgColor()
+ // ���������������������������������������������������������������������������������������������
+ // ������������fade������������png���������������������������������������
+ // if (!this.fade) return this.removeBgColor();
+ // // ������opacity���1(������������������������������������)���������0(���������������������������������������������������������������������)������������1������������������������������
+ // this.opacity = 0;
+ // // ���������������0���������������������������������������������������������������0������������������������������������������duration������������������������������(������)
+ // // ������������������������������������������
+ // this.durationTime = 0;
+ // // ������50ms���������������������H5���������������������
+ // setTimeout(() => {
+ // this.durationTime = this.duration;
+ // this.opacity = 1;
+ // setTimeout(() => {
+ // this.removeBgColor();
+ // }, this.durationTime);
+ // }, 50);
+ },
+ // ������������������������
+ removeBgColor() {
+ // ������������������������������������������������������������������png������������������������������
+ this.backgroundStyle = {
+ backgroundColor: 'transparent'
+ };
+ }
+ }
+ };
+</script>
+
+<style lang="scss" scoped>
+ @import '../../libs/css/components.scss';
+
+ $u-image-error-top:0px !default;
+ $u-image-error-left:0px !default;
+ $u-image-error-width:100% !default;
+ $u-image-error-hight:100% !default;
+ $u-image-error-background-color:$u-bg-color !default;
+ $u-image-error-color:$u-tips-color !default;
+ $u-image-error-font-size: 46rpx !default;
+
+ .u-image {
+ position: relative;
+ transition: opacity 0.5s ease-in-out;
+
+ &__image {
+ width: 100%;
+ height: 100%;
+ }
+
+ &__loading,
+ &__error {
+ position: absolute;
+ top: $u-image-error-top;
+ left: $u-image-error-left;
+ width: $u-image-error-width;
+ height: $u-image-error-hight;
+ @include flex;
+ align-items: center;
+ justify-content: center;
+ background-color: $u-image-error-background-color;
+ color: $u-image-error-color;
+ font-size: $u-image-error-font-size;
+ }
+ }
+</style>
diff --git a/uni_modules/uview-ui/components/u-index-anchor/props.js b/uni_modules/uview-ui/components/u-index-anchor/props.js
new file mode 100644
index 0000000..6d8b59a
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-index-anchor/props.js
@@ -0,0 +1,29 @@
+export default {
+ props: {
+ // ������������������������
+ text: {
+ type: [String, Number],
+ default: uni.$u.props.indexAnchor.text
+ },
+ // ������������������������
+ color: {
+ type: String,
+ default: uni.$u.props.indexAnchor.color
+ },
+ // ���������������������������������������px
+ size: {
+ type: [String, Number],
+ default: uni.$u.props.indexAnchor.size
+ },
+ // ������������������������
+ bgColor: {
+ type: String,
+ default: uni.$u.props.indexAnchor.bgColor
+ },
+ // ���������������������������������px
+ height: {
+ type: [String, Number],
+ default: uni.$u.props.indexAnchor.height
+ }
+ }
+}
diff --git a/uni_modules/uview-ui/components/u-index-anchor/u-index-anchor.vue b/uni_modules/uview-ui/components/u-index-anchor/u-index-anchor.vue
new file mode 100644
index 0000000..b95ddef
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-index-anchor/u-index-anchor.vue
@@ -0,0 +1,91 @@
+<template>
+ <!-- #ifdef APP-NVUE -->
+ <header>
+ <!-- #endif -->
+ <view
+ class="u-index-anchor u-border-bottom"
+ :ref="`u-index-anchor-${text}`"
+ :style="{
+ height: $u.addUnit(height),
+ backgroundColor: bgColor
+ }"
+ >
+ <text
+ class="u-index-anchor__text"
+ :style="{
+ fontSize: $u.addUnit(size),
+ color: color
+ }"
+ >{{ text }}</text>
+ </view>
+ <!-- #ifdef APP-NVUE -->
+ </header>
+ <!-- #endif -->
+</template>
+
+<script>
+ import props from './props.js';
+ // #ifdef APP-NVUE
+ const dom = uni.requireNativePlugin('dom')
+ // #endif
+ /**
+ * IndexAnchor ������������
+ * @description
+ * @tutorial https://uviewui.com/components/indexList.html
+ * @property {String | Number} text ������������������������
+ * @property {String} color ������������������������ ( ������ '#606266' )
+ * @property {String | Number} size ���������������������������������������px ( ������ 14 )
+ * @property {String} bgColor ������������������������ ( ������ '#dedede' )
+ * @property {String | Number} height ���������������������������������px ( ������ 32 )
+ * @example <u-index-anchor :text="indexList[index]"></u-index-anchor>
+ */
+ export default {
+ name: 'u-index-anchor',
+ mixins: [uni.$u.mpMixin, uni.$u.mixin,props],
+ data() {
+ return {
+ }
+ },
+ mounted() {
+ this.init()
+ },
+ methods: {
+ init() {
+ // ������������������������������������������������������parent������
+ const indexList = uni.$u.$parent.call(this, 'u-index-list')
+ if (!indexList) {
+ return uni.$u.error('u-index-anchor���������������u-index-list������������')
+ }
+ // ������������������������u-index-list���
+ indexList.anchors.push(this)
+ const indexListItem = uni.$u.$parent.call(this, 'u-index-item')
+ // #ifndef APP-NVUE
+ // ������������nvue������u-index-anchor���������������u-index-item������
+ if (!indexListItem) {
+ return uni.$u.error('u-index-anchor���������������u-index-item������������')
+ }
+ // ������u-index-item���id���anchor���text���������������������nvue���������������������������scroll-view������������������������
+ indexListItem.id = this.text.charCodeAt(0)
+ // #endif
+ }
+ },
+ }
+</script>
+
+<style lang="scss" scoped>
+ @import "../../libs/css/components.scss";
+
+ .u-index-anchor {
+ position: sticky;
+ top: 0;
+ @include flex;
+ align-items: center;
+ padding-left: 15px;
+ z-index: 1;
+
+ &__text {
+ @include flex;
+ align-items: center;
+ }
+ }
+</style>
diff --git a/uni_modules/uview-ui/components/u-index-item/props.js b/uni_modules/uview-ui/components/u-index-item/props.js
new file mode 100644
index 0000000..7c11331
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-index-item/props.js
@@ -0,0 +1,5 @@
+export default {
+ props: {
+
+ }
+}
diff --git a/uni_modules/uview-ui/components/u-index-item/u-index-item.vue b/uni_modules/uview-ui/components/u-index-item/u-index-item.vue
new file mode 100644
index 0000000..0bc7fb3
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-index-item/u-index-item.vue
@@ -0,0 +1,87 @@
+<template>
+ <!-- #ifdef APP-NVUE -->
+ <cell ref="u-index-item">
+ <!-- #endif -->
+ <view
+ class="u-index-item"
+ :id="`u-index-item-${id}`"
+ :class="[`u-index-item-${id}`]"
+ >
+ <slot />
+ </view>
+ <!-- #ifdef APP-NVUE -->
+ </cell>
+ <!-- #endif -->
+</template>
+
+<script>
+ import props from './props.js';
+ // #ifdef APP-NVUE
+ // ������weex������������KPI���������������������������������������������������������������������������dom���������������������
+ const dom = uni.requireNativePlugin('dom')
+ // #endif
+ /**
+ * IndexItem
+ * @description
+ * @tutorial https://uviewui.com/components/indexList.html
+ * @property {String}
+ * @event {Function}
+ * @example
+ */
+ export default {
+ name: 'u-index-item',
+ mixins: [uni.$u.mpMixin, uni.$u.mixin,props],
+ data() {
+ return {
+ // ������������������������������������
+ top: 0,
+ height: 0,
+ id: ''
+ }
+ },
+ created() {
+ // ���������u-index-anchor���������
+ this.anchor = {}
+ },
+ mounted() {
+ this.init()
+ },
+ methods: {
+ init() {
+ // ������������������������������������������������������parent������
+ this.getParentData('u-index-list')
+ if (!this.parent) {
+ return uni.$u.error('u-index-item���������������u-index-list������������')
+ }
+ uni.$u.sleep().then(() =>{
+ this.getIndexItemRect().then(size => {
+ // ������������������������������������������������������������������children���������������������top������������������������������������
+ this.top = Math.ceil(size.top)
+ this.height = Math.ceil(size.height)
+ })
+ })
+ },
+ getIndexItemRect() {
+ return new Promise(resolve => {
+ // #ifndef APP-NVUE
+ this.$uGetRect('.u-index-item').then(size => {
+ resolve(size)
+ })
+ // #endif
+
+ // #ifdef APP-NVUE
+ const ref = this.$refs['u-index-item']
+ dom.getComponentRect(ref, res => {
+ resolve(res.size)
+ })
+ // #endif
+ })
+ }
+ },
+ }
+</script>
+
+<style lang="scss" scoped>
+ @import "../../libs/css/components.scss";
+
+</style>
diff --git a/uni_modules/uview-ui/components/u-index-list/props.js b/uni_modules/uview-ui/components/u-index-list/props.js
new file mode 100644
index 0000000..354d459
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-index-list/props.js
@@ -0,0 +1,29 @@
+export default {
+ props: {
+ // ������������������������������
+ inactiveColor: {
+ type: String,
+ default: uni.$u.props.indexList.inactiveColor
+ },
+ // ���������������������������
+ activeColor: {
+ type: String,
+ default: uni.$u.props.indexList.activeColor
+ },
+ // ���������������������������������
+ indexList: {
+ type: Array,
+ default: uni.$u.props.indexList.indexList
+ },
+ // ������������������������������
+ sticky: {
+ type: Boolean,
+ default: uni.$u.props.indexList.sticky
+ },
+ // ���������������������������
+ customNavHeight: {
+ type: [String, Number],
+ default: uni.$u.props.indexList.customNavHeight
+ }
+ }
+}
diff --git a/uni_modules/uview-ui/components/u-index-list/u-index-list.vue b/uni_modules/uview-ui/components/u-index-list/u-index-list.vue
new file mode 100644
index 0000000..d712618
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-index-list/u-index-list.vue
@@ -0,0 +1,440 @@
+<template>
+ <view class="u-index-list">
+ <!-- #ifdef APP-NVUE -->
+ <list
+ :scrollTop="scrollTop"
+ enable-back-to-top
+ :offset-accuracy="1"
+ :style="{
+ maxHeight: $u.addUnit(scrollViewHeight)
+ }"
+ @scroll="scrollHandler"
+ ref="uList"
+ >
+ <cell
+ v-if="$slots.header"
+ ref="header"
+ >
+ <slot name="header" />
+ </cell>
+ <slot />
+ <cell v-if="$slots.footer">
+ <slot name="footer" />
+ </cell>
+ </list>
+ <!-- #endif -->
+ <!-- #ifndef APP-NVUE -->
+ <scroll-view
+ :scrollTop="scrollTop"
+ :scrollIntoView="scrollIntoView"
+ :offset-accuracy="1"
+ :style="{
+ maxHeight: $u.addUnit(scrollViewHeight)
+ }"
+ scroll-y
+ @scroll="scrollHandler"
+ ref="uList"
+ >
+ <view v-if="$slots.header">
+ <slot name="header" />
+ </view>
+ <slot />
+ <view v-if="$slots.footer">
+ <slot name="footer" />
+ </view>
+ </scroll-view>
+ <!-- #endif -->
+ <view
+ class="u-index-list__letter"
+ ref="u-index-list__letter"
+ :style="{ top: $u.addUnit(letterInfo.top || 100) }"
+ @touchstart="touchStart"
+ @touchmove.stop.prevent="touchMove"
+ @touchend.stop.prevent="touchEnd"
+ @touchcancel.stop.prevent="touchEnd"
+ >
+ <view
+ class="u-index-list__letter__item"
+ v-for="(item, index) in uIndexList"
+ :key="index"
+ :style="{
+ backgroundColor: activeIndex === index ? activeColor : 'transparent'
+ }"
+ >
+ <text
+ class="u-index-list__letter__item__index"
+ :style="{color: activeIndex === index ? '#fff' : inactiveColor}"
+ >{{ item }}</text>
+ </view>
+ </view>
+ <u-transition
+ mode="fade"
+ :show="touching"
+ :customStyle="{
+ position: 'fixed',
+ right: '50px',
+ top: $u.addUnit(indicatorTop),
+ zIndex: 2
+ }"
+ >
+ <view
+ class="u-index-list__indicator"
+ :class="['u-index-list__indicator--show']"
+ :style="{
+ height: $u.addUnit(indicatorHeight),
+ width: $u.addUnit(indicatorHeight)
+ }"
+ >
+ <text class="u-index-list__indicator__text">{{ uIndexList[activeIndex] }}</text>
+ </view>
+ </u-transition>
+ </view>
+</template>
+
+<script>
+ const indexList = () => {
+ const indexList = [];
+ const charCodeOfA = 'A'.charCodeAt(0);
+ for (let i = 0; i < 26; i++) {
+ indexList.push(String.fromCharCode(charCodeOfA + i));
+ }
+ return indexList;
+ }
+ import props from './props.js';
+ // #ifdef APP-NVUE
+ // ������weex������������KPI���������������������������������������������������������������������������dom���������������������
+ const dom = uni.requireNativePlugin('dom')
+ // #endif
+ /**
+ * IndexList ������������
+ * @description ������������������������������������
+ * @tutorial https://uviewui.com/components/indexList.html
+ * @property {String} inactiveColor ������������������������������ ( ������ '#606266' )
+ * @property {String} activeColor ��������������������������� ( ������ '#5677fc' )
+ * @property {Array} indexList ���������������������������������
+ * @property {Boolean} sticky ������������������������������ ( ������ true )
+ * @property {String | Number} customNavHeight ��������������������������� ( ������ 0 )
+ * */
+ export default {
+ name: 'u-index-list',
+ mixins: [uni.$u.mpMixin, uni.$u.mixin, props],
+ // #ifdef MP-WEIXIN
+ // ���������������������������������������������������Vue������������������������������������flex������
+ options: {
+ virtualHost: true
+ },
+ // #endif
+ data() {
+ return {
+ // ������������������������������������
+ activeIndex: -1,
+ touchmoveIndex: 1,
+ // ���������������������
+ letterInfo: {
+ height: 0,
+ itemHeight: 0,
+ top: 0
+ },
+ // ������������������������������������������������������������������������������������������������������������������������������������
+ indicatorHeight: 50,
+ // ������������������������top���������������������������������������������
+ // indicatorTop: 0
+ // ���������������������������������
+ touching: false,
+ // ���������������top���
+ scrollTop: 0,
+ // scroll-view���������
+ scrollViewHeight: 0,
+ // ������������
+ sys: uni.$u.sys(),
+ scrolling: false,
+ scrollIntoView: '',
+ }
+ },
+ computed: {
+ // ������������������������indexList������������������������������������������������A-Z������
+ uIndexList() {
+ return this.indexList.length ? this.indexList : indexList()
+ },
+ // ������������������������top���������������������������������������������
+ indicatorTop() {
+ const {
+ top,
+ itemHeight
+ } = this.letterInfo
+ return Math.floor(top + itemHeight * this.activeIndex + itemHeight / 2 - this.indicatorHeight / 2)
+ }
+ },
+ watch: {
+ // ������������������������������������������������
+ uIndexList: {
+ immediate: true,
+ handler() {
+ uni.$u.sleep().then(() => {
+ this.setIndexListLetterInfo()
+ })
+ }
+ }
+ },
+ created() {
+ this.children = []
+ this.anchors = []
+ this.init()
+ },
+ mounted() {
+ this.setIndexListLetterInfo()
+ },
+ methods: {
+ init() {
+ // ���������������������������������������������
+ //������this.customNavHeight���������this.scrollViewHeight���������maxHeight
+ //���������u-index-list������������tabbar���������,scroll-view������������������������������
+ this.scrollViewHeight = this.sys.windowHeight - this.customNavHeight
+ },
+ // ���������������������
+ touchStart(e) {
+ // ���������������������
+ const touchStart = e.changedTouches[0]
+ if (!touchStart) return
+ this.touching = true
+ const {
+ pageY
+ } = touchStart
+ // ������������������������������������������������������������������������
+ const currentIndex = this.getIndexListLetter(pageY)
+ this.setValueForTouch(currentIndex)
+ },
+ // ������������������������������������
+ touchMove(e) {
+ // ���������������������
+ let touchMove = e.changedTouches[0]
+ if (!touchMove) return;
+
+ // ������������������������������������������������ touching ��� false ��������������� indicator ������
+ if (!this.touching) {
+ this.touching = true
+ }
+ const {
+ pageY
+ } = touchMove
+ const currentIndex = this.getIndexListLetter(pageY)
+ this.setValueForTouch(currentIndex)
+ },
+ // ������������
+ touchEnd(e) {
+ // ���������������������������������������������������������������������������������������������������������������u-transition���show���������������
+ uni.$u.sleep(300).then(() => {
+ this.touching = false
+ })
+ },
+ // ������������������������������������������������������������
+ getIndexListLetterRect() {
+ return new Promise(resolve => {
+ // ������������������������������dom������
+ // #ifndef APP-NVUE
+ this.$uGetRect('.u-index-list__letter').then(size => {
+ resolve(size)
+ })
+ // #endif
+
+ // #ifdef APP-NVUE
+ const ref = this.$refs['u-index-list__letter']
+ dom.getComponentRect(ref, res => {
+ resolve(res.size)
+ })
+ // #endif
+ })
+ },
+ // ������indexList���������������������
+ setIndexListLetterInfo() {
+ this.getIndexListLetterRect().then(size => {
+ const {
+ height
+ } = size
+ const sys = uni.$u.sys()
+ const windowHeight = sys.windowHeight
+ let customNavHeight = 0
+ // ���������������������������������������������������������������������������������������������������
+ if (this.customNavHeight == 0) {
+ // #ifdef H5
+ customNavHeight = sys.windowTop
+ // #endif
+ // #ifndef H5
+ // ������H5���������������������������������������������windowHeight���������������������������������������������������������������������������
+ customNavHeight = -(sys.statusBarHeight + 44)
+ // #endif
+ } else {
+ customNavHeight = uni.$u.getPx(this.customNavHeight)
+ }
+ this.letterInfo = {
+ height,
+ // ������������������������������������������������������������������������������������������������������������������������
+ top: (windowHeight - height) / 2 + customNavHeight / 2,
+ itemHeight: Math.floor(height / this.uIndexList.length)
+ }
+ })
+ },
+ // ������������������������������������
+ getIndexListLetter(pageY) {
+ const {
+ top,
+ height,
+ itemHeight
+ } = this.letterInfo
+ // ���H5���pageY���������������������������uni-app���������������H5���������������������������H5���������������������������������
+ // #ifdef H5
+ pageY += uni.$u.sys().windowTop
+ // #endif
+ // ���������������������������������������������������������������������������������������������������������������������������������
+ if (pageY < top) {
+ return 0
+ } else if (pageY >= top + height) {
+ // ���������������������������������������
+ return this.uIndexList.length - 1
+ } else {
+ // ���������������Y������������������������������������top������������������������������������������������������������������������������������
+ return Math.floor((pageY - top) / itemHeight);
+ }
+ },
+ // ������������������������������������������
+ setValueForTouch(currentIndex) {
+ // ������������������������������������������������������������������������������������������������
+ if (currentIndex === this.activeIndex) return
+ this.activeIndex = currentIndex
+ // #ifndef APP-NVUE || MP-WEIXIN
+ // ������nvue������������anchor���item������u-index-item���������������������index-item������������
+ this.scrollIntoView = `u-index-item-${this.uIndexList[currentIndex].charCodeAt(0)}`
+ // #endif
+ // #ifdef MP-WEIXIN
+ // ���������������������scroll-view���scroll-into-view���������������slot���������������id���������������������������scrollTop���������������������������
+ this.scrollTop = this.children[currentIndex].top
+ // #endif
+ // #ifdef APP-NVUE
+ // ���nvue������������cell���header������������������������������������������header(anchor)������������
+ const anchor = `u-index-anchor-${this.uIndexList[currentIndex]}`
+ dom.scrollToElement(this.anchors[currentIndex].$refs[anchor], {
+ offset: 0,
+ animated: false
+ })
+ // #endif
+ },
+ getHeaderRect() {
+ // ������header slot������������������list���������������������������������������top������
+ return new Promise(resolve => {
+ dom.getComponentRect(this.$refs.header, res => {
+ resolve(res.size)
+ })
+ })
+ },
+ // scroll-view���������������
+ async scrollHandler(e) {
+ if (this.touching || this.scrolling) return
+ // ������������������������������������������������������������������������������
+ this.scrolling = true
+ uni.$u.sleep(10).then(() => {
+ this.scrolling = false
+ })
+ let scrollTop = 0
+ const len = this.children.length
+ let children = this.children
+ const anchors = this.anchors
+ // #ifdef APP-NVUE
+ // nvue���������������������������������������������������������
+ scrollTop = Math.abs(e.contentOffset.y)
+ // ������header slot���������������
+ const header = await this.getHeaderRect()
+ // item���top���������nvue������������������anchor���top������������nvue������index-item���top
+ let top = header.height
+ // ������list������������������cell���top������������������header slot���������item���������height���������������������nvue������������������
+ children = this.children.map((item, index) => {
+ const child = {
+ height: item.height,
+ top
+ }
+ // ���������������������������item������������������
+ top += item.height + anchors[index].height
+ return child
+ })
+ // #endif
+ // #ifndef APP-NVUE
+ // ���nvue������detail���������������������
+ scrollTop = e.detail.scrollTop
+ // #endif
+ for (let i = 0; i < len; i++) {
+ const item = children[i],
+ nextItem = children[i + 1]
+ // ������������������������������������item���top���������������������������������������������
+ if (scrollTop <= children[0].top || scrollTop >= children[len - 1].top + children[len -
+ 1].height) {
+ this.activeIndex = -1
+ break
+ } else if (!nextItem) {
+ // ���������������������item���������������������������������������
+ this.activeIndex = len - 1
+ break
+ } else if (scrollTop > item.top && scrollTop < nextItem.top) {
+ this.activeIndex = i
+ break
+ }
+ }
+ },
+ },
+ }
+</script>
+
+<style lang="scss" scoped>
+ @import "../../libs/css/components.scss";
+
+ .u-index-list {
+
+ &__letter {
+ position: fixed;
+ right: 0;
+ text-align: center;
+ z-index: 3;
+ padding: 0 6px;
+
+ &__item {
+ width: 16px;
+ height: 16px;
+ border-radius: 100px;
+ margin: 1px 0;
+ @include flex;
+ align-items: center;
+ justify-content: center;
+
+ &--active {
+ background-color: $u-primary;
+ }
+
+ &__index {
+ font-size: 12px;
+ text-align: center;
+ line-height: 12px;
+ }
+ }
+ }
+
+ &__indicator {
+ width: 50px;
+ height: 50px;
+ border-radius: 100px 100px 0 100px;
+ text-align: center;
+ color: #ffffff;
+ background-color: #c9c9c9;
+ transform: rotate(-45deg);
+ @include flex;
+ justify-content: center;
+ align-items: center;
+
+ &__text {
+ font-size: 28px;
+ line-height: 28px;
+ font-weight: bold;
+ color: #fff;
+ transform: rotate(45deg);
+ text-align: center;
+ }
+ }
+ }
+</style>
diff --git a/uni_modules/uview-ui/components/u-input/props.js b/uni_modules/uview-ui/components/u-input/props.js
new file mode 100644
index 0000000..2c50870
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-input/props.js
@@ -0,0 +1,187 @@
+export default {
+ props: {
+ // ������������
+ value: {
+ type: [String, Number],
+ default: uni.$u.props.input.value
+ },
+ // ���������������
+ // number-���������������������app-vue���������������������������app-nvue���������������������������������������
+ // idcard-������������������������������������������������������QQ���������
+ // digit-������������������������������App���nvue������������������������������������������������QQ���������
+ // text-������������������
+ type: {
+ type: String,
+ default: uni.$u.props.input.type
+ },
+ // ������ textarea ������������ position:fixed ������������������������������������ fixed ��� true���
+ // ������������������������������������������������������������������������QQ���������
+ fixed: {
+ type: Boolean,
+ default: uni.$u.props.input.fixed
+ },
+ // ���������������������
+ disabled: {
+ type: Boolean,
+ default: uni.$u.props.input.disabled
+ },
+ // ���������������������������
+ disabledColor: {
+ type: String,
+ default: uni.$u.props.input.disabledColor
+ },
+ // ������������������������
+ clearable: {
+ type: Boolean,
+ default: uni.$u.props.input.clearable
+ },
+ // ������������������
+ password: {
+ type: Boolean,
+ default: uni.$u.props.input.password
+ },
+ // ������������������������������ -1 ������������������������������
+ maxlength: {
+ type: [String, Number],
+ default: uni.$u.props.input.maxlength
+ },
+ // ������������������������������
+ placeholder: {
+ type: String,
+ default: uni.$u.props.input.placeholder
+ },
+ // ������placeholder���������������������������������������style���������scoped���������������������������/deep/
+ placeholderClass: {
+ type: String,
+ default: uni.$u.props.input.placeholderClass
+ },
+ // ������placeholder���������
+ placeholderStyle: {
+ type: [String, Object],
+ default: uni.$u.props.input.placeholderStyle
+ },
+ // ��������������������������������������� type ="text"���type ="textarea"���������
+ showWordLimit: {
+ type: Boolean,
+ default: uni.$u.props.input.showWordLimit
+ },
+ // ���������������������������������������������send|search|next|go|done������������������uni-app������
+ // https://uniapp.dcloud.io/component/input
+ // https://uniapp.dcloud.io/component/textarea
+ confirmType: {
+ type: String,
+ default: uni.$u.props.input.confirmType
+ },
+ // ������������������������������������������������������������H5������
+ confirmHold: {
+ type: Boolean,
+ default: uni.$u.props.input.confirmHold
+ },
+ // focus������������������������������������������������������������������
+ holdKeyboard: {
+ type: Boolean,
+ default: uni.$u.props.input.holdKeyboard
+ },
+ // ������������������
+ // ��� H5 ������������������������������������������������������������������������������������������������nvue ������������������������������������ focus()���blur() ������������������
+ focus: {
+ type: Boolean,
+ default: uni.$u.props.input.focus
+ },
+ // ������������������������������������������������������App3.0.0+������
+ autoBlur: {
+ type: Boolean,
+ default: uni.$u.props.input.autoBlur
+ },
+ // ������������ iOS ������������������������������������������������type=textarea���������
+ disableDefaultPadding: {
+ type: Boolean,
+ default: uni.$u.props.input.disableDefaultPadding
+ },
+ // ������focus������������������
+ cursor: {
+ type: [String, Number],
+ default: uni.$u.props.input.cursor
+ },
+ // ������������������������������������������
+ cursorSpacing: {
+ type: [String, Number],
+ default: uni.$u.props.input.cursorSpacing
+ },
+ // ���������������������������������������������������selection-end������������
+ selectionStart: {
+ type: [String, Number],
+ default: uni.$u.props.input.selectionStart
+ },
+ // ���������������������������������������������������selection-start������������
+ selectionEnd: {
+ type: [String, Number],
+ default: uni.$u.props.input.selectionEnd
+ },
+ // ������������������������������������������
+ adjustPosition: {
+ type: Boolean,
+ default: uni.$u.props.input.adjustPosition
+ },
+ // ���������������������������������������������left|center|right
+ inputAlign: {
+ type: String,
+ default: uni.$u.props.input.inputAlign
+ },
+ // ������������������������
+ fontSize: {
+ type: [String, Number],
+ default: uni.$u.props.input.fontSize
+ },
+ // ���������������������
+ color: {
+ type: String,
+ default: uni.$u.props.input.color
+ },
+ // ���������������������
+ prefixIcon: {
+ type: String,
+ default: uni.$u.props.input.prefixIcon
+ },
+ // ���������������������������������������
+ prefixIconStyle: {
+ type: [String, Object],
+ default: uni.$u.props.input.prefixIconStyle
+ },
+ // ���������������������
+ suffixIcon: {
+ type: String,
+ default: uni.$u.props.input.suffixIcon
+ },
+ // ���������������������������������������
+ suffixIconStyle: {
+ type: [String, Object],
+ default: uni.$u.props.input.suffixIconStyle
+ },
+ // ���������������surround-���������������bottom-���������������none-���������
+ border: {
+ type: String,
+ default: uni.$u.props.input.border
+ },
+ // ������������������disabled������������������disabled���������������������readonly���������
+ readonly: {
+ type: Boolean,
+ default: uni.$u.props.input.readonly
+ },
+ // ������������������circle-���������square-������
+ shape: {
+ type: String,
+ default: uni.$u.props.input.shape
+ },
+ // ������������������������������������������������
+ formatter: {
+ type: [Function, null],
+ default: uni.$u.props.input.formatter
+ },
+ // ���������������������������������������������������������
+ ignoreCompositionEvent: {
+ type: Boolean,
+ default: true
+ }
+ }
+}
diff --git a/uni_modules/uview-ui/components/u-input/u-input.vue b/uni_modules/uview-ui/components/u-input/u-input.vue
new file mode 100644
index 0000000..30073eb
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-input/u-input.vue
@@ -0,0 +1,354 @@
+<template>
+ <view class="u-input" :class="inputClass" :style="[wrapperStyle]">
+ <view class="u-input__content">
+ <view
+ class="u-input__content__prefix-icon"
+ v-if="prefixIcon || $slots.prefix"
+ >
+ <slot name="prefix">
+ <u-icon
+ :name="prefixIcon"
+ size="18"
+ :customStyle="prefixIconStyle"
+ ></u-icon>
+ </slot>
+ </view>
+ <view class="u-input__content__field-wrapper" @tap="clickHandler">
+ <!-- ������uni-app���input���������������H5���APP������������������password������(������true������false)���type������������������
+ ������������type=number���������������password���������type���������������������������password���undefined
+ -->
+ <input
+ class="u-input__content__field-wrapper__field"
+ :style="[inputStyle]"
+ :type="type"
+ :focus="focus"
+ :cursor="cursor"
+ :value="innerValue"
+ :auto-blur="autoBlur"
+ :disabled="disabled || readonly"
+ :maxlength="maxlength"
+ :placeholder="placeholder"
+ :placeholder-style="placeholderStyle"
+ :placeholder-class="placeholderClass"
+ :confirm-type="confirmType"
+ :confirm-hold="confirmHold"
+ :hold-keyboard="holdKeyboard"
+ :cursor-spacing="cursorSpacing"
+ :adjust-position="adjustPosition"
+ :selection-end="selectionEnd"
+ :selection-start="selectionStart"
+ :password="password || type === 'password' || undefined"
+ :ignoreCompositionEvent="ignoreCompositionEvent"
+ @input="onInput"
+ @blur="onBlur"
+ @focus="onFocus"
+ @confirm="onConfirm"
+ @keyboardheightchange="onkeyboardheightchange"
+ />
+ </view>
+ <view
+ class="u-input__content__clear"
+ v-if="isShowClear"
+ @tap="onClear"
+ >
+ <u-icon
+ name="close"
+ size="11"
+ color="#ffffff"
+ customStyle="line-height: 12px"
+ ></u-icon>
+ </view>
+ <view
+ class="u-input__content__subfix-icon"
+ v-if="suffixIcon || $slots.suffix"
+ >
+ <slot name="suffix">
+ <u-icon
+ :name="suffixIcon"
+ size="18"
+ :customStyle="suffixIconStyle"
+ ></u-icon>
+ </slot>
+ </view>
+ </view>
+ </view>
+</template>
+
+<script>
+import props from "./props.js";
+/**
+ * Input ���������
+ * @description ������������������������������������������������������������������������������������������u-form������������������������������������������������������������������������������������������������
+ * @tutorial https://uviewui.com/components/input.html
+ * @property {String | Number} value ������������
+ * @property {String} type ��������������������������������� ��� ������ 'text' ���
+ * @property {Boolean} fixed ������ textarea ������������ position:fixed ������������������������������������ fixed ��� true���������������������������������������������������������������������������QQ��������� ��� ������ false ���
+ * @property {Boolean} disabled ��������������������� ��� ������ false ���
+ * @property {String} disabledColor ������������������������������ ������ '#f5f7fa' ���
+ * @property {Boolean} clearable ������������������������ ��� ������ false ���
+ * @property {Boolean} password ������������������ ��� ������ false ���
+ * @property {String | Number} maxlength ������������������������������ -1 ������������������������������ ��� ������ -1 ���
+ * @property {String} placeholder ������������������������������
+ * @property {String} placeholderClass ������placeholder���������������������������������������style���������scoped���������������������������/deep/ ��� ������ 'input-placeholder' ���
+ * @property {String | Object} placeholderStyle ������placeholder���������������������/������������������"color: red;"
+ * @property {Boolean} showWordLimit ��������������������������������������� type ="text"���type ="textarea"��������� ��� ������ false ���
+ * @property {String} confirmType ������������������������������������������������uni-app������ ��� ������ 'done' ���
+ * @property {Boolean} confirmHold ������������������������������������������������������������H5������ ��� ������ false ���
+ * @property {Boolean} holdKeyboard focus������������������������������������������������������������������ ��� ������ false ���
+ * @property {Boolean} focus ������������������������ H5 ������������������������������������������������������������������������������������������������nvue ������������������������������������ focus()���blur() ������������������ ��� ������ false ���
+ * @property {Boolean} autoBlur ������������������������������������������������������App3.0.0+������ ��� ������ false ���
+ * @property {Boolean} disableDefaultPadding ������������ iOS ������������������������������������������������type=textarea��������� ��� ������ false ���
+ * @property {String ��� Number} cursor ������focus��������������������� ������ -1 ���
+ * @property {String ��� Number} cursorSpacing ������������������������������������������ ��� ������ 30 ���
+ * @property {String ��� Number} selectionStart ���������������������������������������������������selection-end������������ ��� ������ -1 ���
+ * @property {String ��� Number} selectionEnd ���������������������������������������������������selection-start������������ ��� ������ -1 ���
+ * @property {Boolean} adjustPosition ������������������������������������������ ��� ������ true ���
+ * @property {String} inputAlign ������������������������������ ������ 'left' ���
+ * @property {String | Number} fontSize ������������������������ ��� ������ '15px' ���
+ * @property {String} color ��������������������� ��� ������ '#303133' ���
+ * @property {Function} formatter ������������������
+ * @property {String} prefixIcon ���������������������
+ * @property {String | Object} prefixIconStyle ���������������������������������������
+ * @property {String} suffixIcon ���������������������
+ * @property {String | Object} suffixIconStyle ���������������������������������������
+ * @property {String} border ���������������surround-���������������bottom-���������������none-��������� ��� ������ 'surround' ���
+ * @property {Boolean} readonly ������������������disabled������������������disabled���������������������readonly��������� ��� ������ false ���
+ * @property {String} shape ������������������circle-���������square-������ ��� ������ 'square' ���
+ * @property {Object} customStyle ���������������������������������
+ * @property {Boolean} ignoreCompositionEvent ������������������������������������������������������������
+ * @example <u-input v-model="value" :password="true" suffix-icon="lock-fill" />
+ */
+export default {
+ name: "u-input",
+ mixins: [uni.$u.mpMixin, uni.$u.mixin, props],
+ data() {
+ return {
+ // ���������������
+ innerValue: "",
+ // ������������������������������
+ focused: false,
+ // value���������������������������watch������������������immediate������������������������������������������������������value���������������
+ firstChange: true,
+ // value���������������������������������������������������
+ changeFromInner: false,
+ // ������������������
+ innerFormatter: value => value
+ };
+ },
+ watch: {
+ value: {
+ immediate: true,
+ handler(newVal, oldVal) {
+ this.innerValue = newVal;
+ /* #ifdef H5 */
+ // ���H5������������value������������������input������������������������@input������������������������������������������
+ if (
+ this.firstChange === false &&
+ this.changeFromInner === false
+ ) {
+ this.valueChange();
+ }
+ /* #endif */
+ this.firstChange = false;
+ // ������changeFromInner���������false������������������������������������������������
+ this.changeFromInner = false;
+ },
+ },
+ },
+ computed: {
+ // ������������������������
+ isShowClear() {
+ const { clearable, readonly, focused, innerValue } = this;
+ return !!clearable && !readonly && !!focused && innerValue !== "";
+ },
+ // ���������������
+ inputClass() {
+ let classes = [],
+ { border, disabled, shape } = this;
+ border === "surround" &&
+ (classes = classes.concat(["u-border", "u-input--radius"]));
+ classes.push(`u-input--${shape}`);
+ border === "bottom" &&
+ (classes = classes.concat([
+ "u-border-bottom",
+ "u-input--no-radius",
+ ]));
+ return classes.join(" ");
+ },
+ // ���������������
+ wrapperStyle() {
+ const style = {};
+ // ���������������������������������������������������
+ if (this.disabled) {
+ style.backgroundColor = this.disabledColor;
+ }
+ // ������������������������������
+ if (this.border === "none") {
+ style.padding = "0";
+ } else {
+ // ������uni-app���iOS������������������������������������������������������
+ style.paddingTop = "6px";
+ style.paddingBottom = "6px";
+ style.paddingLeft = "9px";
+ style.paddingRight = "9px";
+ }
+ return uni.$u.deepMerge(style, uni.$u.addStyle(this.customStyle));
+ },
+ // ������������������
+ inputStyle() {
+ const style = {
+ color: this.color,
+ fontSize: uni.$u.addUnit(this.fontSize),
+ textAlign: this.inputAlign
+ };
+ return style;
+ },
+ },
+ methods: {
+ // ������������������������������������������������props������������������������ref������������
+ setFormatter(e) {
+ this.innerFormatter = e
+ },
+ // ���������������������������input������
+ onInput(e) {
+ let { value = "" } = e.detail || {};
+ // ���������������������
+ const formatter = this.formatter || this.innerFormatter
+ const formatValue = formatter(value)
+ // ������������props���������������������������������������innerValue������������������������������$nextTick���������������������������������������
+ this.innerValue = value
+ this.$nextTick(() => {
+ this.innerValue = formatValue;
+ this.valueChange();
+ })
+ },
+ // ������������������������������
+ onBlur(event) {
+ this.$emit("blur", event.detail.value);
+ // H5������blur������������������������������������click���������������������focused
+ // ���������false���������������������������������������������������
+ uni.$u.sleep(50).then(() => {
+ this.focused = false;
+ });
+ // ������������u-form���������������
+ uni.$u.formValidate(this, "blur");
+ },
+ // ������������������������
+ onFocus(event) {
+ this.focused = true;
+ this.$emit("focus");
+ },
+ // ���������������������������
+ onConfirm(event) {
+ this.$emit("confirm", this.innerValue);
+ },
+ // ������������������������������������������������
+ // ���������������������������2.7.0+���App 3.1.0+
+ onkeyboardheightchange() {
+ this.$emit("keyboardheightchange");
+ },
+ // ���������������������������������
+ valueChange() {
+ const value = this.innerValue;
+ this.$nextTick(() => {
+ this.$emit("input", value);
+ // ������value���������������������������������
+ this.changeFromInner = true;
+ this.$emit("change", value);
+ // ������������u-form���������������
+ uni.$u.formValidate(this, "change");
+ });
+ },
+ // ������������������
+ onClear() {
+ this.innerValue = "";
+ this.$nextTick(() => {
+ this.valueChange();
+ this.$emit("clear");
+ });
+ },
+ /**
+ * ���������nvue������������������������
+ * ������������������������������������u-from-item���������������������������������������u-form-item������u-input���
+ * ������������u-form-item������������������������������������������u-form-item���������������������
+ */
+ clickHandler() {
+ // #ifdef APP-NVUE
+ if (uni.$u.os() === "android") {
+ const formItem = uni.$u.$parent.call(this, "u-form-item");
+ if (formItem) {
+ formItem.clickHandler();
+ }
+ }
+ // #endif
+ },
+ },
+};
+</script>
+
+<style lang="scss" scoped>
+@import "../../libs/css/components.scss";
+
+.u-input {
+ @include flex(row);
+ align-items: center;
+ justify-content: space-between;
+ flex: 1;
+
+ &--radius,
+ &--square {
+ border-radius: 4px;
+ }
+
+ &--no-radius {
+ border-radius: 0;
+ }
+
+ &--circle {
+ border-radius: 100px;
+ }
+
+ &__content {
+ flex: 1;
+ @include flex(row);
+ align-items: center;
+ justify-content: space-between;
+
+ &__field-wrapper {
+ position: relative;
+ @include flex(row);
+ margin: 0;
+ flex: 1;
+
+ &__field {
+ line-height: 26px;
+ text-align: left;
+ color: $u-main-color;
+ height: 24px;
+ font-size: 15px;
+ flex: 1;
+ }
+ }
+
+ &__clear {
+ width: 20px;
+ height: 20px;
+ border-radius: 100px;
+ background-color: #c6c7cb;
+ @include flex(row);
+ align-items: center;
+ justify-content: center;
+ transform: scale(0.82);
+ margin-left: 4px;
+ }
+
+ &__subfix-icon {
+ margin-left: 4px;
+ }
+
+ &__prefix-icon {
+ margin-right: 4px;
+ }
+ }
+}
+</style>
diff --git a/uni_modules/uview-ui/components/u-keyboard/props.js b/uni_modules/uview-ui/components/u-keyboard/props.js
new file mode 100644
index 0000000..cfdb00a
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-keyboard/props.js
@@ -0,0 +1,84 @@
+export default {
+ props: {
+ // ������������������number-���������������card-������������������car-���������������
+ mode: {
+ type: String,
+ default: uni.$u.props.keyboard.mode
+ },
+ // ���������������������"."������
+ dotDisabled: {
+ type: Boolean,
+ default: uni.$u.props.keyboard.dotDisabled
+ },
+ // ���������������������������
+ tooltip: {
+ type: Boolean,
+ default: uni.$u.props.keyboard.tooltip
+ },
+ // ������������������������������������
+ showTips: {
+ type: Boolean,
+ default: uni.$u.props.keyboard.showTips
+ },
+ // ������������������������������
+ tips: {
+ type: String,
+ default: uni.$u.props.keyboard.tips
+ },
+ // ������������������������������"������"������
+ showCancel: {
+ type: Boolean,
+ default: uni.$u.props.keyboard.showCancel
+ },
+ // ������������������������������"������"������
+ showConfirm: {
+ type: Boolean,
+ default: uni.$u.props.keyboard.showConfirm
+ },
+ // ���������������������������������
+ random: {
+ type: Boolean,
+ default: uni.$u.props.keyboard.random
+ },
+ // ���������������������������������������������������������iPhoneX������������������������������������
+ safeAreaInsetBottom: {
+ type: Boolean,
+ default: uni.$u.props.keyboard.safeAreaInsetBottom
+ },
+ // ������������������������������������������
+ closeOnClickOverlay: {
+ type: Boolean,
+ default: uni.$u.props.keyboard.closeOnClickOverlay
+ },
+ // ������������������������������
+ show: {
+ type: Boolean,
+ default: uni.$u.props.keyboard.show
+ },
+ // ������������������������������������������������������������������������������������������������������������������
+ overlay: {
+ type: Boolean,
+ default: uni.$u.props.keyboard.overlay
+ },
+ // z-index���
+ zIndex: {
+ type: [String, Number],
+ default: uni.$u.props.keyboard.zIndex
+ },
+ // ���������������������
+ cancelText: {
+ type: String,
+ default: uni.$u.props.keyboard.cancelText
+ },
+ // ���������������������
+ confirmText: {
+ type: String,
+ default: uni.$u.props.keyboard.confirmText
+ },
+ // ���������������������������������������������������
+ autoChange: {
+ type: Boolean,
+ default: uni.$u.props.keyboard.autoChange
+ }
+ }
+}
diff --git a/uni_modules/uview-ui/components/u-keyboard/u-keyboard.vue b/uni_modules/uview-ui/components/u-keyboard/u-keyboard.vue
new file mode 100644
index 0000000..14228cb
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-keyboard/u-keyboard.vue
@@ -0,0 +1,164 @@
+<template>
+ <u-popup
+ :overlay="overlay"
+ :closeOnClickOverlay="closeOnClickOverlay"
+ mode="bottom"
+ :popup="false"
+ :show="show"
+ :safeAreaInsetBottom="safeAreaInsetBottom"
+ @close="popupClose"
+ :zIndex="zIndex"
+ :customStyle="{
+ backgroundColor: 'rgb(214, 218, 220)'
+ }"
+ >
+ <view class="u-keyboard">
+ <slot />
+ <view
+ class="u-keyboard__tooltip"
+ v-if="tooltip"
+ >
+ <view
+ hover-class="u-hover-class"
+ :hover-stay-time="100"
+ >
+ <text
+ class="u-keyboard__tooltip__item u-keyboard__tooltip__cancel"
+ v-if="showCancel"
+ @tap="onCancel"
+ >{{showCancel && cancelText}}</text>
+ </view>
+ <view>
+ <text
+ v-if="showTips"
+ class="u-keyboard__tooltip__item u-keyboard__tooltip__tips"
+ >{{tips ? tips : mode == 'number' ? '������������' : mode == 'card' ? '���������������' : '���������������'}}</text>
+ </view>
+ <view
+ hover-class="u-hover-class"
+ :hover-stay-time="100"
+ >
+ <text
+ v-if="showConfirm"
+ @tap="onConfirm"
+ class="u-keyboard__tooltip__item u-keyboard__tooltip__submit"
+ hover-class="u-hover-class"
+ >{{showConfirm && confirmText}}</text>
+ </view>
+ </view>
+ <template v-if="mode == 'number' || mode == 'card'">
+ <u-number-keyboard
+ :random="random"
+ @backspace="backspace"
+ @change="change"
+ :mode="mode"
+ :dotDisabled="dotDisabled"
+ ></u-number-keyboard>
+ </template>
+ <template v-else>
+ <u-car-keyboard
+ :random="random"
+ :autoChange="autoChange"
+ @backspace="backspace"
+ @change="change"
+ ></u-car-keyboard>
+ </template>
+ </view>
+ </u-popup>
+</template>
+
+<script>
+ import props from './props.js';
+
+ /**
+ * keyboard ������
+ * @description ������uViw������������������������������������������������������������������������������������3������������������������������������������������������
+ * @tutorial https://www.uviewui.com/components/keyboard.html
+ * @property {String} mode ��������������������������������������������� ��������� 'number' ���
+ * @property {Boolean} dotDisabled ������������"."���������������mode=number��������� ��������� false ���
+ * @property {Boolean} tooltip ��������������������������������� ��������� true ���
+ * @property {Boolean} showTips ������������������������������������ ��������� true ���
+ * @property {String} tips ���������������������������������������������������������������������������������������""���������
+ * @property {Boolean} showCancel ������������������������������"������"������ ��������� true ���
+ * @property {Boolean} showConfirm ������������������������������"������"��������� ������ true ���
+ * @property {Boolean} random ��������������������������������� ��������� false ���
+ * @property {Boolean} safeAreaInsetBottom ��������������������������������� ��������� true ���
+ * @property {Boolean} closeOnClickOverlay ������������������������������������ ��������� true ���
+ * @property {Boolean} show ��������������������������������������� false ���
+ * @property {Boolean} overlay ������������������ ��������� true ���
+ * @property {String | Number} zIndex ���������������z-index��� ��������� 1075 ���
+ * @property {String} cancelText ��������������������� ��������� '������' ���
+ * @property {String} confirmText ��������������������� ��������� '������' ���
+ * @property {Object} customStyle ������������������������������
+ * @event {Function} change ���������������(���������������������������)
+ * @event {Function} cancel ������������������������������"������"���������������
+ * @event {Function} confirm ������������������������������"������"���������������
+ * @event {Function} backspace ������������������������
+ * @example <u-keyboard mode="number" v-model="show"></u-keyboard>
+ */
+ export default {
+ name: "u-keyboard",
+ data() {
+ return {
+
+ }
+ },
+ mixins: [uni.$u.mpMixin, uni.$u.mixin,props],
+ methods: {
+ change(e) {
+ this.$emit('change', e);
+ },
+ // ������������
+ popupClose() {
+ this.$emit('close');
+ },
+ // ������������
+ onConfirm() {
+ this.$emit('confirm');
+ },
+ // ������������
+ onCancel() {
+ this.$emit('cancel');
+ },
+ // ���������
+ backspace() {
+ this.$emit('backspace');
+ }
+ }
+ }
+</script>
+
+<style lang="scss" scoped>
+ @import "../../libs/css/components.scss";
+
+ .u-keyboard {
+
+ &__tooltip {
+ @include flex;
+ justify-content: space-between;
+ background-color: #FFFFFF;
+ padding: 14px 12px;
+
+ &__item {
+ color: #333333;
+ flex: 1;
+ text-align: center;
+ font-size: 15px;
+ }
+
+ &__submit {
+ text-align: right;
+ color: $u-primary;
+ }
+
+ &__cancel {
+ text-align: left;
+ color: #888888;
+ }
+
+ &__tips {
+ color: $u-tips-color;
+ }
+ }
+ }
+</style>
diff --git a/uni_modules/uview-ui/components/u-line-progress/props.js b/uni_modules/uview-ui/components/u-line-progress/props.js
new file mode 100644
index 0000000..a4210bd
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-line-progress/props.js
@@ -0,0 +1,28 @@
+export default {
+ props: {
+ // ���������������������
+ activeColor: {
+ type: String,
+ default: uni.$u.props.lineProgress.activeColor
+ },
+ inactiveColor: {
+ type: String,
+ default: uni.$u.props.lineProgress.color
+ },
+ // ������������������������
+ percentage: {
+ type: [String, Number],
+ default: uni.$u.props.lineProgress.inactiveColor
+ },
+ // ���������������������������������������������
+ showText: {
+ type: Boolean,
+ default: uni.$u.props.lineProgress.showText
+ },
+ // ���������������������������px
+ height: {
+ type: [String, Number],
+ default: uni.$u.props.lineProgress.height
+ }
+ }
+}
diff --git a/uni_modules/uview-ui/components/u-line-progress/u-line-progress.vue b/uni_modules/uview-ui/components/u-line-progress/u-line-progress.vue
new file mode 100644
index 0000000..4e27931
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-line-progress/u-line-progress.vue
@@ -0,0 +1,144 @@
+<template>
+ <view
+ class="u-line-progress"
+ :style="[$u.addStyle(customStyle)]"
+ >
+ <view
+ class="u-line-progress__background"
+ ref="u-line-progress__background"
+ :style="[{
+ backgroundColor: inactiveColor,
+ height: $u.addUnit(height),
+ }]"
+ >
+ </view>
+ <view
+ class="u-line-progress__line"
+ :style="[progressStyle]"
+ >
+ <slot>
+ <text v-if="showText && percentage >= 10" class="u-line-progress__text">{{innserPercentage + '%'}}</text>
+ </slot>
+ </view>
+ </view>
+</template>
+
+<script>
+ import props from './props.js';
+ // #ifdef APP-NVUE
+ const dom = uni.requireNativePlugin('dom')
+ // #endif
+ /**
+ * lineProgress ���������������
+ * @description ������������������������������������������������������������������������������������������
+ * @tutorial https://www.uviewui.com/components/lineProgress.html
+ * @property {String} activeColor ��������������������� ( ������ '#19be6b' )
+ * @property {String} inactiveColor ��������� ( ������ '#ececec' )
+ * @property {String | Number} percentage ������������������������ ( ������ 0 )
+ * @property {Boolean} showText ��������������������������������������������� ( ������ true )
+ * @property {String | Number} height ���������������������������px ( ������ 12 )
+ *
+ * @example <u-line-progress :percent="70" :show-percent="true"></u-line-progress>
+ */
+ export default {
+ name: "u-line-progress",
+ mixins: [uni.$u.mpMixin, uni.$u.mixin,props],
+ data() {
+ return {
+ lineWidth: 0,
+ }
+ },
+ watch: {
+ percentage(n) {
+ this.resizeProgressWidth()
+ }
+ },
+ computed: {
+ progressStyle() {
+ let style = {}
+ style.width = this.lineWidth
+ style.backgroundColor = this.activeColor
+ style.height = uni.$u.addUnit(this.height)
+ return style
+ },
+ innserPercentage() {
+ // ���������������0-100������
+ return uni.$u.range(0, 100, this.percentage)
+ }
+ },
+ mounted() {
+ this.init()
+ },
+ methods: {
+ init() {
+ uni.$u.sleep(20).then(() => {
+ this.resizeProgressWidth()
+ })
+ },
+ getProgressWidth() {
+ // #ifndef APP-NVUE
+ return this.$uGetRect('.u-line-progress__background')
+ // #endif
+
+ // #ifdef APP-NVUE
+ // ������������promise
+ return new Promise(resolve => {
+ dom.getComponentRect(this.$refs['u-line-progress__background'], (res) => {
+ resolve(res.size)
+ })
+ })
+ // #endif
+ },
+ resizeProgressWidth() {
+ this.getProgressWidth().then(size => {
+ const {
+ width
+ } = size
+ // ���������������percentage������������������������������������������
+ this.lineWidth = width * this.innserPercentage / 100 + 'px'
+ })
+ }
+ }
+ }
+</script>
+
+<style lang="scss" scoped>
+ @import "../../libs/css/components.scss";
+
+ .u-line-progress {
+ align-items: stretch;
+ position: relative;
+ @include flex(row);
+ flex: 1;
+ overflow: hidden;
+ border-radius: 100px;
+
+ &__background {
+ background-color: #ececec;
+ border-radius: 100px;
+ flex: 1;
+ }
+
+ &__line {
+ position: absolute;
+ top: 0;
+ left: 0;
+ bottom: 0;
+ align-items: center;
+ @include flex(row);
+ color: #ffffff;
+ border-radius: 100px;
+ transition: width 0.5s ease;
+ justify-content: flex-end;
+ }
+
+ &__text {
+ font-size: 10px;
+ align-items: center;
+ text-align: right;
+ color: #FFFFFF;
+ margin-right: 5px;
+ transform: scale(0.9);
+ }
+ }
+</style>
diff --git a/uni_modules/uview-ui/components/u-line/props.js b/uni_modules/uview-ui/components/u-line/props.js
new file mode 100644
index 0000000..2308cc3
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-line/props.js
@@ -0,0 +1,33 @@
+export default {
+ props: {
+ color: {
+ type: String,
+ default: uni.$u.props.line.color
+ },
+ // ���������������������������������������������������������������������������������������px���������������
+ length: {
+ type: [String, Number],
+ default: uni.$u.props.line.length
+ },
+ // ���������������col-���������row-������
+ direction: {
+ type: String,
+ default: uni.$u.props.line.direction
+ },
+ // ���������������������
+ hairline: {
+ type: Boolean,
+ default: uni.$u.props.line.hairline
+ },
+ // ������������������������������������������������������������"30px"���"20px 30px"
+ margin: {
+ type: [String, Number],
+ default: uni.$u.props.line.margin
+ },
+ // ���������������true-���������false-������
+ dashed: {
+ type: Boolean,
+ default: uni.$u.props.line.dashed
+ }
+ }
+}
diff --git a/uni_modules/uview-ui/components/u-line/u-line.vue b/uni_modules/uview-ui/components/u-line/u-line.vue
new file mode 100644
index 0000000..e0a6d92
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-line/u-line.vue
@@ -0,0 +1,62 @@
+<template>
+ <view
+ class="u-line"
+ :style="[lineStyle]"
+ >
+
+ </view>
+</template>
+
+<script>
+ import props from './props.js';
+ /**
+ * line ������
+ * @description ���������������������������������������������������������������������������������������������������������������0.5px���������������������������
+ * @tutorial https://www.uviewui.com/components/line.html
+ * @property {String} color ��������������� ( ������ '#d6d7d9' )
+ * @property {String | Number} length ���������������������������������������������������������������������������������������px��������������� ( ������ '100%' )
+ * @property {String} direction ������������������row-���������col-������ (������ 'row' )
+ * @property {Boolean} hairline ��������������������� (������ true )
+ * @property {String | Number} margin ������������������������������������������������������������"30px" (������ 0 )
+ * @property {Boolean} dashed ���������������true-���������false-������ (������ false )
+ * @property {Object} customStyle ���������������������������������
+ * @example <u-line color="red"></u-line>
+ */
+ export default {
+ name: 'u-line',
+ mixins: [uni.$u.mpMixin, uni.$u.mixin,props],
+ computed: {
+ lineStyle() {
+ const style = {}
+ style.margin = this.margin
+ // ���������������������������������������1px������������transform���������������������0.5px���
+ if (this.direction === 'row') {
+ // ������������������������������������nvue���������
+ style.borderBottomWidth = '1px'
+ style.borderBottomStyle = this.dashed ? 'dashed' : 'solid'
+ style.width = uni.$u.addUnit(this.length)
+ if (this.hairline) style.transform = 'scaleY(0.5)'
+ } else {
+ // ���������������������������������������1px������������transform���������������������0.5px���
+ style.borderLeftWidth = '1px'
+ style.borderLeftStyle = this.dashed ? 'dashed' : 'solid'
+ style.height = uni.$u.addUnit(this.length)
+ if (this.hairline) style.transform = 'scaleX(0.5)'
+ }
+
+ style.borderColor = this.color
+ return uni.$u.deepMerge(style, uni.$u.addStyle(this.customStyle))
+ }
+ }
+ }
+</script>
+
+<style lang="scss" scoped>
+ @import "../../libs/css/components.scss";
+
+ .u-line {
+ /* #ifndef APP-NVUE */
+ vertical-align: middle;
+ /* #endif */
+ }
+</style>
diff --git a/uni_modules/uview-ui/components/u-link/props.js b/uni_modules/uview-ui/components/u-link/props.js
new file mode 100644
index 0000000..d39353f
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-link/props.js
@@ -0,0 +1,39 @@
+export default {
+ props: {
+ // ������������
+ color: {
+ type: String,
+ default: uni.$u.props.link.color
+ },
+ // ���������������������px
+ fontSize: {
+ type: [String, Number],
+ default: uni.$u.props.link.fontSize
+ },
+ // ���������������������
+ underLine: {
+ type: Boolean,
+ default: uni.$u.props.link.underLine
+ },
+ // ������������������
+ href: {
+ type: String,
+ default: uni.$u.props.link.href
+ },
+ // ������������������������������������������
+ mpTips: {
+ type: String,
+ default: uni.$u.props.link.mpTips
+ },
+ // ���������������
+ lineColor: {
+ type: String,
+ default: uni.$u.props.link.lineColor
+ },
+ // ������������������������������slot������������������������nvue���������������������
+ text: {
+ type: String,
+ default: uni.$u.props.link.text
+ }
+ }
+}
diff --git a/uni_modules/uview-ui/components/u-link/u-link.vue b/uni_modules/uview-ui/components/u-link/u-link.vue
new file mode 100644
index 0000000..c6802a5
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-link/u-link.vue
@@ -0,0 +1,83 @@
+<template>
+ <text
+ class="u-link"
+ @tap.stop="openLink"
+ :style="[linkStyle, $u.addStyle(customStyle)]"
+ >{{text}}</text>
+</template>
+
+<script>
+ import props from './props.js';
+
+ /**
+ * link ���������
+ * @description ������������������������������������������������������������������������APP���������������plus���������������������������������������������������������������������������������������������������H5���������window.open���������������
+ * @tutorial https://www.uviewui.com/components/link.html
+ * @property {String} color ������������ ��������� color['u-primary'] ���
+ * @property {String ��� Number} fontSize ���������������������px ��������� 15 ���
+ * @property {Boolean} underLine ��������������������� ��������� false ���
+ * @property {String} href ���������������������������http(s)
+ * @property {String} mpTips ������������������������������������������������������������������������������������������������������������������������
+ * @property {String} lineColor ���������������������������color������������
+ * @property {String} text ������������������������������slot������������������������nvue���������������������
+ * @property {Object} customStyle ���������������������������������
+ *
+ * @example <u-link href="http://www.uviewui.com">���������������������������</u-link>
+ */
+ export default {
+ name: "u-link",
+ mixins: [uni.$u.mpMixin, uni.$u.mixin,props],
+ computed: {
+ linkStyle() {
+ const style = {
+ color: this.color,
+ fontSize: uni.$u.addUnit(this.fontSize),
+ // line-height���������������������������2px
+ lineHeight: uni.$u.addUnit(uni.$u.getPx(this.fontSize) + 2),
+ textDecoration: this.underLine ? 'underline' : 'none'
+ }
+ // if (this.underLine) {
+ // style.borderBottomColor = this.lineColor || this.color
+ // style.borderBottomWidth = '1px'
+ // }
+ return style
+ }
+ },
+ methods: {
+ openLink() {
+ // #ifdef APP-PLUS
+ plus.runtime.openURL(this.href)
+ // #endif
+ // #ifdef H5
+ window.open(this.href)
+ // #endif
+ // #ifdef MP
+ uni.setClipboardData({
+ data: this.href,
+ success: () => {
+ uni.hideToast();
+ this.$nextTick(() => {
+ uni.$u.toast(this.mpTips);
+ })
+ }
+ });
+ // #endif
+ this.$emit('click')
+ }
+ }
+ }
+</script>
+
+<style lang="scss" scoped>
+ @import "../../libs/css/components.scss";
+ $u-link-line-height:1 !default;
+
+ .u-link {
+ /* #ifndef APP-NVUE */
+ line-height: $u-link-line-height;
+ /* #endif */
+ @include flex;
+ flex-wrap: wrap;
+ flex: 1;
+ }
+</style>
diff --git a/uni_modules/uview-ui/components/u-list-item/props.js b/uni_modules/uview-ui/components/u-list-item/props.js
new file mode 100644
index 0000000..58ddc49
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-list-item/props.js
@@ -0,0 +1,9 @@
+export default {
+ props: {
+ // ���������������������item
+ anchor: {
+ type: [String, Number],
+ default: uni.$u.props.listItem.anchor
+ }
+ }
+}
diff --git a/uni_modules/uview-ui/components/u-list-item/u-list-item.vue b/uni_modules/uview-ui/components/u-list-item/u-list-item.vue
new file mode 100644
index 0000000..1a25db6
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-list-item/u-list-item.vue
@@ -0,0 +1,116 @@
+<template>
+ <!-- #ifdef APP-NVUE -->
+ <cell>
+ <!-- #endif -->
+ <view
+ class="u-list-item"
+ :ref="`u-list-item-${anchor}`"
+ :anchor="`u-list-item-${anchor}`"
+ :class="[`u-list-item-${anchor}`]"
+ >
+ <slot />
+ </view>
+ <!-- #ifdef APP-NVUE -->
+ </cell>
+ <!-- #endif -->
+</template>
+
+<script>
+ import props from './props.js';
+ // #ifdef APP-NVUE
+ const dom = uni.requireNativePlugin('dom')
+ // #endif
+ /**
+ * List ������
+ * @description ���������������������������������
+ * @tutorial https://www.uviewui.com/components/list.html
+ * @property {String | Number} anchor ���������������������item
+ * @example <u-list-ite v-for="(item, index) in indexList" :key="index" ></u-list-item>
+ */
+ export default {
+ name: 'u-list-item',
+ mixins: [uni.$u.mpMixin, uni.$u.mixin,props],
+ data() {
+ return {
+ // ������������
+ rect: {},
+ index: 0,
+ show: true,
+ sys: uni.$u.sys()
+ }
+ },
+ computed: {
+
+ },
+ inject: ['uList'],
+ watch: {
+ // #ifndef APP-NVUE
+ 'uList.innerScrollTop'(n) {
+ const preLoadScreen = this.uList.preLoadScreen
+ const windowHeight = this.sys.windowHeight
+ if(n <= windowHeight * preLoadScreen) {
+ this.parent.updateOffsetFromChild(0)
+ } else if (this.rect.top <= n - windowHeight * preLoadScreen) {
+ this.parent.updateOffsetFromChild(this.rect.top)
+ }
+ }
+ // #endif
+ },
+ created() {
+ this.parent = {}
+ },
+ mounted() {
+ this.init()
+ },
+ methods: {
+ init() {
+ // ���������������
+ this.updateParentData()
+ this.index = this.parent.children.indexOf(this)
+ this.resize()
+ },
+ updateParentData() {
+ // ������������mixin���
+ this.getParentData('u-list')
+ },
+ resize() {
+ this.queryRect(`u-list-item-${this.anchor}`).then(size => {
+ const lastChild = this.parent.children[this.index - 1]
+ this.rect = size
+ const preLoadScreen = this.uList.preLoadScreen
+ const windowHeight = this.sys.windowHeight
+ // #ifndef APP-NVUE
+ if (lastChild) {
+ this.rect.top = lastChild.rect.top + lastChild.rect.height
+ }
+ if (size.top >= this.uList.innerScrollTop + (1 + preLoadScreen) * windowHeight) this.show =
+ false
+ // #endif
+ })
+ },
+ // ������������������
+ queryRect(el) {
+ return new Promise(resolve => {
+ // #ifndef APP-NVUE
+ this.$uGetRect(`.${el}`).then(size => {
+ resolve(size)
+ })
+ // #endif
+
+ // #ifdef APP-NVUE
+ const ref = this.$refs[el]
+ dom.getComponentRect(ref, res => {
+ resolve(res.size)
+ })
+ // #endif
+ })
+ }
+ }
+ }
+</script>
+
+<style lang="scss" scoped>
+ @import "../../libs/css/components.scss";
+
+ .u-list-item {}
+</style>
diff --git a/uni_modules/uview-ui/components/u-list/props.js b/uni_modules/uview-ui/components/u-list/props.js
new file mode 100644
index 0000000..25406f4
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-list/props.js
@@ -0,0 +1,76 @@
+export default {
+ props: {
+ // ���������������������������������nvue������
+ showScrollbar: {
+ type: Boolean,
+ default: uni.$u.props.list.showScrollbar
+ },
+ // ������������������������scrolltolower������
+ lowerThreshold: {
+ type: [String, Number],
+ default: uni.$u.props.list.lowerThreshold
+ },
+ // ������������������������scrolltoupper������������nvue������
+ upperThreshold: {
+ type: [String, Number],
+ default: uni.$u.props.list.upperThreshold
+ },
+ // ���������������������������
+ scrollTop: {
+ type: [String, Number],
+ default: uni.$u.props.list.scrollTop
+ },
+ // ������ onscroll ���������������������������nvue������
+ offsetAccuracy: {
+ type: [String, Number],
+ default: uni.$u.props.list.offsetAccuracy
+ },
+ // ������ flexbox ������������������������������������������display: flex������������flex container���������������������������������������������������������
+ enableFlex: {
+ type: Boolean,
+ default: uni.$u.props.list.enableFlex
+ },
+ // ���������������������������List������������false
+ pagingEnabled: {
+ type: Boolean,
+ default: uni.$u.props.list.pagingEnabled
+ },
+ // ������������List������
+ scrollable: {
+ type: Boolean,
+ default: uni.$u.props.list.scrollable
+ },
+ // ���������������������id���id������������������������
+ scrollIntoView: {
+ type: String,
+ default: uni.$u.props.list.scrollIntoView
+ },
+ // ���������������������������������������������
+ scrollWithAnimation: {
+ type: Boolean,
+ default: uni.$u.props.list.scrollWithAnimation
+ },
+ // iOS������������������������������������������������������������������������������������������������������
+ enableBackToTop: {
+ type: Boolean,
+ default: uni.$u.props.list.enableBackToTop
+ },
+ // ���������������
+ height: {
+ type: [String, Number],
+ default: uni.$u.props.list.height
+ },
+ // ������������
+ width: {
+ type: [String, Number],
+ default: uni.$u.props.list.width
+ },
+ // ���������������������������������1������������������������������1.5������1������������������
+ preLoadScreen: {
+ type: [String, Number],
+ default: uni.$u.props.list.preLoadScreen
+ }
+ // vue������������������������������
+
+ }
+}
diff --git a/uni_modules/uview-ui/components/u-list/u-list.vue b/uni_modules/uview-ui/components/u-list/u-list.vue
new file mode 100644
index 0000000..4447cab
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-list/u-list.vue
@@ -0,0 +1,157 @@
+<template>
+ <!-- #ifdef APP-NVUE -->
+ <list
+ class="u-list"
+ :enableBackToTop="enableBackToTop"
+ :loadmoreoffset="lowerThreshold"
+ :showScrollbar="showScrollbar"
+ :style="[listStyle]"
+ :offset-accuracy="Number(offsetAccuracy)"
+ @scroll="onScroll"
+ @loadmore="scrolltolower"
+ >
+ <slot />
+ </list>
+ <!-- #endif -->
+ <!-- #ifndef APP-NVUE -->
+ <scroll-view
+ class="u-list"
+ :scroll-into-view="scrollIntoView"
+ :style="[listStyle]"
+ scroll-y
+ :scroll-top="Number(scrollTop)"
+ :lower-threshold="Number(lowerThreshold)"
+ :upper-threshold="Number(upperThreshold)"
+ :show-scrollbar="showScrollbar"
+ :enable-back-to-top="enableBackToTop"
+ :scroll-with-animation="scrollWithAnimation"
+ @scroll="onScroll"
+ @scrolltolower="scrolltolower"
+ @scrolltoupper="scrolltoupper"
+ >
+ <view>
+ <slot />
+ </view>
+ </scroll-view>
+ <!-- #endif -->
+</template>
+
+<script>
+ import props from './props.js';
+ // #ifdef APP-NVUE
+ const dom = uni.requireNativePlugin('dom')
+ // #endif
+ /**
+ * List ������
+ * @description ���������������������������������
+ * @tutorial https://www.uviewui.com/components/list.html
+ * @property {Boolean} showScrollbar ���������������������������������nvue������ ��������� false ���
+ * @property {String ��� Number} lowerThreshold ������������������������scrolltolower������ ��������� 50 ���
+ * @property {String ��� Number} upperThreshold ������������������������scrolltoupper������������nvue������ ��������� 0 ���
+ * @property {String ��� Number} scrollTop ������������������������������������ 0 ���
+ * @property {String ��� Number} offsetAccuracy ������ onscroll ���������������������������nvue��������������� 10 ���
+ * @property {Boolean} enableFlex ������ flexbox ������������������������������������������display: flex������������flex container������������������������������������������������������������������ false ���
+ * @property {Boolean} pagingEnabled ���������������������������List������������ false ���
+ * @property {Boolean} scrollable ������������List��������������� true ���
+ * @property {String} scrollIntoView ���������������������id���id������������������������
+ * @property {Boolean} scrollWithAnimation ��������������������������������������������� ��������� false ���
+ * @property {Boolean} enableBackToTop iOS������������������������������������������������������������������������������������������������������ ��������� false ���
+ * @property {String ��� Number} height ��������������� ��������� 0 ���
+ * @property {String ��� Number} width ������������ ��������� 0 ���
+ * @property {String ��� Number} preLoadScreen ���������������������������������1������������������������������1.5������1������������������ ��������� 1 ���
+ * @property {Object} customStyle ���������������������������������
+ *
+ * @example <u-list @scrolltolower="scrolltolower"></u-list>
+ */
+ export default {
+ name: 'u-list',
+ mixins: [uni.$u.mpMixin, uni.$u.mixin,props],
+ watch: {
+ scrollIntoView(n) {
+ this.scrollIntoViewById(n)
+ }
+ },
+ data() {
+ return {
+ // ���������������������������
+ innerScrollTop: 0,
+ // vue������scroll-view������������������������������
+ offset: 0,
+ sys: uni.$u.sys()
+ }
+ },
+ computed: {
+ listStyle() {
+ const style = {},
+ addUnit = uni.$u.addUnit
+ if (this.width != 0) style.width = addUnit(this.width)
+ if (this.height != 0) style.height = addUnit(this.height)
+ // ������������������������������������������������������������
+ if (!style.height) style.height = addUnit(this.sys.windowHeight, 'px')
+ return uni.$u.deepMerge(style, uni.$u.addStyle(this.customStyle))
+ }
+ },
+ provide() {
+ return {
+ uList: this
+ }
+ },
+ created() {
+ this.refs = []
+ this.children = []
+ this.anchors = []
+ },
+ mounted() {},
+ methods: {
+ updateOffsetFromChild(top) {
+ this.offset = top
+ },
+ onScroll(e) {
+ let scrollTop = 0
+ // #ifdef APP-NVUE
+ scrollTop = e.contentOffset.y
+ // #endif
+ // #ifndef APP-NVUE
+ scrollTop = e.detail.scrollTop
+ // #endif
+ this.innerScrollTop = scrollTop
+ this.$emit('scroll', Math.abs(scrollTop))
+ },
+ scrollIntoViewById(id) {
+ // #ifdef APP-NVUE
+ // ������id���������������������u-list-item������������������������������dom������������������������������
+ const item = this.refs.find(item => item.$refs[id] ? true : false)
+ dom.scrollToElement(item.$refs[id], {
+ // ������������������������
+ animated: this.scrollWithAnimation
+ })
+ // #endif
+ },
+ // ���������������������������
+ scrolltolower(e) {
+ uni.$u.sleep(30).then(() => {
+ this.$emit('scrolltolower')
+ })
+ },
+ // #ifndef APP-NVUE
+ // ������������������������������nvue������
+ scrolltoupper(e) {
+ uni.$u.sleep(30).then(() => {
+ this.$emit('scrolltoupper')
+ // ���������������������������������������������������������webview���������������������������������������������������������
+ this.offset = 0
+ })
+ }
+ // #endif
+ },
+ }
+</script>
+
+<style lang="scss" scoped>
+ @import "../../libs/css/components.scss";
+
+ .u-list {
+ @include flex(column);
+
+ }
+</style>
diff --git a/uni_modules/uview-ui/components/u-loading-icon/props.js b/uni_modules/uview-ui/components/u-loading-icon/props.js
new file mode 100644
index 0000000..c35524e
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-loading-icon/props.js
@@ -0,0 +1,59 @@
+export default {
+ props: {
+ // ������������������
+ show: {
+ type: Boolean,
+ default: uni.$u.props.loadingIcon.show
+ },
+ // ������
+ color: {
+ type: String,
+ default: uni.$u.props.loadingIcon.color
+ },
+ // ������������������
+ textColor: {
+ type: String,
+ default: uni.$u.props.loadingIcon.textColor
+ },
+ // ���������������������������������
+ vertical: {
+ type: Boolean,
+ default: uni.$u.props.loadingIcon.vertical
+ },
+ // ���������������circle-���������spinner-������������semicircle-���������
+ mode: {
+ type: String,
+ default: uni.$u.props.loadingIcon.mode
+ },
+ // ���������������������������px
+ size: {
+ type: [String, Number],
+ default: uni.$u.props.loadingIcon.size
+ },
+ // ������������
+ textSize: {
+ type: [String, Number],
+ default: uni.$u.props.loadingIcon.textSize
+ },
+ // ������������
+ text: {
+ type: [String, Number],
+ default: uni.$u.props.loadingIcon.text
+ },
+ // ������������
+ timingFunction: {
+ type: String,
+ default: uni.$u.props.loadingIcon.timingFunction
+ },
+ // ������������������������
+ duration: {
+ type: [String, Number],
+ default: uni.$u.props.loadingIcon.duration
+ },
+ // mode=circle������������������
+ inactiveColor: {
+ type: String,
+ default: uni.$u.props.loadingIcon.inactiveColor
+ }
+ }
+}
diff --git a/uni_modules/uview-ui/components/u-loading-icon/u-loading-icon.vue b/uni_modules/uview-ui/components/u-loading-icon/u-loading-icon.vue
new file mode 100644
index 0000000..2ede5c3
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-loading-icon/u-loading-icon.vue
@@ -0,0 +1,343 @@
+<template>
+ <view
+ class="u-loading-icon"
+ :style="[$u.addStyle(customStyle)]"
+ :class="[vertical && 'u-loading-icon--vertical']"
+ v-if="show"
+ >
+ <view
+ v-if="!webviewHide"
+ class="u-loading-icon__spinner"
+ :class="[`u-loading-icon__spinner--${mode}`]"
+ ref="ani"
+ :style="{
+ color: color,
+ width: $u.addUnit(size),
+ height: $u.addUnit(size),
+ borderTopColor: color,
+ borderBottomColor: otherBorderColor,
+ borderLeftColor: otherBorderColor,
+ borderRightColor: otherBorderColor,
+ 'animation-duration': `${duration}ms`,
+ 'animation-timing-function': mode === 'semicircle' || mode === 'circle' ? timingFunction : ''
+ }"
+ >
+ <block v-if="mode === 'spinner'">
+ <!-- #ifndef APP-NVUE -->
+ <view
+ v-for="(item, index) in array12"
+ :key="index"
+ class="u-loading-icon__dot"
+ >
+ </view>
+ <!-- #endif -->
+ <!-- #ifdef APP-NVUE -->
+ <!-- ������������������������������������������������������������width���height������������������ -->
+ <loading-indicator
+ v-if="!webviewHide"
+ class="u-loading-indicator"
+ :animating="true"
+ :style="{
+ color: color,
+ width: $u.addUnit(size),
+ height: $u.addUnit(size)
+ }"
+ />
+ <!-- #endif -->
+ </block>
+ </view>
+ <text
+ v-if="text"
+ class="u-loading-icon__text"
+ :style="{
+ fontSize: $u.addUnit(textSize),
+ color: textColor,
+ }"
+ >{{text}}</text>
+ </view>
+</template>
+
+<script>
+ import props from './props.js';
+ // #ifdef APP-NVUE
+ const animation = weex.requireModule('animation');
+ // #endif
+ /**
+ * loading ������������
+ * @description ���������������������������������������������uView���loadmore���������������switch���������������������������������������������
+ * @tutorial https://www.uviewui.com/components/loading.html
+ * @property {Boolean} show ������������������ (������ true)
+ * @property {String} color ������������������������������������ mode = flower ���������������������color['u-tips-color']���
+ * @property {String} textColor ������������������������������color['u-tips-color']���
+ * @property {Boolean} vertical ��������������������������������� (������ false )
+ * @property {String} mode ��������������������������������������� 'circle' ���
+ * @property {String | Number} size ������������������������������px ��������� 24 ���
+ * @property {String | Number} textSize ��������������������� 15 ���
+ * @property {String | Number} text ������������
+ * @property {String} timingFunction ������������ ��������� 'ease-in-out' ���
+ * @property {String | Number} duration ��������������������������������� 1200���
+ * @property {String} inactiveColor mode=circle������������������
+ * @property {Object} customStyle ���������������������������������
+ * @example <u-loading mode="circle"></u-loading>
+ */
+ export default {
+ name: 'u-loading-icon',
+ mixins: [uni.$u.mpMixin, uni.$u.mixin, props],
+ data() {
+ return {
+ // Array.form������������������������������������������������������������
+ // https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/from
+ array12: Array.from({
+ length: 12
+ }),
+ // ������������������������������360������������������nvue���������������������duration������������������
+ // ���iOS nvue������������������������������������������������������
+ aniAngel: 360, // ������������������
+ webviewHide: false, // ������webview������������������������������������������������������������������������
+ loading: false, // ������������������������nvue������
+ }
+ },
+ computed: {
+ // ������circle���������������������������������������������������������������
+ // ������������������������������������������������������������color������������������������������������������������������
+ // ������������������������������������������(������������������������������������������������������������������������������)
+ otherBorderColor() {
+ const lightColor = uni.$u.colorGradient(this.color, '#ffffff', 100)[80]
+ if (this.mode === 'circle') {
+ return this.inactiveColor ? this.inactiveColor : lightColor
+ } else {
+ return 'transparent'
+ }
+ // return this.mode === 'circle' ? this.inactiveColor ? this.inactiveColor : lightColor : 'transparent'
+ }
+ },
+ watch: {
+ show(n) {
+ // nvue������show���true������������loading������������������������������������
+ // #ifdef APP-NVUE
+ if (n && !this.loading) {
+ setTimeout(() => {
+ this.startAnimate()
+ }, 30)
+ }
+ // #endif
+ }
+ },
+ mounted() {
+ this.init()
+ },
+ methods: {
+ init() {
+ setTimeout(() => {
+ // #ifdef APP-NVUE
+ this.show && this.nvueAnimate()
+ // #endif
+ // #ifdef APP-PLUS
+ this.show && this.addEventListenerToWebview()
+ // #endif
+ }, 20)
+ },
+ // ������webview������������������
+ addEventListenerToWebview() {
+ // webview���������
+ const pages = getCurrentPages()
+ // ������������
+ const page = pages[pages.length - 1]
+ // ���������������webview������
+ const currentWebview = page.$getAppWebview()
+ // ������webview���������������������������������������������������(������������)
+ currentWebview.addEventListener('hide', () => {
+ this.webviewHide = true
+ })
+ currentWebview.addEventListener('show', () => {
+ this.webviewHide = false
+ })
+ },
+ // #ifdef APP-NVUE
+ nvueAnimate() {
+ // nvue���������spinner���������������������������������nvue���spinner������������������weex���
+ // loading-indicator���������������������������
+ this.mode !== 'spinner' && this.startAnimate()
+ },
+ // ������nvue���animate������������
+ startAnimate() {
+ this.loading = true
+ const ani = this.$refs.ani
+ if (!ani) return
+ animation.transition(ani, {
+ // ������������������
+ styles: {
+ transform: `rotate(${this.aniAngel}deg)`,
+ transformOrigin: 'center center'
+ },
+ duration: this.duration,
+ timingFunction: this.timingFunction,
+ // delay: 10
+ }, () => {
+ // ������������360deg���������������������������������
+ this.aniAngel += 360
+ // ���������������������������������������������������������������webviewHide������
+ // nvue���������������������������������������������startAnimate������
+ this.show && !this.webviewHide ? this.startAnimate() : this.loading = false
+ })
+ }
+ // #endif
+ }
+ }
+</script>
+
+<style lang="scss" scoped>
+ @import "../../libs/css/components.scss";
+ $u-loading-icon-color: #c8c9cc !default;
+ $u-loading-icon-text-margin-left:4px !default;
+ $u-loading-icon-text-color:$u-content-color !default;
+ $u-loading-icon-text-font-size:14px !default;
+ $u-loading-icon-text-line-height:20px !default;
+ $u-loading-width:30px !default;
+ $u-loading-height:30px !default;
+ $u-loading-max-width:100% !default;
+ $u-loading-max-height:100% !default;
+ $u-loading-semicircle-border-width: 2px !default;
+ $u-loading-semicircle-border-color:transparent !default;
+ $u-loading-semicircle-border-top-right-radius: 100px !default;
+ $u-loading-semicircle-border-top-left-radius: 100px !default;
+ $u-loading-semicircle-border-bottom-left-radius: 100px !default;
+ $u-loading-semicircle-border-bottom-right-radiu: 100px !default;
+ $u-loading-semicircle-border-style: solid !default;
+ $u-loading-circle-border-top-right-radius: 100px !default;
+ $u-loading-circle-border-top-left-radius: 100px !default;
+ $u-loading-circle-border-bottom-left-radius: 100px !default;
+ $u-loading-circle-border-bottom-right-radiu: 100px !default;
+ $u-loading-circle-border-width:2px !default;
+ $u-loading-circle-border-top-color:#e5e5e5 !default;
+ $u-loading-circle-border-right-color:$u-loading-circle-border-top-color !default;
+ $u-loading-circle-border-bottom-color:$u-loading-circle-border-top-color !default;
+ $u-loading-circle-border-left-color:$u-loading-circle-border-top-color !default;
+ $u-loading-circle-border-style:solid !default;
+ $u-loading-icon-host-font-size:0px !default;
+ $u-loading-icon-host-line-height:1 !default;
+ $u-loading-icon-vertical-margin:6px 0 0 !default;
+ $u-loading-icon-dot-top:0 !default;
+ $u-loading-icon-dot-left:0 !default;
+ $u-loading-icon-dot-width:100% !default;
+ $u-loading-icon-dot-height:100% !default;
+ $u-loading-icon-dot-before-width:2px !default;
+ $u-loading-icon-dot-before-height:25% !default;
+ $u-loading-icon-dot-before-margin:0 auto !default;
+ $u-loading-icon-dot-before-background-color:currentColor !default;
+ $u-loading-icon-dot-before-border-radius:40% !default;
+
+ .u-loading-icon {
+ /* #ifndef APP-NVUE */
+ // display: inline-flex;
+ /* #endif */
+ flex-direction: row;
+ align-items: center;
+ justify-content: center;
+ color: $u-loading-icon-color;
+
+ &__text {
+ margin-left: $u-loading-icon-text-margin-left;
+ color: $u-loading-icon-text-color;
+ font-size: $u-loading-icon-text-font-size;
+ line-height: $u-loading-icon-text-line-height;
+ }
+
+ &__spinner {
+ width: $u-loading-width;
+ height: $u-loading-height;
+ position: relative;
+ /* #ifndef APP-NVUE */
+ box-sizing: border-box;
+ max-width: $u-loading-max-width;
+ max-height: $u-loading-max-height;
+ animation: u-rotate 1s linear infinite;
+ /* #endif */
+ }
+
+ &__spinner--semicircle {
+ border-width: $u-loading-semicircle-border-width;
+ border-color: $u-loading-semicircle-border-color;
+ border-top-right-radius: $u-loading-semicircle-border-top-right-radius;
+ border-top-left-radius: $u-loading-semicircle-border-top-left-radius;
+ border-bottom-left-radius: $u-loading-semicircle-border-bottom-left-radius;
+ border-bottom-right-radius: $u-loading-semicircle-border-bottom-right-radiu;
+ border-style: $u-loading-semicircle-border-style;
+ }
+
+ &__spinner--circle {
+ border-top-right-radius: $u-loading-circle-border-top-right-radius;
+ border-top-left-radius: $u-loading-circle-border-top-left-radius;
+ border-bottom-left-radius: $u-loading-circle-border-bottom-left-radius;
+ border-bottom-right-radius: $u-loading-circle-border-bottom-right-radiu;
+ border-width: $u-loading-circle-border-width;
+ border-top-color: $u-loading-circle-border-top-color;
+ border-right-color: $u-loading-circle-border-right-color;
+ border-bottom-color: $u-loading-circle-border-bottom-color;
+ border-left-color: $u-loading-circle-border-left-color;
+ border-style: $u-loading-circle-border-style;
+ }
+
+ &--vertical {
+ flex-direction: column
+ }
+ }
+
+ /* #ifndef APP-NVUE */
+ :host {
+ font-size: $u-loading-icon-host-font-size;
+ line-height: $u-loading-icon-host-line-height;
+ }
+
+ .u-loading-icon {
+ &__spinner--spinner {
+ animation-timing-function: steps(12)
+ }
+
+ &__text:empty {
+ display: none
+ }
+
+ &--vertical &__text {
+ margin: $u-loading-icon-vertical-margin;
+ color: $u-content-color;
+ }
+
+ &__dot {
+ position: absolute;
+ top: $u-loading-icon-dot-top;
+ left: $u-loading-icon-dot-left;
+ width: $u-loading-icon-dot-width;
+ height: $u-loading-icon-dot-height;
+
+ &:before {
+ display: block;
+ width: $u-loading-icon-dot-before-width;
+ height: $u-loading-icon-dot-before-height;
+ margin: $u-loading-icon-dot-before-margin;
+ background-color: $u-loading-icon-dot-before-background-color;
+ border-radius: $u-loading-icon-dot-before-border-radius;
+ content: " "
+ }
+ }
+ }
+
+ @for $i from 1 through 12 {
+ .u-loading-icon__dot:nth-of-type(#{$i}) {
+ transform: rotate($i * 30deg);
+ opacity: 1 - 0.0625 * ($i - 1);
+ }
+ }
+
+ @keyframes u-rotate {
+ 0% {
+ transform: rotate(0deg)
+ }
+
+ to {
+ transform: rotate(1turn)
+ }
+ }
+
+ /* #endif */
+</style>
diff --git a/uni_modules/uview-ui/components/u-loading-page/props.js b/uni_modules/uview-ui/components/u-loading-page/props.js
new file mode 100644
index 0000000..e239b61
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-loading-page/props.js
@@ -0,0 +1,49 @@
+export default {
+ props: {
+ // ������������
+ loadingText: {
+ type: [String, Number],
+ default: uni.$u.props.loadingPage.loadingText
+ },
+ // ������������������������loading���������������
+ image: {
+ type: String,
+ default: uni.$u.props.loadingPage.image
+ },
+ // ������������������������circle-���������spinner-������������semicircle-���������
+ loadingMode: {
+ type: String,
+ default: uni.$u.props.loadingPage.loadingMode
+ },
+ // ���������������
+ loading: {
+ type: Boolean,
+ default: uni.$u.props.loadingPage.loading
+ },
+ // ���������
+ bgColor: {
+ type: String,
+ default: uni.$u.props.loadingPage.bgColor
+ },
+ // ������������
+ color: {
+ type: String,
+ default: uni.$u.props.loadingPage.color
+ },
+ // ������������
+ fontSize: {
+ type: [String, Number],
+ default: uni.$u.props.loadingPage.fontSize
+ },
+ // ������������
+ iconSize: {
+ type: [String, Number],
+ default: uni.$u.props.loadingPage.fontSize
+ },
+ // ���������������������������������rgb���������������������������
+ loadingColor: {
+ type: String,
+ default: uni.$u.props.loadingPage.loadingColor
+ }
+ }
+}
diff --git a/uni_modules/uview-ui/components/u-loading-page/u-loading-page.vue b/uni_modules/uview-ui/components/u-loading-page/u-loading-page.vue
new file mode 100644
index 0000000..03a78ad
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-loading-page/u-loading-page.vue
@@ -0,0 +1,115 @@
+<template>
+ <u-transition
+ :show="loading"
+ :custom-style="{
+ position: 'fixed',
+ top: 0,
+ left: 0,
+ right: 0,
+ bottom: 0,
+ backgroundColor: bgColor,
+ display: 'flex',
+ }"
+ >
+ <view class="u-loading-page">
+ <view class="u-loading-page__warpper">
+ <view class="u-loading-page__warpper__loading-icon">
+ <image
+ v-if="image"
+ :src="image"
+ class="u-loading-page__warpper__loading-icon__img"
+ mode="widthFit"
+ :style="{
+ width: $u.addUnit(iconSize),
+ height: $u.addUnit(iconSize)
+ }"
+ ></image>
+ <u-loading-icon
+ v-else
+ :mode="loadingMode"
+ :size="$u.addUnit(iconSize)"
+ :color="loadingColor"
+ ></u-loading-icon>
+ </view>
+ <slot>
+ <text
+ class="u-loading-page__warpper__text"
+ :style="{
+ fontSize: $u.addUnit(fontSize),
+ color: color,
+ }"
+ >{{ loadingText }}</text
+ >
+ </slot>
+ </view>
+ </view>
+ </u-transition>
+</template>
+
+<script>
+import props from "./props.js";
+/**
+ * loadingPage ������������
+ * @description ���������������������������������������������uView���loadmore���������������switch���������������������������������������������
+ * @tutorial https://www.uviewui.com/components/loading.html
+ * @property {String | Number} loadingText ������������ (������ '������������' )
+ * @property {String} image ������������������������loading���������������
+ * @property {String} loadingMode ������������������������circle-���������spinner-������������semicircle-��������� ��������� 'circle' ���
+ * @property {Boolean} loading ��������������� ��������� false ���
+ * @property {String} bgColor ��������� ��������� '#ffffff' ���
+ * @property {String} color ������������ ��������� '#C8C8C8' ���
+ * @property {String | Number} fontSize ������������ ��������� 19 ���
+ * @property {String | Number} iconSize ������������ ��������� 28 ���
+ * @property {String} loadingColor ���������������������������������rgb��������������������������� ��������� '#C8C8C8' ���
+ * @property {Object} customStyle ���������������
+ * @example <u-loading mode="circle"></u-loading>
+ */
+export default {
+ name: "u-loading-page",
+ mixins: [uni.$u.mpMixin, uni.$u.mixin, props],
+ data() {
+ return {};
+ },
+ methods: {},
+};
+</script>
+
+<style lang="scss" scoped>
+@import "../../libs/css/components.scss";
+
+$text-color: rgb(200, 200, 200) !default;
+$text-size: 19px !default;
+$u-loading-icon-margin-bottom: 10px !default;
+
+.u-loading-page {
+ @include flex(column);
+ flex: 1;
+ align-items: center;
+ justify-content: center;
+
+ &__warpper {
+ margin-top: -150px;
+ justify-content: center;
+ align-items: center;
+ /* #ifndef APP-NVUE */
+ color: $text-color;
+ font-size: $text-size;
+ /* #endif */
+ @include flex(column);
+
+ &__loading-icon {
+ margin-bottom: $u-loading-icon-margin-bottom;
+
+ &__img {
+ width: 40px;
+ height: 40px;
+ }
+ }
+
+ &__text {
+ font-size: $text-size;
+ color: $text-color;
+ }
+ }
+}
+</style>
diff --git a/uni_modules/uview-ui/components/u-loadmore/props.js b/uni_modules/uview-ui/components/u-loadmore/props.js
new file mode 100644
index 0000000..1e67d89
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-loadmore/props.js
@@ -0,0 +1,94 @@
+export default {
+ props: {
+ // ���������������loadmore-���������������������loading-���������������������nomore-���������������������
+ status: {
+ type: String,
+ default: uni.$u.props.loadmore.status
+ },
+ // ���������������
+ bgColor: {
+ type: String,
+ default: uni.$u.props.loadmore.bgColor
+ },
+ // ������������������������������
+ icon: {
+ type: Boolean,
+ default: uni.$u.props.loadmore.icon
+ },
+ // ������������
+ fontSize: {
+ type: [String, Number],
+ default: uni.$u.props.loadmore.fontSize
+ },
+ // ������������
+ iconSize: {
+ type: [String, Number],
+ default: uni.$u.props.loadmore.iconSize
+ },
+ // ������������
+ color: {
+ type: String,
+ default: uni.$u.props.loadmore.color
+ },
+ // ���������������������������spinner-������������������circle-������������semicircle-������
+ loadingIcon: {
+ type: String,
+ default: uni.$u.props.loadmore.loadingIcon
+ },
+ // ���������������������
+ loadmoreText: {
+ type: String,
+ default: uni.$u.props.loadmore.loadmoreText
+ },
+ // ������������������
+ loadingText: {
+ type: String,
+ default: uni.$u.props.loadmore.loadingText
+ },
+ // ������������������������
+ nomoreText: {
+ type: String,
+ default: uni.$u.props.loadmore.nomoreText
+ },
+ // ���������������������������������������������������
+ isDot: {
+ type: Boolean,
+ default: uni.$u.props.loadmore.isDot
+ },
+ // ������������������������
+ iconColor: {
+ type: String,
+ default: uni.$u.props.loadmore.iconColor
+ },
+ // ���������
+ marginTop: {
+ type: [String, Number],
+ default: uni.$u.props.loadmore.marginTop
+ },
+ // ���������
+ marginBottom: {
+ type: [String, Number],
+ default: uni.$u.props.loadmore.marginBottom
+ },
+ // ���������������px
+ height: {
+ type: [String, Number],
+ default: uni.$u.props.loadmore.height
+ },
+ // ���������������������������
+ line: {
+ type: Boolean,
+ default: uni.$u.props.loadmore.line
+ },
+ // ������������
+ lineColor: {
+ type: String,
+ default: uni.$u.props.loadmore.lineColor
+ },
+ // ���������������true-���������false-������
+ dashed: {
+ type: Boolean,
+ default: uni.$u.props.loadmore.dashed
+ }
+ }
+}
diff --git a/uni_modules/uview-ui/components/u-loadmore/u-loadmore.vue b/uni_modules/uview-ui/components/u-loadmore/u-loadmore.vue
new file mode 100644
index 0000000..73c79fe
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-loadmore/u-loadmore.vue
@@ -0,0 +1,150 @@
+<template>
+ <view
+ class="u-loadmore"
+ :style="[
+ $u.addStyle(customStyle),
+ {
+ backgroundColor: bgColor,
+ marginBottom: $u.addUnit(marginBottom),
+ marginTop: $u.addUnit(marginTop),
+ height: $u.addUnit(height),
+ },
+ ]"
+ >
+ <u-line
+ length="140rpx"
+ :color="lineColor"
+ :hairline="false"
+ :dashed="dashed"
+ v-if="line"
+ ></u-line>
+ <!-- ��������������������������������������������������������� -->
+ <view
+ :class="status == 'loadmore' || status == 'nomore' ? 'u-more' : ''"
+ class="u-loadmore__content"
+ >
+ <view
+ class="u-loadmore__content__icon-wrap"
+ v-if="status === 'loading' && icon"
+ >
+ <u-loading-icon
+ :color="iconColor"
+ :size="iconSize"
+ :mode="loadingIcon"
+ ></u-loading-icon>
+ </view>
+ <!-- ������������������������������������������������dot��������������������������������� -->
+ <text
+ class="u-line-1"
+ :style="[loadTextStyle]"
+ :class="[(status == 'nomore' && isDot == true) ? 'u-loadmore__content__dot-text' : 'u-loadmore__content__text']"
+ @tap="loadMore"
+ >{{ showText }}</text>
+ </view>
+ <u-line
+ length="140rpx"
+ :color="lineColor"
+ :hairline="false"
+ :dashed="dashed"
+ v-if="line"
+ ></u-line>
+ </view>
+</template>
+
+<script>
+ import props from './props.js';
+
+ /**
+ * loadmore ������������
+ * @description ������������������������������������������������������������������
+ * @tutorial https://www.uviewui.com/components/loadMore.html
+ * @property {String} status ��������������������� 'loadmore' ���
+ * @property {String} bgColor ��������������������������������������������������������������� 'transparent' ���
+ * @property {Boolean} icon ��������������������������������������� true ���
+ * @property {String | Number} fontSize ��������������������� 14 ���
+ * @property {String | Number} iconSize ��������������������� 17 ���
+ * @property {String} color ��������������������� '#606266' ���
+ * @property {String} loadingIcon ��������������������� 'circle' ���
+ * @property {String} loadmoreText ������������������������������ '������������' ���
+ * @property {String} loadingText ��������������������������� '������������...' ���
+ * @property {String} nomoreText ��������������������������������� '���������������' ���
+ * @property {Boolean} isDot ��������������������������������� ��������� false ���
+ * @property {String} iconColor ������������������������ ��������� '#b7b7b7' ���
+ * @property {String} lineColor ��������������������� #E6E8EB ���
+ * @property {String | Number} marginTop ��������� ��������� 10 ���
+ * @property {String | Number} marginBottom ��������� ��������� 10 ���
+ * @property {String | Number} height ���������������px ��������� 'auto' ���
+ * @property {Boolean} line ��������������������������� ��������� false ���
+ * @property {Boolean} dashed // ���������������true-���������false-������ ��������� false ���
+ * @event {Function} loadmore status���loadmore������������������������������������
+ * @example <u-loadmore :status="status" icon-type="iconType" load-text="loadText" />
+ */
+ export default {
+ name: "u-loadmore",
+ mixins: [uni.$u.mpMixin, uni.$u.mixin,props],
+ data() {
+ return {
+ // ������
+ dotText: "���"
+ }
+ },
+ computed: {
+ // ������������������������������
+ loadTextStyle() {
+ return {
+ color: this.color,
+ fontSize: uni.$u.addUnit(this.fontSize),
+ lineHeight: uni.$u.addUnit(this.fontSize),
+ backgroundColor: this.bgColor,
+ }
+ },
+ // ���������������������
+ showText() {
+ let text = '';
+ if (this.status == 'loadmore') text = this.loadmoreText
+ else if (this.status == 'loading') text = this.loadingText
+ else if (this.status == 'nomore' && this.isDot) text = this.dotText;
+ else text = this.nomoreText;
+ return text;
+ }
+ },
+ methods: {
+ loadMore() {
+ // ������������������������������������������������������������������������������������������������������������������������������������������������
+ if (this.status == 'loadmore') this.$emit('loadmore');
+ }
+ }
+ }
+</script>
+
+<style lang="scss" scoped>
+ @import "../../libs/css/components.scss";
+
+ .u-loadmore {
+ @include flex(row);
+ align-items: center;
+ justify-content: center;
+ flex: 1;
+
+ &__content {
+ margin: 0 15px;
+ @include flex(row);
+ align-items: center;
+ justify-content: center;
+
+ &__icon-wrap {
+ margin-right: 8px;
+ }
+
+ &__text {
+ font-size: 14px;
+ color: $u-content-color;
+ }
+
+ &__dot-text {
+ font-size: 15px;
+ color: $u-tips-color;
+ }
+ }
+ }
+</style>
diff --git a/uni_modules/uview-ui/components/u-modal/props.js b/uni_modules/uview-ui/components/u-modal/props.js
new file mode 100644
index 0000000..f76672c
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-modal/props.js
@@ -0,0 +1,84 @@
+export default {
+ props: {
+ // ������������modal
+ show: {
+ type: Boolean,
+ default: uni.$u.props.modal.show
+ },
+ // ������
+ title: {
+ type: [String],
+ default: uni.$u.props.modal.title
+ },
+ // ������������
+ content: {
+ type: String,
+ default: uni.$u.props.modal.content
+ },
+ // ������������
+ confirmText: {
+ type: String,
+ default: uni.$u.props.modal.confirmText
+ },
+ // ������������
+ cancelText: {
+ type: String,
+ default: uni.$u.props.modal.cancelText
+ },
+ // ������������������������
+ showConfirmButton: {
+ type: Boolean,
+ default: uni.$u.props.modal.showConfirmButton
+ },
+ // ������������������������
+ showCancelButton: {
+ type: Boolean,
+ default: uni.$u.props.modal.showCancelButton
+ },
+ // ������������������
+ confirmColor: {
+ type: String,
+ default: uni.$u.props.modal.confirmColor
+ },
+ // ������������������
+ cancelColor: {
+ type: String,
+ default: uni.$u.props.modal.cancelColor
+ },
+ // ������������������������������
+ buttonReverse: {
+ type: Boolean,
+ default: uni.$u.props.modal.buttonReverse
+ },
+ // ������������������������
+ zoom: {
+ type: Boolean,
+ default: uni.$u.props.modal.zoom
+ },
+ // ���������������������������������������������
+ asyncClose: {
+ type: Boolean,
+ default: uni.$u.props.modal.asyncClose
+ },
+ // ������������������������������modal
+ closeOnClickOverlay: {
+ type: Boolean,
+ default: uni.$u.props.modal.closeOnClickOverlay
+ },
+ // ���������������margin-top������������������������������������������������
+ negativeTop: {
+ type: [String, Number],
+ default: uni.$u.props.modal.negativeTop
+ },
+ // modal���������������������������������������������px���rpx������
+ width: {
+ type: [String, Number],
+ default: uni.$u.props.modal.width
+ },
+ // ������������������������circle-���������square-������������������������������������������������
+ confirmButtonShape: {
+ type: String,
+ default: uni.$u.props.modal.confirmButtonShape
+ }
+ }
+}
diff --git a/uni_modules/uview-ui/components/u-modal/u-modal.vue b/uni_modules/uview-ui/components/u-modal/u-modal.vue
new file mode 100644
index 0000000..2cbc737
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-modal/u-modal.vue
@@ -0,0 +1,227 @@
+<template>
+ <u-popup
+ mode="center"
+ :zoom="zoom"
+ :show="show"
+ :customStyle="{
+ borderRadius: '6px',
+ overflow: 'hidden',
+ marginTop: `-${$u.addUnit(negativeTop)}`
+ }"
+ :closeOnClickOverlay="closeOnClickOverlay"
+ :safeAreaInsetBottom="false"
+ :duration="400"
+ @click="clickHandler"
+ >
+ <view
+ class="u-modal"
+ :style="{
+ width: $u.addUnit(width),
+ }"
+ >
+ <text
+ class="u-modal__title"
+ v-if="title"
+ >{{ title }}</text>
+ <view
+ class="u-modal__content"
+ :style="{
+ paddingTop: `${title ? 12 : 25}px`
+ }"
+ >
+ <slot>
+ <text class="u-modal__content__text">{{ content }}</text>
+ </slot>
+ </view>
+ <view
+ class="u-modal__button-group--confirm-button"
+ v-if="$slots.confirmButton"
+ >
+ <slot name="confirmButton"></slot>
+ </view>
+ <template v-else>
+ <u-line></u-line>
+ <view
+ class="u-modal__button-group"
+ :style="{
+ flexDirection: buttonReverse ? 'row-reverse' : 'row'
+ }"
+ >
+ <view
+ class="u-modal__button-group__wrapper u-modal__button-group__wrapper--cancel"
+ :hover-stay-time="150"
+ hover-class="u-modal__button-group__wrapper--hover"
+ :class="[showCancelButton && !showConfirmButton && 'u-modal__button-group__wrapper--only-cancel']"
+ v-if="showCancelButton"
+ @tap="cancelHandler"
+ >
+ <text
+ class="u-modal__button-group__wrapper__text"
+ :style="{
+ color: cancelColor
+ }"
+ >{{ cancelText }}</text>
+ </view>
+ <u-line
+ direction="column"
+ v-if="showConfirmButton && showCancelButton"
+ ></u-line>
+ <view
+ class="u-modal__button-group__wrapper u-modal__button-group__wrapper--confirm"
+ :hover-stay-time="150"
+ hover-class="u-modal__button-group__wrapper--hover"
+ :class="[!showCancelButton && showConfirmButton && 'u-modal__button-group__wrapper--only-confirm']"
+ v-if="showConfirmButton"
+ @tap="confirmHandler"
+ >
+ <u-loading-icon v-if="loading"></u-loading-icon>
+ <text
+ v-else
+ class="u-modal__button-group__wrapper__text"
+ :style="{
+ color: confirmColor
+ }"
+ >{{ confirmText }}</text>
+ </view>
+ </view>
+ </template>
+ </view>
+ </u-popup>
+</template>
+
+<script>
+ import props from './props.js';
+ /**
+ * Modal ���������
+ * @description ���������������������������������������������������������������������������������������������������������
+ * @tutorial https://www.uviewui.com/components/modul.html
+ * @property {Boolean} show ������������������������������������show ��������� false ���
+ * @property {String} title ������������
+ * @property {String} content ���������������������������slot���������������������������
+ * @property {String} confirmText ��������������������� ��������� '������' ���
+ * @property {String} cancelText ��������������������� ��������� '������' ���
+ * @property {Boolean} showConfirmButton ������������������������ ��������� true ���
+ * @property {Boolean} showCancelButton ������������������������ ��������� false ���
+ * @property {String} confirmColor ��������������������� ��������� '#2979ff' ���
+ * @property {String} cancelColor ��������������������� ��������� '#606266' ���
+ * @property {Boolean} buttonReverse ������������������������������ ��������� false ���
+ * @property {Boolean} zoom ������������������������ ��������� true ���
+ * @property {Boolean} asyncClose ��������������������������������������������������������������� ��������� false ���
+ * @property {Boolean} closeOnClickOverlay ������������������������������Modal ��������� false ���
+ * @property {String | Number} negativeTop ������������������������������������margin-top������������������������������������������������������������������������������������px������ ��������� 0 ���
+ * @property {String | Number} width modal���������������������������������������������px���rpx������ ��������� '650rpx' ���
+ * @property {String} confirmButtonShape ���������������������,���������������������������������������
+ * @event {Function} confirm ���������������������������
+ * @event {Function} cancel ���������������������������
+ * @event {Function} close ���������������������������closeOnClickOverlay���true������
+ * @example <u-modal :show="true" title="title" content="content"></u-modal>
+ */
+ export default {
+ name: 'u-modal',
+ mixins: [uni.$u.mpMixin, uni.$u.mixin, props],
+ data() {
+ return {
+ loading: false
+ }
+ },
+ watch: {
+ show(n) {
+ // ���������������������������modal������������������������������loading
+ // ���������������modal������loading���������������������
+ if (n && this.loading) this.loading = false
+ }
+ },
+ methods: {
+ // ������������������
+ confirmHandler() {
+ // ���������������������������������������������loading������
+ if (this.asyncClose) {
+ this.loading = true;
+ }
+ this.$emit('confirm')
+ },
+ // ������������������
+ cancelHandler() {
+ this.$emit('cancel')
+ },
+ // ������������
+ // ���������������������modal���������������������������������������������������
+ // ������modal���������popup���������������������������������������������������������������������������������������������������flex������
+ // ���������������������������������������������������������������������������������������������������������������������������������popup���������
+ // ������������������������������.stop���������������������������������������������������������
+ clickHandler() {
+ if (this.closeOnClickOverlay) {
+ this.$emit('close')
+ }
+ }
+ }
+ }
+</script>
+
+<style lang="scss" scoped>
+ @import "../../libs/css/components.scss";
+ $u-modal-border-radius: 6px;
+
+ .u-modal {
+ width: 650rpx;
+ border-radius: $u-modal-border-radius;
+ overflow: hidden;
+
+ &__title {
+ font-size: 16px;
+ font-weight: bold;
+ color: $u-content-color;
+ text-align: center;
+ padding-top: 25px;
+ }
+
+ &__content {
+ padding: 12px 25px 25px 25px;
+ @include flex;
+ justify-content: center;
+
+ &__text {
+ font-size: 15px;
+ color: $u-content-color;
+ flex: 1;
+ }
+ }
+
+ &__button-group {
+ @include flex;
+
+ &--confirm-button {
+ flex-direction: column;
+ padding: 0px 25px 15px 25px;
+ }
+
+ &__wrapper {
+ flex: 1;
+ @include flex;
+ justify-content: center;
+ align-items: center;
+ height: 48px;
+
+ &--confirm,
+ &--only-cancel {
+ border-bottom-right-radius: $u-modal-border-radius;
+ }
+
+ &--cancel,
+ &--only-confirm {
+ border-bottom-left-radius: $u-modal-border-radius;
+ }
+
+ &--hover {
+ background-color: $u-bg-color;
+ }
+
+ &__text {
+ color: $u-content-color;
+ font-size: 16px;
+ text-align: center;
+ }
+ }
+ }
+ }
+</style>
diff --git a/uni_modules/uview-ui/components/u-navbar/props.js b/uni_modules/uview-ui/components/u-navbar/props.js
new file mode 100644
index 0000000..5398de2
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-navbar/props.js
@@ -0,0 +1,84 @@
+export default {
+ props: {
+ // ���������������������������������
+ safeAreaInsetTop: {
+ type: Boolean,
+ default: uni.$u.props.navbar.safeAreaInsetTop
+ },
+ // ���������������������������������������������������������������������
+ placeholder: {
+ type: Boolean,
+ default: uni.$u.props.navbar.placeholder
+ },
+ // ���������������������
+ fixed: {
+ type: Boolean,
+ default: uni.$u.props.navbar.fixed
+ },
+ // ���������������������
+ border: {
+ type: Boolean,
+ default: uni.$u.props.navbar.border
+ },
+ // ���������������
+ leftIcon: {
+ type: String,
+ default: uni.$u.props.navbar.leftIcon
+ },
+ // ���������������������
+ leftText: {
+ type: String,
+ default: uni.$u.props.navbar.leftText
+ },
+ // ���������������������
+ rightText: {
+ type: String,
+ default: uni.$u.props.navbar.rightText
+ },
+ // ���������������
+ rightIcon: {
+ type: String,
+ default: uni.$u.props.navbar.rightIcon
+ },
+ // ������
+ title: {
+ type: [String, Number],
+ default: uni.$u.props.navbar.title
+ },
+ // ������������
+ bgColor: {
+ type: String,
+ default: uni.$u.props.navbar.bgColor
+ },
+ // ���������������
+ titleWidth: {
+ type: [String, Number],
+ default: uni.$u.props.navbar.titleWidth
+ },
+ // ���������������
+ height: {
+ type: [String, Number],
+ default: uni.$u.props.navbar.height
+ },
+ // ���������������������������
+ leftIconSize: {
+ type: [String, Number],
+ default: uni.$u.props.navbar.leftIconSize
+ },
+ // ���������������������������
+ leftIconColor: {
+ type: String,
+ default: uni.$u.props.navbar.leftIconColor
+ },
+ // ������������������(������������)������������������������������
+ autoBack: {
+ type: Boolean,
+ default: uni.$u.props.navbar.autoBack
+ },
+ // ������������������������������������
+ titleStyle: {
+ type: [String, Object],
+ default: uni.$u.props.navbar.titleStyle
+ }
+ }
+}
diff --git a/uni_modules/uview-ui/components/u-navbar/u-navbar.vue b/uni_modules/uview-ui/components/u-navbar/u-navbar.vue
new file mode 100644
index 0000000..2b206b7
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-navbar/u-navbar.vue
@@ -0,0 +1,186 @@
+<template>
+ <view class="u-navbar">
+ <view
+ class="u-navbar__placeholder"
+ v-if="fixed && placeholder"
+ :style="{
+ height: $u.addUnit($u.getPx(height) + $u.sys().statusBarHeight,'px'),
+ }"
+ ></view>
+ <view :class="[fixed && 'u-navbar--fixed']">
+ <u-status-bar
+ v-if="safeAreaInsetTop"
+ :bgColor="bgColor"
+ ></u-status-bar>
+ <view
+ class="u-navbar__content"
+ :class="[border && 'u-border-bottom']"
+ :style="{
+ height: $u.addUnit(height),
+ backgroundColor: bgColor,
+ }"
+ >
+ <view
+ class="u-navbar__content__left"
+ hover-class="u-navbar__content__left--hover"
+ hover-start-time="150"
+ @tap="leftClick"
+ >
+ <slot name="left">
+ <u-icon
+ v-if="leftIcon"
+ :name="leftIcon"
+ :size="leftIconSize"
+ :color="leftIconColor"
+ ></u-icon>
+ <text
+ v-if="leftText"
+ :style="{
+ color: leftIconColor
+ }"
+ class="u-navbar__content__left__text"
+ >{{ leftText }}</text>
+ </slot>
+ </view>
+ <slot name="center">
+ <text
+ class="u-line-1 u-navbar__content__title"
+ :style="[{
+ width: $u.addUnit(titleWidth),
+ }, $u.addStyle(titleStyle)]"
+ >{{ title }}</text>
+ </slot>
+ <view
+ class="u-navbar__content__right"
+ v-if="$slots.right || rightIcon || rightText"
+ @tap="rightClick"
+ >
+ <slot name="right">
+ <u-icon
+ v-if="rightIcon"
+ :name="rightIcon"
+ size="20"
+ ></u-icon>
+ <text
+ v-if="rightText"
+ class="u-navbar__content__right__text"
+ >{{ rightText }}</text>
+ </slot>
+ </view>
+ </view>
+ </view>
+ </view>
+</template>
+
+<script>
+ import props from './props.js';
+ /**
+ * Navbar ������������������
+ * @description ������������������������������������������������������������������������������������������������������uni-app������������������
+ * @tutorial https://www.uviewui.com/components/navbar.html
+ * @property {Boolean} safeAreaInsetTop ��������������������������������� ��������� true ���
+ * @property {Boolean} placeholder ��������������������������������������������������������������������� ��������� false ���
+ * @property {Boolean} fixed ������������������������������ ��������� false ���
+ * @property {Boolean} border ������������������������������������ ��������� false ���
+ * @property {String} leftIcon ���������������������������������������uView��������������� ��������� 'arrow-left' ���
+ * @property {String} leftText ���������������������
+ * @property {String} rightText ���������������������
+ * @property {String} rightIcon ���������������������������������������uView���������������
+ * @property {String} title ������������������������������������������������������������������������
+ * @property {String} bgColor ��������������������� ��������� '#ffffff' ���
+ * @property {String | Number} titleWidth ������������������������������������������������������������������ ��������� '400rpx' ���
+ * @property {String | Number} height ���������������(���������������������������������������������������)��������� '44px' ���
+ * @property {String | Number} leftIconSize ������������������������������������ 20px ���
+ * @property {String | Number} leftIconColor ������������������������������������ #303133 ���
+ * @property {Boolean} autoBack ������������������(������������)��������������������������������������� false ���
+ * @property {Object | String} titleStyle ������������������������������������
+ * @event {Function} leftClick ������������������
+ * @event {Function} rightClick ������������������
+ * @example <u-navbar title="���������������������������������" left-text="������" right-text="������" @click-left="onClickBack" @click-right="onClickRight"></u-navbar>
+ */
+ export default {
+ name: 'u-navbar',
+ mixins: [uni.$u.mpMixin, uni.$u.mixin, props],
+ data() {
+ return {
+
+ }
+ },
+ methods: {
+ // ������������������
+ leftClick() {
+ // ���������������autoBack������������������������
+ this.$emit('leftClick')
+ if(this.autoBack) {
+ uni.navigateBack()
+ }
+ },
+ // ������������������
+ rightClick() {
+ this.$emit('rightClick')
+ },
+ }
+ }
+</script>
+
+<style lang="scss" scoped>
+ @import "../../libs/css/components.scss";
+
+ .u-navbar {
+
+ &--fixed {
+ position: fixed;
+ left: 0;
+ right: 0;
+ top: 0;
+ z-index: 11;
+ }
+
+ &__content {
+ @include flex(row);
+ align-items: center;
+ height: 44px;
+ background-color: #9acafc;
+ position: relative;
+ justify-content: center;
+
+ &__left,
+ &__right {
+ padding: 0 13px;
+ position: absolute;
+ top: 0;
+ bottom: 0;
+ @include flex(row);
+ align-items: center;
+ }
+
+ &__left {
+ left: 0;
+
+ &--hover {
+ opacity: 0.7;
+ }
+
+ &__text {
+ font-size: 15px;
+ margin-left: 3px;
+ }
+ }
+
+ &__title {
+ text-align: center;
+ font-size: 16px;
+ color: $u-main-color;
+ }
+
+ &__right {
+ right: 0;
+
+ &__text {
+ font-size: 15px;
+ margin-left: 3px;
+ }
+ }
+ }
+ }
+</style>
diff --git a/uni_modules/uview-ui/components/u-no-network/props.js b/uni_modules/uview-ui/components/u-no-network/props.js
new file mode 100644
index 0000000..9f3af62
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-no-network/props.js
@@ -0,0 +1,19 @@
+export default {
+ props: {
+ // ������������������
+ tips: {
+ type: String,
+ default: uni.$u.props.noNetwork.tips
+ },
+ // ������z-index������������������������������������������������������������������������������������������������������������������������������������������
+ zIndex: {
+ type: [String, Number],
+ default: uni.$u.props.noNetwork.zIndex
+ },
+ // image ���������������������������
+ image: {
+ type: String,
+ default: uni.$u.props.noNetwork.image
+ }
+ }
+}
diff --git a/uni_modules/uview-ui/components/u-no-network/u-no-network.vue b/uni_modules/uview-ui/components/u-no-network/u-no-network.vue
new file mode 100644
index 0000000..9710729
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-no-network/u-no-network.vue
@@ -0,0 +1,220 @@
+<template>
+ <u-overlay
+ :show="!isConnected"
+ :zIndex="zIndex"
+ @touchmove.stop.prevent="noop"
+ :customStyle="{
+ backgroundColor: '#fff',
+ display: 'flex',
+ justifyContent: 'center',
+ }"
+ >
+ <view
+ class="u-no-network"
+ >
+ <u-icon
+ :name="image"
+ size="150"
+ imgMode="widthFit"
+ class="u-no-network__error-icon"
+ ></u-icon>
+ <text class="u-no-network__tips">{{tips}}</text>
+ <!-- ������APP���������������������������������������������������plus������ -->
+ <!-- #ifdef APP-PLUS -->
+ <view class="u-no-network__app">
+ <text class="u-no-network__app__setting">���������������������������</text>
+ <text
+ class="u-no-network__app__to-setting"
+ @tap="openSettings"
+ >������</text>
+ </view>
+ <!-- #endif -->
+ <view class="u-no-network__retry">
+ <u-button
+ size="mini"
+ text="������"
+ type="primary"
+ plain
+ @click="retry"
+ ></u-button>
+ </view>
+ </view>
+ </u-overlay>
+</template>
+
+<script>
+ import props from './props.js';
+
+ /**
+ * noNetwork ���������������
+ * @description ���������������������������������������������������������������������������������������
+ * @tutorial https://www.uviewui.com/components/noNetwork.html
+ * @property {String} tips ��������������������������� ������������'���������������������������' ���
+ * @property {String | Number} zIndex ���������z-index���
+ * @property {String} image ������������������������������������src���������base64������
+ * @event {Function} retry ���������������������"������"���������������
+ * @example <u-no-network></u-no-network>
+ */
+ export default {
+ name: "u-no-network",
+ mixins: [uni.$u.mpMixin, uni.$u.mixin,props],
+ data() {
+ return {
+ isConnected: true, // ���������������������
+ networkType: "none", // ������������
+ }
+ },
+ mounted() {
+ this.isIOS = (uni.getSystemInfoSync().platform === 'ios')
+ uni.onNetworkStatusChange((res) => {
+ this.isConnected = res.isConnected
+ this.networkType = res.networkType
+ this.emitEvent(this.networkType)
+ })
+ uni.getNetworkType({
+ success: (res) => {
+ this.networkType = res.networkType
+ this.emitEvent(this.networkType)
+ if (res.networkType == 'none') {
+ this.isConnected = false
+ } else {
+ this.isConnected = true
+ }
+ }
+ })
+ },
+ methods: {
+ retry() {
+ // ������������������
+ uni.getNetworkType({
+ success: (res) => {
+ this.networkType = res.networkType
+ this.emitEvent(this.networkType)
+ if (res.networkType == 'none') {
+ uni.$u.toast('���������������')
+ this.isConnected = false
+ } else {
+ uni.$u.toast('���������������')
+ this.isConnected = true
+ }
+ }
+ })
+ this.$emit('retry')
+ },
+ // ������������������������
+ emitEvent(networkType) {
+ this.$emit(networkType === 'none' ? 'disconnected' : 'connected')
+ },
+ async openSettings() {
+ if (this.networkType == "none") {
+ this.openSystemSettings()
+ return
+ }
+ },
+ openAppSettings() {
+ this.gotoAppSetting()
+ },
+ openSystemSettings() {
+ // ������������������5+���������������������������������������������������
+ // https://ask.dcloud.net.cn/docs/
+ if (this.isIOS) {
+ this.gotoiOSSetting()
+ } else {
+ this.gotoAndroidSetting()
+ }
+ },
+ network() {
+ var result = null
+ var cellularData = plus.ios.newObject("CTCellularData")
+ var state = cellularData.plusGetAttribute("restrictedState")
+ if (state == 0) {
+ result = null
+ } else if (state == 2) {
+ result = 1
+ } else if (state == 1) {
+ result = 2
+ }
+ plus.ios.deleteObject(cellularData)
+ return result
+ },
+ gotoAppSetting() {
+ if (this.isIOS) {
+ var UIApplication = plus.ios.import("UIApplication")
+ var application2 = UIApplication.sharedApplication()
+ var NSURL2 = plus.ios.import("NSURL")
+ var setting2 = NSURL2.URLWithString("app-settings:")
+ application2.openURL(setting2)
+ plus.ios.deleteObject(setting2)
+ plus.ios.deleteObject(NSURL2)
+ plus.ios.deleteObject(application2)
+ } else {
+ var Intent = plus.android.importClass("android.content.Intent")
+ var Settings = plus.android.importClass("android.provider.Settings")
+ var Uri = plus.android.importClass("android.net.Uri")
+ var mainActivity = plus.android.runtimeMainActivity()
+ var intent = new Intent()
+ intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS)
+ var uri = Uri.fromParts("package", mainActivity.getPackageName(), null)
+ intent.setData(uri)
+ mainActivity.startActivity(intent)
+ }
+ },
+ gotoiOSSetting() {
+ var UIApplication = plus.ios.import("UIApplication")
+ var application2 = UIApplication.sharedApplication()
+ var NSURL2 = plus.ios.import("NSURL")
+ var setting2 = NSURL2.URLWithString("App-prefs:root=General")
+ application2.openURL(setting2)
+ plus.ios.deleteObject(setting2)
+ plus.ios.deleteObject(NSURL2)
+ plus.ios.deleteObject(application2)
+ },
+ gotoAndroidSetting() {
+ var Intent = plus.android.importClass("android.content.Intent")
+ var Settings = plus.android.importClass("android.provider.Settings")
+ var mainActivity = plus.android.runtimeMainActivity()
+ var intent = new Intent(Settings.ACTION_SETTINGS)
+ mainActivity.startActivity(intent)
+ }
+ }
+ }
+</script>
+
+<style lang="scss" scoped>
+ @import "../../libs/css/components.scss";
+
+ .u-no-network {
+ @include flex(column);
+ justify-content: center;
+ align-items: center;
+ margin-top: -100px;
+
+ &__tips {
+ color: $u-tips-color;
+ font-size: 14px;
+ margin-top: 15px;
+ }
+
+ &__app {
+ @include flex(row);
+ margin-top: 6px;
+
+ &__setting {
+ color: $u-light-color;
+ font-size: 13px;
+ }
+
+ &__to-setting {
+ font-size: 13px;
+ color: $u-primary;
+ margin-left: 3px;
+ }
+ }
+
+ &__retry {
+ @include flex(row);
+ justify-content: center;
+ margin-top: 15px;
+ }
+ }
+</style>
diff --git a/uni_modules/uview-ui/components/u-notice-bar/props.js b/uni_modules/uview-ui/components/u-notice-bar/props.js
new file mode 100644
index 0000000..7040c29
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-notice-bar/props.js
@@ -0,0 +1,70 @@
+export default {
+ props: {
+ // ������������������������
+ text: {
+ type: [Array, String],
+ default: uni.$u.props.noticeBar.text
+ },
+ // ���������������������row-���������������column-������������
+ direction: {
+ type: String,
+ default: uni.$u.props.noticeBar.direction
+ },
+ // direction = row������������������������������������
+ step: {
+ type: Boolean,
+ default: uni.$u.props.noticeBar.step
+ },
+ // ���������������������������������
+ icon: {
+ type: String,
+ default: uni.$u.props.noticeBar.icon
+ },
+ // ���������������link-������������������closable-������������������������
+ mode: {
+ type: String,
+ default: uni.$u.props.noticeBar.mode
+ },
+ // ������������������������������������������������
+ color: {
+ type: String,
+ default: uni.$u.props.noticeBar.color
+ },
+ // ������������
+ bgColor: {
+ type: String,
+ default: uni.$u.props.noticeBar.bgColor
+ },
+ // ������������������������������������������������������px(px)���������������������������������������������������������������������������
+ speed: {
+ type: [String, Number],
+ default: uni.$u.props.noticeBar.speed
+ },
+ // ������������
+ fontSize: {
+ type: [String, Number],
+ default: uni.$u.props.noticeBar.fontSize
+ },
+ // ���������������������������������������ms
+ duration: {
+ type: [String, Number],
+ default: uni.$u.props.noticeBar.duration
+ },
+ // ������������������������������
+ // ������HX2.6.11������������App 2.5.5+���H5 2.5.5+���������������������������������������������
+ disableTouch: {
+ type: Boolean,
+ default: uni.$u.props.noticeBar.disableTouch
+ },
+ // ���������������������
+ url: {
+ type: String,
+ default: uni.$u.props.noticeBar.url
+ },
+ // ���������������������
+ linkType: {
+ type: String,
+ default: uni.$u.props.noticeBar.linkType
+ }
+ }
+}
diff --git a/uni_modules/uview-ui/components/u-notice-bar/u-notice-bar.vue b/uni_modules/uview-ui/components/u-notice-bar/u-notice-bar.vue
new file mode 100644
index 0000000..a06eb39
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-notice-bar/u-notice-bar.vue
@@ -0,0 +1,101 @@
+<template>
+ <view
+ class="u-notice-bar"
+ v-if="show"
+ :style="[{
+ backgroundColor: bgColor
+ }, $u.addStyle(customStyle)]"
+ >
+ <template v-if="direction === 'column' || (direction === 'row' && step)">
+ <u-column-notice
+ :color="color"
+ :bgColor="bgColor"
+ :text="text"
+ :mode="mode"
+ :step="step"
+ :icon="icon"
+ :disable-touch="disableTouch"
+ :fontSize="fontSize"
+ :duration="duration"
+ @close="close"
+ @click="click"
+ ></u-column-notice>
+ </template>
+ <template v-else>
+ <u-row-notice
+ :color="color"
+ :bgColor="bgColor"
+ :text="text"
+ :mode="mode"
+ :fontSize="fontSize"
+ :speed="speed"
+ :url="url"
+ :linkType="linkType"
+ :icon="icon"
+ @close="close"
+ @click="click"
+ ></u-row-notice>
+ </template>
+ </view>
+</template>
+<script>
+ import props from './props.js';
+
+ /**
+ * noticeBar ������������
+ * @description ���������������������������������������������������������������
+ * @tutorial https://www.uviewui.com/components/noticeBar.html
+ * @property {Array | String} text ������������������������
+ * @property {String} direction ���������������������row-���������������column-������������ ( ������ 'row' )
+ * @property {Boolean} step direction = row������������������������������������ ( ������ false )
+ * @property {String} icon ��������������������������������� ( ������ 'volume' )
+ * @property {String} mode ���������������link-������������������closable-������������������������
+ * @property {String} color ������������������������������������������������ ( ������ '#f9ae3d' )
+ * @property {String} bgColor ������������ ( ������ '#fdf6ec' )
+ * @property {String | Number} speed ������������������������������������������������������px(px)��������������������������������������������������������������������������� ( ������ 80 )
+ * @property {String | Number} fontSize ������������ ( ������ 14 )
+ * @property {String | Number} duration ���������������������������������������ms ( ������ 2000 )
+ * @property {Boolean} disableTouch ������������������������������ ������HX2.6.11������������App 2.5.5+���H5 2.5.5+������������������������������������������������������34��� ( ������ true )
+ * @property {String} url ���������������������
+ * @property {String} linkType ��������������������� ( ������ navigateTo )
+ * @property {Object} customStyle ���������������������������������
+ *
+ * @event {Function} click ������������������������
+ * @event {Function} close ������������������������������
+ * @example <u-notice-bar :more-icon="true" :list="list"></u-notice-bar>
+ */
+ export default {
+ name: "u-notice-bar",
+ mixins: [uni.$u.mpMixin, uni.$u.mixin,props],
+ data() {
+ return {
+ show: true
+ }
+ },
+ methods: {
+ // ���������������
+ click(index) {
+ this.$emit('click', index)
+ if (this.url && this.linkType) {
+ // ���������������mixin���������������������url���linkType������������mixin���props���
+ this.openPage()
+ }
+ },
+ // ������������������
+ close() {
+ this.show = false
+ this.$emit('close')
+ }
+ }
+ };
+</script>
+
+<style lang="scss" scoped>
+ @import "../../libs/css/components.scss";
+
+ .u-notice-bar {
+ overflow: hidden;
+ padding: 9px 12px;
+ flex: 1;
+ }
+</style>
diff --git a/uni_modules/uview-ui/components/u-notify/props.js b/uni_modules/uview-ui/components/u-notify/props.js
new file mode 100644
index 0000000..57a9d71
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-notify/props.js
@@ -0,0 +1,49 @@
+export default {
+ props: {
+ // ������������������
+ top: {
+ type: [String, Number],
+ default: uni.$u.props.notify.top
+ },
+ // ������������������
+ // show: {
+ // type: Boolean,
+ // default: uni.$u.props.notify.show
+ // },
+ // type���������primary���success���warning���error
+ type: {
+ type: String,
+ default: uni.$u.props.notify.type
+ },
+ // ������������
+ color: {
+ type: String,
+ default: uni.$u.props.notify.color
+ },
+ // ������������
+ bgColor: {
+ type: String,
+ default: uni.$u.props.notify.bgColor
+ },
+ // ���������������������
+ message: {
+ type: String,
+ default: uni.$u.props.notify.message
+ },
+ // ������������������0���������������������ms
+ duration: {
+ type: [String, Number],
+ default: uni.$u.props.notify.duration
+ },
+ // ������������
+ fontSize: {
+ type: [String, Number],
+ default: uni.$u.props.notify.fontSize
+ },
+ // ���������������������������������������������������
+ safeAreaInsetTop: {
+ type: Boolean,
+ default: uni.$u.props.notify.safeAreaInsetTop
+ }
+ }
+}
diff --git a/uni_modules/uview-ui/components/u-notify/u-notify.vue b/uni_modules/uview-ui/components/u-notify/u-notify.vue
new file mode 100644
index 0000000..30adb72
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-notify/u-notify.vue
@@ -0,0 +1,211 @@
+<template>
+ <u-transition
+ mode="slide-down"
+ :customStyle="containerStyle"
+ :show="open"
+ >
+ <view
+ class="u-notify"
+ :class="[`u-notify--${tmpConfig.type}`]"
+ :style="[backgroundColor, $u.addStyle(customStyle)]"
+ >
+ <u-status-bar v-if="tmpConfig.safeAreaInsetTop"></u-status-bar>
+ <view class="u-notify__warpper">
+ <slot name="icon">
+ <u-icon
+ v-if="['success', 'warning', 'error'].includes(tmpConfig.type)"
+ :name="tmpConfig.icon"
+ :color="tmpConfig.color"
+ :size="1.3 * tmpConfig.fontSize"
+ :customStyle="{marginRight: '4px'}"
+ ></u-icon>
+ </slot>
+ <text
+ class="u-notify__warpper__text"
+ :style="{
+ fontSize: $u.addUnit(tmpConfig.fontSize),
+ color: tmpConfig.color
+ }"
+ >{{ tmpConfig.message }}</text>
+ </view>
+ </view>
+ </u-transition>
+</template>
+
+<script>
+ import props from './props.js';
+ /**
+ * notify ������������
+ * @description ���������������������������������������������������������������������������������������
+ * @tutorial
+ * @property {String | Number} top ������������������ ( ������ 0 )
+ * @property {String} type ���������primary���success���warning���error ( ������ 'primary' )
+ * @property {String} color ������������ ( ������ '#ffffff' )
+ * @property {String} bgColor ������������
+ * @property {String} message ���������������������
+ * @property {String | Number} duration ������������������0���������������������ms ( ������ 3000 )
+ * @property {String | Number} fontSize ������������ ( ������ 15 )
+ * @property {Boolean} safeAreaInsetTop ��������������������������������������������������� ( ������ false )
+ * @property {Object} customStyle ������������������������������
+ * @event {Function} open ������������������������������
+ * @event {Function} close ������������������������������
+ * @example <u-notify message="Hi uView"></u-notify>
+ */
+ export default {
+ name: 'u-notify',
+ mixins: [uni.$u.mpMixin, uni.$u.mixin,props],
+ data() {
+ return {
+ // ������������������
+ open: false,
+ timer: null,
+ config: {
+ // ������������������
+ top: uni.$u.props.notify.top,
+ // type���������primary���success���warning���error
+ type: uni.$u.props.notify.type,
+ // ������������
+ color: uni.$u.props.notify.color,
+ // ������������
+ bgColor: uni.$u.props.notify.bgColor,
+ // ���������������������
+ message: uni.$u.props.notify.message,
+ // ������������������0���������������������ms
+ duration: uni.$u.props.notify.duration,
+ // ������������
+ fontSize: uni.$u.props.notify.fontSize,
+ // ���������������������������������������������������
+ safeAreaInsetTop: uni.$u.props.notify.safeAreaInsetTop
+ },
+ // ���������������������������������������������������������������������������������������������
+ tmpConfig: {}
+ }
+ },
+ computed: {
+ containerStyle() {
+ let top = 0
+ if (this.tmpConfig.top === 0) {
+ // #ifdef H5
+ // H5������������������������������������������������������������������������������
+ // H5���������������������44px
+ top = 44
+ // #endif
+ }
+ const style = {
+ top: uni.$u.addUnit(this.tmpConfig.top === 0 ? top : this.tmpConfig.top),
+ // ���������������������u-transition������������������������������fixed������
+ // ������������������������������
+ position: 'fixed',
+ left: 0,
+ right: 0,
+ zIndex: 10076
+ }
+ return style
+ },
+ // ������������������
+ backgroundColor() {
+ const style = {}
+ if (this.tmpConfig.bgColor) {
+ style.backgroundColor = this.tmpConfig.bgColor
+ }
+ return style
+ },
+ // ������������������������
+ icon() {
+ let icon
+ if (this.tmpConfig.type === 'success') {
+ icon = 'checkmark-circle'
+ } else if (this.tmpConfig.type === 'error') {
+ icon = 'close-circle'
+ } else if (this.tmpConfig.type === 'warning') {
+ icon = 'error-circle'
+ }
+ return icon
+ }
+ },
+ created() {
+ // ���������������������������toast���������������������������
+ ['primary', 'success', 'error', 'warning'].map(item => {
+ this[item] = message => this.show({
+ type: item,
+ message
+ })
+ })
+ },
+ methods: {
+ show(options) {
+ // ���������������������this.config���������������������������u-toast������������������������������
+ this.tmpConfig = uni.$u.deepMerge(this.config, options)
+ // ���������������������������������������������������������������������������������������
+ this.clearTimer()
+ this.open = true
+ if (this.tmpConfig.duration > 0) {
+ this.timer = setTimeout(() => {
+ this.open = false
+ // ������������������������������������������toast������
+ this.clearTimer()
+ // ������������������callback������������������������������
+ typeof(this.tmpConfig.complete) === 'function' && this.tmpConfig.complete()
+ }, this.tmpConfig.duration)
+ }
+ },
+ // ������notify
+ close() {
+ this.clearTimer()
+ },
+ clearTimer() {
+ this.open = false
+ // ���������������
+ clearTimeout(this.timer)
+ this.timer = null
+ }
+ },
+ beforeDestroy() {
+ this.clearTimer()
+ }
+ }
+</script>
+
+<style lang="scss" scoped>
+ @import "../../libs/css/components.scss";
+
+ $u-notify-padding: 8px 10px !default;
+ $u-notify-text-font-size: 15px !default;
+ $u-notify-primary-bgColor: $u-primary !default;
+ $u-notify-success-bgColor: $u-success !default;
+ $u-notify-error-bgColor: $u-error !default;
+ $u-notify-warning-bgColor: $u-warning !default;
+
+
+ .u-notify {
+ padding: $u-notify-padding;
+
+ &__warpper {
+ @include flex;
+ align-items: center;
+ text-align: center;
+ justify-content: center;
+
+ &__text {
+ font-size: $u-notify-text-font-size;
+ text-align: center;
+ }
+ }
+
+ &--primary {
+ background-color: $u-notify-primary-bgColor;
+ }
+
+ &--success {
+ background-color: $u-notify-success-bgColor;
+ }
+
+ &--error {
+ background-color: $u-notify-error-bgColor;
+ }
+
+ &--warning {
+ background-color: $u-notify-warning-bgColor;
+ }
+ }
+</style>
diff --git a/uni_modules/uview-ui/components/u-number-box/props.js b/uni_modules/uview-ui/components/u-number-box/props.js
new file mode 100644
index 0000000..fb0fa94
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-number-box/props.js
@@ -0,0 +1,109 @@
+export default {
+ props: {
+ // ������������������������change������������
+ name: {
+ type: [String, Number],
+ default: uni.$u.props.numberBox.name
+ },
+ // ���������������������������������������������������������min���(���������)
+ value: {
+ type: [String, Number],
+ default: uni.$u.props.numberBox.value
+ },
+ // ���������
+ min: {
+ type: [String, Number],
+ default: uni.$u.props.numberBox.min
+ },
+ // ���������
+ max: {
+ type: [String, Number],
+ default: uni.$u.props.numberBox.max
+ },
+ // ������������������������������
+ step: {
+ type: [String, Number],
+ default: uni.$u.props.numberBox.step
+ },
+ // ���������������������������
+ integer: {
+ type: Boolean,
+ default: uni.$u.props.numberBox.integer
+ },
+ // ���������������������������������������������
+ disabled: {
+ type: Boolean,
+ default: uni.$u.props.numberBox.disabled
+ },
+ // ���������������������
+ disabledInput: {
+ type: Boolean,
+ default: uni.$u.props.numberBox.disabledInput
+ },
+ // ���������������������������������������������������������������
+ asyncChange: {
+ type: Boolean,
+ default: uni.$u.props.numberBox.asyncChange
+ },
+ // ���������������������������px
+ inputWidth: {
+ type: [String, Number],
+ default: uni.$u.props.numberBox.inputWidth
+ },
+ // ������������������������
+ showMinus: {
+ type: Boolean,
+ default: uni.$u.props.numberBox.showMinus
+ },
+ // ������������������������
+ showPlus: {
+ type: Boolean,
+ default: uni.$u.props.numberBox.showPlus
+ },
+ // ���������������������
+ decimalLength: {
+ type: [String, Number, null],
+ default: uni.$u.props.numberBox.decimalLength
+ },
+ // ������������������������������
+ longPress: {
+ type: Boolean,
+ default: uni.$u.props.numberBox.longPress
+ },
+ // ���������������������������������������������
+ color: {
+ type: String,
+ default: uni.$u.props.numberBox.color
+ },
+ // ������������������������������������������px���������������������������������������
+ buttonSize: {
+ type: [String, Number],
+ default: uni.$u.props.numberBox.buttonSize
+ },
+ // ���������������������������������
+ bgColor: {
+ type: String,
+ default: uni.$u.props.numberBox.bgColor
+ },
+ // ���������������������������������������������������������������������px
+ cursorSpacing: {
+ type: [String, Number],
+ default: uni.$u.props.numberBox.cursorSpacing
+ },
+ // ������������������������
+ disablePlus: {
+ type: Boolean,
+ default: uni.$u.props.numberBox.disablePlus
+ },
+ // ������������������������
+ disableMinus: {
+ type: Boolean,
+ default: uni.$u.props.numberBox.disableMinus
+ },
+ // ���������������������������
+ iconStyle: {
+ type: [Object, String],
+ default: uni.$u.props.numberBox.iconStyle
+ }
+ }
+}
diff --git a/uni_modules/uview-ui/components/u-number-box/u-number-box.vue b/uni_modules/uview-ui/components/u-number-box/u-number-box.vue
new file mode 100644
index 0000000..69211c5
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-number-box/u-number-box.vue
@@ -0,0 +1,416 @@
+<template>
+ <view class="u-number-box">
+ <view
+ class="u-number-box__slot"
+ @tap.stop="clickHandler('minus')"
+ @touchstart="onTouchStart('minus')"
+ @touchend.stop="clearTimeout"
+ v-if="showMinus && $slots.minus"
+ >
+ <slot name="minus" />
+ </view>
+ <view
+ v-else-if="showMinus"
+ class="u-number-box__minus"
+ @tap.stop="clickHandler('minus')"
+ @touchstart="onTouchStart('minus')"
+ @touchend.stop="clearTimeout"
+ hover-class="u-number-box__minus--hover"
+ hover-stay-time="150"
+ :class="{ 'u-number-box__minus--disabled': isDisabled('minus') }"
+ :style="[buttonStyle('minus')]"
+ >
+ <u-icon
+ name="minus"
+ :color="isDisabled('minus') ? '#c8c9cc' : '#323233'"
+ size="15"
+ bold
+ :customStyle="iconStyle"
+ ></u-icon>
+ </view>
+
+ <slot name="input">
+ <input
+ :disabled="disabledInput || disabled"
+ :cursor-spacing="getCursorSpacing"
+ :class="{ 'u-number-box__input--disabled': disabled || disabledInput }"
+ v-model="currentValue"
+ class="u-number-box__input"
+ @blur="onBlur"
+ @focus="onFocus"
+ @input="onInput"
+ type="number"
+ :style="[inputStyle]"
+ />
+ </slot>
+ <view
+ class="u-number-box__slot"
+ @tap.stop="clickHandler('plus')"
+ @touchstart="onTouchStart('plus')"
+ @touchend.stop="clearTimeout"
+ v-if="showPlus && $slots.plus"
+ >
+ <slot name="plus" />
+ </view>
+ <view
+ v-else-if="showPlus"
+ class="u-number-box__plus"
+ @tap.stop="clickHandler('plus')"
+ @touchstart="onTouchStart('plus')"
+ @touchend.stop="clearTimeout"
+ hover-class="u-number-box__plus--hover"
+ hover-stay-time="150"
+ :class="{ 'u-number-box__minus--disabled': isDisabled('plus') }"
+ :style="[buttonStyle('plus')]"
+ >
+ <u-icon
+ name="plus"
+ :color="isDisabled('plus') ? '#c8c9cc' : '#323233'"
+ size="15"
+ bold
+ :customStyle="iconStyle"
+ ></u-icon>
+ </view>
+ </view>
+</template>
+
+<script>
+ import props from './props.js';
+ /**
+ * numberBox ���������
+ * @description ���������������������������������������������������������������
+ * @tutorial https://uviewui.com/components/numberBox.html
+ * @property {String | Number} name ������������������������change������������
+ * @property {String | Number} value ���������������������������������������������������������min���(���������) ��������� 0 ���
+ * @property {String | Number} min ��������� ��������� 1 ���
+ * @property {String | Number} max ��������� ��������� Number.MAX_SAFE_INTEGER ���
+ * @property {String | Number} step ������������������������������ ��������� 1 ���
+ * @property {Boolean} integer ��������������������������� ��������� false ���
+ * @property {Boolean} disabled ��������������������������������������������� ��������� false ���
+ * @property {Boolean} disabledInput ��������������������� ��������� false ���
+ * @property {Boolean} asyncChange ��������������������������������������������������������������� ��������� false ���
+ * @property {String | Number} inputWidth ���������������������������px ��������� 35 ���
+ * @property {Boolean} showMinus ������������������������ ��������� true ���
+ * @property {Boolean} showPlus ������������������������ ��������� true ���
+ * @property {String | Number} decimalLength ���������������������
+ * @property {Boolean} longPress ������������������������������ ��������� true ���
+ * @property {String} color ��������������������������������������������� ��������� '#323233' ���
+ * @property {String | Number} buttonSize ������������������������������������������px��������������������������������������� ��������� 30 ���
+ * @property {String} bgColor ��������������������������������� ��������� '#EBECEE' ���
+ * @property {String | Number} cursorSpacing ���������������������������������������������������������������������px ��������� 100 ���
+ * @property {Boolean} disablePlus ������������������������ ��������� false ���
+ * @property {Boolean} disableMinus ������������������������ ��������� false ���
+ * @property {Object ��� String} iconStyle ���������������������������
+ *
+ * @event {Function} onFocus ���������������������
+ * @event {Function} onBlur ���������������������
+ * @event {Function} onInput ������������������������
+ * @event {Function} onChange
+ * @example <u-number-box v-model="value" @change="valChange"></u-number-box>
+ */
+ export default {
+ name: 'u-number-box',
+ mixins: [uni.$u.mpMixin, uni.$u.mixin, props],
+ data() {
+ return {
+ // ���������������������������
+ currentValue: '',
+ // ���������
+ longPressTimer: null
+ }
+ },
+ watch: {
+ // ������������������������������������������������������������������check()������
+ watchChange(n) {
+ this.check()
+ },
+ // ������v-mode���������������������������������������
+ value(n) {
+ if (n !== this.currentValue) {
+ this.currentValue = this.format(this.value)
+ }
+ }
+ },
+ computed: {
+ getCursorSpacing() {
+ // ���������������������������������px���������������������px
+ return uni.$u.getPx(this.cursorSpacing)
+ },
+ // ���������������
+ buttonStyle() {
+ return (type) => {
+ const style = {
+ backgroundColor: this.bgColor,
+ height: uni.$u.addUnit(this.buttonSize),
+ color: this.color
+ }
+ if (this.isDisabled(type)) {
+ style.backgroundColor = '#f7f8fa'
+ }
+ return style
+ }
+ },
+ // ������������������
+ inputStyle() {
+ const disabled = this.disabled || this.disabledInput
+ const style = {
+ color: this.color,
+ backgroundColor: this.bgColor,
+ height: uni.$u.addUnit(this.buttonSize),
+ width: uni.$u.addUnit(this.inputWidth)
+ }
+ return style
+ },
+ // ���������������������������������
+ watchChange() {
+ return [this.integer, this.decimalLength, this.min, this.max]
+ },
+ isDisabled() {
+ return (type) => {
+ if (type === 'plus') {
+ // ������������������������������������������������disabled���������������������������������������������������������������������������������
+ return (
+ this.disabled ||
+ this.disablePlus ||
+ this.currentValue >= this.max
+ )
+ }
+ // ������������������������
+ return (
+ this.disabled ||
+ this.disableMinus ||
+ this.currentValue <= this.min
+ )
+ }
+ },
+ },
+ mounted() {
+ this.init()
+ },
+ methods: {
+ init() {
+ this.currentValue = this.format(this.value)
+ },
+ // ������������������������������������
+ format(value) {
+ value = this.filter(value)
+ // ���������������������������������������0���������������������Number������
+ value = value === '' ? 0 : +value
+ // ������������������������������min���max������������
+ value = Math.max(Math.min(this.max, value), this.min)
+ // ���������������������������������������������toFixed������������������
+ if (this.decimalLength !== null) {
+ value = value.toFixed(this.decimalLength)
+ }
+ return value
+ },
+ // ���������������������
+ filter(value) {
+ // ���������0-9������������������"."���������������"-"���������������������
+ value = String(value).replace(/[^0-9.-]/g, '')
+ // ���������������������������������������������������������������
+ if (this.integer && value.indexOf('.') !== -1) {
+ value = value.split('.')[0]
+ }
+ return value;
+ },
+ check() {
+ // ������������������������������������������������������������������������������������
+ const val = this.format(this.currentValue);
+ if (val !== this.currentValue) {
+ this.currentValue = val
+ }
+ },
+ // ������������������������������������
+ // isDisabled(type) {
+ // if (type === 'plus') {
+ // // ������������������������������������������������disabled���������������������������������������������������������������������������������
+ // return (
+ // this.disabled ||
+ // this.disablePlus ||
+ // this.currentValue >= this.max
+ // )
+ // }
+ // // ������������������������
+ // return (
+ // this.disabled ||
+ // this.disableMinus ||
+ // this.currentValue <= this.min
+ // )
+ // },
+ // ���������������������
+ onFocus(event) {
+ this.$emit('focus', {
+ ...event.detail,
+ name: this.name,
+ })
+ },
+ // ���������������������
+ onBlur(event) {
+ // ���������������������������
+ const value = this.format(event.detail.value)
+ // ������blur������
+ this.$emit(
+ 'blur',{
+ ...event.detail,
+ name: this.name,
+ }
+ )
+ },
+ // ������������������������
+ onInput(e) {
+ const {
+ value = ''
+ } = e.detail || {}
+ // ������������
+ if (value === '') return
+ let formatted = this.filter(value)
+ // ���������������������������
+ if (this.decimalLength !== null && formatted.indexOf('.') !== -1) {
+ const pair = formatted.split('.');
+ formatted = `${pair[0]}.${pair[1].slice(0, this.decimalLength)}`
+ }
+ formatted = this.format(formatted)
+ this.emitChange(formatted);
+ },
+ // ������change������
+ emitChange(value) {
+ // ���������������������������������������������������������������������������������������������v-model������
+ if (!this.asyncChange) {
+ this.$nextTick(() => {
+ this.$emit('input', value)
+ this.currentValue = value
+ this.$forceUpdate()
+ })
+ }
+ this.$emit('change', {
+ value,
+ name: this.name,
+ });
+ },
+ onChange() {
+ const {
+ type
+ } = this
+ if (this.isDisabled(type)) {
+ return this.$emit('overlimit', type)
+ }
+ const diff = type === 'minus' ? -this.step : +this.step
+ const value = this.format(this.add(+this.currentValue, diff))
+ this.emitChange(value)
+ this.$emit(type)
+ },
+ // ������������������������������������������������������������������������������������������������������
+ add(num1, num2) {
+ const cardinal = Math.pow(10, 10);
+ return Math.round((num1 + num2) * cardinal) / cardinal
+ },
+ // ������������������
+ clickHandler(type) {
+ this.type = type
+ this.onChange()
+ },
+ longPressStep() {
+ // ���������������������������������longPressStep���������������������������
+ this.clearTimeout()
+ this.longPressTimer = setTimeout(() => {
+ this.onChange()
+ this.longPressStep()
+ }, 250);
+ },
+ onTouchStart(type) {
+ if (!this.longPress) return
+ this.clearTimeout()
+ this.type = type
+ // ������������������������������������������
+ this.longPressTimer = setTimeout(() => {
+ this.onChange()
+ this.longPressStep()
+ }, 600)
+ },
+ // ���������������������������������������������������
+ onTouchEnd() {
+ if (!this.longPress) return
+ this.clearTimeout()
+ },
+ // ���������������
+ clearTimeout() {
+ clearTimeout(this.longPressTimer)
+ this.longPressTimer = null
+ }
+ }
+ }
+</script>
+
+<style lang="scss" scoped>
+ @import '../../libs/css/components.scss';
+
+ $u-numberBox-hover-bgColor: #E6E6E6 !default;
+ $u-numberBox-disabled-color: #c8c9cc !default;
+ $u-numberBox-disabled-bgColor: #f7f8fa !default;
+ $u-numberBox-plus-radius: 4px !default;
+ $u-numberBox-minus-radius: 4px !default;
+ $u-numberBox-input-text-align: center !default;
+ $u-numberBox-input-font-size: 15px !default;
+ $u-numberBox-input-padding: 0 !default;
+ $u-numberBox-input-margin: 0 2px !default;
+ $u-numberBox-input-disabled-color: #c8c9cc !default;
+ $u-numberBox-input-disabled-bgColor: #f2f3f5 !default;
+
+ .u-number-box {
+ @include flex(row);
+ align-items: center;
+
+ &__slot {
+ /* #ifndef APP-NVUE */
+ touch-action: none;
+ /* #endif */
+ }
+
+ &__plus,
+ &__minus {
+ width: 35px;
+ @include flex;
+ justify-content: center;
+ align-items: center;
+ /* #ifndef APP-NVUE */
+ touch-action: none;
+ /* #endif */
+
+ &--hover {
+ background-color: $u-numberBox-hover-bgColor !important;
+ }
+
+ &--disabled {
+ color: $u-numberBox-disabled-color;
+ background-color: $u-numberBox-disabled-bgColor;
+ }
+ }
+
+ &__plus {
+ border-top-right-radius: $u-numberBox-plus-radius;
+ border-bottom-right-radius: $u-numberBox-plus-radius;
+ }
+
+ &__minus {
+ border-top-left-radius: $u-numberBox-minus-radius;
+ border-bottom-left-radius: $u-numberBox-minus-radius;
+ }
+
+ &__input {
+ position: relative;
+ text-align: $u-numberBox-input-text-align;
+ font-size: $u-numberBox-input-font-size;
+ padding: $u-numberBox-input-padding;
+ margin: $u-numberBox-input-margin;
+ @include flex;
+ align-items: center;
+ justify-content: center;
+
+ &--disabled {
+ color: $u-numberBox-input-disabled-color;
+ background-color: $u-numberBox-input-disabled-bgColor;
+ }
+ }
+ }
+</style>
diff --git a/uni_modules/uview-ui/components/u-number-keyboard/props.js b/uni_modules/uview-ui/components/u-number-keyboard/props.js
new file mode 100644
index 0000000..5e3bf55
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-number-keyboard/props.js
@@ -0,0 +1,19 @@
+export default {
+ props: {
+ // ������������������number-���������������card-���������������
+ mode: {
+ type: String,
+ default: uni.$u.props.numberKeyboard.value
+ },
+ // ���������������������"."������
+ dotDisabled: {
+ type: Boolean,
+ default: uni.$u.props.numberKeyboard.dotDisabled
+ },
+ // ���������������������������������
+ random: {
+ type: Boolean,
+ default: uni.$u.props.numberKeyboard.random
+ }
+ }
+}
diff --git a/uni_modules/uview-ui/components/u-number-keyboard/u-number-keyboard.vue b/uni_modules/uview-ui/components/u-number-keyboard/u-number-keyboard.vue
new file mode 100644
index 0000000..4f505c6
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-number-keyboard/u-number-keyboard.vue
@@ -0,0 +1,196 @@
+<template>
+ <view
+ class="u-keyboard"
+ @touchmove.stop.prevent="noop"
+ >
+ <view
+ class="u-keyboard__button-wrapper"
+ v-for="(item, index) in numList"
+ :key="index"
+ >
+ <view
+ class="u-keyboard__button-wrapper__button"
+ :style="[itemStyle(index)]"
+ @tap="keyboardClick(item)"
+ hover-class="u-hover-class"
+ :hover-stay-time="200"
+ >
+ <text class="u-keyboard__button-wrapper__button__text">{{ item }}</text>
+ </view>
+ </view>
+ <view
+ class="u-keyboard__button-wrapper"
+ >
+ <view
+ class="u-keyboard__button-wrapper__button u-keyboard__button-wrapper__button--gray"
+ hover-class="u-hover-class"
+ :hover-stay-time="200"
+ @touchstart.stop="backspaceClick"
+ @touchend="clearTimer"
+ >
+ <u-icon
+ name="backspace"
+ color="#303133"
+ size="28"
+ ></u-icon>
+ </view>
+ </view>
+ </view>
+</template>
+
+<script>
+ import props from './props.js';
+
+ /**
+ * keyboard ������������
+ * @description
+ * @tutorial
+ * @property {String} mode ������������������number-���������������card-���������������
+ * @property {Boolean} dotDisabled ���������������������"."������
+ * @property {Boolean} random ���������������������������������
+ * @event {Function} change ������������������
+ * @event {Function} backspace ���������������������
+ * @example
+ */
+ export default {
+ mixins: [uni.$u.mpMixin, uni.$u.mixin, props],
+ data() {
+ return {
+ backspace: 'backspace', // ���������������
+ dot: '.', // ���
+ timer: null, // ���������������������������������
+ cardX: 'X' // ������������X������
+ };
+ },
+ computed: {
+ // ���������������������������
+ numList() {
+ let tmp = [];
+ if (this.dotDisabled && this.mode == 'number') {
+ if (!this.random) {
+ return [1, 2, 3, 4, 5, 6, 7, 8, 9, 0];
+ } else {
+ return uni.$u.randomArray([1, 2, 3, 4, 5, 6, 7, 8, 9, 0]);
+ }
+ } else if (!this.dotDisabled && this.mode == 'number') {
+ if (!this.random) {
+ return [1, 2, 3, 4, 5, 6, 7, 8, 9, this.dot, 0];
+ } else {
+ return uni.$u.randomArray([1, 2, 3, 4, 5, 6, 7, 8, 9, this.dot, 0]);
+ }
+ } else if (this.mode == 'card') {
+ if (!this.random) {
+ return [1, 2, 3, 4, 5, 6, 7, 8, 9, this.cardX, 0];
+ } else {
+ return uni.$u.randomArray([1, 2, 3, 4, 5, 6, 7, 8, 9, this.cardX, 0]);
+ }
+ }
+ },
+ // ������������������������������&&������������&&������������������������index���9������������������������������
+ itemStyle() {
+ return index => {
+ let style = {};
+ if (this.mode == 'number' && this.dotDisabled && index == 9) style.width = '464rpx';
+ return style;
+ };
+ },
+ // ���������������������������������������������&&������������&&���������������������������
+ btnBgGray() {
+ return index => {
+ if (!this.random && index == 9 && (this.mode != 'number' || (this.mode == 'number' && !this
+ .dotDisabled))) return true;
+ else return false;
+ };
+ },
+ },
+ created() {
+
+ },
+ methods: {
+ // ���������������
+ backspaceClick() {
+ this.$emit('backspace');
+ clearInterval(this.timer); //���������������������������������������������������
+ this.timer = null;
+ this.timer = setInterval(() => {
+ this.$emit('backspace');
+ }, 250);
+ },
+ clearTimer() {
+ clearInterval(this.timer);
+ this.timer = null;
+ },
+ // ���������������������������
+ keyboardClick(val) {
+ // ���������������������������������������������������������������������������������
+ if (!this.dotDisabled && val != this.dot && val != this.cardX) val = Number(val);
+ this.$emit('change', val);
+ }
+ }
+ };
+</script>
+
+<style lang="scss" scoped>
+ @import "../../libs/css/components.scss";
+ $u-number-keyboard-background-color:rgb(224, 228, 230) !default;
+ $u-number-keyboard-padding:8px 10rpx 8px 10rpx !default;
+ $u-number-keyboard-button-width:222rpx !default;
+ $u-number-keyboard-button-margin:4px 6rpx !default;
+ $u-number-keyboard-button-border-top-left-radius:4px !default;
+ $u-number-keyboard-button-border-top-right-radius:4px !default;
+ $u-number-keyboard-button-border-bottom-left-radius:4px !default;
+ $u-number-keyboard-button-border-bottom-right-radius:4px !default;
+ $u-number-keyboard-button-height: 90rpx!default;
+ $u-number-keyboard-button-background-color:#FFFFFF !default;
+ $u-number-keyboard-button-box-shadow:0 2px 0px #BBBCBE !default;
+ $u-number-keyboard-text-font-size:20px !default;
+ $u-number-keyboard-text-font-weight:500 !default;
+ $u-number-keyboard-text-color:$u-main-color !default;
+ $u-number-keyboard-gray-background-color:rgb(200, 202, 210) !default;
+ $u-number-keyboard-u-hover-class-background-color: #BBBCC6 !default;
+
+ .u-keyboard {
+ @include flex;
+ flex-direction: row;
+ justify-content: space-around;
+ background-color: $u-number-keyboard-background-color;
+ flex-wrap: wrap;
+ padding: $u-number-keyboard-padding;
+
+ &__button-wrapper {
+ box-shadow: $u-number-keyboard-button-box-shadow;
+ margin: $u-number-keyboard-button-margin;
+ border-top-left-radius: $u-number-keyboard-button-border-top-left-radius;
+ border-top-right-radius: $u-number-keyboard-button-border-top-right-radius;
+ border-bottom-left-radius: $u-number-keyboard-button-border-bottom-left-radius;
+ border-bottom-right-radius: $u-number-keyboard-button-border-bottom-right-radius;
+
+ &__button {
+ width: $u-number-keyboard-button-width;
+ height: $u-number-keyboard-button-height;
+ background-color: $u-number-keyboard-button-background-color;
+ @include flex;
+ justify-content: center;
+ align-items: center;
+ border-top-left-radius: $u-number-keyboard-button-border-top-left-radius;
+ border-top-right-radius: $u-number-keyboard-button-border-top-right-radius;
+ border-bottom-left-radius: $u-number-keyboard-button-border-bottom-left-radius;
+ border-bottom-right-radius: $u-number-keyboard-button-border-bottom-right-radius;
+
+ &__text {
+ font-size: $u-number-keyboard-text-font-size;
+ font-weight: $u-number-keyboard-text-font-weight;
+ color: $u-number-keyboard-text-color;
+ }
+
+ &--gray {
+ background-color: $u-number-keyboard-gray-background-color;
+ }
+ }
+ }
+ }
+
+ .u-hover-class {
+ background-color: $u-number-keyboard-u-hover-class-background-color;
+ }
+</style>
diff --git a/uni_modules/uview-ui/components/u-overlay/props.js b/uni_modules/uview-ui/components/u-overlay/props.js
new file mode 100644
index 0000000..e6974df
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-overlay/props.js
@@ -0,0 +1,24 @@
+export default {
+ props: {
+ // ������������������
+ show: {
+ type: Boolean,
+ default: uni.$u.props.overlay.show
+ },
+ // ������z-index
+ zIndex: {
+ type: [String, Number],
+ default: uni.$u.props.overlay.zIndex
+ },
+ // ���������������������������������ms
+ duration: {
+ type: [String, Number],
+ default: uni.$u.props.overlay.duration
+ },
+ // ������������������������rgba������������������
+ opacity: {
+ type: [String, Number],
+ default: uni.$u.props.overlay.opacity
+ }
+ }
+}
diff --git a/uni_modules/uview-ui/components/u-overlay/u-overlay.vue b/uni_modules/uview-ui/components/u-overlay/u-overlay.vue
new file mode 100644
index 0000000..92de4e9
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-overlay/u-overlay.vue
@@ -0,0 +1,68 @@
+<template>
+ <u-transition
+ :show="show"
+ custom-class="u-overlay"
+ :duration="duration"
+ :custom-style="overlayStyle"
+ @click="clickHandler"
+ >
+ <slot />
+ </u-transition>
+</template>
+
+<script>
+ import props from './props.js';
+
+ /**
+ * overlay ������
+ * @description ������������������������������������������������������������������������������������������������������������������������������������������
+ * @tutorial https://www.uviewui.com/components/overlay.html
+ * @property {Boolean} show ��������������������������� false ���
+ * @property {String | Number} zIndex zIndex ��������������� 10070 ���
+ * @property {String | Number} duration ������������������������������������ 300 ���
+ * @property {String | Number} opacity ������������������������rgba������������������ ��������� 0.5 ���
+ * @property {Object} customStyle ���������������������������������
+ * @event {Function} click ������������������������
+ * @example <u-overlay :show="show" @click="show = false"></u-overlay>
+ */
+ export default {
+ name: "u-overlay",
+ mixins: [uni.$u.mpMixin, uni.$u.mixin,props],
+ computed: {
+ overlayStyle() {
+ const style = {
+ position: 'fixed',
+ top: 0,
+ left: 0,
+ right: 0,
+ zIndex: this.zIndex,
+ bottom: 0,
+ 'background-color': `rgba(0, 0, 0, ${this.opacity})`
+ }
+ return uni.$u.deepMerge(style, uni.$u.addStyle(this.customStyle))
+ }
+ },
+ methods: {
+ clickHandler() {
+ this.$emit('click')
+ }
+ }
+ }
+</script>
+
+<style lang="scss" scoped>
+ @import "../../libs/css/components.scss";
+ $u-overlay-top:0 !default;
+ $u-overlay-left:0 !default;
+ $u-overlay-width:100% !default;
+ $u-overlay-height:100% !default;
+ $u-overlay-background-color:rgba(0, 0, 0, .7) !default;
+ .u-overlay {
+ position: fixed;
+ top:$u-overlay-top;
+ left:$u-overlay-left;
+ width: $u-overlay-width;
+ height:$u-overlay-height;
+ background-color:$u-overlay-background-color;
+ }
+</style>
diff --git a/uni_modules/uview-ui/components/u-parse/node/node.vue b/uni_modules/uview-ui/components/u-parse/node/node.vue
new file mode 100644
index 0000000..73e30fd
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-parse/node/node.vue
@@ -0,0 +1,499 @@
+<template>
+ <view :id="attrs.id" :class="'_'+name+' '+attrs.class" :style="attrs.style">
+ <block v-for="(n, i) in childs" v-bind:key="i">
+ <!-- ������ -->
+ <!-- ��������� -->
+ <image v-if="n.name=='img'&&((opts[1]&&!ctrl[i])||ctrl[i]<0)" class="_img" :style="n.attrs.style" :src="ctrl[i]<0?opts[2]:opts[1]" mode="widthFix" />
+ <!-- ������������ -->
+ <!-- #ifdef H5 || APP-PLUS -->
+ <img v-if="n.name=='img'" :id="n.attrs.id" :class="'_img '+n.attrs.class" :style="(ctrl[i]==-1?'display:none;':'')+n.attrs.style" :src="n.attrs.src||(ctrl.load?n.attrs['data-src']:'')" :data-i="i" @load="imgLoad" @error="mediaError" @tap.stop="imgTap" @longpress="imgLongTap"/>
+ <!-- #endif -->
+ <!-- #ifndef H5 || APP-PLUS -->
+ <image v-if="n.name=='img'" :id="n.attrs.id" :class="'_img '+n.attrs.class" :style="(ctrl[i]==-1?'display:none;':'')+'width:'+(ctrl[i]||1)+'px;height:1px;'+n.attrs.style" :src="n.attrs.src" :mode="n.h?'':'widthFix'" :lazy-load="opts[0]" :webp="n.webp" :show-menu-by-longpress="opts[3]&&!n.attrs.ignore" :image-menu-prevent="!opts[3]||n.attrs.ignore" :data-i="i" @load="imgLoad" @error="mediaError" @tap.stop="imgTap" @longpress="imgLongTap" />
+ <!-- #endif -->
+ <!-- ������ -->
+ <!-- #ifndef MP-BAIDU -->
+ <text v-else-if="n.type=='text'" decode>{{n.text}}</text>
+ <!-- #endif -->
+ <text v-else-if="n.name=='br'">\n</text>
+ <!-- ������ -->
+ <view v-else-if="n.name=='a'" :id="n.attrs.id" :class="(n.attrs.href?'_a ':'')+n.attrs.class" hover-class="_hover" :style="'display:inline;'+n.attrs.style" :data-i="i" @tap.stop="linkTap">
+ <node name="span" :childs="n.children" :opts="opts" style="display:inherit" />
+ </view>
+ <!-- ������ -->
+ <!-- #ifdef APP-PLUS -->
+ <view v-else-if="n.html" :id="n.attrs.id" :class="'_video '+n.attrs.class" :style="n.attrs.style" v-html="n.html" />
+ <!-- #endif -->
+ <!-- #ifndef APP-PLUS -->
+ <video v-else-if="n.name=='video'" :id="n.attrs.id" :class="n.attrs.class" :style="n.attrs.style" :autoplay="n.attrs.autoplay" :controls="n.attrs.controls" :loop="n.attrs.loop" :muted="n.attrs.muted" :poster="n.attrs.poster" :src="n.src[ctrl[i]||0]" :data-i="i" @play="play" @error="mediaError" />
+ <!-- #endif -->
+ <!-- #ifdef H5 || APP-PLUS -->
+ <iframe v-else-if="n.name=='iframe'" :style="n.attrs.style" :allowfullscreen="n.attrs.allowfullscreen" :frameborder="n.attrs.frameborder" :src="n.attrs.src" />
+ <embed v-else-if="n.name=='embed'" :style="n.attrs.style" :src="n.attrs.src" />
+ <!-- #endif -->
+ <!-- #ifndef MP-TOUTIAO -->
+ <!-- ������ -->
+ <audio v-else-if="n.name=='audio'" :id="n.attrs.id" :class="n.attrs.class" :style="n.attrs.style" :author="n.attrs.author" :controls="n.attrs.controls" :loop="n.attrs.loop" :name="n.attrs.name" :poster="n.attrs.poster" :src="n.src[ctrl[i]||0]" :data-i="i" @play="play" @error="mediaError" />
+ <!-- #endif -->
+ <view v-else-if="(n.name=='table'&&n.c)||n.name=='li'" :id="n.attrs.id" :class="'_'+n.name+' '+n.attrs.class" :style="n.attrs.style">
+ <node v-if="n.name=='li'" :childs="n.children" :opts="opts" />
+ <view v-else v-for="(tbody, x) in n.children" v-bind:key="x" :class="'_'+tbody.name+' '+tbody.attrs.class" :style="tbody.attrs.style">
+ <node v-if="tbody.name=='td'||tbody.name=='th'" :childs="tbody.children" :opts="opts" />
+ <block v-else v-for="(tr, y) in tbody.children" v-bind:key="y">
+ <view v-if="tr.name=='td'||tr.name=='th'" :class="'_'+tr.name+' '+tr.attrs.class" :style="tr.attrs.style">
+ <node :childs="tr.children" :opts="opts" />
+ </view>
+ <view v-else :class="'_'+tr.name+' '+tr.attrs.class" :style="tr.attrs.style">
+ <view v-for="(td, z) in tr.children" v-bind:key="z" :class="'_'+td.name+' '+td.attrs.class" :style="td.attrs.style">
+ <node :childs="td.children" :opts="opts" />
+ </view>
+ </view>
+ </block>
+ </view>
+ </view>
+
+ <!-- ��������� -->
+ <!-- #ifdef H5 || MP-WEIXIN || MP-QQ || APP-PLUS || MP-360 -->
+ <rich-text v-else-if="handler.use(n)" :id="n.attrs.id" :style="n.f" :nodes="[n]" />
+ <!-- #endif -->
+ <!-- #ifndef H5 || MP-WEIXIN || MP-QQ || APP-PLUS || MP-360 -->
+ <rich-text v-else-if="!n.c" :id="n.attrs.id" :style="n.f+';display:inline'" :preview="false" :nodes="[n]" />
+ <!-- #endif -->
+ <!-- ������������ -->
+ <view v-else-if="n.c==2" :id="n.attrs.id" :class="'_'+n.name+' '+n.attrs.class" :style="n.f+';'+n.attrs.style">
+ <node v-for="(n2, j) in n.children" v-bind:key="j" :style="n2.f" :name="n2.name" :attrs="n2.attrs" :childs="n2.children" :opts="opts" />
+ </view>
+ <node v-else :style="n.f" :name="n.name" :attrs="n.attrs" :childs="n.children" :opts="opts" />
+ </block>
+ </view>
+</template>
+<script module="handler" lang="wxs">
+// ������������������
+var inlineTags = {
+ abbr: true,
+ b: true,
+ big: true,
+ code: true,
+ del: true,
+ em: true,
+ i: true,
+ ins: true,
+ label: true,
+ q: true,
+ small: true,
+ span: true,
+ strong: true,
+ sub: true,
+ sup: true
+}
+/**
+ * @description ������������ rich-text ������������������
+ */
+module.exports = {
+ use: function (item) {
+ // ��������� QQ ��� rich-text inline ������������
+ if (inlineTags[item.name] || (item.attrs.style || '').indexOf('display:inline') != -1)
+ return false
+ return !item.c
+ }
+}
+</script>
+<script>
+
+import node from './node'
+export default {
+ name: 'node',
+ // #ifdef MP-WEIXIN
+ options: {
+ virtualHost: true
+ },
+ // #endif
+ data() {
+ return {
+ ctrl: {}
+ }
+ },
+ props: {
+ name: String,
+ attrs: {
+ type: Object,
+ default() {
+ return {}
+ }
+ },
+ childs: Array,
+ opts: Array
+ },
+ components: {
+
+ node
+ },
+ mounted() {
+ for (this.root = this.$parent; this.root.$options.name != 'mp-html'; this.root = this.root.$parent);
+ // #ifdef H5 || APP-PLUS
+ if (this.opts[0]) {
+ for (var i = this.childs.length; i--;)
+ if (this.childs[i].name == 'img')
+ break
+ if (i != -1) {
+ this.observer = uni.createIntersectionObserver(this).relativeToViewport({
+ top: 500,
+ bottom: 500
+ })
+ this.observer.observe('._img', res => {
+ if (res.intersectionRatio) {
+ this.$set(this.ctrl, 'load', 1)
+ this.observer.disconnect()
+ }
+ })
+ }
+ }
+ // #endif
+ },
+ beforeDestroy() {
+ // #ifdef H5 || APP-PLUS
+ if (this.observer)
+ this.observer.disconnect()
+ // #endif
+ },
+ methods:{
+ // #ifdef MP-WEIXIN
+ toJSON() { },
+ // #endif
+ /**
+ * @description ������������������
+ * @param {Event} e
+ */
+ play(e) {
+ // #ifndef APP-PLUS
+ if (this.root.pauseVideo) {
+ var flag = false, id = e.target.id
+ for (var i = this.root._videos.length; i--;) {
+ if (this.root._videos[i].id == id)
+ flag = true
+ else
+ this.root._videos[i].pause() // ������������������������
+ }
+ // ���������������������
+ if (!flag) {
+ var ctx = uni.createVideoContext(id
+ // #ifndef MP-BAIDU
+ , this
+ // #endif
+ )
+ ctx.id = id
+ this.root._videos.push(ctx)
+ }
+ }
+ // #endif
+ },
+
+ /**
+ * @description ������������������
+ * @param {Event} e
+ */
+ imgTap(e) {
+ var node = this.childs[e.currentTarget.dataset.i]
+ if (node.a)
+ return this.linkTap(node.a)
+ if (node.attrs.ignore)
+ return
+ // #ifdef H5 || APP-PLUS
+ node.attrs.src = node.attrs.src || node.attrs['data-src']
+ // #endif
+ this.root.$emit('imgTap', node.attrs)
+ // ������������������
+ if (this.root.previewImg)
+ uni.previewImage({
+ current: parseInt(node.attrs.i),
+ urls: this.root.imgList
+ })
+ },
+
+ /**
+ * @description ������������
+ */
+ imgLongTap(e) {
+ // #ifdef APP-PLUS
+ var attrs = this.childs[e.currentTarget.dataset.i].attrs
+ if (!attrs.ignore)
+ uni.showActionSheet({
+ itemList: ['������������'],
+ success: () => {
+ uni.downloadFile({
+ url: this.root.imgList[attrs.i],
+ success: res => {
+ uni.saveImageToPhotosAlbum({
+ filePath: res.tempFilePath,
+ success() {
+ uni.showToast({
+ title: '������������'
+ })
+ }
+ })
+ }
+ })
+ }
+ })
+ // #endif
+ },
+
+ /**
+ * @description ������������������������
+ * @param {Event} e
+ */
+ imgLoad(e) {
+ var i = e.currentTarget.dataset.i
+ // #ifndef H5 || APP-PLUS
+ // ���������������
+ if (!this.childs[i].w)
+ this.$set(this.ctrl, i, e.detail.width)
+ else
+ // #endif
+ // ���������������������������������������
+ if ((this.opts[1] && !this.ctrl[i]) || this.ctrl[i] == -1)
+ this.$set(this.ctrl, i, 1)
+ },
+
+ /**
+ * @description ������������������
+ * @param {Event} e
+ */
+ linkTap(e) {
+ var attrs = e.currentTarget ? this.childs[e.currentTarget.dataset.i].attrs : e,
+ href = attrs.href
+ this.root.$emit('linkTap', attrs)
+ if (href) {
+ // ������������
+ if (href[0] == '#')
+ this.root.navigateTo(href.substring(1)).catch(() => { })
+ // ������������������
+ else if (href.includes('://')) {
+ if (this.root.copyLink) {
+ // #ifdef H5
+ window.open(href)
+ // #endif
+ // #ifdef MP
+ uni.setClipboardData({
+ data: href,
+ success: () =>
+ uni.showToast({
+ title: '���������������'
+ })
+ })
+ // #endif
+ // #ifdef APP-PLUS
+ plus.runtime.openWeb(href)
+ // #endif
+ }
+ }
+ // ������������
+ else
+ uni.navigateTo({
+ url: href,
+ fail() {
+ uni.switchTab({
+ url: href,
+ fail() { }
+ })
+ }
+ })
+ }
+ },
+
+ /**
+ * @description ������������
+ * @param {Event} e
+ */
+ mediaError(e) {
+ var i = e.currentTarget.dataset.i,
+ node = this.childs[i]
+ // ���������������
+ if (node.name == 'video' || node.name == 'audio') {
+ var index = (this.ctrl[i] || 0) + 1
+ if (index > node.src.length)
+ index = 0
+ if (index < node.src.length)
+ return this.$set(this.ctrl, i, index)
+ }
+ // ���������������������
+ else if (node.name == 'img' && this.opts[2])
+ this.$set(this.ctrl, i, -1)
+ if (this.root)
+ this.root.$emit('error', {
+ source: node.name,
+ attrs: node.attrs,
+ errMsg: e.detail.errMsg
+ })
+ }
+ }
+}
+</script>
+<style>
+/* a ������������������ */
+._a {
+ padding: 1.5px 0 1.5px 0;
+ color: #366092;
+ word-break: break-all;
+}
+
+/* a ��������������������� */
+._hover {
+ text-decoration: underline;
+ opacity: 0.7;
+}
+
+/* ������������������ */
+._img {
+ max-width: 100%;
+ -webkit-touch-callout: none;
+}
+
+/* ������������ */
+
+._b,
+._strong {
+ font-weight: bold;
+}
+
+._code {
+ font-family: monospace;
+}
+
+._del {
+ text-decoration: line-through;
+}
+
+._em,
+._i {
+ font-style: italic;
+}
+
+._h1 {
+ font-size: 2em;
+}
+
+._h2 {
+ font-size: 1.5em;
+}
+
+._h3 {
+ font-size: 1.17em;
+}
+
+._h5 {
+ font-size: 0.83em;
+}
+
+._h6 {
+ font-size: 0.67em;
+}
+
+._h1,
+._h2,
+._h3,
+._h4,
+._h5,
+._h6 {
+ display: block;
+ font-weight: bold;
+}
+
+._image {
+ height: 1px;
+}
+
+._ins {
+ text-decoration: underline;
+}
+
+._li {
+ display: list-item;
+}
+
+._ol {
+ list-style-type: decimal;
+}
+
+._ol,
+._ul {
+ display: block;
+ padding-left: 40px;
+ margin: 1em 0;
+}
+
+._q::before {
+ content: '"';
+}
+
+._q::after {
+ content: '"';
+}
+
+._sub {
+ font-size: smaller;
+ vertical-align: sub;
+}
+
+._sup {
+ font-size: smaller;
+ vertical-align: super;
+}
+
+._thead,
+._tbody,
+._tfoot {
+ display: table-row-group;
+}
+
+._tr {
+ display: table-row;
+}
+
+._td,
+._th {
+ display: table-cell;
+ vertical-align: middle;
+}
+
+._th {
+ font-weight: bold;
+ text-align: center;
+}
+
+._ul {
+ list-style-type: disc;
+}
+
+._ul ._ul {
+ margin: 0;
+ list-style-type: circle;
+}
+
+._ul ._ul ._ul {
+ list-style-type: square;
+}
+
+._abbr,
+._b,
+._code,
+._del,
+._em,
+._i,
+._ins,
+._label,
+._q,
+._span,
+._strong,
+._sub,
+._sup {
+ display: inline;
+}
+
+/* #ifdef APP-PLUS */
+._video {
+ width: 300px;
+ height: 225px;
+}
+/* #endif */
+</style>
diff --git a/uni_modules/uview-ui/components/u-parse/parser.js b/uni_modules/uview-ui/components/u-parse/parser.js
new file mode 100644
index 0000000..a78a654
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-parse/parser.js
@@ -0,0 +1,1075 @@
+'use strict'
+
+/**
+ * @fileoverview html ���������
+ */
+// ������
+const config = {
+ // ������������������������������������������
+ trustTags: makeMap('a,abbr,ad,audio,b,blockquote,br,code,col,colgroup,dd,del,dl,dt,div,em,fieldset,h1,h2,h3,h4,h5,h6,hr,i,img,ins,label,legend,li,ol,p,q,ruby,rt,source,span,strong,sub,sup,table,tbody,td,tfoot,th,thead,tr,title,ul,video'),
+ // ��������������������� div��������������������������������� span���
+ blockTags: makeMap('address,article,aside,body,caption,center,cite,footer,header,html,nav,pre,section'),
+ // ������������������
+ ignoreTags: makeMap('area,base,canvas,embed,frame,head,iframe,input,link,map,meta,param,rp,script,source,style,textarea,title,track,wbr'),
+ // ������������������
+ voidTags: makeMap('area,base,br,col,circle,ellipse,embed,frame,hr,img,input,line,link,meta,param,path,polygon,rect,source,track,use,wbr'),
+ // html ������
+ entities: {
+ lt: '<',
+ gt: '>',
+ quot: '"',
+ apos: "'",
+ ensp: '\u2002',
+ emsp: '\u2003',
+ nbsp: '\xA0',
+ semi: ';',
+ ndash: '���',
+ mdash: '���',
+ middot: '��',
+ lsquo: '���',
+ rsquo: '���',
+ ldquo: '���',
+ rdquo: '���',
+ bull: '���',
+ hellip: '���'
+ },
+ // ���������������������
+ tagStyle: {
+ // #ifndef APP-PLUS-NVUE
+ address: 'font-style:italic',
+ big: 'display:inline;font-size:1.2em',
+ caption: 'display:table-caption;text-align:center',
+ center: 'text-align:center',
+ cite: 'font-style:italic',
+ dd: 'margin-left:40px',
+ mark: 'background-color:yellow',
+ pre: 'font-family:monospace;white-space:pre',
+ s: 'text-decoration:line-through',
+ small: 'display:inline;font-size:0.8em',
+ u: 'text-decoration:underline' // #endif
+
+ }
+}
+const { windowWidth } = uni.getSystemInfoSync()
+const blankChar = makeMap(' ,\r,\n,\t,\f')
+let idIndex = 0 // #ifdef H5 || APP-PLUS
+
+config.ignoreTags.iframe = void 0
+config.trustTags.iframe = true
+config.ignoreTags.embed = void 0
+config.trustTags.embed = true // #endif
+// #ifdef APP-PLUS-NVUE
+
+config.ignoreTags.source = void 0
+config.ignoreTags.style = void 0 // #endif
+
+/**
+ * @description ������ map
+ * @param {String} str ������������
+ */
+
+function makeMap(str) {
+ const map = Object.create(null)
+ const list = str.split(',')
+
+ for (let i = list.length; i--;) {
+ map[list[i]] = true
+ }
+
+ return map
+}
+/**
+ * @description ������ html ������
+ * @param {String} str ���������������������
+ * @param {Boolean} amp ��������������� &
+ * @returns {String} ���������������������
+ */
+
+function decodeEntity(str, amp) {
+ let i = str.indexOf('&')
+
+ while (i != -1) {
+ const j = str.indexOf(';', i + 3)
+ let code = void 0
+ if (j == -1) break
+
+ if (str[i + 1] == '#') {
+ // { ���������������
+ code = parseInt((str[i + 2] == 'x' ? '0' : '') + str.substring(i + 2, j))
+ if (!isNaN(code)) str = str.substr(0, i) + String.fromCharCode(code) + str.substr(j + 1)
+ } else {
+ // ���������������
+ code = str.substring(i + 1, j)
+ if (config.entities[code] || code == 'amp' && amp) str = str.substr(0, i) + (config.entities[code] || '&') + str.substr(j + 1)
+ }
+
+ i = str.indexOf('&', i + 1)
+ }
+
+ return str
+}
+/**
+ * @description html ���������
+ * @param {Object} vm ������������
+ */
+
+function parser(vm) {
+ this.options = vm || {}
+ this.tagStyle = Object.assign(config.tagStyle, this.options.tagStyle)
+ this.imgList = vm.imgList || []
+ this.plugins = vm.plugins || []
+ this.attrs = Object.create(null)
+ this.stack = []
+ this.nodes = []
+}
+/**
+ * @description ������������
+ * @param {String} content ������������������
+ */
+
+parser.prototype.parse = function (content) {
+ // ������������
+ for (let i = this.plugins.length; i--;) {
+ if (this.plugins[i].onUpdate) content = this.plugins[i].onUpdate(content, config) || content
+ }
+
+ new lexer(this).parse(content) // ������������������������
+
+ while (this.stack.length) {
+ this.popNode()
+ }
+
+ return this.nodes
+}
+/**
+ * @description ������������������������������ rich-text ���������
+ */
+
+parser.prototype.expose = function () {
+ // #ifndef APP-PLUS-NVUE
+ for (let i = this.stack.length; i--;) {
+ const item = this.stack[i]
+ if (item.name == 'a' || item.c) return
+ item.c = 1
+ } // #endif
+}
+/**
+ * @description ������������
+ * @param {Object} node ������������������
+ * @returns {Boolean} ������������������������
+ */
+
+parser.prototype.hook = function (node) {
+ for (let i = this.plugins.length; i--;) {
+ if (this.plugins[i].onParse && this.plugins[i].onParse(node, this) == false) return false
+ }
+
+ return true
+}
+/**
+ * @description ���������������������������
+ * @param {String} url ���������������������
+ * @returns {String} ������������������
+ */
+
+parser.prototype.getUrl = function (url) {
+ const { domain } = this.options
+
+ if (url[0] == '/') {
+ // // ������������������������
+ if (url[1] == '/') url = `${domain ? domain.split('://')[0] : 'http'}:${url}` // ������������������������
+ else if (domain) url = domain + url
+ } else if (domain && !url.includes('data:') && !url.includes('://')) url = `${domain}/${url}`
+
+ return url
+}
+/**
+ * @description ���������������
+ * @param {Object} node ������
+ * @returns {Object}
+ */
+
+parser.prototype.parseStyle = function (node) {
+ const { attrs } = node
+ const list = (this.tagStyle[node.name] || '').split(';').concat((attrs.style || '').split(';'))
+ const styleObj = {}
+ let tmp = ''
+
+ if (attrs.id) {
+ // ������������
+ if (this.options.useAnchor) this.expose(); else if (node.name != 'img' && node.name != 'a' && node.name != 'video' && node.name != 'audio') attrs.id = void 0
+ } // ������ width ��� height ������
+
+ if (attrs.width) {
+ styleObj.width = parseFloat(attrs.width) + (attrs.width.includes('%') ? '%' : 'px')
+ attrs.width = void 0
+ }
+
+ if (attrs.height) {
+ styleObj.height = parseFloat(attrs.height) + (attrs.height.includes('%') ? '%' : 'px')
+ attrs.height = void 0
+ }
+
+ for (let i = 0, len = list.length; i < len; i++) {
+ const info = list[i].split(':')
+ if (info.length < 2) continue
+ const key = info.shift().trim().toLowerCase()
+ let value = info.join(':').trim() // ������������ css ���������
+
+ if (value[0] == '-' && value.lastIndexOf('-') > 0 || value.includes('safe')) tmp += ';'.concat(key, ':').concat(value) // ���������������������������
+ else if (!styleObj[key] || value.includes('import') || !styleObj[key].includes('import')) {
+ // ������������
+ if (value.includes('url')) {
+ let j = value.indexOf('(') + 1
+
+ if (j) {
+ while (value[j] == '"' || value[j] == "'" || blankChar[value[j]]) {
+ j++
+ }
+
+ value = value.substr(0, j) + this.getUrl(value.substr(j))
+ }
+ } // ������ rpx���rich-text ��������������� rpx���
+ else if (value.includes('rpx')) {
+ value = value.replace(/[0-9.]+\s*rpx/g, ($) => `${parseFloat($) * windowWidth / 750}px`)
+ }
+
+ styleObj[key] = value
+ }
+ }
+
+ node.attrs.style = tmp
+ return styleObj
+}
+/**
+ * @description ������������������
+ * @param {String} name ���������
+ * @private
+ */
+
+parser.prototype.onTagName = function (name) {
+ this.tagName = this.xml ? name : name.toLowerCase()
+ if (this.tagName == 'svg') this.xml = true // svg ������������������������
+}
+/**
+ * @description ������������������
+ * @param {String} name ���������
+ * @private
+ */
+
+parser.prototype.onAttrName = function (name) {
+ name = this.xml ? name : name.toLowerCase()
+
+ if (name.substr(0, 5) == 'data-') {
+ // data-src ������������ src
+ if (name == 'data-src' && !this.attrs.src) this.attrName = 'src' // a ��� img ������������ data- ��������������������� imgtap ��� linktap ���������������
+ else if (this.tagName == 'img' || this.tagName == 'a') this.attrName = name // ������������������������������
+ else this.attrName = void 0
+ } else {
+ this.attrName = name
+ this.attrs[name] = 'T' // boolean ���������������������
+ }
+}
+/**
+ * @description ������������������
+ * @param {String} val ���������
+ * @private
+ */
+
+parser.prototype.onAttrVal = function (val) {
+ const name = this.attrName || '' // ������������������������������
+
+ if (name == 'style' || name == 'href') this.attrs[name] = decodeEntity(val, true) // ���������������
+ else if (name.includes('src')) this.attrs[name] = this.getUrl(decodeEntity(val, true)); else if (name) this.attrs[name] = val
+}
+/**
+ * @description ���������������������
+ * @param {Boolean} selfClose ������������������������ />
+ * @private
+ */
+
+parser.prototype.onOpenTag = function (selfClose) {
+ // ������ node
+ const node = Object.create(null)
+ node.name = this.tagName
+ node.attrs = this.attrs
+ this.attrs = Object.create(null)
+ const { attrs } = node
+ const parent = this.stack[this.stack.length - 1]
+ const siblings = parent ? parent.children : this.nodes
+ const close = this.xml ? selfClose : config.voidTags[node.name] // ������ embed ������
+
+ if (node.name == 'embed') {
+ // #ifndef H5 || APP-PLUS
+ const src = attrs.src || '' // ������������������ type ��� embed ������ video ��� audio
+
+ if (src.includes('.mp4') || src.includes('.3gp') || src.includes('.m3u8') || (attrs.type || '').includes('video')) node.name = 'video'; else if (src.includes('.mp3') || src.includes('.wav') || src.includes('.aac') || src.includes('.m4a') || (attrs.type || '').includes('audio')) node.name = 'audio'
+ if (attrs.autostart) attrs.autoplay = 'T'
+ attrs.controls = 'T' // #endif
+ // #ifdef H5 || APP-PLUS
+
+ this.expose() // #endif
+ } // #ifndef APP-PLUS-NVUE
+ // ���������������
+
+ if (node.name == 'video' || node.name == 'audio') {
+ // ������ id ������������ context
+ if (node.name == 'video' && !attrs.id) attrs.id = `v${idIndex++}` // ������������ controls ��������������� autoplay ��������������� controls
+
+ if (!attrs.controls && !attrs.autoplay) attrs.controls = 'T' // ������������������������������ source
+
+ node.src = []
+
+ if (attrs.src) {
+ node.src.push(attrs.src)
+ attrs.src = void 0
+ }
+
+ this.expose()
+ } // #endif
+ // ���������������������
+
+ if (close) {
+ if (!this.hook(node) || config.ignoreTags[node.name]) {
+ // ������ base ���������������������
+ if (node.name == 'base' && !this.options.domain) this.options.domain = attrs.href // #ifndef APP-PLUS-NVUE
+ // ������ source ������������������������ video ��� audio ������������
+ else if (node.name == 'source' && parent && (parent.name == 'video' || parent.name == 'audio') && attrs.src) parent.src.push(attrs.src) // #endif
+
+ return
+ } // ������ style
+
+ const styleObj = this.parseStyle(node) // ������������
+
+ if (node.name == 'img') {
+ if (attrs.src) {
+ // ������ webp
+ if (attrs.src.includes('webp')) node.webp = 'T' // data url ������������������������ original-src ���������������������������������
+
+ if (attrs.src.includes('data:') && !attrs['original-src']) attrs.ignore = 'T'
+
+ if (!attrs.ignore || node.webp || attrs.src.includes('cloud://')) {
+ for (let i = this.stack.length; i--;) {
+ const item = this.stack[i]
+
+ if (item.name == 'a') {
+ node.a = item.attrs
+ break
+ } // #ifndef H5 || APP-PLUS
+
+ const style = item.attrs.style || ''
+
+ if (style.includes('flex:') && !style.includes('flex:0') && !style.includes('flex: 0') && (!styleObj.width || !styleObj.width.includes('%'))) {
+ styleObj.width = '100% !important'
+ styleObj.height = ''
+
+ for (let j = i + 1; j < this.stack.length; j++) {
+ this.stack[j].attrs.style = (this.stack[j].attrs.style || '').replace('inline-', '')
+ }
+ } else if (style.includes('flex') && styleObj.width == '100%') {
+ for (let _j = i + 1; _j < this.stack.length; _j++) {
+ const _style = this.stack[_j].attrs.style || ''
+
+ if (!_style.includes(';width') && !_style.includes(' width') && _style.indexOf('width') != 0) {
+ styleObj.width = ''
+ break
+ }
+ }
+ } else if (style.includes('inline-block')) {
+ if (styleObj.width && styleObj.width[styleObj.width.length - 1] == '%') {
+ item.attrs.style += `;max-width:${styleObj.width}`
+ styleObj.width = ''
+ } else item.attrs.style += ';max-width:100%'
+ } // #endif
+
+ item.c = 1
+ }
+
+ attrs.i = this.imgList.length.toString()
+
+ let _src = attrs['original-src'] || attrs.src // #ifndef H5 || MP-ALIPAY || APP-PLUS || MP-360
+
+ if (this.imgList.includes(_src)) {
+ // ������������������������������������������������������������������������������������
+ let _i = _src.indexOf('://')
+
+ if (_i != -1) {
+ _i += 3
+
+ let newSrc = _src.substr(0, _i)
+
+ for (; _i < _src.length; _i++) {
+ if (_src[_i] == '/') break
+ newSrc += Math.random() > 0.5 ? _src[_i].toUpperCase() : _src[_i]
+ }
+
+ newSrc += _src.substr(_i)
+ _src = newSrc
+ }
+ } // #endif
+
+ this.imgList.push(_src) // #ifdef H5 || APP-PLUS
+
+ if (this.options.lazyLoad) {
+ attrs['data-src'] = attrs.src
+ attrs.src = void 0
+ } // #endif
+ }
+ }
+
+ if (styleObj.display == 'inline') styleObj.display = '' // #ifndef APP-PLUS-NVUE
+
+ if (attrs.ignore) {
+ styleObj['max-width'] = styleObj['max-width'] || '100%'
+ attrs.style += ';-webkit-touch-callout:none'
+ } // #endif
+ // ������������������������������������������������������������������
+
+ if (parseInt(styleObj.width) > windowWidth) styleObj.height = void 0 // ���������������������������
+
+ if (styleObj.width) {
+ if (styleObj.width.includes('auto')) styleObj.width = ''; else {
+ node.w = 'T'
+ if (styleObj.height && !styleObj.height.includes('auto')) node.h = 'T'
+ }
+ }
+ } else if (node.name == 'svg') {
+ siblings.push(node)
+ this.stack.push(node)
+ this.popNode()
+ return
+ }
+
+ for (const key in styleObj) {
+ if (styleObj[key]) attrs.style += ';'.concat(key, ':').concat(styleObj[key].replace(' !important', ''))
+ }
+
+ attrs.style = attrs.style.substr(1) || void 0
+ } else {
+ if (node.name == 'pre' || (attrs.style || '').includes('white-space') && attrs.style.includes('pre')) this.pre = node.pre = true
+ node.children = []
+ this.stack.push(node)
+ } // ���������������
+
+ siblings.push(node)
+}
+/**
+ * @description ���������������������
+ * @param {String} name ���������
+ * @private
+ */
+
+parser.prototype.onCloseTag = function (name) {
+ // ���������������������������
+ name = this.xml ? name : name.toLowerCase()
+ let i
+
+ for (i = this.stack.length; i--;) {
+ if (this.stack[i].name == name) break
+ }
+
+ if (i != -1) {
+ while (this.stack.length > i) {
+ this.popNode()
+ }
+ } else if (name == 'p' || name == 'br') {
+ const siblings = this.stack.length ? this.stack[this.stack.length - 1].children : this.nodes
+ siblings.push({
+ name,
+ attrs: {}
+ })
+ }
+}
+/**
+ * @description ������������������
+ * @private
+ */
+
+parser.prototype.popNode = function () {
+ const node = this.stack.pop()
+ let { attrs } = node
+ const { children } = node
+ const parent = this.stack[this.stack.length - 1]
+ const siblings = parent ? parent.children : this.nodes
+
+ if (!this.hook(node) || config.ignoreTags[node.name]) {
+ // ������������
+ if (node.name == 'title' && children.length && children[0].type == 'text' && this.options.setTitle) {
+ uni.setNavigationBarTitle({
+ title: children[0].text
+ })
+ }
+ siblings.pop()
+ return
+ }
+
+ if (node.pre) {
+ // ���������������������������
+ node.pre = this.pre = void 0
+
+ for (let i = this.stack.length; i--;) {
+ if (this.stack[i].pre) this.pre = true
+ }
+ }
+
+ const styleObj = {} // ������ svg
+
+ if (node.name == 'svg') {
+ // #ifndef APP-PLUS-NVUE
+ let src = ''
+ const { style } = attrs
+ attrs.style = ''
+ attrs.xmlns = 'http://www.w3.org/2000/svg';
+
+ (function traversal(node) {
+ src += `<${node.name}`
+
+ for (let item in node.attrs) {
+ const val = node.attrs[item]
+
+ if (val) {
+ if (item == 'viewbox') item = 'viewBox'
+ src += ' '.concat(item, '="').concat(val, '"')
+ }
+ }
+
+ if (!node.children) src += '/>'; else {
+ src += '>'
+
+ for (let _i2 = 0; _i2 < node.children.length; _i2++) {
+ traversal(node.children[_i2])
+ }
+
+ src += `</${node.name}>`
+ }
+ }(node))
+
+ node.name = 'img'
+ node.attrs = {
+ src: `data:image/svg+xml;utf8,${src.replace(/#/g, '%23')}`,
+ style,
+ ignore: 'T'
+ }
+ node.children = void 0 // #endif
+
+ this.xml = false
+ return
+ } // #ifndef APP-PLUS-NVUE
+ // ������ align ������
+
+ if (attrs.align) {
+ if (node.name == 'table') {
+ if (attrs.align == 'center') styleObj['margin-inline-start'] = styleObj['margin-inline-end'] = 'auto'; else styleObj.float = attrs.align
+ } else styleObj['text-align'] = attrs.align
+
+ attrs.align = void 0
+ } // ������ font ���������������
+
+ if (node.name == 'font') {
+ if (attrs.color) {
+ styleObj.color = attrs.color
+ attrs.color = void 0
+ }
+
+ if (attrs.face) {
+ styleObj['font-family'] = attrs.face
+ attrs.face = void 0
+ }
+
+ if (attrs.size) {
+ let size = parseInt(attrs.size)
+
+ if (!isNaN(size)) {
+ if (size < 1) size = 1; else if (size > 7) size = 7
+ styleObj['font-size'] = ['xx-small', 'x-small', 'small', 'medium', 'large', 'x-large', 'xx-large'][size - 1]
+ }
+
+ attrs.size = void 0
+ }
+ } // #endif
+ // ������������������������ class
+
+ if ((attrs.class || '').includes('align-center')) styleObj['text-align'] = 'center'
+ Object.assign(styleObj, this.parseStyle(node))
+
+ if (parseInt(styleObj.width) > windowWidth) {
+ styleObj['max-width'] = '100%'
+ styleObj['box-sizing'] = 'border-box'
+ } // #ifndef APP-PLUS-NVUE
+
+ if (config.blockTags[node.name]) node.name = 'div' // ������������������ span���������������������
+ else if (!config.trustTags[node.name] && !this.xml) node.name = 'span'
+ if (node.name == 'a' || node.name == 'ad' // #ifdef H5 || APP-PLUS
+ || node.name == 'iframe' // #endif
+ ) this.expose() // #ifdef APP-PLUS
+ else if (node.name == 'video') {
+ let str = '<video style="width:100%;height:100%"' // ���������������
+
+ if (!attrs.poster && !attrs.autoplay) attrs.poster = "data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg'/>"
+
+ for (const item in attrs) {
+ if (attrs[item]) str += ` ${item}="${attrs[item]}"`
+ }
+
+ if (this.options.pauseVideo) str += ' onplay="for(var e=document.getElementsByTagName(\'video\'),t=0;t<e.length;t++)e[t]!=this&&e[t].pause()"'
+ str += '>'
+
+ for (let _i3 = 0; _i3 < node.src.length; _i3++) {
+ str += `<source src="${node.src[_i3]}">`
+ }
+
+ str += '</video>'
+ node.html = str
+ } // #endif
+ // ������������
+ else if ((node.name == 'ul' || node.name == 'ol') && node.c) {
+ const types = {
+ a: 'lower-alpha',
+ A: 'upper-alpha',
+ i: 'lower-roman',
+ I: 'upper-roman'
+ }
+
+ if (types[attrs.type]) {
+ attrs.style += `;list-style-type:${types[attrs.type]}`
+ attrs.type = void 0
+ }
+
+ for (let _i4 = children.length; _i4--;) {
+ if (children[_i4].name == 'li') children[_i4].c = 1
+ }
+ } // ������������
+ else if (node.name == 'table') {
+ // cellpadding���cellspacing���border ���������������������������������������������������
+ let padding = parseFloat(attrs.cellpadding)
+ let spacing = parseFloat(attrs.cellspacing)
+ const border = parseFloat(attrs.border)
+
+ if (node.c) {
+ // padding ��� spacing ������ 2
+ if (isNaN(padding)) padding = 2
+ if (isNaN(spacing)) spacing = 2
+ }
+
+ if (border) attrs.style += `;border:${border}px solid gray`
+
+ if (node.flag && node.c) {
+ // ��� colspan ��� rowspan ������������������������������ grid ������������
+ styleObj.display = 'grid'
+
+ if (spacing) {
+ styleObj['grid-gap'] = `${spacing}px`
+ styleObj.padding = `${spacing}px`
+ } // ���������������������������������������
+ else if (border) attrs.style += ';border-left:0;border-top:0'
+
+ const width = []
+ // ���������������
+ const trList = []
+ // tr ������
+ const cells = []
+ // ���������������������
+ const map = {}; // ���������������������������������
+
+ (function traversal(nodes) {
+ for (let _i5 = 0; _i5 < nodes.length; _i5++) {
+ if (nodes[_i5].name == 'tr') trList.push(nodes[_i5]); else traversal(nodes[_i5].children || [])
+ }
+ }(children))
+
+ for (let row = 1; row <= trList.length; row++) {
+ let col = 1
+
+ for (let j = 0; j < trList[row - 1].children.length; j++, col++) {
+ const td = trList[row - 1].children[j]
+
+ if (td.name == 'td' || td.name == 'th') {
+ // ���������������������������������������������������++
+ while (map[`${row}.${col}`]) {
+ col++
+ }
+
+ let _style2 = td.attrs.style || ''
+ const start = _style2.indexOf('width') ? _style2.indexOf(';width') : 0 // ��������� td ���������
+
+ if (start != -1) {
+ let end = _style2.indexOf(';', start + 6)
+
+ if (end == -1) end = _style2.length
+ if (!td.attrs.colspan) width[col] = _style2.substring(start ? start + 7 : 6, end)
+ _style2 = _style2.substr(0, start) + _style2.substr(end)
+ }
+
+ _style2 += (border ? ';border:'.concat(border, 'px solid gray') + (spacing ? '' : ';border-right:0;border-bottom:0') : '') + (padding ? ';padding:'.concat(padding, 'px') : '') // ���������������
+
+ if (td.attrs.colspan) {
+ _style2 += ';grid-column-start:'.concat(col, ';grid-column-end:').concat(col + parseInt(td.attrs.colspan))
+ if (!td.attrs.rowspan) _style2 += ';grid-row-start:'.concat(row, ';grid-row-end:').concat(row + 1)
+ col += parseInt(td.attrs.colspan) - 1
+ } // ���������������
+
+ if (td.attrs.rowspan) {
+ _style2 += ';grid-row-start:'.concat(row, ';grid-row-end:').concat(row + parseInt(td.attrs.rowspan))
+ if (!td.attrs.colspan) _style2 += ';grid-column-start:'.concat(col, ';grid-column-end:').concat(col + 1) // ������������������������������
+
+ for (let k = 1; k < td.attrs.rowspan; k++) {
+ map[`${row + k}.${col}`] = 1
+ }
+ }
+
+ if (_style2) td.attrs.style = _style2
+ cells.push(td)
+ }
+ }
+
+ if (row == 1) {
+ let temp = ''
+
+ for (let _i6 = 1; _i6 < col; _i6++) {
+ temp += `${width[_i6] ? width[_i6] : 'auto'} `
+ }
+
+ styleObj['grid-template-columns'] = temp
+ }
+ }
+
+ node.children = cells
+ } else {
+ // ������������������������������������������ table ������������
+ if (node.c) styleObj.display = 'table'
+ if (!isNaN(spacing)) styleObj['border-spacing'] = `${spacing}px`
+
+ if (border || padding) {
+ // ������
+ (function traversal(nodes) {
+ for (let _i7 = 0; _i7 < nodes.length; _i7++) {
+ const _td = nodes[_i7]
+
+ if (_td.name == 'th' || _td.name == 'td') {
+ if (border) _td.attrs.style = 'border:'.concat(border, 'px solid gray;').concat(_td.attrs.style || '')
+ if (padding) _td.attrs.style = 'padding:'.concat(padding, 'px;').concat(_td.attrs.style || '')
+ } else if (_td.children) traversal(_td.children)
+ }
+ }(children))
+ }
+ } // ���������������������������������������������
+
+ if (this.options.scrollTable && !(attrs.style || '').includes('inline')) {
+ const table = { ...node }
+ node.name = 'div'
+ node.attrs = {
+ style: 'overflow:auto'
+ }
+ node.children = [table]
+ attrs = table.attrs
+ }
+ } else if ((node.name == 'td' || node.name == 'th') && (attrs.colspan || attrs.rowspan)) {
+ for (let _i8 = this.stack.length; _i8--;) {
+ if (this.stack[_i8].name == 'table') {
+ this.stack[_i8].flag = 1 // ���������������������������
+
+ break
+ }
+ }
+ } // ������ ruby
+ else if (node.name == 'ruby') {
+ node.name = 'span'
+
+ for (let _i9 = 0; _i9 < children.length - 1; _i9++) {
+ if (children[_i9].type == 'text' && children[_i9 + 1].name == 'rt') {
+ children[_i9] = {
+ name: 'div',
+ attrs: {
+ style: 'display:inline-block'
+ },
+ children: [{
+ name: 'div',
+ attrs: {
+ style: 'font-size:50%;text-align:start'
+ },
+ children: children[_i9 + 1].children
+ }, children[_i9]]
+ }
+ children.splice(_i9 + 1, 1)
+ }
+ }
+ } else if (node.c) {
+ node.c = 2
+
+ for (let _i10 = node.children.length; _i10--;) {
+ if (!node.children[_i10].c || node.children[_i10].name == 'table') node.c = 1
+ }
+ }
+ if ((styleObj.display || '').includes('flex') && !node.c) {
+ for (let _i11 = children.length; _i11--;) {
+ const _item = children[_i11]
+
+ if (_item.f) {
+ _item.attrs.style = (_item.attrs.style || '') + _item.f
+ _item.f = void 0
+ }
+ }
+ } // flex ������������������������������������ rich-text ������
+
+ const flex = parent && (parent.attrs.style || '').includes('flex') // #ifdef MP-WEIXIN
+ // ��������������������� virtualHost ������������
+ && !(node.c && wx.getNFCAdapter) // #endif
+ // #ifndef MP-WEIXIN || MP-QQ || MP-BAIDU || MP-TOUTIAO
+ && !node.c // #endif
+
+ if (flex) node.f = ';max-width:100%' // #endif
+
+ for (const key in styleObj) {
+ if (styleObj[key]) {
+ const val = ';'.concat(key, ':').concat(styleObj[key].replace(' !important', '')) // #ifndef APP-PLUS-NVUE
+
+ if (flex && (key.includes('flex') && key != 'flex-direction' || key == 'align-self' || styleObj[key][0] == '-' || key == 'width' && val.includes('%'))) {
+ node.f += val
+ if (key == 'width') attrs.style += ';width:100%'
+ } else // #endif
+ { attrs.style += val }
+ }
+ }
+
+ attrs.style = attrs.style.substr(1) || void 0
+}
+/**
+ * @description ���������������
+ * @param {String} text ������������
+ */
+
+parser.prototype.onText = function (text) {
+ if (!this.pre) {
+ // ���������������
+ let trim = ''
+ let flag
+
+ for (let i = 0, len = text.length; i < len; i++) {
+ if (!blankChar[text[i]]) trim += text[i]; else {
+ if (trim[trim.length - 1] != ' ') trim += ' '
+ if (text[i] == '\n' && !flag) flag = true
+ }
+ } // ������������������������������
+
+ if (trim == ' ' && flag) return
+ text = trim
+ }
+
+ const node = Object.create(null)
+ node.type = 'text'
+ node.text = decodeEntity(text)
+
+ if (this.hook(node)) {
+ const siblings = this.stack.length ? this.stack[this.stack.length - 1].children : this.nodes
+ siblings.push(node)
+ }
+}
+/**
+ * @description html ���������������
+ * @param {Object} handler ���������������
+ */
+
+function lexer(handler) {
+ this.handler = handler
+}
+/**
+ * @description ������������
+ * @param {String} content ������������������
+ */
+
+lexer.prototype.parse = function (content) {
+ this.content = content || ''
+ this.i = 0 // ������������������
+
+ this.start = 0 // ���������������������������������
+
+ this.state = this.text // ������������
+
+ for (let len = this.content.length; this.i != -1 && this.i < len;) {
+ this.state()
+ }
+}
+/**
+ * @description ������������������������
+ * @param {String} method ������������������������������
+ * @returns {Boolean} ������������
+ * @private
+ */
+
+lexer.prototype.checkClose = function (method) {
+ const selfClose = this.content[this.i] == '/'
+
+ if (this.content[this.i] == '>' || selfClose && this.content[this.i + 1] == '>') {
+ if (method) this.handler[method](this.content.substring(this.start, this.i))
+ this.i += selfClose ? 2 : 1
+ this.start = this.i
+ this.handler.onOpenTag(selfClose)
+
+ if (this.handler.tagName == 'script') {
+ this.i = this.content.indexOf('</', this.i)
+
+ if (this.i != -1) {
+ this.i += 2
+ this.start = this.i
+ }
+
+ this.state = this.endTag
+ } else this.state = this.text
+
+ return true
+ }
+
+ return false
+}
+/**
+ * @description ������������
+ * @private
+ */
+
+lexer.prototype.text = function () {
+ this.i = this.content.indexOf('<', this.i) // ���������������������
+
+ if (this.i == -1) {
+ // ���������������
+ if (this.start < this.content.length) this.handler.onText(this.content.substring(this.start, this.content.length))
+ return
+ }
+
+ const c = this.content[this.i + 1]
+
+ if (c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z') {
+ // ������������
+ if (this.start != this.i) this.handler.onText(this.content.substring(this.start, this.i))
+ this.start = ++this.i
+ this.state = this.tagName
+ } else if (c == '/' || c == '!' || c == '?') {
+ if (this.start != this.i) this.handler.onText(this.content.substring(this.start, this.i))
+ const next = this.content[this.i + 2]
+
+ if (c == '/' && (next >= 'a' && next <= 'z' || next >= 'A' && next <= 'Z')) {
+ // ������������
+ this.i += 2
+ this.start = this.i
+ return this.state = this.endTag
+ } // ������������
+
+ let end = '-->'
+ if (c != '!' || this.content[this.i + 2] != '-' || this.content[this.i + 3] != '-') end = '>'
+ this.i = this.content.indexOf(end, this.i)
+
+ if (this.i != -1) {
+ this.i += end.length
+ this.start = this.i
+ }
+ } else this.i++
+}
+/**
+ * @description ���������������
+ * @private
+ */
+
+lexer.prototype.tagName = function () {
+ if (blankChar[this.content[this.i]]) {
+ // ������������������
+ this.handler.onTagName(this.content.substring(this.start, this.i))
+
+ while (blankChar[this.content[++this.i]]) {
+
+ }
+
+ if (this.i < this.content.length && !this.checkClose()) {
+ this.start = this.i
+ this.state = this.attrName
+ }
+ } else if (!this.checkClose('onTagName')) this.i++
+}
+/**
+ * @description ���������������
+ * @private
+ */
+
+lexer.prototype.attrName = function () {
+ let c = this.content[this.i]
+
+ if (blankChar[c] || c == '=') {
+ // ������������������
+ this.handler.onAttrName(this.content.substring(this.start, this.i))
+ let needVal = c == '='
+ const len = this.content.length
+
+ while (++this.i < len) {
+ c = this.content[this.i]
+
+ if (!blankChar[c]) {
+ if (this.checkClose()) return
+
+ if (needVal) {
+ // ������������������������������������
+ this.start = this.i
+ return this.state = this.attrVal
+ }
+
+ if (this.content[this.i] == '=') needVal = true; else {
+ this.start = this.i
+ return this.state = this.attrName
+ }
+ }
+ }
+ } else if (!this.checkClose('onAttrName')) this.i++
+}
+/**
+ * @description ���������������
+ * @private
+ */
+
+lexer.prototype.attrVal = function () {
+ const c = this.content[this.i]
+ const len = this.content.length // ������������������
+
+ if (c == '"' || c == "'") {
+ this.start = ++this.i
+ this.i = this.content.indexOf(c, this.i)
+ if (this.i == -1) return
+ this.handler.onAttrVal(this.content.substring(this.start, this.i))
+ } // ���������������������
+ else {
+ for (; this.i < len; this.i++) {
+ if (blankChar[this.content[this.i]]) {
+ this.handler.onAttrVal(this.content.substring(this.start, this.i))
+ break
+ } else if (this.checkClose('onAttrVal')) return
+ }
+ }
+
+ while (blankChar[this.content[++this.i]]) {
+
+ }
+
+ if (this.i < len && !this.checkClose()) {
+ this.start = this.i
+ this.state = this.attrName
+ }
+}
+/**
+ * @description ������������������
+ * @returns {String} ������������������
+ * @private
+ */
+
+lexer.prototype.endTag = function () {
+ const c = this.content[this.i]
+
+ if (blankChar[c] || c == '>' || c == '/') {
+ this.handler.onCloseTag(this.content.substring(this.start, this.i))
+
+ if (c != '>') {
+ this.i = this.content.indexOf('>', this.i)
+ if (this.i == -1) return
+ }
+
+ this.start = ++this.i
+ this.state = this.text
+ } else this.i++
+}
+
+module.exports = parser
diff --git a/uni_modules/uview-ui/components/u-parse/props.js b/uni_modules/uview-ui/components/u-parse/props.js
new file mode 100644
index 0000000..defd06c
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-parse/props.js
@@ -0,0 +1,45 @@
+export default {
+ props: {
+ // #ifdef APP-PLUS-NVUE
+ bgColor: String,
+ // #endif
+ content: String,
+ copyLink: {
+ type: Boolean,
+ default: uni.$u.props.parse.copyLink
+ },
+ domain: String,
+ errorImg: {
+ type: String,
+ default: uni.$u.props.parse.errorImg
+ },
+ lazyLoad: {
+ type: Boolean,
+ default: uni.$u.props.parse.lazyLoad
+ },
+ loadingImg: {
+ type: String,
+ default: uni.$u.props.parse.loadingImg
+ },
+ pauseVideo: {
+ type: Boolean,
+ default: uni.$u.props.parse.pauseVideo
+ },
+ previewImg: {
+ type: Boolean,
+ default: uni.$u.props.parse.previewImg
+ },
+ scrollTable: Boolean,
+ selectable: Boolean,
+ setTitle: {
+ type: Boolean,
+ default: uni.$u.props.parse.setTitle
+ },
+ showImgMenu: {
+ type: Boolean,
+ default: uni.$u.props.parse.showImgMenu
+ },
+ tagStyle: Object,
+ useAnchor: null
+ }
+}
diff --git a/uni_modules/uview-ui/components/u-parse/u-parse.vue b/uni_modules/uview-ui/components/u-parse/u-parse.vue
new file mode 100644
index 0000000..7bc8b3d
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-parse/u-parse.vue
@@ -0,0 +1,366 @@
+<template>
+ <view id="_root" :class="(selectable?'_select ':'')+'_root'">
+ <slot v-if="!nodes[0]" />
+ <!-- #ifndef APP-PLUS-NVUE -->
+ <node v-else :childs="nodes" :opts="[lazyLoad,loadingImg,errorImg,showImgMenu]" />
+ <!-- #endif -->
+ <!-- #ifdef APP-PLUS-NVUE -->
+ <web-view ref="web" src="/static/app-plus/mp-html/local.html" :style="'margin-top:-2px;height:' + height + 'px'" @onPostMessage="_onMessage" />
+ <!-- #endif -->
+ </view>
+</template>
+
+<script>
+ import props from './props.js';
+/**
+ * mp-html v2.0.4
+ * @description ���������������
+ * @tutorial https://github.com/jin-yufeng/mp-html
+ * @property {String} bgColor ���������������������������APP-PLUS-NVUE
+ * @property {String} content ������������������������������������������ true ���
+ * @property {Boolean} copyLink ������������������������������������������������
+ * @property {String} domain ������������������������������
+ * @property {String} errorImg ���������������������������������
+ * @property {Boolean} lazyLoad ������������������������������������ true ���
+ * @property {string} loadingImg ���������������������������������������
+ * @property {Boolean} pauseVideo ��������������������������������������������������������������� true ���
+ * @property {Boolean} previewImg ��������������������������������������������������� true ���
+ * @property {Boolean} scrollTable ���������������������������������������������������������������������
+ * @property {Boolean} selectable ������������������������
+ * @property {Boolean} setTitle ��������� title ��������������������������������������������� true ���
+ * @property {Boolean} showImgMenu ��������������������������������������������������� true ���
+ * @property {Object} tagStyle ���������������������
+ * @property {Boolean | Number} useAnchor ������������������������
+ *
+ * @event {Function} load dom ���������������������������
+ * @event {Function} ready ���������������������������������
+ * @event {Function} imgTap ������������������������
+ * @event {Function} linkTap ������������������������
+ * @event {Function} error ���������������������������
+ */
+const plugins=[]
+const parser = require('./parser')
+// #ifndef APP-PLUS-NVUE
+import node from './node/node'
+// #endif
+// #ifdef APP-PLUS-NVUE
+const dom = weex.requireModule('dom')
+// #endif
+export default {
+ name: 'mp-html',
+ data() {
+ return {
+ nodes: [],
+ // #ifdef APP-PLUS-NVUE
+ height: 0
+ // #endif
+ }
+ },
+ mixins:[props],
+ // #ifndef APP-PLUS-NVUE
+ components: {
+ node
+ },
+ // #endif
+ watch: {
+ content(content) {
+ this.setContent(content)
+ }
+ },
+ created() {
+ this.plugins = []
+ for (let i = plugins.length; i--;)
+ this.plugins.push(new plugins[i](this))
+ },
+ mounted() {
+ if (this.content && !this.nodes.length)
+ this.setContent(this.content)
+ },
+ beforeDestroy() {
+ this._hook('onDetached')
+ clearInterval(this._timer)
+ },
+ methods: {
+ /**
+ * @description ��������������������������������������� scroll-view ���
+ * @param {Object} page scroll-view ���������������������
+ * @param {String} selector scroll-view ������������
+ * @param {String} scrollTop scroll-view scroll-top ������������������������
+ */
+ in(page, selector, scrollTop) {
+ // #ifndef APP-PLUS-NVUE
+ if (page && selector && scrollTop)
+ this._in = {
+ page,
+ selector,
+ scrollTop
+ }
+ // #endif
+ },
+
+ /**
+ * @description ������������
+ * @param {String} id ������������������ id
+ * @param {Number} offset ������������������������
+ * @returns {Promise}
+ */
+ navigateTo(id, offset) {
+ return new Promise((resolve, reject) => {
+ if (!this.useAnchor)
+ return reject('Anchor is disabled')
+ offset = offset || parseInt(this.useAnchor) || 0
+ // #ifdef APP-PLUS-NVUE
+ if (!id) {
+ dom.scrollToElement(this.$refs.web, {
+ offset
+ })
+ resolve()
+ } else {
+ this._navigateTo = {
+ resolve,
+ reject,
+ offset
+ }
+ this.$refs.web.evalJs('uni.postMessage({data:{action:"getOffset",offset:(document.getElementById(' + id + ')||{}).offsetTop}})')
+ }
+ // #endif
+ // #ifndef APP-PLUS-NVUE
+ let deep = ' '
+ // #ifdef MP-WEIXIN || MP-QQ || MP-TOUTIAO
+ deep = '>>>'
+ // #endif
+ const selector = uni.createSelectorQuery()
+ // #ifndef MP-ALIPAY
+ .in(this._in ? this._in.page : this)
+ // #endif
+ .select((this._in ? this._in.selector : '._root') + (id ? `${deep}#${id}` : '')).boundingClientRect()
+ if (this._in)
+ selector.select(this._in.selector).scrollOffset()
+ .select(this._in.selector).boundingClientRect() // ������ scroll-view ������������������������
+ else
+ selector.selectViewport().scrollOffset() // ���������������������������
+ selector.exec(res => {
+ if (!res[0])
+ return reject('Label not found')
+ const scrollTop = res[1].scrollTop + res[0].top - (res[2] ? res[2].top : 0) + offset
+ if (this._in)
+ // scroll-view ������
+ this._in.page[this._in.scrollTop] = scrollTop
+ else
+ // ������������
+ uni.pageScrollTo({
+ scrollTop,
+ duration: 300
+ })
+ resolve()
+ })
+ // #endif
+ })
+ },
+
+ /**
+ * @description ������������������
+ * @return {String}
+ */
+ getText() {
+ let text = '';
+ (function traversal(nodes) {
+ for (let i = 0; i < nodes.length; i++) {
+ const node = nodes[i]
+ if (node.type == 'text')
+ text += node.text.replace(/&/g, '&')
+ else if (node.name == 'br')
+ text += '\n'
+ else {
+ // ���������������������������
+ const isBlock = node.name == 'p' || node.name == 'div' || node.name == 'tr' || node.name == 'li' || (node.name[0] == 'h' && node.name[1] > '0' && node.name[1] < '7')
+ if (isBlock && text && text[text.length - 1] != '\n')
+ text += '\n'
+ // ������������������������������
+ if (node.children)
+ traversal(node.children)
+ if (isBlock && text[text.length - 1] != '\n')
+ text += '\n'
+ else if (node.name == 'td' || node.name == 'th')
+ text += '\t'
+ }
+ }
+ })(this.nodes)
+ return text
+ },
+
+ /**
+ * @description ���������������������������
+ * @return {Promise}
+ */
+ getRect() {
+ return new Promise((resolve, reject) => {
+ uni.createSelectorQuery()
+ // #ifndef MP-ALIPAY
+ .in(this)
+ // #endif
+ .select('#_root').boundingClientRect().exec(res => res[0] ? resolve(res[0]) : reject('Root label not found'))
+ })
+ },
+
+ /**
+ * @description ������������
+ * @param {String} content html ������
+ * @param {Boolean} append ���������������������
+ */
+ setContent(content, append) {
+ if (!append || !this.imgList)
+ this.imgList = []
+ const nodes = new parser(this).parse(content)
+ // #ifdef APP-PLUS-NVUE
+ if (this._ready)
+ this._set(nodes, append)
+ // #endif
+ this.$set(this, 'nodes', append ? (this.nodes || []).concat(nodes) : nodes)
+
+ // #ifndef APP-PLUS-NVUE
+ this._videos = []
+ this.$nextTick(() => {
+ this._hook('onLoad')
+ this.$emit('load')
+ })
+
+ // ������������������������
+ let height
+ clearInterval(this._timer)
+ this._timer = setInterval(() => {
+ this.getRect().then(rect => {
+ // 350ms ��������������������������� ready ������
+ if (rect.height == height) {
+ this.$emit('ready', rect)
+ clearInterval(this._timer)
+ }
+ height = rect.height
+ }).catch(() => { })
+ }, 350)
+ // #endif
+ },
+
+ /**
+ * @description ������������������������
+ */
+ _hook(name) {
+ for (let i = plugins.length; i--;)
+ if (this.plugins[i][name])
+ this.plugins[i][name]()
+ },
+
+ // #ifdef APP-PLUS-NVUE
+ /**
+ * @description ������������
+ */
+ _set(nodes, append) {
+ this.$refs.web.evalJs('setContent(' + JSON.stringify(nodes) + ',' + JSON.stringify([this.bgColor, this.errorImg, this.loadingImg, this.pauseVideo, this.scrollTable, this.selectable]) + ',' + append + ')')
+ },
+
+ /**
+ * @description ��������� web-view ������
+ */
+ _onMessage(e) {
+ const message = e.detail.data[0]
+ switch (message.action) {
+ // web-view ���������������
+ case 'onJSBridgeReady':
+ this._ready = true
+ if (this.nodes)
+ this._set(this.nodes)
+ break
+ // ������ dom ������������
+ case 'onLoad':
+ this.height = message.height
+ this._hook('onLoad')
+ this.$emit('load')
+ break
+ // ������������������������
+ case 'onReady':
+ this.getRect().then(res => {
+ this.$emit('ready', res)
+ }).catch(() => { })
+ break
+ // ���������������������
+ case 'onHeightChange':
+ this.height = message.height
+ break
+ // ������������
+ case 'onImgTap':
+ this.$emit('imgTap', message.attrs)
+ if (this.previewImg)
+ uni.previewImage({
+ current: parseInt(message.attrs.i),
+ urls: this.imgList
+ })
+ break
+ // ������������
+ case 'onLinkTap':
+ const href = message.attrs.href
+ this.$emit('linkTap', message.attrs)
+ if (href) {
+ // ������������
+ if (href[0] == '#') {
+ if (this.useAnchor)
+ dom.scrollToElement(this.$refs.web, {
+ offset: message.offset
+ })
+ }
+ // ������������
+ else if (href.includes('://')) {
+ if (this.copyLink)
+ plus.runtime.openWeb(href)
+ }
+ else
+ uni.navigateTo({
+ url: href,
+ fail() {
+ wx.switchTab({
+ url: href
+ })
+ }
+ })
+ }
+ break
+ // ���������������������������
+ case 'getOffset':
+ if (typeof message.offset == 'number') {
+ dom.scrollToElement(this.$refs.web, {
+ offset: message.offset + this._navigateTo.offset
+ })
+ this._navigateTo.resolve()
+ } else
+ this._navigateTo.reject('Label not found')
+ break
+ // ������
+ case 'onClick':
+ this.$emit('tap')
+ break
+ // ������
+ case 'onError':
+ this.$emit('error', {
+ source: message.source,
+ attrs: message.attrs
+ })
+ }
+ }
+ // #endif
+ }
+}
+</script>
+
+<style>
+/* #ifndef APP-PLUS-NVUE */
+/* ��������������� */
+._root {
+ overflow: auto;
+ -webkit-overflow-scrolling: touch;
+}
+
+/* ������������ */
+._select {
+ user-select: text;
+}
+/* #endif */
+</style>
diff --git a/uni_modules/uview-ui/components/u-picker-column/props.js b/uni_modules/uview-ui/components/u-picker-column/props.js
new file mode 100644
index 0000000..7c11331
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-picker-column/props.js
@@ -0,0 +1,5 @@
+export default {
+ props: {
+
+ }
+}
diff --git a/uni_modules/uview-ui/components/u-picker-column/u-picker-column.vue b/uni_modules/uview-ui/components/u-picker-column/u-picker-column.vue
new file mode 100644
index 0000000..53553f3
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-picker-column/u-picker-column.vue
@@ -0,0 +1,27 @@
+<template>
+ <picker-view-column>
+ <view class="u-picker-column">
+
+ </view>
+ </picker-view-column>
+</template>
+
+<script>
+ import props from './props.js';
+ /**
+ * PickerColumn
+ * @description
+ * @tutorial url
+ * @property {String}
+ * @event {Function}
+ * @example
+ */
+ export default {
+ name: 'u-picker-column',
+ mixins: [uni.$u.mpMixin, uni.$u.mixin,props],
+ }
+</script>
+
+<style lang="scss" scoped>
+ @import "../../libs/css/components.scss";
+</style>
diff --git a/uni_modules/uview-ui/components/u-picker/props.js b/uni_modules/uview-ui/components/u-picker/props.js
new file mode 100644
index 0000000..7b5d091
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-picker/props.js
@@ -0,0 +1,79 @@
+export default {
+ props: {
+ // ������������picker������
+ show: {
+ type: Boolean,
+ default: uni.$u.props.picker.show
+ },
+ // ������������������������������
+ showToolbar: {
+ type: Boolean,
+ default: uni.$u.props.picker.showToolbar
+ },
+ // ������������
+ title: {
+ type: String,
+ default: uni.$u.props.picker.title
+ },
+ // ���������������������������������������
+ columns: {
+ type: Array,
+ default: uni.$u.props.picker.columns
+ },
+ // ���������������������������
+ loading: {
+ type: Boolean,
+ default: uni.$u.props.picker.loading
+ },
+ // ���������������������������������
+ itemHeight: {
+ type: [String, Number],
+ default: uni.$u.props.picker.itemHeight
+ },
+ // ���������������������
+ cancelText: {
+ type: String,
+ default: uni.$u.props.picker.cancelText
+ },
+ // ���������������������
+ confirmText: {
+ type: String,
+ default: uni.$u.props.picker.confirmText
+ },
+ // ���������������������
+ cancelColor: {
+ type: String,
+ default: uni.$u.props.picker.cancelColor
+ },
+ // ���������������������
+ confirmColor: {
+ type: String,
+ default: uni.$u.props.picker.confirmColor
+ },
+ // ������������������������������
+ visibleItemCount: {
+ type: [String, Number],
+ default: uni.$u.props.picker.visibleItemCount
+ },
+ // ���������������������������������������������
+ keyName: {
+ type: String,
+ default: uni.$u.props.picker.keyName
+ },
+ // ���������������������������������������
+ closeOnClickOverlay: {
+ type: Boolean,
+ default: uni.$u.props.picker.closeOnClickOverlay
+ },
+ // ���������������������
+ defaultIndex: {
+ type: Array,
+ default: uni.$u.props.picker.defaultIndex
+ },
+ // ������������������������������������ change ��������������������������������������������������������� change ���������������������2.21.1���������������
+ immediateChange: {
+ type: Boolean,
+ default: uni.$u.props.picker.immediateChange
+ }
+ }
+}
diff --git a/uni_modules/uview-ui/components/u-picker/u-picker.vue b/uni_modules/uview-ui/components/u-picker/u-picker.vue
new file mode 100644
index 0000000..8885917
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-picker/u-picker.vue
@@ -0,0 +1,283 @@
+<template>
+ <u-popup
+ :show="show"
+ @close="closeHandler"
+ >
+ <view class="u-picker">
+ <u-toolbar
+ v-if="showToolbar"
+ :cancelColor="cancelColor"
+ :confirmColor="confirmColor"
+ :cancelText="cancelText"
+ :confirmText="confirmText"
+ :title="title"
+ @cancel="cancel"
+ @confirm="confirm"
+ ></u-toolbar>
+ <picker-view
+ class="u-picker__view"
+ :indicatorStyle="`height: ${$u.addUnit(itemHeight)}`"
+ :value="innerIndex"
+ :immediateChange="immediateChange"
+ :style="{
+ height: `${$u.addUnit(visibleItemCount * itemHeight)}`
+ }"
+ @change="changeHandler"
+ >
+ <picker-view-column
+ v-for="(item, index) in innerColumns"
+ :key="index"
+ class="u-picker__view__column"
+ >
+ <text
+ v-if="$u.test.array(item)"
+ class="u-picker__view__column__item u-line-1"
+ v-for="(item1, index1) in item"
+ :key="index1"
+ :style="{
+ height: $u.addUnit(itemHeight),
+ lineHeight: $u.addUnit(itemHeight),
+ fontWeight: index1 === innerIndex[index] ? 'bold' : 'normal'
+ }"
+ >{{ getItemText(item1) }}</text>
+ </picker-view-column>
+ </picker-view>
+ <view
+ v-if="loading"
+ class="u-picker--loading"
+ >
+ <u-loading-icon mode="circle"></u-loading-icon>
+ </view>
+ </view>
+ </u-popup>
+</template>
+
+<script>
+/**
+ * u-picker
+ * @description ���������
+ * @property {Boolean} show ������������picker��������������� false ���
+ * @property {Boolean} showToolbar ��������������������������������������� true ���
+ * @property {String} title ������������
+ * @property {Array} columns ���������������������������������������
+ * @property {Boolean} loading ������������������������������������ false ���
+ * @property {String | Number} itemHeight ������������������������������������������ 44 ���
+ * @property {String} cancelText ������������������������������ '������' ���
+ * @property {String} confirmText ������������������������������ '������' ���
+ * @property {String} cancelColor ������������������������������ '#909193' ���
+ * @property {String} confirmColor ������������������������������ '#3c9cff' ���
+ * @property {String | Number} visibleItemCount ��������������������������������������� 5 ���
+ * @property {String} keyName ������������������������������������������������������ 'text' ���
+ * @property {Boolean} closeOnClickOverlay ������������������������������������������������ false ���
+ * @property {Array} defaultIndex ���������������������
+ * @property {Boolean} immediateChange ������������������������������������change��������������� false ���
+ * @event {Function} close ������������������������
+ * @event {Function} cancel ������������������������
+ * @event {Function} change ���������������������������
+ * @event {Function} confirm ���������������������������������������������
+ */
+import props from './props.js';
+export default {
+ name: 'u-picker',
+ mixins: [uni.$u.mpMixin, uni.$u.mixin, props],
+ data() {
+ return {
+ // ���������������������������
+ lastIndex: [],
+ // ��������� ���������picker-view���value
+ innerIndex: [],
+ // ������������
+ innerColumns: [],
+ // ���������������������������
+ columnIndex: 0,
+ }
+ },
+ watch: {
+ // ������������������������������������������������������
+ defaultIndex: {
+ immediate: true,
+ handler(n) {
+ this.setIndexs(n, true)
+ }
+ },
+ // ������columns���������������
+ columns: {
+ immediate: true,
+ handler(n) {
+ this.setColumns(n)
+ }
+ },
+ },
+ methods: {
+ // ������item���������������������������������������������������
+ getItemText(item) {
+ if (uni.$u.test.object(item)) {
+ return item[this.keyName]
+ } else {
+ return item
+ }
+ },
+ // ���������������
+ closeHandler() {
+ if (this.closeOnClickOverlay) {
+ this.$emit('close')
+ }
+ },
+ // ������������������������������
+ cancel() {
+ this.$emit('cancel')
+ },
+ // ������������������������������
+ confirm() {
+ this.$emit('confirm', {
+ indexs: this.innerIndex,
+ value: this.innerColumns.map((item, index) => item[this.innerIndex[index]]),
+ values: this.innerColumns
+ })
+ },
+ // ������������������������������������������������
+ changeHandler(e) {
+ const {
+ value
+ } = e.detail
+ let index = 0,
+ columnIndex = 0
+ // ������������������������������������������������������������������������
+ for (let i = 0; i < value.length; i++) {
+ let item = value[i]
+ if (item !== (this.lastIndex[i] || 0)) { // ���undefined������������������0
+ // ������columnIndex���������������������������
+ columnIndex = i
+ // index���������������������������������������
+ index = item
+ break // ������������������������������������������������������������
+ }
+ }
+ this.columnIndex = columnIndex
+ const values = this.innerColumns
+ // ������������������������������������������"���������"������������������
+ this.setLastIndex(value)
+ this.setIndexs(value)
+
+ this.$emit('change', {
+ // #ifndef MP-WEIXIN || MP-LARK
+ // ���������������������������this���������������������������������
+ picker: this,
+ // #endif
+ value: this.innerColumns.map((item, index) => item[value[index]]),
+ index,
+ indexs: value,
+ // values���������������������������������
+ values,
+ columnIndex
+ })
+ },
+ // ������index������������������������������������������
+ setIndexs(index, setLastIndex) {
+ this.innerIndex = uni.$u.deepClone(index)
+ if (setLastIndex) {
+ this.setLastIndex(index)
+ }
+ },
+ // ������������������������������������
+ setLastIndex(index) {
+ // ���������������������������������������������������������������������������������������������������������������������������������changeHandler���
+ // ���������������������������������������������������������������������������������
+ this.lastIndex = uni.$u.deepClone(index)
+ },
+ // ���������������������������������
+ setColumnValues(columnIndex, values) {
+ // ������innerColumns���������columnIndex���������������values������������������������splice������
+ this.innerColumns.splice(columnIndex, 1, values)
+ // ���������������������innerIndex���������������������������������������������������������������������������������0
+ let tmpIndex = uni.$u.deepClone(this.innerIndex)
+ for (let i = 0; i < this.innerColumns.length; i++) {
+ if (i > this.columnIndex) {
+ tmpIndex[i] = 0
+ }
+ }
+ // ���������������������������������������������������
+ this.setIndexs(tmpIndex)
+ },
+ // ������������������������������
+ getColumnValues(columnIndex) {
+ // ���������������������������������������change���������������������������������setColumnValues���������������
+ // ���������������������change������������������getColumnValues������������������������������������������������������������������������������������������������
+ (async () => {
+ await uni.$u.sleep()
+ })()
+ return this.innerColumns[columnIndex]
+ },
+ // ���������������������columns������
+ setColumns(columns) {
+ this.innerColumns = uni.$u.deepClone(columns)
+ // ���������������������������������������������������������������������defaultIndex������������0������������������������������������������
+ if (this.innerIndex.length === 0) {
+ this.innerIndex = new Array(columns.length).fill(0)
+ }
+ },
+ // ������������������������������������
+ getIndexs() {
+ return this.innerIndex
+ },
+ // ������������������������
+ getValues() {
+ // ���������������������������������������change���������������������������������setColumnValues���������������
+ // ���������������������change������������������getValues������������������������������������������������������������������������������������������������
+ (async () => {
+ await uni.$u.sleep()
+ })()
+ return this.innerColumns.map((item, index) => item[this.innerIndex[index]])
+ }
+ },
+}
+</script>
+
+<style lang="scss" scoped>
+ @import "../../libs/css/components.scss";
+
+ .u-picker {
+ position: relative;
+
+ &__view {
+
+ &__column {
+ @include flex;
+ flex: 1;
+ justify-content: center;
+
+ &__item {
+ @include flex;
+ justify-content: center;
+ align-items: center;
+ font-size: 16px;
+ text-align: center;
+ /* #ifndef APP-NVUE */
+ display: block;
+ /* #endif */
+ color: $u-main-color;
+
+ &--disabled {
+ /* #ifndef APP-NVUE */
+ cursor: not-allowed;
+ /* #endif */
+ opacity: 0.35;
+ }
+ }
+ }
+ }
+
+ &--loading {
+ position: absolute;
+ top: 0;
+ right: 0;
+ left: 0;
+ bottom: 0;
+ @include flex;
+ justify-content: center;
+ align-items: center;
+ background-color: rgba(255, 255, 255, 0.87);
+ z-index: 1000;
+ }
+ }
+</style>
diff --git a/uni_modules/uview-ui/components/u-popup/props.js b/uni_modules/uview-ui/components/u-popup/props.js
new file mode 100644
index 0000000..d9fe952
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-popup/props.js
@@ -0,0 +1,79 @@
+export default {
+ props: {
+ // ������������������
+ show: {
+ type: Boolean,
+ default: uni.$u.props.popup.show
+ },
+ // ������������������
+ overlay: {
+ type: Boolean,
+ default: uni.$u.props.popup.overlay
+ },
+ // ������������������������������ top bottom right left center
+ mode: {
+ type: String,
+ default: uni.$u.props.popup.mode
+ },
+ // ���������������������ms
+ duration: {
+ type: [String, Number],
+ default: uni.$u.props.popup.duration
+ },
+ // ������������������������
+ closeable: {
+ type: Boolean,
+ default: uni.$u.props.popup.closeable
+ },
+ // ������������������������
+ overlayStyle: {
+ type: [Object, String],
+ default: uni.$u.props.popup.overlayStyle
+ },
+ // ������������������������������
+ closeOnClickOverlay: {
+ type: Boolean,
+ default: uni.$u.props.popup.closeOnClickOverlay
+ },
+ // ������
+ zIndex: {
+ type: [String, Number],
+ default: uni.$u.props.popup.zIndex
+ },
+ // ���������iPhoneX������������������������
+ safeAreaInsetBottom: {
+ type: Boolean,
+ default: uni.$u.props.popup.safeAreaInsetBottom
+ },
+ // ���������������������������������������������������
+ safeAreaInsetTop: {
+ type: Boolean,
+ default: uni.$u.props.popup.safeAreaInsetTop
+ },
+ // ������������������������������top-left���������������top-right���������������bottom-left���������������bottom-right������������
+ closeIconPos: {
+ type: String,
+ default: uni.$u.props.popup.closeIconPos
+ },
+ // ������������������
+ round: {
+ type: [Boolean, String, Number],
+ default: uni.$u.props.popup.round
+ },
+ // mode=center���������������������������������������������������
+ zoom: {
+ type: Boolean,
+ default: uni.$u.props.popup.zoom
+ },
+ // ���������������������������transparent���������������������
+ bgColor: {
+ type: String,
+ default: uni.$u.props.popup.bgColor
+ },
+ // ���������������������0-1������
+ overlayOpacity: {
+ type: [Number, String],
+ default: uni.$u.props.popup.overlayOpacity
+ }
+ }
+}
diff --git a/uni_modules/uview-ui/components/u-popup/u-popup.vue b/uni_modules/uview-ui/components/u-popup/u-popup.vue
new file mode 100644
index 0000000..2ca51cc
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-popup/u-popup.vue
@@ -0,0 +1,304 @@
+<template>
+ <view class="u-popup">
+ <u-overlay
+ :show="show"
+ @click="overlayClick"
+ v-if="overlay"
+ :duration="overlayDuration"
+ :customStyle="overlayStyle"
+ :opacity="overlayOpacity"
+ ></u-overlay>
+ <u-transition
+ :show="show"
+ :customStyle="transitionStyle"
+ :mode="position"
+ :duration="duration"
+ @afterEnter="afterEnter"
+ @click="clickHandler"
+ >
+ <view
+ class="u-popup__content"
+ :style="[contentStyle]"
+ @tap.stop="noop"
+ >
+ <u-status-bar v-if="safeAreaInsetTop"></u-status-bar>
+ <slot></slot>
+ <view
+ v-if="closeable"
+ @tap.stop="close"
+ class="u-popup__content__close"
+ :class="['u-popup__content__close--' + closeIconPos]"
+ hover-class="u-popup__content__close--hover"
+ hover-stay-time="150"
+ >
+ <u-icon
+ name="close"
+ color="#909399"
+ size="18"
+ bold
+ ></u-icon>
+ </view>
+ <u-safe-bottom v-if="safeAreaInsetBottom"></u-safe-bottom>
+ </view>
+ </u-transition>
+ </view>
+</template>
+
+<script>
+ import props from './props.js';
+
+ /**
+ * popup ������
+ * @description ������������������������������������������������������������������������������������������������������������������������������������������������������������������
+ * @tutorial https://www.uviewui.com/components/popup.html
+ * @property {Boolean} show ������������������ (������ false )
+ * @property {Boolean} overlay ������������������ ��������� true ���
+ * @property {String} mode ��������������������� 'bottom' ���
+ * @property {String | Number} duration ���������������������ms ��������� 300 ���
+ * @property {String | Number} overlayDuration ������������������������������ms ��������� 350 ���
+ * @property {Boolean} closeable ��������������������������������� false ���
+ * @property {Object | String} overlayStyle ������������������������
+ * @property {String | Number} overlayOpacity ������������������0-1��������������� 0.5���
+ * @property {Boolean} closeOnClickOverlay ������������������������������ ��������� true ���
+ * @property {String | Number} zIndex ������ ��������� 10075 ���
+ * @property {Boolean} safeAreaInsetBottom ���������iPhoneX������������������������ ��������� true ���
+ * @property {Boolean} safeAreaInsetTop ��������������������������������������������������� ��������� false ���
+ * @property {String} closeIconPos ������������������������������������ 'top-right' ���
+ * @property {String | Number} round ������������������ 0���
+ * @property {Boolean} zoom ���mode=center��� ��������������������������� true ���
+ * @property {Object} customStyle ������������������������������
+ * @event {Function} open ���������������
+ * @event {Function} close ���������������
+ * @example <u-popup v-model="show"><text>���������������������������������������</text></u-popup>
+ */
+ export default {
+ name: 'u-popup',
+ mixins: [uni.$u.mpMixin, uni.$u.mixin, props],
+ data() {
+ return {
+ overlayDuration: this.duration + 50
+ }
+ },
+ watch: {
+ show(newValue, oldValue) {
+ if (newValue === true) {
+ // #ifdef MP-WEIXIN
+ const children = this.$children
+ this.retryComputedComponentRect(children)
+ // #endif
+ }
+ }
+ },
+ computed: {
+ transitionStyle() {
+ const style = {
+ zIndex: this.zIndex,
+ position: 'fixed',
+ display: 'flex',
+ }
+ style[this.mode] = 0
+ if (this.mode === 'left') {
+ return uni.$u.deepMerge(style, {
+ bottom: 0,
+ top: 0,
+ })
+ } else if (this.mode === 'right') {
+ return uni.$u.deepMerge(style, {
+ bottom: 0,
+ top: 0,
+ })
+ } else if (this.mode === 'top') {
+ return uni.$u.deepMerge(style, {
+ left: 0,
+ right: 0
+ })
+ } else if (this.mode === 'bottom') {
+ return uni.$u.deepMerge(style, {
+ left: 0,
+ right: 0,
+ })
+ } else if (this.mode === 'center') {
+ return uni.$u.deepMerge(style, {
+ alignItems: 'center',
+ 'justify-content': 'center',
+ top: 0,
+ left: 0,
+ right: 0,
+ bottom: 0
+ })
+ }
+ },
+ contentStyle() {
+ const style = {}
+ // ���������������������safeAreaInsets������������������������������������������������������������������������
+ // ���������css������������������nvue���������css���iPhoneX���������������������
+ const {
+ safeAreaInsets
+ } = uni.$u.sys()
+ if (this.mode !== 'center') {
+ style.flex = 1
+ }
+ // ���������������������������������transparent������������������������������
+ if (this.bgColor) {
+ style.backgroundColor = this.bgColor
+ }
+ if(this.round) {
+ const value = uni.$u.addUnit(this.round)
+ if(this.mode === 'top') {
+ style.borderBottomLeftRadius = value
+ style.borderBottomRightRadius = value
+ } else if(this.mode === 'bottom') {
+ style.borderTopLeftRadius = value
+ style.borderTopRightRadius = value
+ } else if(this.mode === 'center') {
+ style.borderRadius = value
+ }
+ }
+ return uni.$u.deepMerge(style, uni.$u.addStyle(this.customStyle))
+ },
+ position() {
+ if (this.mode === 'center') {
+ return this.zoom ? 'fade-zoom' : 'fade'
+ }
+ if (this.mode === 'left') {
+ return 'slide-left'
+ }
+ if (this.mode === 'right') {
+ return 'slide-right'
+ }
+ if (this.mode === 'bottom') {
+ return 'slide-up'
+ }
+ if (this.mode === 'top') {
+ return 'slide-down'
+ }
+ },
+ },
+ methods: {
+ // ������������
+ overlayClick() {
+ if (this.closeOnClickOverlay) {
+ this.$emit('close')
+ }
+ },
+ close(e) {
+ this.$emit('close')
+ },
+ afterEnter() {
+ this.$emit('open')
+ },
+ clickHandler() {
+ // ���������������������������u-transition������������������������������������������������������������������������������������������������������������������������
+ if(this.mode === 'center') {
+ this.overlayClick()
+ }
+ this.$emit('click')
+ },
+ // #ifdef MP-WEIXIN
+ retryComputedComponentRect(children) {
+ // ���������������������������������������
+ const names = ['u-calendar-month', 'u-album', 'u-collapse-item', 'u-dropdown', 'u-index-item', 'u-index-list',
+ 'u-line-progress', 'u-list-item', 'u-rate', 'u-read-more', 'u-row', 'u-row-notice', 'u-scroll-list',
+ 'u-skeleton', 'u-slider', 'u-steps-item', 'u-sticky', 'u-subsection', 'u-swipe-action-item', 'u-tabbar',
+ 'u-tabs', 'u-tooltip'
+ ]
+ // ������������������������������
+ for (let i = 0; i < children.length; i++) {
+ const child = children[i]
+ // ���������������������������
+ const grandChild = child.$children
+ // ���������������������������������������������������������������������������init������������������������
+ if (names.includes(child.$options.name) && typeof child?.init === 'function') {
+ // ���������������������������������������������������������������
+ uni.$u.sleep(50).then(() => {
+ child.init()
+ })
+ }
+ // ���������������������������������������������������
+ if (grandChild.length) {
+ this.retryComputedComponentRect(grandChild)
+ }
+ }
+ }
+ // #endif
+ }
+ }
+</script>
+
+<style lang="scss" scoped>
+ @import "../../libs/css/components.scss";
+ $u-popup-flex:1 !default;
+ $u-popup-content-background-color: #fff !default;
+
+ .u-popup {
+ flex: $u-popup-flex;
+
+ &__content {
+ background-color: $u-popup-content-background-color;
+ position: relative;
+
+ &--round-top {
+ border-top-left-radius: 0;
+ border-top-right-radius: 0;
+ border-bottom-left-radius: 10px;
+ border-bottom-right-radius: 10px;
+ }
+
+ &--round-left {
+ border-top-left-radius: 0;
+ border-top-right-radius: 10px;
+ border-bottom-left-radius: 0;
+ border-bottom-right-radius: 10px;
+ }
+
+ &--round-right {
+ border-top-left-radius: 10px;
+ border-top-right-radius: 0;
+ border-bottom-left-radius: 10px;
+ border-bottom-right-radius: 0;
+ }
+
+ &--round-bottom {
+ border-top-left-radius: 10px;
+ border-top-right-radius: 10px;
+ border-bottom-left-radius: 0;
+ border-bottom-right-radius: 0;
+ }
+
+ &--round-center {
+ border-top-left-radius: 10px;
+ border-top-right-radius: 10px;
+ border-bottom-left-radius: 10px;
+ border-bottom-right-radius: 10px;
+ }
+
+ &__close {
+ position: absolute;
+
+ &--hover {
+ opacity: 0.4;
+ }
+ }
+
+ &__close--top-left {
+ top: 15px;
+ left: 15px;
+ }
+
+ &__close--top-right {
+ top: 15px;
+ right: 15px;
+ }
+
+ &__close--bottom-left {
+ bottom: 15px;
+ left: 15px;
+ }
+
+ &__close--bottom-right {
+ right: 15px;
+ bottom: 15px;
+ }
+ }
+ }
+</style>
diff --git a/uni_modules/uview-ui/components/u-radio-group/props.js b/uni_modules/uview-ui/components/u-radio-group/props.js
new file mode 100644
index 0000000..bb86cba
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-radio-group/props.js
@@ -0,0 +1,85 @@
+export default {
+ props: {
+ // ������������
+ value: {
+ type: [String, Number, Boolean],
+ default: uni.$u.props.radioGroup.value
+ },
+
+ // ������������������radio
+ disabled: {
+ type: Boolean,
+ default: uni.$u.props.radioGroup.disabled
+ },
+ // ���������circle-���������square-������
+ shape: {
+ type: String,
+ default: uni.$u.props.radioGroup.shape
+ },
+ // ���������������������������������������������������������parent���activeColor���
+ activeColor: {
+ type: String,
+ default: uni.$u.props.radioGroup.activeColor
+ },
+ // ������������������
+ inactiveColor: {
+ type: String,
+ default: uni.$u.props.radioGroup.inactiveColor
+ },
+ // ���������
+ name: {
+ type: String,
+ default: uni.$u.props.radioGroup.name
+ },
+ // ������������������������������px
+ size: {
+ type: [String, Number],
+ default: uni.$u.props.radioGroup.size
+ },
+ // ���������������row-���������column-������
+ placement: {
+ type: String,
+ default: uni.$u.props.radioGroup.placement
+ },
+ // label���������
+ label: {
+ type: [String],
+ default: uni.$u.props.radioGroup.label
+ },
+ // label��������� ��������� '#303133' ���
+ labelColor: {
+ type: [String],
+ default: uni.$u.props.radioGroup.labelColor
+ },
+ // label������������������px������
+ labelSize: {
+ type: [String, Number],
+ default: uni.$u.props.radioGroup.labelSize
+ },
+ // ������������������������������checkbox(������ false )
+ labelDisabled: {
+ type: Boolean,
+ default: uni.$u.props.radioGroup.labelDisabled
+ },
+ // ������������
+ iconColor: {
+ type: String,
+ default: uni.$u.props.radioGroup.iconColor
+ },
+ // ������������������������px
+ iconSize: {
+ type: [String, Number],
+ default: uni.$u.props.radioGroup.iconSize
+ },
+ // ���������������������������������������
+ borderBottom: {
+ type: Boolean,
+ default: uni.$u.props.radioGroup.borderBottom
+ },
+ // ������������������������������
+ iconPlacement: {
+ type: String,
+ default: uni.$u.props.radio.iconPlacement
+ }
+ }
+}
diff --git a/uni_modules/uview-ui/components/u-radio-group/u-radio-group.vue b/uni_modules/uview-ui/components/u-radio-group/u-radio-group.vue
new file mode 100644
index 0000000..0d3c9b5
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-radio-group/u-radio-group.vue
@@ -0,0 +1,108 @@
+<template>
+ <view
+ class="u-radio-group"
+ :class="bemClass"
+ >
+ <slot></slot>
+ </view>
+</template>
+
+<script>
+ import props from './props.js';
+
+ /**
+ * radioRroup ������������������
+ * @description ���������������������������������������������������������������������������������u-radio������
+ * @tutorial https://www.uviewui.com/components/radio.html
+ * @property {String | Number | Boolean} value ������������
+ * @property {Boolean} disabled ������������������radio��������� false ���
+ * @property {String} shape ���������������shape-���������circle-������(������ circle )
+ * @property {String} activeColor ���������������������������������������Radio��������������� '#2979ff' ���
+ * @property {String} inactiveColor ������������������ (������ '#c8c9cc' )
+ * @property {String} name ���������
+ * @property {String | Number} size ������������������������������px��������� 18 ���
+ * @property {String} placement ���������������row-���������column-������ ��������� 'row' ���
+ * @property {String} label ������
+ * @property {String} labelColor label��������� ��������� '#303133' ���
+ * @property {String | Number} labelSize label������������������px������ ��������� 14 ���
+ * @property {Boolean} labelDisabled ������������������������������checkbox(������ false )
+ * @property {String} iconColor ������������ ��������� '#ffffff' ���
+ * @property {String | Number} iconSize ������������������������px ��������� 12 ���
+ * @property {Boolean} borderBottom placement���row��������������������������� ��������� false ���
+ * @property {String} iconPlacement ������������������������������ ��������� 'left' ���
+ * @property {Object} customStyle ������������������������������
+ * @event {Function} change ���������radio���������������������������
+ * @example <u-radio-group v-model="value"></u-radio-group>
+ */
+ export default {
+ name: 'u-radio-group',
+ mixins: [uni.$u.mpMixin, uni.$u.mixin,props],
+ computed: {
+ // ������computed���������������������������u-radio���������������������������������������������������������������������������������������������������������������
+ // ������������������������������������������������������parentData������������watch���������������������������������������������������������������(u-radio-group)
+ // ���������������������������������������
+ parentData() {
+ return [this.value, this.disabled, this.inactiveColor, this.activeColor, this.size, this.labelDisabled, this.shape,
+ this.iconSize, this.borderBottom, this.placement
+ ]
+ },
+ bemClass() {
+ // this.bem���������computed������������mixin���
+ return this.bem('radio-group', ['placement'])
+ },
+ },
+ watch: {
+ // ���������������������������������������������������������������������������������������
+ parentData() {
+ if (this.children.length) {
+ this.children.map(child => {
+ // ���������������(u-radio)���������init���������������������������(������������������������������������������������������������������)
+ typeof(child.init) === 'function' && child.init()
+ })
+ }
+ },
+ },
+ data() {
+ return {
+
+ }
+ },
+ created() {
+ this.children = []
+ },
+ methods: {
+ // ������������radio���������������������������
+ unCheckedOther(childInstance) {
+ this.children.map(child => {
+ // ���������radio������������������������������checked������������������
+ if (childInstance !== child) {
+ child.checked = false
+ }
+ })
+ const {
+ name
+ } = childInstance
+ // ������emit������������������������������v-model������������������
+ this.$emit('input', name)
+ // ������������
+ this.$emit('change', name)
+ },
+ }
+ }
+</script>
+
+<style lang="scss" scoped>
+ @import "../../libs/css/components.scss";
+
+ .u-radio-group {
+ flex: 1;
+
+ &--row {
+ @include flex;
+ }
+
+ &--column {
+ @include flex(column);
+ }
+ }
+</style>
diff --git a/uni_modules/uview-ui/components/u-radio/props.js b/uni_modules/uview-ui/components/u-radio/props.js
new file mode 100644
index 0000000..3ec5f6b
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-radio/props.js
@@ -0,0 +1,64 @@
+export default {
+ props: {
+ // radio���������
+ name: {
+ type: [String, Number, Boolean],
+ default: uni.$u.props.radio.name
+ },
+ // ���������square������������circle���������
+ shape: {
+ type: String,
+ default: uni.$u.props.radio.shape
+ },
+ // ������������
+ disabled: {
+ type: [String, Boolean],
+ default: uni.$u.props.radio.disabled
+ },
+ // ������������������������������������������
+ labelDisabled: {
+ type: [String, Boolean],
+ default: uni.$u.props.radio.labelDisabled
+ },
+ // ���������������������������������������������������������parent���activeColor���
+ activeColor: {
+ type: String,
+ default: uni.$u.props.radio.activeColor
+ },
+ // ������������������
+ inactiveColor: {
+ type: String,
+ default: uni.$u.props.radio.inactiveColor
+ },
+ // ������������������������px
+ iconSize: {
+ type: [String, Number],
+ default: uni.$u.props.radio.iconSize
+ },
+ // label������������������px������
+ labelSize: {
+ type: [String, Number],
+ default: uni.$u.props.radio.labelSize
+ },
+ // label���������������������nvue������������slot������������������������������������������������������������
+ label: {
+ type: [String, Number],
+ default: uni.$u.props.radio.label
+ },
+ // ���������������
+ size: {
+ type: [String, Number],
+ default: uni.$u.props.radio.size
+ },
+ // ������������
+ color: {
+ type: String,
+ default: uni.$u.props.radio.color
+ },
+ // label���������
+ labelColor: {
+ type: String,
+ default: uni.$u.props.radio.labelColor
+ }
+ }
+}
diff --git a/uni_modules/uview-ui/components/u-radio/u-radio.vue b/uni_modules/uview-ui/components/u-radio/u-radio.vue
new file mode 100644
index 0000000..c0caab6
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-radio/u-radio.vue
@@ -0,0 +1,339 @@
+<template>
+ <view
+ class="u-radio"
+ @tap.stop="wrapperClickHandler"
+ :style="[radioStyle]"
+ :class="[`u-radio-label--${parentData.iconPlacement}`, parentData.borderBottom && parentData.placement === 'column' && 'u-border-bottom']"
+ >
+ <view
+ class="u-radio__icon-wrap"
+ @tap.stop="iconClickHandler"
+ :class="iconClasses"
+ :style="[iconWrapStyle]"
+ >
+ <slot name="icon">
+ <u-icon
+ class="u-radio__icon-wrap__icon"
+ name="checkbox-mark"
+ :size="elIconSize"
+ :color="elIconColor"
+ />
+ </slot>
+ </view>
+ <slot>
+ <text
+ class="u-radio__text"
+ @tap.stop="labelClickHandler"
+ :style="{
+ color: elDisabled ? elInactiveColor : elLabelColor,
+ fontSize: elLabelSize,
+ lineHeight: elLabelSize
+ }"
+ >{{label}}</text>
+ </slot>
+ </view>
+</template>
+
+<script>
+ import props from './props.js';
+ /**
+ * radio ���������
+ * @description ���������������������������������������������������������������������������������u-radio-group������
+ * @tutorial https://www.uviewui.com/components/radio.html
+ * @property {String | Number} name radio���������
+ * @property {String} shape ���������square������������circle���������
+ * @property {Boolean} disabled ������������
+ * @property {String | Boolean} labelDisabled ������������������������������������������
+ * @property {String} activeColor ������������������������������parent���active-color���������
+ * @property {String} inactiveColor ������������������
+ * @property {String | Number} iconSize ���������������������px
+ * @property {String | Number} labelSize label���������������������px
+ * @property {String | Number} label label���������������������nvue������������slot������������������������������������������������������������
+ * @property {String | Number} size ���������������
+ * @property {String} iconColor ������������
+ * @property {String} labelColor label���������
+ * @property {Object} customStyle ������������������������������
+ *
+ * @event {Function} change ������radio���������������������������(������������)
+ * @example <u-radio :labelDisabled="false">������������������������������</u-radio>
+ */
+ export default {
+ name: "u-radio",
+
+ mixins: [uni.$u.mpMixin, uni.$u.mixin,props],
+ data() {
+ return {
+ checked: false,
+ // ������������������������������������
+ // ���������������������������������������������������������computed���������this.parent.shape���������
+ // ���������������������������
+ parentData: {
+ iconSize: 12,
+ labelDisabled: null,
+ disabled: null,
+ shape: null,
+ activeColor: null,
+ inactiveColor: null,
+ size: 18,
+ value: null,
+ iconColor: null,
+ placement: 'row',
+ borderBottom: false,
+ iconPlacement: 'left'
+ }
+ }
+ },
+ computed: {
+ // ������������������������������u-raios-group���������������������������������������������
+ elDisabled() {
+ return this.disabled !== '' ? this.disabled : this.parentData.disabled !== null ? this.parentData.disabled : false;
+ },
+ // ������������label������
+ elLabelDisabled() {
+ return this.labelDisabled !== '' ? this.labelDisabled : this.parentData.labelDisabled !== null ? this.parentData.labelDisabled :
+ false;
+ },
+ // ���������������������size���������������������21px
+ elSize() {
+ return this.size ? this.size : (this.parentData.size ? this.parentData.size : 21);
+ },
+ // ���������������������������������������12px
+ elIconSize() {
+ return this.iconSize ? this.iconSize : (this.parentData.iconSize ? this.parentData.iconSize : 12);
+ },
+ // ������������������������������
+ elActiveColor() {
+ return this.activeColor ? this.activeColor : (this.parentData.activeColor ? this.parentData.activeColor : '#2979ff');
+ },
+ // ���������������������������������
+ elInactiveColor() {
+ return this.inactiveColor ? this.inactiveColor : (this.parentData.inactiveColor ? this.parentData.inactiveColor :
+ '#c8c9cc');
+ },
+ // label���������
+ elLabelColor() {
+ return this.labelColor ? this.labelColor : (this.parentData.labelColor ? this.parentData.labelColor : '#606266')
+ },
+ // ���������������
+ elShape() {
+ return this.shape ? this.shape : (this.parentData.shape ? this.parentData.shape : 'circle');
+ },
+ // label������
+ elLabelSize() {
+ return uni.$u.addUnit(this.labelSize ? this.labelSize : (this.parentData.labelSize ? this.parentData.labelSize :
+ '15'))
+ },
+ elIconColor() {
+ const iconColor = this.iconColor ? this.iconColor : (this.parentData.iconColor ? this.parentData.iconColor :
+ '#ffffff');
+ // ���������������
+ if (this.elDisabled) {
+ // disabled������������������������radio������������elInactiveColor
+ return this.checked ? this.elInactiveColor : 'transparent'
+ } else {
+ return this.checked ? iconColor : 'transparent'
+ }
+ },
+ iconClasses() {
+ let classes = []
+ // ���������������
+ classes.push('u-radio__icon-wrap--' + this.elShape)
+ if (this.elDisabled) {
+ classes.push('u-radio__icon-wrap--disabled')
+ }
+ if (this.checked && this.elDisabled) {
+ classes.push('u-radio__icon-wrap--disabled--checked')
+ }
+ // ������������������������������������������������������������������������������������������������������","������������������
+ // #ifdef MP-ALIPAY || MP-TOUTIAO
+ classes = classes.join(' ')
+ // #endif
+ return classes
+ },
+ iconWrapStyle() {
+ // radio���������������
+ const style = {}
+ style.backgroundColor = this.checked && !this.elDisabled ? this.elActiveColor : '#ffffff'
+ style.borderColor = this.checked && !this.elDisabled ? this.elActiveColor : this.elInactiveColor
+ style.width = uni.$u.addUnit(this.elSize)
+ style.height = uni.$u.addUnit(this.elSize)
+ // ������������������������������������������������������
+ if (this.parentData.iconPlacement === 'right') {
+ style.marginRight = 0
+ }
+ return style
+ },
+ radioStyle() {
+ const style = {}
+ if(this.parentData.borderBottom && this.parentData.placement === 'row') {
+ uni.$u.error('���������������borderBottom���������true������������������u-radio-group���placement���������column���������')
+ }
+ // ���������������������������������������������������������������������������������������������������������������
+ if(this.parentData.borderBottom && this.parentData.placement === 'column') {
+ // ios������������������������������������������
+ style.paddingBottom = uni.$u.os() === 'ios' ? '12px' : '8px'
+ }
+ return uni.$u.deepMerge(style, uni.$u.addStyle(this.customStyle))
+ }
+ },
+ mounted() {
+ this.init()
+ },
+ methods: {
+ init() {
+ // ���������������������������provide/inject������������������������������������������������������created���������������������������
+ this.updateParentData()
+ if (!this.parent) {
+ uni.$u.error('u-radio������������u-radio-group������������')
+ }
+ // ������������������������������������������������
+ this.checked = this.name === this.parentData.value
+ },
+ updateParentData() {
+ this.getParentData('u-radio-group')
+ },
+ // ������������
+ iconClickHandler(e) {
+ this.preventEvent(e)
+ // ������������������������������������������
+ if (!this.elDisabled) {
+ this.setRadioCheckedStatus()
+ }
+ },
+ // ������������������������������������������������������������
+ wrapperClickHandler(e) {
+ this.parentData.iconPlacement === 'right' && this.iconClickHandler(e)
+ },
+ // ������label
+ labelClickHandler(e) {
+ this.preventEvent(e)
+ // ���������������������������������label������������������������������������������������
+ if (!this.elLabelDisabled && !this.elDisabled) {
+ this.setRadioCheckedStatus()
+ }
+ },
+ emitEvent() {
+ // u-radio���checked������true���(������������������)���������������������������������������������������
+ if (!this.checked) {
+ this.$emit('change', this.name)
+ // ������������u-form������������������������������������������������������������������������������������
+ this.$nextTick(() => {
+ uni.$u.formValidate(this, 'change')
+ })
+ }
+ },
+ // ������������������������
+ // ������������������������������������������������checked������true������������������������������������u-radio������
+ // ������������������������u-radio���checked������������false(������������������������)���������������������������������������
+ setRadioCheckedStatus() {
+ this.emitEvent()
+ // ���������������������������������
+ this.checked = true
+ typeof this.parent.unCheckedOther === 'function' && this.parent.unCheckedOther(this)
+ }
+ }
+ }
+</script>
+
+<style lang="scss" scoped>
+ @import "../../libs/css/components.scss";
+ $u-radio-wrap-margin-right:6px !default;
+ $u-radio-wrap-font-size:20px !default;
+ $u-radio-wrap-border-width:1px !default;
+ $u-radio-wrap-border-color: #c8c9cc !default;
+ $u-radio-line-height:0 !default;
+ $u-radio-circle-border-radius:100% !default;
+ $u-radio-square-border-radius:3px !default;
+ $u-radio-checked-color:#fff !default;
+ $u-radio-checked-background-color:red !default;
+ $u-radio-checked-border-color: #2979ff !default;
+ $u-radio-disabled-background-color:#ebedf0 !default;
+ $u-radio-disabled--checked-color:#c8c9cc !default;
+ $u-radio-label-margin-left: 5px !default;
+ $u-radio-label-margin-right:12px !default;
+ $u-radio-label-color:$u-content-color !default;
+ $u-radio-label-font-size:15px !default;
+ $u-radio-label-disabled-color:#c8c9cc !default;
+
+ .u-radio {
+ /* #ifndef APP-NVUE */
+ @include flex(row);
+ /* #endif */
+ overflow: hidden;
+ flex-direction: row;
+ align-items: center;
+
+ &-label--left {
+ flex-direction: row
+ }
+
+ &-label--right {
+ flex-direction: row-reverse;
+ justify-content: space-between
+ }
+
+ &__icon-wrap {
+ /* #ifndef APP-NVUE */
+ box-sizing: border-box;
+ // nvue������border-color���������������
+ transition-property: border-color, background-color, color;
+ transition-duration: 0.2s;
+ /* #endif */
+ color: $u-content-color;
+ @include flex;
+ align-items: center;
+ justify-content: center;
+ color: transparent;
+ text-align: center;
+ margin-right: $u-radio-wrap-margin-right;
+ font-size: $u-radio-wrap-font-size;
+ border-width: $u-radio-wrap-border-width;
+ border-color: $u-radio-wrap-border-color;
+ border-style: solid;
+
+ /* #ifdef MP-TOUTIAO */
+ // ������������������������������������������������������0���������������������
+ &__icon {
+ line-height: $u-radio-line-height;
+ }
+
+ /* #endif */
+
+ &--circle {
+ border-radius: $u-radio-circle-border-radius;
+ }
+
+ &--square {
+ border-radius: $u-radio-square-border-radius;
+ }
+
+ &--checked {
+ color: $u-radio-checked-color;
+ background-color: $u-radio-checked-background-color;
+ border-color: $u-radio-checked-border-color;
+ }
+
+ &--disabled {
+ background-color: $u-radio-disabled-background-color !important;
+ }
+
+ &--disabled--checked {
+ color: $u-radio-disabled--checked-color !important;
+ }
+ }
+
+ &__label {
+ /* #ifndef APP-NVUE */
+ word-wrap: break-word;
+ /* #endif */
+ margin-left: $u-radio-label-margin-left;
+ margin-right: $u-radio-label-margin-right;
+ color: $u-radio-label-color;
+ font-size: $u-radio-label-font-size;
+
+ &--disabled {
+ color: $u-radio-label-disabled-color;
+ }
+ }
+ }
+</style>
diff --git a/uni_modules/uview-ui/components/u-rate/props.js b/uni_modules/uview-ui/components/u-rate/props.js
new file mode 100644
index 0000000..2a56350
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-rate/props.js
@@ -0,0 +1,69 @@
+export default {
+ props: {
+ // ������v-model���������������������������������
+ value: {
+ type: [String, Number],
+ default: uni.$u.props.rate.value
+ },
+ // ������������������������
+ count: {
+ type: [String, Number],
+ default: uni.$u.props.rate.count
+ },
+ // ������������������
+ disabled: {
+ type: Boolean,
+ default: uni.$u.props.rate.disabled
+ },
+ // ������������
+ readonly: {
+ type: Boolean,
+ default: uni.$u.props.rate.readonly
+ },
+ // ������������������������px
+ size: {
+ type: [String, Number],
+ default: uni.$u.props.rate.size
+ },
+ // ���������������������
+ inactiveColor: {
+ type: String,
+ default: uni.$u.props.rate.inactiveColor
+ },
+ // ���������������
+ activeColor: {
+ type: String,
+ default: uni.$u.props.rate.activeColor
+ },
+ // ������������������������������px
+ gutter: {
+ type: [String, Number],
+ default: uni.$u.props.rate.gutter
+ },
+ // ������������������������������
+ minCount: {
+ type: [String, Number],
+ default: uni.$u.props.rate.minCount
+ },
+ // ������������������
+ allowHalf: {
+ type: Boolean,
+ default: uni.$u.props.rate.allowHalf
+ },
+ // ������������������(������)
+ activeIcon: {
+ type: String,
+ default: uni.$u.props.rate.activeIcon
+ },
+ // ���������������������(������)
+ inactiveIcon: {
+ type: String,
+ default: uni.$u.props.rate.inactiveIcon
+ },
+ // ������������������������������������������
+ touchable: {
+ type: Boolean,
+ default: uni.$u.props.rate.touchable
+ }
+ }
+}
diff --git a/uni_modules/uview-ui/components/u-rate/u-rate.vue b/uni_modules/uview-ui/components/u-rate/u-rate.vue
new file mode 100644
index 0000000..1aa5dd0
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-rate/u-rate.vue
@@ -0,0 +1,306 @@
+<template>
+ <view
+ class="u-rate"
+ :id="elId"
+ ref="u-rate"
+ :style="[$u.addStyle(customStyle)]"
+ >
+ <view
+ class="u-rate__content"
+ @touchmove.stop="touchMove"
+ @touchend.stop="touchEnd"
+ >
+ <view
+ class="u-rate__content__item"
+ v-for="(item, index) in Number(count)"
+ :key="index"
+ :class="[elClass]"
+ >
+ <view
+ class="u-rate__content__item__icon-wrap"
+ ref="u-rate__content__item__icon-wrap"
+ @tap.stop="clickHandler($event, index + 1)"
+ >
+ <u-icon
+ :name="
+ Math.floor(activeIndex) > index
+ ? activeIcon
+ : inactiveIcon
+ "
+ :color="
+ disabled
+ ? '#c8c9cc'
+ : Math.floor(activeIndex) > index
+ ? activeColor
+ : inactiveColor
+ "
+ :custom-style="{
+ 'padding-left': $u.addUnit(gutter / 2),
+ 'padding-right': $u.addUnit(gutter / 2)
+ }"
+ :size="size"
+ ></u-icon>
+ </view>
+ <view
+ v-if="allowHalf"
+ @tap.stop="clickHandler($event, index + 1)"
+ class="u-rate__content__item__icon-wrap u-rate__content__item__icon-wrap--half"
+ :style="[{
+ width: $u.addUnit(rateWidth / 2),
+ }]"
+ ref="u-rate__content__item__icon-wrap"
+ >
+ <u-icon
+ :name="
+ Math.ceil(activeIndex) > index
+ ? activeIcon
+ : inactiveIcon
+ "
+ :color="
+ disabled
+ ? '#c8c9cc'
+ : Math.ceil(activeIndex) > index
+ ? activeColor
+ : inactiveColor
+ "
+ :custom-style="{
+ 'padding-left': $u.addUnit(gutter / 2),
+ 'padding-right': $u.addUnit(gutter / 2)
+ }"
+ :size="size"
+ ></u-icon>
+ </view>
+ </view>
+ </view>
+ </view>
+</template>
+
+<script>
+ import props from './props.js';
+
+ // #ifdef APP-NVUE
+ const dom = weex.requireModule("dom");
+ // #endif
+ /**
+ * rate ������
+ * @description ������������������������������������������������������������
+ * @tutorial https://www.uviewui.com/components/rate.html
+ * @property {String | Number} value ������v-model��������������������������������� (������ 1 )
+ * @property {String | Number} count ��������������������������� ��������� 5 ���
+ * @property {Boolean} disabled ������������������������ ��������� false ���
+ * @property {Boolean} readonly ������������ ��������� false ���
+ * @property {String | Number} size ������������������������px ��������� 18 ���
+ * @property {String} inactiveColor ������������������������ ��������� '#b2b2b2' ���
+ * @property {String} activeColor ��������������������� ��������� '#FA3534' ���
+ * @property {String | Number} gutter ��������������������� ��������� 4 ���
+ * @property {String | Number} minCount ��������������������������� ��������� 1 ���
+ * @property {Boolean} allowHalf ������������������������ ��������� false ���
+ * @property {String} activeIcon ���������������������������������uView��������������� ��������� 'star-fill' ���
+ * @property {String} inactiveIcon ������������������������������������uView��������������� ��������� 'star' ���
+ * @property {Boolean} touchable ������������������������������������������ ��������� 'true' ���
+ * @property {Object} customStyle ������������������������������
+ * @event {Function} change ������������������������������������
+ * @example <u-rate :count="count" :value="2"></u-rate>
+ */
+ export default {
+ name: "u-rate",
+ mixins: [uni.$u.mpMixin, uni.$u.mixin,props],
+ data() {
+ return {
+ // ������������������id���������������������������������������������������������
+ elId: uni.$u.guid(),
+ elClass: uni.$u.guid(),
+ rateBoxLeft: 0, // ������������������������������������������������������������������������������
+ activeIndex: this.value,
+ rateWidth: 0, // ���������������������
+ // ���������������������������������iOS���������touch���click������������������������������������������������������click������������������������������
+ moving: false,
+ };
+ },
+ watch: {
+ value(val) {
+ this.activeIndex = val;
+ },
+ activeIndex: 'emitEvent'
+ },
+ methods: {
+ init() {
+ uni.$u.sleep().then(() => {
+ this.getRateItemRect();
+ this.getRateIconWrapRect();
+ })
+ },
+ // ���������������������������������������
+ async getRateItemRect() {
+ await uni.$u.sleep();
+ // uView���������������������������������������������
+ // #ifndef APP-NVUE
+ this.$uGetRect("#" + this.elId).then((res) => {
+ this.rateBoxLeft = res.left;
+ });
+ // #endif
+ // #ifdef APP-NVUE
+ dom.getComponentRect(this.$refs["u-rate"], (res) => {
+ this.rateBoxLeft = res.size.left;
+ });
+ // #endif
+ },
+ // ���������������������������
+ getRateIconWrapRect() {
+ // uView���������������������������������������������
+ // #ifndef APP-NVUE
+ this.$uGetRect("." + this.elClass).then((res) => {
+ this.rateWidth = res.width;
+ });
+ // #endif
+ // #ifdef APP-NVUE
+ dom.getComponentRect(
+ this.$refs["u-rate__content__item__icon-wrap"][0],
+ (res) => {
+ this.rateWidth = res.size.width;
+ }
+ );
+ // #endif
+ },
+ // ������������
+ touchMove(e) {
+ // ���������������������������������������������
+ if (!this.touchable) {
+ return;
+ }
+ this.preventEvent(e);
+ const x = e.changedTouches[0].pageX;
+ this.getActiveIndex(x);
+ },
+ // ������������
+ touchEnd(e) {
+ // ���������������������������������������������
+ if (!this.touchable) {
+ return;
+ }
+ this.preventEvent(e);
+ const x = e.changedTouches[0].pageX;
+ this.getActiveIndex(x);
+ },
+ // ���������������������������
+ clickHandler(e, index) {
+ // ios������moving������������������������
+ if (uni.$u.os() === "ios" && this.moving) {
+ return;
+ }
+ this.preventEvent(e);
+ let x = 0;
+ // ���������������nvue������������������������������������������������������������������������
+ // #ifndef APP-NVUE
+ x = e.changedTouches[0].pageX;
+ // #endif
+ // #ifdef APP-NVUE
+ // nvue���������������������������������������������������������������������������������������������
+ x = index * this.rateWidth + this.rateBoxLeft;
+ // #endif
+ this.getActiveIndex(x,true);
+ },
+ // ������������
+ emitEvent() {
+ // ������change������
+ this.$emit("change", this.activeIndex);
+ // ���������������������������value������
+ this.$emit("input", this.activeIndex);
+ },
+ // ���������������������������������
+ getActiveIndex(x,isClick = false) {
+ if (this.disabled || this.readonly) {
+ return;
+ }
+ // ���������������������������x���������������������������������������������
+ const allRateWidth = this.rateWidth * this.count + this.rateBoxLeft;
+ // ������������������������������������������������������������������������������������������������������������������������
+ x = uni.$u.range(this.rateBoxLeft, allRateWidth, x) - this.rateBoxLeft
+ // ���������������������������������������������
+ const distance = x;
+ // ������������������������������������������
+ let index;
+ // ������������������������
+ if (this.allowHalf) {
+ index = Math.floor(distance / this.rateWidth);
+ // ������������������������������������
+ const decimal = distance % this.rateWidth;
+ if (decimal <= this.rateWidth / 2 && decimal > 0) {
+ index += 0.5;
+ } else if (decimal > this.rateWidth / 2) {
+ index++;
+ }
+ } else {
+ index = Math.floor(distance / this.rateWidth);
+ // ������������������������������������
+ const decimal = distance % this.rateWidth;
+ // ������������������������������������������������������������������������������������
+ if (isClick){
+ if (decimal > 0) index++;
+ } else {
+ if (decimal > this.rateWidth / 2) index++;
+ }
+
+ }
+ this.activeIndex = Math.min(index, this.count);
+ // ���������������������������
+ if (this.activeIndex < this.minCount) {
+ this.activeIndex = this.minCount;
+ }
+
+ // ���������������������click���������touchmove������������
+ setTimeout(() => {
+ this.moving = true;
+ }, 10);
+ // ���������������������������������������������������������������click������������
+ setTimeout(() => {
+ this.moving = false;
+ }, 10);
+ },
+ },
+ mounted() {
+ this.init();
+ },
+ };
+</script>
+
+<style lang="scss" scoped>
+@import "../../libs/css/components.scss";
+$u-rate-margin: 0 !default;
+$u-rate-padding: 0 !default;
+$u-rate-item-icon-wrap-half-top: 0 !default;
+$u-rate-item-icon-wrap-half-left: 0 !default;
+
+.u-rate {
+ @include flex;
+ align-items: center;
+ margin: $u-rate-margin;
+ padding: $u-rate-padding;
+ /* #ifndef APP-NVUE */
+ touch-action: none;
+ /* #endif */
+
+ &__content {
+ @include flex;
+
+ &__item {
+ position: relative;
+
+ &__icon-wrap {
+ &--half {
+ position: absolute;
+ overflow: hidden;
+ top: $u-rate-item-icon-wrap-half-top;
+ left: $u-rate-item-icon-wrap-half-left;
+ }
+ }
+ }
+ }
+}
+
+.u-icon {
+ /* #ifndef APP-NVUE */
+ box-sizing: border-box;
+ /* #endif */
+}
+</style>
diff --git a/uni_modules/uview-ui/components/u-read-more/props.js b/uni_modules/uview-ui/components/u-read-more/props.js
new file mode 100644
index 0000000..b444e74
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-read-more/props.js
@@ -0,0 +1,61 @@
+export default {
+ props: {
+ // ���������������������������
+ showHeight: {
+ type: [String, Number],
+ default: uni.$u.props.readMore.showHeight
+ },
+ // ���������������������"������"������
+ toggle: {
+ type: Boolean,
+ default: uni.$u.props.readMore.toggle
+ },
+ // ������������������������
+ closeText: {
+ type: String,
+ default: uni.$u.props.readMore.closeText
+ },
+ // ������������������������
+ openText: {
+ type: String,
+ default: uni.$u.props.readMore.openText
+ },
+ // ���������������������
+ color: {
+ type: String,
+ default: uni.$u.props.readMore.color
+ },
+ // ���������������������
+ fontSize: {
+ type: [String, Number],
+ default: uni.$u.props.readMore.fontSize
+ },
+ // ������������������
+ // ���������������������props/readMore.js���������������������������������������������������������������js���
+ // uni������������������������������������nvue���������nvue���
+ shadowStyle: {
+ type: Object,
+ default: () => ({
+ // #ifndef APP-NVUE
+ backgroundImage: 'linear-gradient(-180deg, rgba(255, 255, 255, 0) 0%, #fff 80%)',
+ // #endif
+ // #ifdef APP-NVUE
+ // nvue���������������������������backgroundImage������
+ backgroundImage: 'linear-gradient(to top, #fff, rgba(255, 255, 255, 0.5))',
+ // #endif
+ paddingTop: '100px',
+ marginTop: '-100px'
+ })
+ },
+ // ���������������������������������
+ textIndent: {
+ type: String,
+ default: uni.$u.props.readMore.textIndent
+ },
+ // open���close������������������������������������������������
+ name: {
+ type: [String, Number],
+ default: uni.$u.props.readMore.name
+ }
+ }
+}
diff --git a/uni_modules/uview-ui/components/u-read-more/u-read-more.vue b/uni_modules/uview-ui/components/u-read-more/u-read-more.vue
new file mode 100644
index 0000000..9104e40
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-read-more/u-read-more.vue
@@ -0,0 +1,157 @@
+<template>
+ <view class="u-read-more">
+ <view
+ class="u-read-more__content"
+ :style="{
+ height: isLongContent && status === 'close' ? $u.addUnit(showHeight) : $u.addUnit(contentHeight),
+ textIndent: textIndent
+ }"
+ >
+ <view
+ class="u-read-more__content__inner"
+ ref="u-read-more__content__inner"
+ :class="[elId]"
+ >
+ <slot></slot>
+ </view>
+ </view>
+ <view
+ class="u-read-more__toggle"
+ :style="[innerShadowStyle]"
+ v-if="isLongContent"
+ >
+ <slot name="toggle">
+ <view
+ class="u-read-more__toggle__text"
+ @tap="toggleReadMore"
+ >
+ <u--text
+ :text="status === 'close' ? closeText : openText"
+ :color="color"
+ :size="fontSize"
+ :lineHeight="fontSize"
+ margin="0 5px 0 0"
+ ></u--text>
+ <view class="u-read-more__toggle__icon">
+ <u-icon
+ :color="color"
+ :size="fontSize + 2"
+ :name="status === 'close' ? 'arrow-down' : 'arrow-up'"
+ ></u-icon>
+ </view>
+ </view>
+ </slot>
+ </view>
+ </view>
+</template>
+
+<script>
+ // #ifdef APP-NVUE
+ const dom = uni.requireNativePlugin('dom')
+ // #endif
+ import props from './props.js';
+ /**
+ * readMore ������������
+ * @description ������������������������������������������������������������������������������������������������
+ * @tutorial https://www.uviewui.com/components/readMore.html
+ * @property {String | Number} showHeight ������������������������������������������������������������px��������� 400 ���
+ * @property {Boolean} toggle ������������������������������������������ false ���
+ * @property {String} closeText ��������������������������������� '������������������' ���
+ * @property {String} openText ��������������������������������� '������' ���
+ * @property {String} color ������������������������������ '#2979ff' ���
+ * @property {String | Number} fontSize ������������������������������px ��������� 14 ���
+ * @property {Object} shadowStyle ���������������������
+ * @property {String} textIndent ��������������������������������� ��������� '2em' ���
+ * @property {String | Number} name ��������� open ��� close ���������������������������������
+ * @event {Function} open ������������������������
+ * @event {Function} close ������������������������
+ * @example <u-read-more><rich-text :nodes="content"></rich-text></u-read-more>
+ */
+ export default {
+ name: 'u-read-more',
+ mixins: [uni.$u.mpMixin, uni.$u.mixin, props],
+ data() {
+ return {
+ isLongContent: false, // ���������������������������������
+ status: 'close', // ���������������������������������close-���������������open-������������
+ elId: uni.$u.guid(), // ������������class
+ contentHeight: 100, // ������������
+ }
+ },
+ computed: {
+ // ������������������������������������������������������
+ innerShadowStyle() {
+ if (this.status === 'open') return {}
+ else return this.shadowStyle
+ }
+ },
+ mounted() {
+ this.init()
+ },
+ methods: {
+ async init() {
+ this.getContentHeight().then(height => {
+ this.contentHeight = height
+ // ���������������������������������������������������������������������������������������������������
+ if (height > uni.$u.getPx(this.showHeight)) {
+ this.isLongContent = true
+ this.status = 'close'
+ }
+ })
+ },
+ // ���������������������
+ async getContentHeight() {
+ // ���������������������������������
+ await uni.$u.sleep(30)
+ return new Promise(resolve => {
+ // #ifndef APP-NVUE
+ this.$uGetRect('.' + this.elId).then(res => {
+ resolve(res.height)
+ })
+ // #endif
+
+ // #ifdef APP-NVUE
+ const ref = this.$refs['u-read-more__content__inner']
+ dom.getComponentRect(ref, (res) => {
+ resolve(res.size.height)
+ })
+ // #endif
+ })
+ },
+ // ������������������
+ toggleReadMore() {
+ this.status = this.status === 'close' ? 'open' : 'close'
+ // ������toggle���false���������"������"���������������
+ if (this.toggle == false) this.isLongContent = false
+ // ���������������������������������
+ this.$emit(this.status, this.name)
+ }
+ }
+ }
+</script>
+
+<style lang="scss" scoped>
+@import "../../libs/css/components.scss";
+
+.u-read-more {
+
+ &__content {
+ overflow: hidden;
+ color: $u-content-color;
+ font-size: 15px;
+ text-align: left;
+ }
+
+ &__toggle {
+ @include flex;
+ justify-content: center;
+
+ &__text {
+ @include flex;
+ align-items: center;
+ justify-content: center;
+ margin-top: 5px;
+ }
+ }
+}
+</style>
diff --git a/uni_modules/uview-ui/components/u-row-notice/props.js b/uni_modules/uview-ui/components/u-row-notice/props.js
new file mode 100644
index 0000000..107bd70
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-row-notice/props.js
@@ -0,0 +1,39 @@
+export default {
+ props: {
+ // ���������������������������
+ text: {
+ type: String,
+ default: uni.$u.props.rowNotice.text
+ },
+ // ���������������������������������
+ icon: {
+ type: String,
+ default: uni.$u.props.rowNotice.icon
+ },
+ // ���������������link-������������������closable-������������������������
+ mode: {
+ type: String,
+ default: uni.$u.props.rowNotice.mode
+ },
+ // ������������������������������������������������
+ color: {
+ type: String,
+ default: uni.$u.props.rowNotice.color
+ },
+ // ������������
+ bgColor: {
+ type: String,
+ default: uni.$u.props.rowNotice.bgColor
+ },
+ // ���������������������px
+ fontSize: {
+ type: [String, Number],
+ default: uni.$u.props.rowNotice.fontSize
+ },
+ // ������������������������������������������������������px(rpx)���������������������������������������������������������������������������
+ speed: {
+ type: [String, Number],
+ default: uni.$u.props.rowNotice.speed
+ }
+ }
+}
diff --git a/uni_modules/uview-ui/components/u-row-notice/u-row-notice.vue b/uni_modules/uview-ui/components/u-row-notice/u-row-notice.vue
new file mode 100644
index 0000000..20f43c3
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-row-notice/u-row-notice.vue
@@ -0,0 +1,330 @@
+<template>
+ <view
+ class="u-notice"
+ @tap="clickHandler"
+ >
+ <slot name="icon">
+ <view
+ class="u-notice__left-icon"
+ v-if="icon"
+ >
+ <u-icon
+ :name="icon"
+ :color="color"
+ size="19"
+ ></u-icon>
+ </view>
+ </slot>
+ <view
+ class="u-notice__content"
+ ref="u-notice__content"
+ >
+ <view
+ ref="u-notice__content__text"
+ class="u-notice__content__text"
+ :style="[animationStyle]"
+ >
+ <text
+ v-for="(item, index) in innerText"
+ :key="index"
+ :style="[textStyle]"
+ >{{item}}</text>
+ </view>
+ </view>
+ <view
+ class="u-notice__right-icon"
+ v-if="['link', 'closable'].includes(mode)"
+ >
+ <u-icon
+ v-if="mode === 'link'"
+ name="arrow-right"
+ :size="17"
+ :color="color"
+ ></u-icon>
+ <u-icon
+ v-if="mode === 'closable'"
+ @click="close"
+ name="close"
+ :size="16"
+ :color="color"
+ ></u-icon>
+ </view>
+ </view>
+</template>
+<script>
+ import props from './props.js';
+ // #ifdef APP-NVUE
+ const animation = uni.requireNativePlugin('animation')
+ const dom = uni.requireNativePlugin('dom')
+ // #endif
+ /**
+ * RowNotice ������������������������������������
+ * @description ������������
+ * @tutorial https://www.uviewui.com/components/noticeBar.html
+ * @property {String | Number} text ���������������������������
+ * @property {String} icon ��������������������������������� (������ 'volume' )
+ * @property {String} mode ���������������link-������������������closable-������������������������
+ * @property {String} color ������������������������������������������������ (������ '#f9ae3d' )
+ * @property {String} bgColor ������������ (������ ''#fdf6ec' )
+ * @property {String | Number} fontSize ���������������������px (������ 14 )
+ * @property {String | Number} speed ������������������������������������������������������px(rpx)��������������������������������������������������������������������������� (������ 80 )
+ *
+ * @event {Function} click ������������������������
+ * @event {Function} close ������������������������������
+ * @example
+ */
+ export default {
+ name: 'u-row-notice',
+ mixins: [uni.$u.mpMixin, uni.$u.mixin,props],
+ data() {
+ return {
+ animationDuration: '0', // ������������������
+ animationPlayState: 'paused', // ������������������������������
+ // nvue������������������������������������������������������������������������������������������������������
+ // ���������������������������������������������������nvue���animation���������������������������������������������������������
+ nvueInit: true,
+ show: true
+ };
+ },
+ watch: {
+ text: {
+ immediate: true,
+ handler(newValue, oldValue) {
+ // #ifdef APP-NVUE
+ this.nvueInit = true
+ // #endif
+ // #ifndef APP-NVUE
+ this.vue()
+ // #endif
+
+ if(!uni.$u.test.string(newValue)) {
+ uni.$u.error('noticebar������direction���row������������text������������������������')
+ }
+ }
+ },
+ fontSize() {
+ // #ifdef APP-NVUE
+ this.nvueInit = true
+ // #endif
+ // #ifndef APP-NVUE
+ this.vue()
+ // #endif
+ },
+ speed() {
+ // #ifdef APP-NVUE
+ this.nvueInit = true
+ // #endif
+ // #ifndef APP-NVUE
+ this.vue()
+ // #endif
+ }
+ },
+ computed: {
+ // ���������������������
+ textStyle() {
+ let style = {}
+ style.color = this.color
+ style.fontSize = uni.$u.addUnit(this.fontSize)
+ return style
+ },
+ animationStyle() {
+ let style = {}
+ style.animationDuration = this.animationDuration
+ style.animationPlayState = this.animationPlayState
+ return style
+ },
+ // ������������������������������������������������������������text������������������������������������������������������������100������������������
+ // ������������text���������������������������������������������������������������������������������������������������������text���������������������
+ innerText() {
+ let result = [],
+ // ������text���������������������
+ len = 20
+ const textArr = this.text.split('')
+ for (let i = 0; i < textArr.length; i += len) {
+ // ������������������text������slice������������������������������������join������������������
+ result.push(textArr.slice(i, i + len).join(''))
+ }
+ return result
+ }
+ },
+ mounted() {
+ // #ifdef APP-PLUS
+ // ���APP���(���nvue)���������������webview������������������������(������������������������hide������)
+ // ������webivew������������������������������������������������������������������������������������������������������������������������������������������������
+ var pages = getCurrentPages()
+ var page = pages[pages.length - 1]
+ var currentWebview = page.$getAppWebview()
+ currentWebview.addEventListener('hide', () => {
+ this.webviewHide = true
+ })
+ currentWebview.addEventListener('show', () => {
+ this.webviewHide = false
+ })
+ // #endif
+
+ this.init()
+ },
+ methods: {
+ init() {
+ // #ifdef APP-NVUE
+ this.nvue()
+ // #endif
+
+ // #ifndef APP-NVUE
+ this.vue()
+ // #endif
+
+ if(!uni.$u.test.string(this.text)) {
+ uni.$u.error('noticebar������direction���row������������text������������������������')
+ }
+ },
+ // vue���������
+ async vue() {
+ // #ifndef APP-NVUE
+ let boxWidth = 0,
+ textWidth = 0
+ // ���������������������
+ await uni.$u.sleep()
+ // ������������������������������
+ textWidth = (await this.$uGetRect('.u-notice__content__text')).width
+ boxWidth = (await this.$uGetRect('.u-notice__content')).width
+ // ������t=s/v(������=������/������)������������������������������#u-notice-box������������������������������.u-notice-content������������������padding-left: 100%
+ // ���������������������������������������������#u-notice-box���������
+ this.animationDuration = `${textWidth / uni.$u.getPx(this.speed)}s`
+ // ������������������������������������������APP���������������������������
+ this.animationPlayState = 'paused'
+ setTimeout(() => {
+ this.animationPlayState = 'running'
+ }, 10)
+ // #endif
+ },
+ // nvue���������
+ async nvue() {
+ // #ifdef APP-NVUE
+ this.nvueInit = false
+ let boxWidth = 0,
+ textWidth = 0
+ // ���������������������
+ await uni.$u.sleep()
+ // ������������������������������
+ textWidth = (await this.getNvueRect('u-notice__content__text')).width
+ boxWidth = (await this.getNvueRect('u-notice__content')).width
+ // ���������������������������������������������������������������������������nvue���������100%���������������������������css������
+ animation.transition(this.$refs['u-notice__content__text'], {
+ styles: {
+ transform: `translateX(${boxWidth}px)`
+ },
+ }, () => {
+ // ���������������������������������������
+ !this.stopAnimation && this.loopAnimation(textWidth, boxWidth)
+ });
+ // #endif
+ },
+ loopAnimation(textWidth, boxWidth) {
+ // #ifdef APP-NVUE
+ animation.transition(this.$refs['u-notice__content__text'], {
+ styles: {
+ // ���������������������-textWidth���������������������������������������������������������������
+ transform: `translateX(-${textWidth}px)`
+ },
+ // ��������������������������������� = ������(boxWidth + textWidth) / ���������������������������
+ duration: (boxWidth + textWidth) / uni.$u.getPx(this.speed) * 1000,
+ delay: 10
+ }, () => {
+ animation.transition(this.$refs['u-notice__content__text'], {
+ styles: {
+ // ������������������������������������������
+ transform: `translateX(${this.stopAnimation ? 0 : boxWidth}px)`
+ },
+ }, () => {
+ // ������������������������������������������������
+ if (!this.stopAnimation) {
+ // ���������������������������������������
+ if (this.nvueInit) {
+ this.nvue()
+ } else {
+ this.loopAnimation(textWidth, boxWidth)
+ }
+ }
+ });
+ })
+ // #endif
+ },
+ getNvueRect(el) {
+ // #ifdef APP-NVUE
+ // ������������promise
+ return new Promise(resolve => {
+ dom.getComponentRect(this.$refs[el], (res) => {
+ resolve(res.size)
+ })
+ })
+ // #endif
+ },
+ // ���������������
+ clickHandler(index) {
+ this.$emit('click')
+ },
+ // ���������������������������������������������������������������������������
+ close() {
+ this.$emit('close')
+ }
+ },
+ // #ifdef APP-NVUE
+ beforeDestroy() {
+ this.stopAnimation = true
+ },
+ // #endif
+ };
+</script>
+
+<style lang="scss" scoped>
+ @import "../../libs/css/components.scss";
+
+ .u-notice {
+ @include flex;
+ align-items: center;
+ justify-content: space-between;
+
+ &__left-icon {
+ align-items: center;
+ margin-right: 5px;
+ }
+
+ &__right-icon {
+ margin-left: 5px;
+ align-items: center;
+ }
+
+ &__content {
+ text-align: right;
+ flex: 1;
+ @include flex;
+ flex-wrap: nowrap;
+ overflow: hidden;
+
+ &__text {
+ font-size: 14px;
+ color: $u-warning;
+ /* #ifndef APP-NVUE */
+ // ���������������������������������������������������������
+ padding-left: 100%;
+ word-break: keep-all;
+ white-space: nowrap;
+ animation: u-loop-animation 10s linear infinite both;
+ /* #endif */
+ @include flex(row);
+ }
+ }
+
+ }
+
+ @keyframes u-loop-animation {
+ 0% {
+ transform: translate3d(0, 0, 0);
+ }
+
+ 100% {
+ transform: translate3d(-100%, 0, 0);
+ }
+ }
+</style>
diff --git a/uni_modules/uview-ui/components/u-row/props.js b/uni_modules/uview-ui/components/u-row/props.js
new file mode 100644
index 0000000..4b71b87
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-row/props.js
@@ -0,0 +1,19 @@
+export default {
+ props: {
+ // ���col���������������������������������������
+ gutter: {
+ type: [String, Number],
+ default: uni.$u.props.row.gutter
+ },
+ // ���������������������������������`start`(���`flex-start`)���`end`(���`flex-end`)���`center`���`around`(���`space-around`)���`between`(���`space-between`)
+ justify: {
+ type: String,
+ default: uni.$u.props.row.justify
+ },
+ // ���������������������������������top���center���bottom
+ align: {
+ type: String,
+ default: uni.$u.props.row.align
+ }
+ }
+}
diff --git a/uni_modules/uview-ui/components/u-row/u-row.vue b/uni_modules/uview-ui/components/u-row/u-row.vue
new file mode 100644
index 0000000..e608fc5
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-row/u-row.vue
@@ -0,0 +1,93 @@
+<template>
+ <view
+ class="u-row"
+ ref="u-row"
+ :style="[rowStyle]"
+ @tap="clickHandler"
+ >
+ <slot />
+ </view>
+</template>
+
+<script>
+ // #ifdef APP-NVUE
+ const dom = uni.requireNativePlugin('dom')
+ // #endif
+ import props from './props.js';
+ /**
+ * Row ���������������������
+ * @description ��������������� 12 ������������������������������������
+ * @tutorial https://www.uviewui.com/components/layout.html
+ * @property {String | Number} gutter ���������������������������������������������������px (������ 0 )
+ * @property {String} justify ������������������(���������������������������) ������������`start`(���`flex-start`)���`end`(���`flex-end`)���`center`���`around`(���`space-around`)���`between`(���`space-between`) (������ 'start' )
+ * @property {String} align ������������������ (������ 'center' )
+ * @property {Object} customStyle ���������������������������������
+ *
+ * @event {Function} click row���������
+ * @example <u-row justify="space-between" customStyle="margin-bottom: 10px"></u-row>
+ */
+ export default {
+ name: "u-row",
+ mixins: [uni.$u.mpMixin, uni.$u.mixin, props],
+ data() {
+ return {
+
+ }
+ },
+ computed: {
+ uJustify() {
+ if (this.justify == 'end' || this.justify == 'start') return 'flex-' + this.justify
+ else if (this.justify == 'around' || this.justify == 'between') return 'space-' + this.justify
+ else return this.justify
+ },
+ uAlignItem() {
+ if (this.align == 'top') return 'flex-start'
+ if (this.align == 'bottom') return 'flex-end'
+ else return this.align
+ },
+ rowStyle() {
+ const style = {
+ alignItems: this.uAlignItem,
+ justifyContent: this.uJustify
+ }
+ // ���������u-row������������������������������������u-col������gutter���������������������������������������������������������������������������������
+ if(this.gutter) {
+ style.marginLeft = uni.$u.addUnit(-Number(this.gutter)/2)
+ style.marginRight = uni.$u.addUnit(-Number(this.gutter)/2)
+ }
+ return uni.$u.deepMerge(style, uni.$u.addStyle(this.customStyle))
+ }
+ },
+ methods: {
+ clickHandler(e) {
+ this.$emit('click')
+ },
+ async getComponentWidth() {
+ // ������������������������������������������������
+ await uni.$u.sleep()
+ return new Promise(resolve => {
+ // uView���������������������������������������������
+ // #ifndef APP-NVUE
+ this.$uGetRect('.u-row').then(res => {
+ resolve(res.width)
+ })
+ // #endif
+ // #ifdef APP-NVUE
+ // nvue���dom������������������������
+ dom.getComponentRect(this.$refs['u-row'], (res) => {
+ resolve(res.size.width)
+ })
+ // #endif
+ })
+ },
+ }
+ }
+</script>
+
+<style lang="scss" scoped>
+ @import "../../libs/css/components.scss";
+
+ .u-row {
+ @include flex;
+ }
+</style>
diff --git a/uni_modules/uview-ui/components/u-safe-bottom/props.js b/uni_modules/uview-ui/components/u-safe-bottom/props.js
new file mode 100644
index 0000000..7c11331
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-safe-bottom/props.js
@@ -0,0 +1,5 @@
+export default {
+ props: {
+
+ }
+}
diff --git a/uni_modules/uview-ui/components/u-safe-bottom/u-safe-bottom.vue b/uni_modules/uview-ui/components/u-safe-bottom/u-safe-bottom.vue
new file mode 100644
index 0000000..fb858ea
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-safe-bottom/u-safe-bottom.vue
@@ -0,0 +1,56 @@
+<template>
+ <view
+ class="u-safe-bottom"
+ :style="[style]"
+ :class="[!isNvue && 'u-safe-area-inset-bottom']"
+ >
+ </view>
+</template>
+
+<script>
+ import props from "./props.js";
+ /**
+ * SafeBottom ���������������
+ * @description ������������������������������IPhone X���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������
+ * @tutorial https://www.uviewui.com/components/safeAreaInset.html
+ * @property {type} prop_name
+ * @property {Object} customStyle ���������������������������������
+ *
+ * @event {Function()}
+ * @example <u-status-bar></u-status-bar>
+ */
+ export default {
+ name: "u-safe-bottom",
+ mixins: [uni.$u.mpMixin, uni.$u.mixin, props],
+ data() {
+ return {
+ safeAreaBottomHeight: 0,
+ isNvue: false,
+ };
+ },
+ computed: {
+ style() {
+ const style = {};
+ // #ifdef APP-NVUE
+ // nvue������������������js������������
+ style.height = uni.$u.addUnit(uni.$u.sys().safeAreaInsets.bottom, 'px');
+ // #endif
+ return uni.$u.deepMerge(style, uni.$u.addStyle(this.customStyle));
+ },
+ },
+ mounted() {
+ // #ifdef APP-NVUE
+ // ���������������nvue
+ this.isNvue = true;
+ // #endif
+ },
+ };
+</script>
+
+<style lang="scss" scoped>
+ .u-safe-bottom {
+ /* #ifndef APP-NVUE */
+ width: 100%;
+ /* #endif */
+ }
+</style>
diff --git a/uni_modules/uview-ui/components/u-scroll-list/nvue.js b/uni_modules/uview-ui/components/u-scroll-list/nvue.js
new file mode 100644
index 0000000..94bb056
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-scroll-list/nvue.js
@@ -0,0 +1,28 @@
+// ������bindingx���������������������������������wxs���������������js���������������������������������������������������������������
+const BindingX = uni.requireNativePlugin('bindingx')
+
+export default {
+ methods: {
+ // ������������������������������������
+ nvueScrollHandler(e) {
+ const anchor = this.$refs['u-scroll-list__scroll-view'].ref
+ const element = this.$refs['u-scroll-list__indicator__line__bar'].ref
+ const scrollLeft = e.contentOffset.x
+ const contentSize = e.contentSize.width
+ const { scrollWidth } = this
+ const barAllMoveWidth = this.indicatorWidth - this.indicatorBarWidth
+ // ������������iOS������������������������������������iOS������������2
+ const actionNum = uni.$u.os() === 'ios' ? 2 : 1
+ const expression = `(x / ${actionNum}) / ${contentSize - scrollWidth} * ${barAllMoveWidth}`
+ BindingX.bind({
+ anchor,
+ eventType: 'scroll',
+ props: [{
+ element,
+ property: 'transform.translateX',
+ expression
+ }]
+ })
+ }
+ }
+}
diff --git a/uni_modules/uview-ui/components/u-scroll-list/other.js b/uni_modules/uview-ui/components/u-scroll-list/other.js
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-scroll-list/other.js
diff --git a/uni_modules/uview-ui/components/u-scroll-list/props.js b/uni_modules/uview-ui/components/u-scroll-list/props.js
new file mode 100644
index 0000000..765be54
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-scroll-list/props.js
@@ -0,0 +1,34 @@
+export default {
+ props: {
+ // ������������������������
+ indicatorWidth: {
+ type: [String, Number],
+ default: uni.$u.props.scrollList.indicatorWidth
+ },
+ // ���������������
+ indicatorBarWidth: {
+ type: [String, Number],
+ default: uni.$u.props.scrollList.indicatorBarWidth
+ },
+ // ���������������������������
+ indicator: {
+ type: Boolean,
+ default: uni.$u.props.scrollList.indicator
+ },
+ // ������������������������
+ indicatorColor: {
+ type: String,
+ default: uni.$u.props.scrollList.indicatorColor
+ },
+ // ������������������������
+ indicatorActiveColor: {
+ type: String,
+ default: uni.$u.props.scrollList.indicatorActiveColor
+ },
+ // ���������������������������bottom���left���right������������
+ indicatorStyle: {
+ type: [String, Object],
+ default: uni.$u.props.scrollList.indicatorStyle
+ }
+ }
+}
diff --git a/uni_modules/uview-ui/components/u-scroll-list/scrollWxs.wxs b/uni_modules/uview-ui/components/u-scroll-list/scrollWxs.wxs
new file mode 100644
index 0000000..ce94f1d
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-scroll-list/scrollWxs.wxs
@@ -0,0 +1,50 @@
+function scroll(event, ownerInstance) {
+ // detail���������scroll-view������������������scroll-view���������������������������������scroll-view������������������
+ var detail = event.detail
+ var scrollWidth = detail.scrollWidth
+ var scrollLeft = detail.scrollLeft
+ // ���������������������dataset������������������������������������xun���������������ji
+ var dataset = event.currentTarget.dataset
+ // ������scroll-view���������������������������
+ // ������HX������(3.1.18)���������view������������������data-scrollWidth������wxs������������������������������������������������������������
+ var scrollComponentWidth = dataset.scrollWidth || dataset.scrollwidth || 0
+ // ���������������������������
+ var indicatorWidth = dataset.indicatorWidth || dataset.indicatorwidth || 0
+ var barWidth = dataset.barWidth || dataset.barwidth || 0
+ // ���������������������������scroll-view������������������������������������(scroll-view������������������������������������������)������������������������������������������������
+ // ������������(���������������������������������������)���������
+ var x = scrollLeft / (scrollWidth - scrollComponentWidth) * (indicatorWidth - barWidth)
+ setBarStyle(ownerInstance, x)
+}
+
+// ������webview������������������������scroll-view���������������������������������scroll������������������
+// ������������������������������������������������������������������������������������������������������������������������������������������������������������
+// ������������������������������������������������
+function scrolltolower(event, ownerInstance) {
+ ownerInstance.callMethod('scrollEvent', 'right')
+ // ���������������������dataset
+ var dataset = event.currentTarget.dataset
+ // ���������������������������
+ var indicatorWidth = dataset.indicatorWidth || dataset.indicatorwidth || 0
+ var barWidth = dataset.barWidth || dataset.barwidth || 0
+ // scroll-view������������������������������������������������������������������������������������������������������������������ - ������������
+ setBarStyle(ownerInstance, indicatorWidth - barWidth)
+}
+
+function scrolltoupper(event, ownerInstance) {
+ ownerInstance.callMethod('scrollEvent', 'left')
+ // ���������������������������������������0������������������������������
+ setBarStyle(ownerInstance, 0)
+}
+
+function setBarStyle(ownerInstance, x) {
+ ownerInstance.selectComponent('.u-scroll-list__indicator__line__bar') && ownerInstance.selectComponent('.u-scroll-list__indicator__line__bar').setStyle({
+ transform: 'translateX(' + x + 'px)'
+ })
+}
+
+module.exports = {
+ scroll: scroll,
+ scrolltolower: scrolltolower,
+ scrolltoupper: scrolltoupper
+}
diff --git a/uni_modules/uview-ui/components/u-scroll-list/u-scroll-list.vue b/uni_modules/uview-ui/components/u-scroll-list/u-scroll-list.vue
new file mode 100644
index 0000000..4fe885a
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-scroll-list/u-scroll-list.vue
@@ -0,0 +1,224 @@
+<template>
+ <view
+ class="u-scroll-list"
+ ref="u-scroll-list"
+ >
+ <!-- #ifdef APP-NVUE -->
+ <!-- nvue������bindingX��������������������������������� -->
+ <scroller
+ class="u-scroll-list__scroll-view"
+ ref="u-scroll-list__scroll-view"
+ scroll-direction="horizontal"
+ :show-scrollbar="false"
+ :offset-accuracy="1"
+ @scroll="nvueScrollHandler"
+ >
+ <view class="u-scroll-list__scroll-view__content">
+ <slot />
+ </view>
+ </scroller>
+ <!-- #endif -->
+ <!-- #ifndef APP-NVUE -->
+ <!-- #ifdef MP-WEIXIN || APP-VUE || H5 || MP-QQ -->
+ <!-- ���������������������wxs -->
+ <scroll-view
+ class="u-scroll-list__scroll-view"
+ scroll-x
+ @scroll="wxs.scroll"
+ @scrolltoupper="wxs.scrolltoupper"
+ @scrolltolower="wxs.scrolltolower"
+ :data-scrollWidth="scrollWidth"
+ :data-barWidth="$u.getPx(indicatorBarWidth)"
+ :data-indicatorWidth="$u.getPx(indicatorWidth)"
+ :show-scrollbar="false"
+ :upper-threshold="0"
+ :lower-threshold="0"
+ >
+ <!-- #endif -->
+ <!-- #ifndef APP-NVUE || MP-WEIXIN || H5 || APP-VUE || MP-QQ -->
+ <!-- ������������������������������������js������ -->
+ <scroll-view
+ class="u-scroll-list__scroll-view"
+ scroll-x
+ @scroll="scrollHandler"
+ @scrolltoupper="scrolltoupperHandler"
+ @scrolltolower="scrolltolowerHandler"
+ :show-scrollbar="false"
+ :upper-threshold="0"
+ :lower-threshold="0"
+ >
+ <!-- #endif -->
+ <view class="u-scroll-list__scroll-view__content">
+ <slot />
+ </view>
+ </scroll-view>
+ <!-- #endif -->
+ <view
+ class="u-scroll-list__indicator"
+ v-if="indicator"
+ :style="[$u.addStyle(indicatorStyle)]"
+ >
+ <view
+ class="u-scroll-list__indicator__line"
+ :style="[lineStyle]"
+ >
+ <view
+ class="u-scroll-list__indicator__line__bar"
+ :style="[barStyle]"
+ ref="u-scroll-list__indicator__line__bar"
+ ></view>
+ </view>
+ </view>
+ </view>
+</template>
+
+<script
+ src="./scrollWxs.wxs"
+ module="wxs"
+ lang="wxs"
+></script>
+
+<script>
+/**
+ * scrollList ������������������
+ * @description ���������������������������������������������������������������������������������������������������������
+ * @tutorial https://www.uviewui.com/components/scrollList.html
+ * @property {String | Number} indicatorWidth ������������������������ (������ 50 )
+ * @property {String | Number} indicatorBarWidth ��������������� (������ 20 )
+ * @property {Boolean} indicator ��������������������������� (������ true )
+ * @property {String} indicatorColor ������������������������ (������ '#f2f2f2' )
+ * @property {String} indicatorActiveColor ������������������������ (������ '#3c9cff' )
+ * @property {String | Object} indicatorStyle ���������������������������bottom���left���right������������
+ * @event {Function} left ������������������������
+ * @event {Function} right ������������������������
+ * @example
+ */
+// #ifdef APP-NVUE
+const dom = uni.requireNativePlugin('dom')
+import nvueMixin from "./nvue.js"
+// #endif
+import props from './props.js';
+export default {
+ name: 'u-scroll-list',
+ mixins: [uni.$u.mpMixin, uni.$u.mixin, props],
+ // #ifdef APP-NVUE
+ mixins: [uni.$u.mpMixin, uni.$u.mixin, nvueMixin, props],
+ // #endif
+ data() {
+ return {
+ scrollInfo: {
+ scrollLeft: 0,
+ scrollWidth: 0
+ },
+ scrollWidth: 0
+ }
+ },
+ computed: {
+ // ���������������������������
+ barStyle() {
+ const style = {}
+ // #ifndef APP-NVUE || MP-WEIXIN || H5 || APP-VUE || MP-QQ
+ // ������������js���������������������nvue������������wxs������������������������
+ // ���������������������������scroll-view������������������������������������(scroll-view������������������������������������������)������������������������������������������������
+ // ������������(���������������������������������������)���������
+ const scrollLeft = this.scrollInfo.scrollLeft,
+ scrollWidth = this.scrollInfo.scrollWidth,
+ barAllMoveWidth = this.indicatorWidth - this.indicatorBarWidth
+ const x = scrollLeft / (scrollWidth - this.scrollWidth) * barAllMoveWidth
+ style.transform = `translateX(${ x }px)`
+ // #endif
+ // ���������������������������������������������������������������
+ style.width = uni.$u.addUnit(this.indicatorBarWidth)
+ style.backgroundColor = this.indicatorActiveColor
+ return style
+ },
+ lineStyle() {
+ const style = {}
+ // ������������������������������������������������������������
+ style.width = uni.$u.addUnit(this.indicatorWidth)
+ style.backgroundColor = this.indicatorColor
+ return style
+ }
+ },
+ mounted() {
+ this.init()
+ },
+ methods: {
+ init() {
+ this.getComponentWidth()
+ },
+ // #ifndef APP-NVUE || MP-WEIXIN || H5 || APP-VUE || MP-QQ
+ // scroll-view������������������
+ scrollHandler(e) {
+ this.scrollInfo = e.detail
+ },
+ scrolltoupperHandler() {
+ this.scrollEvent('left')
+ this.scrollInfo.scrollLeft = 0
+ },
+ scrolltolowerHandler() {
+ this.scrollEvent('right')
+ // ���������js���������������������������������������������this.scrollInfo������������������������������������
+ // ���������������������computed������������������������������������������������������
+ this.scrollInfo.scrollLeft = uni.$u.getPx(this.indicatorWidth) - uni.$u.getPx(this.indicatorBarWidth)
+ },
+ // #endif
+ //
+ scrollEvent(status) {
+ this.$emit(status)
+ },
+ // ���������������������
+ async getComponentWidth() {
+ // ������������������������������dom������
+ await uni.$u.sleep(30)
+ // #ifndef APP-NVUE
+ this.$uGetRect('.u-scroll-list').then(size => {
+ this.scrollWidth = size.width
+ })
+ // #endif
+
+ // #ifdef APP-NVUE
+ const ref = this.$refs['u-scroll-list']
+ ref && dom.getComponentRect(ref, (res) => {
+ this.scrollWidth = res.size.width
+ })
+ // #endif
+ },
+ }
+}
+</script>
+
+<style lang="scss" scoped>
+@import "../../libs/css/components.scss";
+
+.u-scroll-list {
+ padding-bottom: 10px;
+
+ &__scroll-view {
+ @include flex;
+
+ &__content {
+ @include flex;
+ }
+ }
+
+ &__indicator {
+ @include flex;
+ justify-content: center;
+ margin-top: 15px;
+
+ &__line {
+ width: 60px;
+ height: 4px;
+ border-radius: 100px;
+ overflow: hidden;
+
+ &__bar {
+ width: 20px;
+ height: 4px;
+ border-radius: 100px;
+ }
+ }
+ }
+}
+</style>
diff --git a/uni_modules/uview-ui/components/u-search/props.js b/uni_modules/uview-ui/components/u-search/props.js
new file mode 100644
index 0000000..df1b342
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-search/props.js
@@ -0,0 +1,118 @@
+export default {
+ props: {
+ // ������������������round-���������square-������
+ shape: {
+ type: String,
+ default: uni.$u.props.search.shape
+ },
+ // ������������������������������#f2f2f2
+ bgColor: {
+ type: String,
+ default: uni.$u.props.search.bgColor
+ },
+ // ������������������
+ placeholder: {
+ type: String,
+ default: uni.$u.props.search.placeholder
+ },
+ // ������������������������
+ clearabled: {
+ type: Boolean,
+ default: uni.$u.props.search.clearabled
+ },
+ // ������������������
+ focus: {
+ type: Boolean,
+ default: uni.$u.props.search.focus
+ },
+ // ������������������������������������������
+ showAction: {
+ type: Boolean,
+ default: uni.$u.props.search.showAction
+ },
+ // ���������������������
+ actionStyle: {
+ type: Object,
+ default: uni.$u.props.search.actionStyle
+ },
+ // ������������������
+ actionText: {
+ type: String,
+ default: uni.$u.props.search.actionText
+ },
+ // ������������������������������������������ left|center|right
+ inputAlign: {
+ type: String,
+ default: uni.$u.props.search.inputAlign
+ },
+ // input������������������������������������������������������������������������
+ inputStyle: {
+ type: Object,
+ default: uni.$u.props.search.inputStyle
+ },
+ // ���������������������
+ disabled: {
+ type: Boolean,
+ default: uni.$u.props.search.disabled
+ },
+ // ������������
+ borderColor: {
+ type: String,
+ default: uni.$u.props.search.borderColor
+ },
+ // ������������������������������������������������������
+ searchIconColor: {
+ type: String,
+ default: uni.$u.props.search.searchIconColor
+ },
+ // ���������������������
+ color: {
+ type: String,
+ default: uni.$u.props.search.color
+ },
+ // placeholder���������
+ placeholderColor: {
+ type: String,
+ default: uni.$u.props.search.placeholderColor
+ },
+ // ������������������������������������uView���������������������������
+ searchIcon: {
+ type: String,
+ default: uni.$u.props.search.searchIcon
+ },
+ searchIconSize: {
+ type: [Number, String],
+ default: uni.$u.props.search.searchIconSize
+ },
+ // ������������������������������������������������������������������������������������"30px"���"30px 20px"���������
+ margin: {
+ type: String,
+ default: uni.$u.props.search.margin
+ },
+ // ������showAction���������������input������������������������
+ animation: {
+ type: Boolean,
+ default: uni.$u.props.search.animation
+ },
+ // ���������������������������
+ value: {
+ type: String,
+ default: uni.$u.props.search.value
+ },
+ // ������������������������������������-1������������������(������uniapp������)
+ maxlength: {
+ type: [String, Number],
+ default: uni.$u.props.search.maxlength
+ },
+ // ������������������������px
+ height: {
+ type: [String, Number],
+ default: uni.$u.props.search.height
+ },
+ // ���������������������
+ label: {
+ type: [String, Number, null],
+ default: uni.$u.props.search.label
+ }
+ }
+}
diff --git a/uni_modules/uview-ui/components/u-search/u-search.vue b/uni_modules/uview-ui/components/u-search/u-search.vue
new file mode 100644
index 0000000..f169c7f
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-search/u-search.vue
@@ -0,0 +1,303 @@
+<template>
+ <view
+ class="u-search"
+ @tap="clickHandler"
+ :style="[{
+ margin: margin,
+ }, $u.addStyle(customStyle)]"
+ >
+ <view
+ class="u-search__content"
+ :style="{
+ backgroundColor: bgColor,
+ borderRadius: shape == 'round' ? '100px' : '4px',
+ borderColor: borderColor,
+ }"
+ >
+ <template v-if="$slots.label || label !== null">
+ <slot name="label">
+ <text class="u-search__content__label">{{ label }}</text>
+ </slot>
+ </template>
+ <view class="u-search__content__icon">
+ <u-icon
+ @tap="clickIcon"
+ :size="searchIconSize"
+ :name="searchIcon"
+ :color="searchIconColor ? searchIconColor : color"
+ ></u-icon>
+ </view>
+ <input
+ confirm-type="search"
+ @blur="blur"
+ :value="value"
+ @confirm="search"
+ @input="inputChange"
+ :disabled="disabled"
+ @focus="getFocus"
+ :focus="focus"
+ :maxlength="maxlength"
+ placeholder-class="u-search__content__input--placeholder"
+ :placeholder="placeholder"
+ :placeholder-style="`color: ${placeholderColor}`"
+ class="u-search__content__input"
+ type="text"
+ :style="[{
+ textAlign: inputAlign,
+ color: color,
+ backgroundColor: bgColor,
+ height: $u.addUnit(height)
+ }, inputStyle]"
+ />
+ <view
+ class="u-search__content__icon u-search__content__close"
+ v-if="keyword && clearabled && focused"
+ @tap="clear"
+ >
+ <u-icon
+ name="close"
+ size="11"
+ color="#ffffff"
+ customStyle="line-height: 12px"
+ ></u-icon>
+ </view>
+ </view>
+ <text
+ :style="[actionStyle]"
+ class="u-search__action"
+ :class="[(showActionBtn || show) && 'u-search__action--active']"
+ @tap.stop.prevent="custom"
+ >{{ actionText }}</text>
+ </view>
+</template>
+
+<script>
+ import props from './props.js';
+
+ /**
+ * search ���������
+ * @description ������������������������������������������������������������������������������������������������
+ * @tutorial https://www.uviewui.com/components/search.html
+ * @property {String} shape ������������������round-���������square-��������������� 'round' ���
+ * @property {String} bgColor ������������������������������ '#f2f2f2' ���
+ * @property {String} placeholder ��������������������������� '������������������' ���
+ * @property {Boolean} clearabled ��������������������������������� true ���
+ * @property {Boolean} focus ��������������������������������� false ���
+ * @property {Boolean} showAction ��������������������������������� true ���
+ * @property {Object} actionStyle ������������������������������������
+ * @property {String} actionText ��������������������������� '������' ���
+ * @property {String} inputAlign ��������������������������������� ��������� 'left' ���
+ * @property {Object} inputStyle ���������������������������������������
+ * @property {Boolean} disabled ������������������������������ false ���
+ * @property {String} borderColor ������������������������������������������������ (������ 'transparent' )
+ * @property {String} searchIconColor ������������������������������������������������������ (������ '#909399' )
+ * @property {Number | String} searchIconSize ������������������������������22
+ * @property {String} color ������������������������������ '#606266' ���
+ * @property {String} placeholderColor placeholder������������������ '#909399' ���
+ * @property {String} searchIcon ������������������������������������uView��������������������������� (������ 'search' )
+ * @property {String} margin ������������������������������������������������������������������������������������"30px" (������ '0' )
+ * @property {Boolean} animation ��������������������������������������������� false ���
+ * @property {String} value ������������������
+ * @property {String | Number} maxlength ������������������������������������-1������������������ (������ '-1' )
+ * @property {String | Number} height ������������������������px��������� 64 ���
+ * @property {String | Number} label ���������������������������
+ * @property {Object} customStyle ���������������������������������
+ *
+ * @event {Function} change ������������������������������������
+ * @event {Function} search ���������������������������������������������������������������������������������"������"������������
+ * @event {Function} custom ���������������������������������
+ * @event {Function} clear ���������������������������������
+ * @example <u-search placeholder="���������������������" v-model="keyword"></u-search>
+ */
+ export default {
+ name: "u-search",
+ mixins: [uni.$u.mpMixin, uni.$u.mixin,props],
+ data() {
+ return {
+ keyword: '',
+ showClear: false, // ���������������������������������
+ show: false,
+ // ������input���������������������������������������������������������������������������������
+ focused: this.focus
+ // ���������������������
+ // inputValue: this.value
+ };
+ },
+ watch: {
+ keyword(nVal) {
+ // ���������������������v-model������������������������
+ this.$emit('input', nVal);
+ // ������change������������������������v-model������������������������������������������������������
+ this.$emit('change', nVal);
+ },
+ value: {
+ immediate: true,
+ handler(nVal) {
+ this.keyword = nVal;
+ }
+ }
+ },
+ computed: {
+ showActionBtn() {
+ return !this.animation && this.showAction
+ }
+ },
+ methods: {
+ // ������HX2.6.9 v-model������������������������������input������������������������������������
+ inputChange(e) {
+ this.keyword = e.detail.value;
+ },
+ // ������������
+ // ���������������������������this.$refs���������������������������������
+ clear() {
+ this.keyword = '';
+ // ���������������������������������������������clear������������value������������������(���������)
+ this.$nextTick(() => {
+ this.$emit('clear');
+ })
+ },
+ // ������������
+ search(e) {
+ this.$emit('search', e.detail.value);
+ try {
+ // ������������
+ uni.hideKeyboard();
+ } catch (e) {}
+ },
+ // ������������������������������������
+ custom() {
+ this.$emit('custom', this.keyword);
+ try {
+ // ������������
+ uni.hideKeyboard();
+ } catch (e) {}
+ },
+ // ������������
+ getFocus() {
+ this.focused = true;
+ // ���������������������������������������������
+ if (this.animation && this.showAction) this.show = true;
+ this.$emit('focus', this.keyword);
+ },
+ // ������������
+ blur() {
+ // ���������������������������������@touchstart���������������hx2.8.4���������������������������������������
+ // ������������������������������������������������������������������������������@blur������������������������������������������������������������������
+ setTimeout(() => {
+ this.focused = false;
+ }, 100)
+ this.show = false;
+ this.$emit('blur', this.keyword);
+ },
+ // ������������������������disabled=true������������������������������������������������������������������������������������
+ clickHandler() {
+ if (this.disabled) this.$emit('click');
+ },
+ // ������������������
+ clickIcon() {
+ this.$emit('clickIcon');
+ }
+ }
+ }
+</script>
+
+<style lang="scss" scoped>
+@import "../../libs/css/components.scss";
+$u-search-content-padding: 0 10px !default;
+$u-search-label-color: $u-main-color !default;
+$u-search-label-font-size: 14px !default;
+$u-search-label-margin: 0 4px !default;
+$u-search-close-size: 20px !default;
+$u-search-close-radius: 100px !default;
+$u-search-close-bgColor: #C6C7CB !default;
+$u-search-close-transform: scale(0.82) !default;
+$u-search-input-font-size: 14px !default;
+$u-search-input-margin: 0 5px !default;
+$u-search-input-color: $u-main-color !default;
+$u-search-input-placeholder-color: $u-tips-color !default;
+$u-search-action-font-size: 14px !default;
+$u-search-action-color: $u-main-color !default;
+$u-search-action-width: 0 !default;
+$u-search-action-active-width: 40px !default;
+$u-search-action-margin-left: 5px !default;
+
+/* #ifdef H5 */
+// iOS15���H5������hx������������������input type=search������������������������������������������������
+[type="search"]::-webkit-search-decoration {
+ display: none;
+}
+/* #endif */
+
+.u-search {
+ @include flex(row);
+ align-items: center;
+ flex: 1;
+
+ &__content {
+ @include flex;
+ align-items: center;
+ padding: $u-search-content-padding;
+ flex: 1;
+ justify-content: space-between;
+ border-width: 1px;
+ border-color: transparent;
+ border-style: solid;
+ overflow: hidden;
+
+ &__icon {
+ @include flex;
+ align-items: center;
+ }
+
+ &__label {
+ color: $u-search-label-color;
+ font-size: $u-search-label-font-size;
+ margin: $u-search-label-margin;
+ }
+
+ &__close {
+ width: $u-search-close-size;
+ height: $u-search-close-size;
+ border-top-left-radius: $u-search-close-radius;
+ border-top-right-radius: $u-search-close-radius;
+ border-bottom-left-radius: $u-search-close-radius;
+ border-bottom-right-radius: $u-search-close-radius;
+ background-color: $u-search-close-bgColor;
+ @include flex(row);
+ align-items: center;
+ justify-content: center;
+ transform: $u-search-close-transform;
+ }
+
+ &__input {
+ flex: 1;
+ font-size: $u-search-input-font-size;
+ line-height: 1;
+ margin: $u-search-input-margin;
+ color: $u-search-input-color;
+
+ &--placeholder {
+ color: $u-search-input-placeholder-color;
+ }
+ }
+ }
+
+ &__action {
+ font-size: $u-search-action-font-size;
+ color: $u-search-action-color;
+ width: $u-search-action-width;
+ overflow: hidden;
+ transition-property: width;
+ transition-duration: 0.3s;
+ /* #ifndef APP-NVUE */
+ white-space: nowrap;
+ /* #endif */
+ text-align: center;
+
+ &--active {
+ width: $u-search-action-active-width;
+ margin-left: $u-search-action-margin-left;
+ }
+ }
+}
+</style>
diff --git a/uni_modules/uview-ui/components/u-skeleton/props.js b/uni_modules/uview-ui/components/u-skeleton/props.js
new file mode 100644
index 0000000..ed3ba5a
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-skeleton/props.js
@@ -0,0 +1,59 @@
+export default {
+ props: {
+ // ������������������������
+ loading: {
+ type: Boolean,
+ default: uni.$u.props.skeleton.loading
+ },
+ // ������������������������
+ animate: {
+ type: Boolean,
+ default: uni.$u.props.skeleton.animate
+ },
+ // ���������������������
+ rows: {
+ type: [String, Number],
+ default: uni.$u.props.skeleton.rows
+ },
+ // ������������������������
+ rowsWidth: {
+ type: [String, Number, Array],
+ default: uni.$u.props.skeleton.rowsWidth
+ },
+ // ������������������������
+ rowsHeight: {
+ type: [String, Number, Array],
+ default: uni.$u.props.skeleton.rowsHeight
+ },
+ // ���������������������������
+ title: {
+ type: Boolean,
+ default: uni.$u.props.skeleton.title
+ },
+ // ���������������������
+ titleWidth: {
+ type: [String, Number],
+ default: uni.$u.props.skeleton.titleWidth
+ },
+ // ���������������������
+ titleHeight: {
+ type: [String, Number],
+ default: uni.$u.props.skeleton.titleHeight
+ },
+ // ���������������������������
+ avatar: {
+ type: Boolean,
+ default: uni.$u.props.skeleton.avatar
+ },
+ // ���������������������
+ avatarSize: {
+ type: [String, Number],
+ default: uni.$u.props.skeleton.avatarSize
+ },
+ // ���������������������������circle-���������square-������
+ avatarShape: {
+ type: String,
+ default: uni.$u.props.skeleton.avatarShape
+ }
+ }
+}
diff --git a/uni_modules/uview-ui/components/u-skeleton/u-skeleton.vue b/uni_modules/uview-ui/components/u-skeleton/u-skeleton.vue
new file mode 100644
index 0000000..efa649e
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-skeleton/u-skeleton.vue
@@ -0,0 +1,244 @@
+<template>
+ <view class="u-skeleton">
+ <view
+ class="u-skeleton__wrapper"
+ ref="u-skeleton__wrapper"
+ v-if="loading"
+ style="display: flex; flex-direction: row;"
+ >
+ <view
+ class="u-skeleton__wrapper__avatar"
+ v-if="avatar"
+ :class="[`u-skeleton__wrapper__avatar--${avatarShape}`, animate && 'animate']"
+ :style="{
+ height: $u.addUnit(avatarSize),
+ width: $u.addUnit(avatarSize)
+ }"
+ ></view>
+ <view
+ class="u-skeleton__wrapper__content"
+ ref="u-skeleton__wrapper__content"
+ style="flex: 1;"
+ >
+ <view
+ class="u-skeleton__wrapper__content__title"
+ v-if="title"
+ :style="{
+ width: uTitleWidth,
+ height: $u.addUnit(titleHeight),
+ }"
+ :class="[animate && 'animate']"
+ ></view>
+ <view
+ class="u-skeleton__wrapper__content__rows"
+ :class="[animate && 'animate']"
+ v-for="(item, index) in rowsArray"
+ :key="index"
+ :style="{
+ width: item.width,
+ height: item.height,
+ marginTop: item.marginTop
+ }"
+ >
+
+ </view>
+ </view>
+ </view>
+ <slot v-else />
+ </view>
+</template>
+
+<script>
+ import props from './props.js';
+ // #ifdef APP-NVUE
+ // ������weex������������KPI���������������������������������������������������������������������������dom���������������������
+ const dom = uni.requireNativePlugin('dom')
+ const animation = uni.requireNativePlugin('animation')
+ // #endif
+ /**
+ * Skeleton ���������
+ * @description ������������������������������������������������������������������������������������������������������������������������������������������������
+ * @tutorial https://www.uviewui.com/components/skeleton.html
+ * @property {Boolean} loading ���������������������������������������false��������������������������� (������ true )
+ * @property {Boolean} animate ������������������������ (������ true )
+ * @property {String | Number} rows ��������������������� (������ 0 )
+ * @property {String | Number | Array} rowsWidth ������������������������������������������������������������������������������������������������������������������������������������ (������ '100%' )
+ * @property {String | Number | Array} rowsHeight ��������������� (������ 18 )
+ * @property {Boolean} title ��������������������������� (������ true )
+ * @property {String | Number} titleWidth ��������������� (������ '50%' )
+ * @property {String | Number} titleHeight ��������������� (������ 18 )
+ * @property {Boolean} avatar ��������������������������� (������ false )
+ * @property {String | Number} avatarSize ��������������������� (������ 32 )
+ * @property {String} avatarShape ���������������������������circle-���������square-������ (������ 'circle' )
+ * @example <u-search placeholder="���������������������" v-model="keyword"></u-search>
+ */
+ export default {
+ name: 'u-skeleton',
+ mixins: [uni.$u.mpMixin, uni.$u.mixin, props],
+ data() {
+ return {
+ width: 0,
+ }
+ },
+ watch: {
+ loading() {
+ this.getComponentWidth()
+ }
+ },
+ computed: {
+ rowsArray() {
+ if (/%$/.test(this.rowsHeight)) {
+ uni.$u.error('rowsHeight������������������������������')
+ }
+ const rows = []
+ for (let i = 0; i < this.rows; i++) {
+ let item = {},
+ // ���������������������������������������
+ rowWidth = uni.$u.test.array(this.rowsWidth) ? (this.rowsWidth[i] || (i === this.row - 1 ? '70%' : '100%')) : i ===
+ this.rows - 1 ? '70%' : this.rowsWidth,
+ rowHeight = uni.$u.test.array(this.rowsHeight) ? (this.rowsHeight[i] || '18px') : this.rowsHeight
+ // ���������title������������������������������������������������������������������������������title������������������������������������������������������
+ // ������������������������������������weex���������������������������������������������css���������������
+ item.marginTop = !this.title && i === 0 ? 0 : this.title && i === 0 ? '20px' : '12px'
+ // ������������������������������������������������px������������nvue������������������������
+ if (/%$/.test(rowWidth)) {
+ // ������parseInt���������������������������������������������������100���������������������������
+ item.width = uni.$u.addUnit(this.width * parseInt(rowWidth) / 100)
+ } else {
+ item.width = uni.$u.addUnit(rowWidth)
+ }
+ item.height = uni.$u.addUnit(rowHeight)
+ rows.push(item)
+ }
+ // console.log(rows);
+ return rows
+ },
+ uTitleWidth() {
+ let tWidth = 0
+ if (/%$/.test(this.titleWidth)) {
+ // ������parseInt���������������������������������������������������100���������������������������
+ tWidth = uni.$u.addUnit(this.width * parseInt(this.titleWidth) / 100)
+ } else {
+ tWidth = uni.$u.addUnit(this.titleWidth)
+ }
+ return uni.$u.addUnit(tWidth)
+ },
+
+ },
+ mounted() {
+ this.init()
+ },
+ methods: {
+ init() {
+ this.getComponentWidth()
+ // #ifdef APP-NVUE
+ this.loading && this.animate && this.setNvueAnimation()
+ // #endif
+ },
+ async setNvueAnimation() {
+ // #ifdef APP-NVUE
+ // ���������opacity:1���������������������������������������������������
+ await uni.$u.sleep(500)
+ const skeleton = this.$refs['u-skeleton__wrapper'];
+ skeleton && this.loading && this.animate && animation.transition(skeleton, {
+ styles: {
+ opacity: 0.5
+ },
+ duration: 600,
+ }, () => {
+ // ������������������������loading���������������������������������������������������������opacity: 1���������������
+ // ������������opacity: 0.5������������
+ animation.transition(skeleton, {
+ styles: {
+ opacity: 1
+ },
+ duration: 600,
+ }, () => {
+ // ���������loading������������������������
+ this.loading && this.animate && this.setNvueAnimation()
+ })
+ })
+ // #endif
+ },
+ // ���������������������
+ async getComponentWidth() {
+ // ������������������������������dom������
+ await uni.$u.sleep(20)
+ // #ifndef APP-NVUE
+ this.$uGetRect('.u-skeleton__wrapper__content').then(size => {
+ this.width = size.width
+ })
+ // #endif
+
+ // #ifdef APP-NVUE
+ const ref = this.$refs['u-skeleton__wrapper__content']
+ ref && dom.getComponentRect(ref, (res) => {
+ this.width = res.size.width
+ })
+ // #endif
+ }
+ }
+ }
+</script>
+
+<style lang="scss" scoped>
+ @import "../../libs/css/components.scss";
+
+ @mixin background {
+ /* #ifdef APP-NVUE */
+ background-color: #F1F2F4;
+ /* #endif */
+ /* #ifndef APP-NVUE */
+ background: linear-gradient(90deg, #F1F2F4 25%, #e6e6e6 37%, #F1F2F4 50%);
+ background-size: 400% 100%;
+ /* #endif */
+ }
+
+ .u-skeleton {
+ flex: 1;
+
+ &__wrapper {
+ @include flex(row);
+
+ &__avatar {
+ @include background;
+ margin-right: 15px;
+
+ &--circle {
+ border-radius: 100px;
+ }
+
+ &--square {
+ border-radius: 4px;
+ }
+ }
+
+ &__content {
+ flex: 1;
+
+ &__rows,
+ &__title {
+ @include background;
+ border-radius: 3px;
+ }
+ }
+ }
+ }
+
+ /* #ifndef APP-NVUE */
+ .animate {
+ animation: skeleton 1.8s ease infinite
+ }
+
+ @keyframes skeleton {
+ 0% {
+ background-position: 100% 50%
+ }
+
+ 100% {
+ background-position: 0 50%
+ }
+ }
+
+ /* #endif */
+</style>
diff --git a/uni_modules/uview-ui/components/u-slider/mpother.js b/uni_modules/uview-ui/components/u-slider/mpother.js
new file mode 100644
index 0000000..040c848
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-slider/mpother.js
@@ -0,0 +1,113 @@
+/**
+ * ���������������js������������slider
+ */
+export default {
+ watch: {
+ value(n) {
+ // ���������������������������������������������value���������������������������������������������������������
+ if (this.status === 'end') {
+ this.updateSliderPlacement(n, true)
+ }
+ }
+ },
+ mounted() {
+ this.init()
+ },
+ methods: {
+ init() {
+ this.getSliderRect()
+ },
+ // ������slider������
+ getSliderRect() {
+ // ������������������������������
+ setTimeout(() => {
+ this.$uGetRect('.u-slider').then((rect) => {
+ this.sliderRect = rect
+ this.updateSliderPlacement(this.value, true)
+ })
+ }, 10)
+ },
+ // ������������������
+ canNotDo() {
+ return this.disabled
+ },
+ // ������������������������X������������
+ getTouchX(e) {
+ return e.touches[0].clientX
+ },
+ formatStep(value) {
+ // ���������������������������������
+ return Math.round(Math.max(this.min, Math.min(value, this.max)) / this.step) * this.step
+ },
+ // ������������
+ emitEvent(event, value) {
+ this.$emit(event, value || this.value)
+ },
+ // ���������������������������
+ setTouchStatus(status) {
+ this.status = status
+ },
+ onTouchStart(e) {
+ if (this.canNotDo()) {
+ return
+ }
+ // ������������������������������������������
+ this.emitEvent('start')
+ this.setTouchStatus('start')
+ },
+ onTouchMove(e) {
+ if (this.canNotDo()) {
+ return
+ }
+ // ������������������������������������������������������������������������������������������������
+ const x = this.getTouchX(e)
+ const { left, width } = this.sliderRect
+ const distanceX = x - left
+ // ������������������������������������������������������������������������������������������������������������
+ // ������������������������������������������������step������������������������
+ const percent = (distanceX / width) * 100
+ this.setTouchStatus('moving')
+ this.updateSliderPlacement(percent, true, 'moving')
+ },
+ onTouchEnd() {
+ if (this.canNotDo()) {
+ return
+ }
+ this.emitEvent('end')
+ this.setTouchStatus('end')
+ },
+ // ���������������������
+ updateSliderPlacement(value, drag, event) {
+ // ������������������������������������step���������������
+ const { width } = this.sliderRect
+ const percent = this.formatStep(value)
+ // ������������������
+ const barStyle = {
+ width: `${percent / 100 * width}px`
+ }
+ // ������������������������������
+ if (drag === true) {
+ barStyle.transition = 'none'
+ } else {
+ // ������������������������������������������������������css������������������
+ delete barStyle.transition
+ }
+ // ������value���
+ this.$emit('input', percent)
+ // ���������������
+ if (event) {
+ this.emitEvent(event, percent)
+ }
+ this.barStyle = barStyle
+ },
+ onClick(e) {
+ if (this.canNotDo()) {
+ return
+ }
+ // ���������������������������������������������onTouchMove������������
+ const { left, width } = this.sliderRect
+ const value = ((e.detail.x - left) / width) * 100
+ this.updateSliderPlacement(value, false, 'click')
+ }
+ }
+}
diff --git a/uni_modules/uview-ui/components/u-slider/mpwxs.js b/uni_modules/uview-ui/components/u-slider/mpwxs.js
new file mode 100644
index 0000000..f263911
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-slider/mpwxs.js
@@ -0,0 +1,42 @@
+export default {
+ data() {
+ return {
+ sliderRect: {},
+ info: {
+ width: null,
+ left: null,
+ step: this.step,
+ disabled: this.disabled,
+ min: this.min,
+ max: this.max,
+ value: this.value
+ }
+ }
+ },
+ mounted() {
+ this.init()
+ },
+ methods: {
+ init() {
+ this.getSliderRect()
+ },
+ // ������slider������
+ getSliderRect() {
+ // ������������������������������
+ uni.$u.sleep().then(() => {
+ this.$uGetRect('.u-slider').then((rect) => {
+ this.info.width = rect.width
+ this.info.left = rect.left
+ })
+ })
+ },
+ // ������������wxs���������������������v-model������������
+ updateValue(value) {
+ this.$emit('input', value)
+ },
+ // ������������wxs���������������������
+ emitEvent(e) {
+ this.$emit(e.event, e.value ? e.value : this.value)
+ }
+ }
+}
diff --git a/uni_modules/uview-ui/components/u-slider/mpwxs.wxs b/uni_modules/uview-ui/components/u-slider/mpwxs.wxs
new file mode 100644
index 0000000..847df4a
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-slider/mpwxs.wxs
@@ -0,0 +1,121 @@
+/**
+ * ������wxs������������slider
+ * ���������������QQ���H5���Vue���������������iOS
+ */
+/**
+ * ������������������
+ * @param {Object} e
+ * @param {Object} ownerInstance
+ */
+function onTouchMove(e, ownerInstance) {
+ // wxs������������������������instance������������������������������������������������������������������������������������������������dataset������������������������
+ // https://developers.weixin.qq.com/miniprogram/dev/framework/view/interactive-animation.html
+ var instance = e.instance;
+ // getState()���������������������������instance���������������������data���������������������������������������������������������������������
+ var state = instance.getState()
+
+ // ���������������������������������
+ var mp = state.mp
+ if(mp.disabled) {
+ return
+ }
+
+ var distanceX = getTouchX(e) - mp.left
+ // ������������������������������������������������������������������������������������step������1������������������������������
+ var percent = (distanceX / mp.width) * 100
+
+ updateSliderPlacement(instance, ownerInstance, percent, 'moving')
+
+ // ������������������������������������������������������������������������������������������������������������
+ e.stopPropagation && e.stopPropagation()
+ e.preventDefault && e.preventDefault()
+}
+
+function onClick(e, ownerInstance) {
+ var instance = e.instance
+ var state = instance.getState()
+ var mp = state.mp
+ if(mp.disabled) {
+ return
+ }
+
+ // ���������������������������������������������onTouchMove������������
+ var value = ((e.detail.x - mp.left) / mp.width) * 100
+ updateSliderPlacement(instance, ownerInstance, value, 'click')
+}
+
+function sizeReady(newValue, oldValue, ownerInstance, instance) {
+ // ���������������������������������������������������������������������������������������������������
+ if(!newValue || newValue.disabled) {
+ return
+ }
+ var state = instance.getState()
+ state.mp = newValue
+ updateSliderPlacement(instance, ownerInstance, newValue.value)
+}
+
+// ���������������������
+function updateSliderPlacement(instance, ownerInstance, value, event) {
+ var state = instance.getState()
+ var mp = state.mp
+ if(mp.disabled) {
+ return
+ }
+
+ var percent = 0
+ if (mp.step > 1) {
+ // ������step������������1������������������������������������Math.round������������
+ percent = Math.round(Math.max(mp.min, Math.min(value, mp.max)) / mp.step) * mp.step
+ } else {
+ // ���step=1���������������������������������wxs���������������������������������������������������������
+ percent = Math.max(mp.min, Math.min(value, mp.max))
+ }
+ // ���������������������
+ var gapInstance = ownerInstance.selectComponent('.u-slider__gap')
+ // ���������������������������transition������������������������������
+ gapInstance[event === 'click' ? 'addClass' : 'removeClass']('u-slider__gap--ani')
+ // ���������������������������������v-model������������
+ ownerInstance.callMethod('updateValue', Math.round(percent))
+ if(event) {
+ ownerInstance.callMethod('emitEvent', {
+ event: event,
+ value: Math.round(percent)
+ })
+ }
+
+ // ������������������
+ gapInstance.requestAnimationFrame(function() {
+ gapInstance.setStyle({
+ width: percent / 100 * mp.width + 'px',
+ })
+ })
+}
+
+// ������������
+function onTouchStart(e, ownerInstance) {
+ ownerInstance.callMethod('emitEvent', {
+ event: 'start',
+ value: null
+ })
+}
+
+// ������������
+function onTouchEnd(e, ownerInstance) {
+ ownerInstance.callMethod('emitEvent', {
+ event: 'end',
+ value: null
+ })
+}
+
+// ������������������������X������������
+function getTouchX(e) {
+ return e.touches[0].clientX
+}
+
+module.exports = {
+ onTouchStart: onTouchStart,
+ onTouchMove: onTouchMove,
+ onTouchEnd: onTouchEnd,
+ sizeReady: sizeReady,
+ onClick: onClick
+}
diff --git "a/uni_modules/uview-ui/components/u-slider/nvue - \345\211\257\346\234\254.js" "b/uni_modules/uview-ui/components/u-slider/nvue - \345\211\257\346\234\254.js"
new file mode 100644
index 0000000..df62349
--- /dev/null
+++ "b/uni_modules/uview-ui/components/u-slider/nvue - \345\211\257\346\234\254.js"
@@ -0,0 +1,180 @@
+/**
+ * ������bindingx������������slider
+ * ���������������nvue���
+ */
+// ������bindingx���������������������������������wxs���������������js���������������������������������������������������������������
+const BindingX = uni.requireNativePlugin('bindingx')
+// nvue������dom���������������������dom���������������
+const dom = uni.requireNativePlugin('dom')
+// nvue���������������������������������������������uni.animation������������uni.animation������������nvue
+const animation = uni.requireNativePlugin('animation')
+
+export default {
+ data() {
+ return {
+ // bindingx���������������������������������
+ panEvent: null,
+ // ������������������������
+ moving: false,
+ // ������������������
+ x: 0,
+ // ������������������������������������������������������������������������
+ touching: false,
+ changeFromInside: false
+ }
+ },
+ watch: {
+ // ������vlaue������������������������������������������������v-model���������������������
+ // ������������������������������������������slider���v-model������������
+ value(n) {
+ if (!this.changeFromInside) {
+ this.initX()
+ } else {
+ this.changeFromInside = false
+ }
+ }
+ },
+ mounted() {
+ this.init()
+ },
+ methods: {
+ init() {
+ this.getSliderRect()
+ },
+ // ������������������
+ // ������slider������
+ getSliderRect() {
+ // ������������������������������
+ // ������nvue���dom���������������������������
+ setTimeout(() => {
+ dom.getComponentRect(this.$refs['slider'], res => {
+ this.sliderRect = res.size
+ this.initX()
+ })
+ }, 10)
+ },
+ // ���������������������
+ initButtonStyle({
+ barStyle,
+ buttonWrapperStyle
+ }) {
+ this.barStyle = barStyle
+ this.buttonWrapperStyle = buttonWrapperStyle
+ },
+ emitEvent(event, value) {
+ this.$emit(event, value ? value : this.value)
+ },
+ formatStep(value) {
+ // ���������������������������������
+ return Math.round(Math.max(this.min, Math.min(value, this.max)) / this.step) * this.step
+ },
+ // ������������
+ onTouchStart(e) {
+ // ������������������������������������������������������������������������������������������������������������
+ e.stopPropagation && e.stopPropagation()
+ e.preventDefault && e.preventDefault()
+ if (this.moving || this.disabled) {
+ // ������������������������
+ if (this.panEvent?.token != 0) {
+ BindingX.unbind({
+ token: this.panEvent.token,
+ // pan���������������
+ eventType: 'pan'
+ })
+ this.gesToken = 0
+ }
+ return
+ }
+
+ this.moving = true
+ this.touching = true
+
+ // ������������ref
+ const button = this.$refs['nvue-button'].ref
+ const gap = this.$refs['nvue-gap'].ref
+
+ const {
+ min,
+ max,
+ step
+ } = this
+ const {
+ left,
+ width
+ } = this.sliderRect
+
+ // ���������������������������x���������������������������������������
+ let exporession = `(${this.x} + x)`
+ // ������������x������������������������������������������������min���max������������
+ exporession = `(${exporession} / ${width}) * 100`
+ if (step > 1) {
+ // ������step������������1������������������������������������Math.round������������
+ exporession = `round(max(${min}, min(${exporession}, ${max})) / ${step}) * ${step}`
+ } else {
+ // ���step=1���������������������������������bindingx���������������������������������������������������������
+ exporession = `max(${min}, min(${exporession}, ${max}))`
+ }
+ // ������������������������������������px���
+ exporession = `${exporession} / 100 * ${width}`
+ // ���������������������������������������
+ const {
+ sliderWidth
+ } = this.sliderRect
+ exporession = `min(${sliderWidth}, ${exporession})`
+ // ���������������������������������������������������������������������
+ const buttonExpression = `${exporession} - ${this.blockHeight / 2}`
+ // ������������KPI������������BindingX
+ this.panEvent = BindingX.bind({
+ anchor: button,
+ eventType: 'pan',
+ props: [{
+ element: gap,
+ // ������width���������������������������
+ property: 'width',
+ expression
+ }, {
+ element: button,
+ // ������width���������������������������
+ property: 'transform.translateX',
+ expression: buttonExpression
+ }]
+ }, (e) => {
+ if (e.state === 'end' || e.state === 'exit') {
+ //
+ this.x = uni.$u.range(0, left + width, e.deltaX + this.x)
+ // ������������������������������������������������������������������������v-model������
+ const value = (this.x / width) * 100
+ const percent = this.formatStep(value)
+ // ������value���
+ this.$emit('input', percent)
+ // ���������������������value���watch������������������������������������������������
+ this.changeFromInside = true
+ this.moving = false
+ this.touching = false
+ }
+ })
+ },
+ // ���value������������������������x������������������
+ initX() {
+ const {
+ left,
+ width
+ } = this.sliderRect
+ // ������x������������������������������������������������������������bindingX������������������������������������������������������������
+ // ���������������������������������������������������������������weex������������������������KPI(������������������)������������������������
+ this.x = this.value / 100 * width
+ // ������������������
+ const barStyle = {
+ width: this.x + 'px'
+ }
+ // ������������������
+ const buttonWrapperStyle = {
+ transform: `translateX(${this.x - this.blockHeight / 2}px)`
+ }
+ this.initButtonStyle({
+ barStyle,
+ buttonWrapperStyle
+ })
+ }
+ }
+}
diff --git a/uni_modules/uview-ui/components/u-slider/nvue.js b/uni_modules/uview-ui/components/u-slider/nvue.js
new file mode 100644
index 0000000..344dce8
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-slider/nvue.js
@@ -0,0 +1,193 @@
+/**
+ * ������bindingx������������slider
+ * ���������������nvue���
+ */
+// ������bindingx���������������������������������wxs���������������js���������������������������������������������������������������
+const BindingX = uni.requireNativePlugin('bindingx')
+// nvue������dom���������������������dom���������������
+const dom = uni.requireNativePlugin('dom')
+// nvue���������������������������������������������uni.animation������������uni.animation������������nvue
+const animation = uni.requireNativePlugin('animation')
+
+export default {
+ data() {
+ return {
+ // ������������������
+ x: 0,
+ // ������������������������������������������������������������������������
+ touching: false,
+ changeFromInside: false
+ }
+ },
+ watch: {
+ // ������vlaue������������������������������������������������v-model���������������������
+ // ������������������������������������������slider���v-model������������
+ value(n) {
+ if (!this.changeFromInside) {
+ this.initX()
+ } else {
+ this.changeFromInside = false
+ }
+ }
+ },
+ mounted() {
+ this.init()
+ },
+ methods: {
+ init() {
+ // ������������������������
+ this.getSliderRect().then((size) => {
+ this.sliderRect = size
+ this.initX()
+ })
+ },
+ // ������������������
+ // ������slider������
+ getSliderRect() {
+ // ������������������������������
+ // ������nvue���dom���������������������������
+ return new Promise((resolve) => {
+ this.$nextTick(() => {
+ dom.getComponentRect(this.$refs.slider, (res) => {
+ resolve(res.size)
+ })
+ })
+ })
+ },
+ // ���������������������
+ initButtonStyle({
+ barStyle,
+ buttonWrapperStyle
+ }) {
+ this.barStyle = barStyle
+ this.buttonWrapperStyle = buttonWrapperStyle
+ },
+ emitEvent(event, value) {
+ this.$emit(event, value || this.value)
+ },
+ // ������������
+ async onTouchStart(e) {
+ // if (this.disabled) return
+ // // ������������������������������������������������������������������������������������������������������������
+ // e.stopPropagation && e.stopPropagation()
+ // e.preventDefault && e.preventDefault()
+ // // ���������������������������
+ // this.sliderRect = await this.getSliderRect()
+ // // ���������������������������������������
+ // this.touchStart(e)
+ // this.startValue = this.format(this.value)
+ // this.dragStatus = 'start'
+
+ // ���������������������������������������
+ // this.touchStart(e)
+ },
+ // ������������
+ onTouchMove(e) {
+ // if (this.disabled) return;
+ // if (this.dragStatus === 'start') {
+ // this.$emit('drag-start')
+ // }
+ // // ���������������������������������������������������������touch mixin���
+ // this.touchMove(e)
+ // this.dragStatus = 'draging'
+ // const {
+ // width: sliderWidth
+ // } = this.sliderRect
+ // const diff = (this.deltaX / sliderWidth) * this.getRange()
+ // this.newValue = this.startValue + diff
+ // this.updateValue(this.newValue, false, true)
+ // ������������ref
+ // const button = this.$refs['nvue-button'].ref
+ // const gap = this.$refs['nvue-gap'].ref
+
+ // animation.transition(gap, {
+ // styles: {
+ // width: `${this.startX + this.deltaX}px`
+ // }
+ // })
+ // // console.log(this.startX + this.deltaX);
+ // animation.transition(button, {
+ // styles: {
+ // transform: `translateX(${this.startX + this.deltaX}px)`
+ // }
+ // })
+ // this.barStyle = {
+ // width: `${this.startX + this.deltaX}px`
+ // }
+ const {
+ x
+ } = this.getTouchPoint(e)
+ this.buttonWrapperStyle = {
+ transform: `translateX(${x}px)`
+ }
+ // this.buttonWrapperStyle = {
+ // transform: `translateX(${this.format(this.startX + this.deltaX)}px)`
+ // }
+ },
+ // onTouchEnd() {
+ // if (this.disabled) return;
+ // if (this.dragStatus === 'draging') {
+ // this.updateValue(this.newValue, true)
+ // this.$emit('drag-end');
+ // }
+ // },
+ updateValue(value, end, drag) {
+ value = this.format(value)
+ const {
+ width: sliderWidth
+ } = this.sliderRect
+ const width = `${((value - this.min) * sliderWidth) / this.getRange()}`
+ this.value = value
+ this.barStyle = {
+ width: `${width}px`
+ }
+ // console.log('width', width);
+ if (drag) {
+ this.$emit('drag', {
+ value
+ })
+ }
+ if (end) {
+ this.$emit('change', value)
+ }
+ if ((drag || end)) {
+ this.changeFromInside = true
+ this.$emit('update', value)
+ }
+ },
+ // ���value������������������������x������������������
+ initX() {
+ const {
+ left,
+ width
+ } = this.sliderRect
+ // ������x������������������������������������������������������������bindingX������������������������������������������������������������
+ // ���������������������������������������������������������������weex������������������������KPI(������������������)������������������������
+ this.x = this.value / 100 * width
+ // ������������������
+ const barStyle = {
+ width: `${this.x}px`
+ }
+ // ������������������
+ const buttonWrapperStyle = {
+ transform: `translateX(${this.x - this.blockHeight / 2}px)`
+ }
+ this.initButtonStyle({
+ barStyle,
+ buttonWrapperStyle
+ })
+ },
+ // ���������������������������������������������������������step������������������step������1������������10������������������11,12px���������
+ // ������������������������������������������������������16,17px���������������������������������������20px���������������������������
+ format(value) {
+ return Math.round(uni.$u.range(this.min, this.max, value) / this.step) * this.step
+ },
+ getRange() {
+ const {
+ max,
+ min
+ } = this
+ return max - min
+ }
+ }
+}
diff --git a/uni_modules/uview-ui/components/u-slider/props.js b/uni_modules/uview-ui/components/u-slider/props.js
new file mode 100644
index 0000000..433a7b5
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-slider/props.js
@@ -0,0 +1,54 @@
+export default {
+ props: {
+ // ���������������
+ min: {
+ type: [Number, String],
+ default: uni.$u.props.slider.min
+ },
+ // ���������������
+ max: {
+ type: [Number, String],
+ default: uni.$u.props.slider.max
+ },
+ // ��������������������������� 0���������������(max - min)������
+ step: {
+ type: [Number, String],
+ default: uni.$u.props.slider.step
+ },
+ // ������������
+ value: {
+ type: [Number, String],
+ default: uni.$u.props.slider.value
+ },
+ // ���������������������������������������
+ activeColor: {
+ type: String,
+ default: uni.$u.props.slider.activeColor
+ },
+ // ���������������������������������������
+ inactiveColor: {
+ type: String,
+ default: uni.$u.props.slider.inactiveColor
+ },
+ // ��������������������������������� 12 - 28
+ blockSize: {
+ type: [Number, String],
+ default: uni.$u.props.slider.blockSize
+ },
+ // ���������������
+ blockColor: {
+ type: String,
+ default: uni.$u.props.slider.blockColor
+ },
+ // ������������
+ disabled: {
+ type: Boolean,
+ default: uni.$u.props.slider.disabled
+ },
+ // ������������������������������
+ showValue: {
+ type: Boolean,
+ default: uni.$u.props.slider.showValue
+ }
+ }
+}
diff --git a/uni_modules/uview-ui/components/u-slider/u-slider.vue b/uni_modules/uview-ui/components/u-slider/u-slider.vue
new file mode 100644
index 0000000..80ebbed
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-slider/u-slider.vue
@@ -0,0 +1,55 @@
+<template>
+ <view
+ class="u-slider"
+ :style="[$u.addStyle(customStyle)]"
+ >
+ <slider
+ :min="min"
+ :max="max"
+ :step="step"
+ :value="value"
+ :activeColor="activeColor"
+ :inactiveColor="inactiveColor"
+ :blockSize="$u.getPx(blockSize)"
+ :blockColor="blockColor"
+ :showValue="showValue"
+ :disabled="disabled"
+ @changing="changingHandler"
+ @change="changeHandler"
+ ></slider>
+ </view>
+</template>
+
+<script>
+ import props from './props.js'
+ export default {
+ name: 'u--slider',
+ mixins: [uni.$u.mpMixin, uni.$u.mixin, props],
+ methods: {
+ // ���������������������
+ changingHandler(e) {
+ const {
+ value
+ } = e.detail
+ // ������v-model������
+ this.$emit('input', value)
+ // ������������
+ this.$emit('changing', value)
+ },
+ // ���������������������
+ changeHandler(e) {
+ const {
+ value
+ } = e.detail
+ // ������v-model������
+ this.$emit('input', value)
+ // ������������
+ this.$emit('change', value)
+ }
+ },
+ }
+</script>
+
+<style lang="scss" scoped>
+ @import "../../libs/css/components.scss";
+</style>
diff --git a/uni_modules/uview-ui/components/u-status-bar/props.js b/uni_modules/uview-ui/components/u-status-bar/props.js
new file mode 100644
index 0000000..64b9e63
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-status-bar/props.js
@@ -0,0 +1,8 @@
+export default {
+ props: {
+ bgColor: {
+ type: String,
+ default: uni.$u.props.statusBar.bgColor
+ }
+ }
+}
diff --git a/uni_modules/uview-ui/components/u-status-bar/u-status-bar.vue b/uni_modules/uview-ui/components/u-status-bar/u-status-bar.vue
new file mode 100644
index 0000000..ed91373
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-status-bar/u-status-bar.vue
@@ -0,0 +1,46 @@
+<template>
+ <view
+ :style="[style]"
+ class="u-status-bar"
+ >
+ <slot />
+ </view>
+</template>
+
+<script>
+ import props from './props.js';
+ /**
+ * StatbusBar ���������������
+ * @description ���������������������������������������������������������������������������������������������������������������������������
+ * @tutorial https://uviewui.com/components/statusBar.html
+ * @property {String} bgColor ��������� (������ 'transparent' )
+ * @property {String | Object} customStyle ���������������
+ * @example <u-status-bar></u-status-bar>
+ */
+ export default {
+ name: 'u-status-bar',
+ mixins: [uni.$u.mpMixin, uni.$u.mixin, props],
+ data() {
+ return {
+ }
+ },
+ computed: {
+ style() {
+ const style = {}
+ // ���������������������������������������������������������������������css���������������������������������������js���������������
+ style.height = uni.$u.addUnit(uni.$u.sys().statusBarHeight, 'px')
+ style.backgroundColor = this.bgColor
+ return uni.$u.deepMerge(style, uni.$u.addStyle(this.customStyle))
+ }
+ },
+ }
+</script>
+
+<style lang="scss" scoped>
+ .u-status-bar {
+ // nvue���������100%���������nvue���������������100%������������������������������100%���������
+ /* #ifndef APP-NVUE */
+ width: 100%;
+ /* #endif */
+ }
+</style>
diff --git a/uni_modules/uview-ui/components/u-steps-item/props.js b/uni_modules/uview-ui/components/u-steps-item/props.js
new file mode 100644
index 0000000..825727a
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-steps-item/props.js
@@ -0,0 +1,24 @@
+export default {
+ props: {
+ // ������
+ title: {
+ type: [String, Number],
+ default: uni.$u.props.stepsItem.title
+ },
+ // ������������
+ desc: {
+ type: [String, Number],
+ default: uni.$u.props.stepsItem.desc
+ },
+ // ������������
+ iconSize: {
+ type: [String, Number],
+ default: uni.$u.props.stepsItem.iconSize
+ },
+ // ������������������������������������
+ error: {
+ type: Boolean,
+ default: uni.$u.props.stepsItem.error
+ }
+ }
+}
diff --git a/uni_modules/uview-ui/components/u-steps-item/u-steps-item.vue b/uni_modules/uview-ui/components/u-steps-item/u-steps-item.vue
new file mode 100644
index 0000000..342fa63
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-steps-item/u-steps-item.vue
@@ -0,0 +1,316 @@
+<template>
+ <view class="u-steps-item" ref="u-steps-item" :class="[`u-steps-item--${parentData.direction}`]">
+ <view class="u-steps-item__line" v-if="index + 1 < childLength"
+ :class="[`u-steps-item__line--${parentData.direction}`]" :style="[lineStyle]"></view>
+ <view class="u-steps-item__wrapper"
+ :class="[`u-steps-item__wrapper--${parentData.direction}`, parentData.dot && `u-steps-item__wrapper--${parentData.direction}--dot`]">
+ <slot name="icon">
+ <view class="u-steps-item__wrapper__dot" v-if="parentData.dot" :style="{
+ backgroundColor: statusColor
+ }">
+
+ </view>
+ <view class="u-steps-item__wrapper__icon" v-else-if="parentData.activeIcon || parentData.inactiveIcon">
+ <u-icon :name="index <= parentData.current ? parentData.activeIcon : parentData.inactiveIcon"
+ :size="iconSize"
+ :color="index <= parentData.current ? parentData.activeColor : parentData.inactiveColor">
+ </u-icon>
+ </view>
+ <view v-else :style="{
+ backgroundColor: statusClass === 'process' ? parentData.activeColor : 'transparent',
+ borderColor: statusColor
+ }" class="u-steps-item__wrapper__circle">
+ <text v-if="statusClass === 'process' || statusClass === 'wait'"
+ class="u-steps-item__wrapper__circle__text" :style="{
+ color: index == parentData.current ? '#ffffff' : parentData.inactiveColor
+ }">{{ index + 1}}</text>
+ <u-icon v-else :color="statusClass === 'error' ? 'error' : parentData.activeColor" size="12"
+ :name="statusClass === 'error' ? 'close' : 'checkmark'"></u-icon>
+ </view>
+ </slot>
+ </view>
+ <view class="u-steps-item__content" :class="[`u-steps-item__content--${parentData.direction}`]"
+ :style="[contentStyle]">
+ <u--text :text="title" :type="parentData.current == index ? 'main' : 'content'" lineHeight="20px"
+ :size="parentData.current == index ? 14 : 13"></u--text>
+ <slot name="desc">
+ <u--text :text="desc" type="tips" size="12"></u--text>
+ </slot>
+ </view>
+ <!-- <view
+ class="u-steps-item__line"
+ v-if="showLine && parentData.direction === 'column'"
+ :class="[`u-steps-item__line--${parentData.direction}`]"
+ :style="[lineStyle]"
+ ></view> -->
+ </view>
+</template>
+
+<script>
+ import props from './props.js';
+ // #ifdef APP-NVUE
+ const dom = uni.requireNativePlugin('dom')
+ // #endif
+ /**
+ * StepsItem ���������������������
+ * @description ������������������u-steps������������
+ * @tutorial https://uviewui.com/components/steps.html
+ * @property {String} title ������������
+ * @property {String} current ������������
+ * @property {String | Number} iconSize ������������ (������ 17 )
+ * @property {Boolean} error ������������������������������������ (������ false )
+ * @example <u-steps current="0"><u-steps-item title="���������" desc="10:35" ></u-steps-item></u-steps>
+ */
+ export default {
+ name: 'u-steps-item',
+ mixins: [uni.$u.mpMixin, uni.$u.mixin, props],
+ data() {
+ return {
+ index: 0,
+ childLength: 0,
+ showLine: false,
+ size: {
+ height: 0,
+ width: 0
+ },
+ parentData: {
+ direction: 'row',
+ current: 0,
+ activeColor: '',
+ inactiveColor: '',
+ activeIcon: '',
+ inactiveIcon: '',
+ dot: false
+ }
+ }
+ },
+ watch: {
+ 'parentData'(newValue, oldValue) {
+ }
+ },
+ created() {
+ this.init()
+ },
+ computed: {
+ lineStyle() {
+ const style = {}
+ if (this.parentData.direction === 'row') {
+ style.width = this.size.width + 'px'
+ style.left = this.size.width / 2 + 'px'
+ } else {
+ style.height = this.size.height + 'px'
+ // style.top = this.size.height / 2 + 'px'
+ }
+ style.backgroundColor = this.parent.children?.[this.index + 1]?.error ? uni.$u.color.error : this.index <
+ this
+ .parentData
+ .current ? this.parentData.activeColor : this.parentData.inactiveColor
+ return style
+ },
+ statusClass() {
+ const {
+ index,
+ error
+ } = this
+ const {
+ current
+ } = this.parentData
+ if (current == index) {
+ return error === true ? 'error' : 'process'
+ } else if (error) {
+ return 'error'
+ } else if (current > index) {
+ return 'finish'
+ } else {
+ return 'wait'
+ }
+ },
+ statusColor() {
+ let color = ''
+ switch (this.statusClass) {
+ case 'finish':
+ color = this.parentData.activeColor
+ break
+ case 'error':
+ color = uni.$u.color.error
+ break
+ case 'process':
+ color = this.parentData.dot ? this.parentData.activeColor : 'transparent'
+ break
+ default:
+ color = this.parentData.inactiveColor
+ break
+ }
+ return color
+ },
+ contentStyle() {
+ const style = {}
+ if (this.parentData.direction === 'column') {
+ style.marginLeft = this.parentData.dot ? '2px' : '6px'
+ style.marginTop = this.parentData.dot ? '0px' : '6px'
+ } else {
+ style.marginTop = this.parentData.dot ? '2px' : '6px'
+ style.marginLeft = this.parentData.dot ? '2px' : '6px'
+ }
+
+ return style
+ }
+ },
+ mounted() {
+ this.parent && this.parent.updateFromChild()
+ uni.$u.sleep().then(() => {
+ this.getStepsItemRect()
+ })
+ },
+ methods: {
+ init() {
+ // ���������������
+ this.updateParentData()
+ if (!this.parent) {
+ return uni.$u.error('u-steps-item���������������u-steps������������')
+ }
+ this.index = this.parent.children.indexOf(this)
+ this.childLength = this.parent.children.length
+ },
+ updateParentData() {
+ // ������������mixin���
+ this.getParentData('u-steps')
+ },
+ // ���������������������������
+ updateFromParent() {
+ this.init()
+ },
+ // ���������������������������������������������������
+ getStepsItemRect() {
+ // #ifndef APP-NVUE
+ this.$uGetRect('.u-steps-item').then(size => {
+ this.size = size
+ })
+ // #endif
+
+ // #ifdef APP-NVUE
+ dom.getComponentRect(this.$refs['u-steps-item'], res => {
+ const {
+ size
+ } = res
+ this.size = size
+ })
+ // #endif
+ }
+ }
+ }
+</script>
+
+<style lang="scss" scoped>
+ @import "../../libs/css/components.scss";
+
+ .u-steps-item {
+ flex: 1;
+ @include flex;
+
+ &--row {
+ flex-direction: column;
+ align-items: center;
+ position: relative;
+ }
+
+ &--column {
+ position: relative;
+ flex-direction: row;
+ justify-content: flex-start;
+ padding-bottom: 5px;
+ }
+
+ &__wrapper {
+ @include flex;
+ justify-content: center;
+ align-items: center;
+ position: relative;
+ background-color: #fff;
+
+ &--column {
+ width: 20px;
+ height: 32px;
+
+ &--dot {
+ height: 20px;
+ width: 20px;
+ }
+ }
+
+ &--row {
+ width: 32px;
+ height: 20px;
+
+ &--dot {
+ width: 20px;
+ height: 20px;
+ }
+ }
+
+ &__circle {
+ width: 20px;
+ height: 20px;
+ /* #ifndef APP-NVUE */
+ box-sizing: border-box;
+ flex-shrink: 0;
+ /* #endif */
+ border-radius: 100px;
+ border-width: 1px;
+ border-color: $u-tips-color;
+ border-style: solid;
+ @include flex(row);
+ align-items: center;
+ justify-content: center;
+ transition: background-color 0.3s;
+
+ &__text {
+ color: $u-tips-color;
+ font-size: 11px;
+ @include flex(row);
+ align-items: center;
+ justify-content: center;
+ text-align: center;
+ line-height: 11px;
+ }
+ }
+
+ &__dot {
+ width: 10px;
+ height: 10px;
+ border-radius: 100px;
+ background-color: $u-content-color;
+ }
+ }
+
+ &__content {
+ @include flex;
+ flex: 1;
+
+ &--row {
+ flex-direction: column;
+ align-items: center;
+ }
+
+ &--column {
+ flex-direction: column;
+ margin-left: 6px;
+ }
+ }
+
+ &__line {
+ position: absolute;
+ background: $u-tips-color;
+
+ &--row {
+ top: 10px;
+ height: 1px;
+ }
+
+ &--column {
+ width: 1px;
+ left: 10px;
+ }
+ }
+ }
+</style>
diff --git a/uni_modules/uview-ui/components/u-steps/props.js b/uni_modules/uview-ui/components/u-steps/props.js
new file mode 100644
index 0000000..6d4c768
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-steps/props.js
@@ -0,0 +1,39 @@
+export default {
+ props: {
+ // ������������
+ direction: {
+ type: String,
+ default: uni.$u.props.steps.direction
+ },
+ // ���������������������
+ current: {
+ type: [String, Number],
+ default: uni.$u.props.steps.current
+ },
+ // ������������������
+ activeColor: {
+ type: String,
+ default: uni.$u.props.steps.activeColor
+ },
+ // ���������������������
+ inactiveColor: {
+ type: String,
+ default: uni.$u.props.steps.inactiveColor
+ },
+ // ���������������������
+ activeIcon: {
+ type: String,
+ default: uni.$u.props.steps.activeIcon
+ },
+ // ���������������������
+ inactiveIcon: {
+ type: String,
+ default: uni.$u.props.steps.inactiveIcon
+ },
+ // ���������������������
+ dot: {
+ type: Boolean,
+ default: uni.$u.props.steps.dot
+ }
+ }
+}
diff --git a/uni_modules/uview-ui/components/u-steps/u-steps.vue b/uni_modules/uview-ui/components/u-steps/u-steps.vue
new file mode 100644
index 0000000..3ab7764
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-steps/u-steps.vue
@@ -0,0 +1,80 @@
+<template>
+ <view
+ class="u-steps"
+ :class="[`u-steps--${direction}`]"
+ >
+ <slot></slot>
+ </view>
+</template>
+
+<script>
+ import props from './props.js';
+ /**
+ * Steps ���������
+ * @description ���������������������������������������������������������������������������������������������������
+ * @tutorial https://uviewui.com/components/steps.html
+ * @property {String} direction row-���������column-������ (������ 'row' )
+ * @property {String | Number} current ��������������������������� (������ 0 )
+ * @property {String} activeColor ������������������ (������ '#3c9cff' )
+ * @property {String} inactiveColor ��������������������� (������ '#969799' )
+ * @property {String} activeIcon ���������������������
+ * @property {String} inactiveIcon ���������������������
+ * @property {Boolean} dot ��������������������� (������ false )
+ * @example <u-steps current="0"><u-steps-item title="���������" desc="10:35" ></u-steps-item></u-steps>
+ */
+ export default {
+ name: 'u-steps',
+ mixins: [uni.$u.mpMixin, uni.$u.mixin, props],
+ data() {
+ return {
+ }
+ },
+ watch: {
+ children() {
+ this.updateChildData()
+ },
+ parentData() {
+ this.updateChildData()
+ }
+ },
+ computed: {
+ // ������������������������������watch���������������������������������������������������������������������������
+ parentData() {
+ return [this.current, this.direction, this.activeColor, this.inactiveColor, this.activeIcon, this.inactiveIcon, this.dot]
+ }
+ },
+ methods: {
+ // ������������������������
+ updateChildData() {
+ this.children.map(child => {
+ // ���������������������������������������������
+ uni.$u.test.func((child || {}).updateFromParent()) && child.updateFromParent()
+ })
+ },
+ // ������������������������������������������������������������
+ updateFromChild() {
+ this.updateChildData()
+ }
+ },
+ created() {
+ this.children = []
+ }
+ }
+</script>
+
+<style lang="scss" scoped>
+ @import "../../libs/css/components.scss";
+
+ .u-steps {
+ @include flex;
+
+ &--column {
+ flex-direction: column
+ }
+
+ &--row {
+ flex-direction: row;
+ flex: 1;
+ }
+ }
+</style>
diff --git a/uni_modules/uview-ui/components/u-sticky/props.js b/uni_modules/uview-ui/components/u-sticky/props.js
new file mode 100644
index 0000000..c2ca8da
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-sticky/props.js
@@ -0,0 +1,40 @@
+export default {
+ props: {
+ // ���������������������������������������������������������������H5���������NavigationBar���44px
+ offsetTop: {
+ type: [String, Number],
+ default: uni.$u.props.sticky.offsetTop
+ },
+ // ���������������������������
+ customNavHeight: {
+ type: [String, Number],
+ // #ifdef H5
+ // H5���������������������������������������������������������������������������������������������������������
+ default: 44,
+ // #endif
+ // #ifndef H5
+ default: uni.$u.props.sticky.customNavHeight
+ // #endif
+ },
+ // ������������������������
+ disabled: {
+ type: Boolean,
+ default: uni.$u.props.sticky.disabled
+ },
+ // ���������������������������
+ bgColor: {
+ type: String,
+ default: uni.$u.props.sticky.bgColor
+ },
+ // z-index���
+ zIndex: {
+ type: [String, Number],
+ default: uni.$u.props.sticky.zIndex
+ },
+ // ���������������������
+ index: {
+ type: [String, Number],
+ default: uni.$u.props.sticky.index
+ }
+ }
+}
diff --git a/uni_modules/uview-ui/components/u-sticky/u-sticky.vue b/uni_modules/uview-ui/components/u-sticky/u-sticky.vue
new file mode 100644
index 0000000..ff74688
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-sticky/u-sticky.vue
@@ -0,0 +1,212 @@
+<template>
+ <view
+ class="u-sticky"
+ :id="elId"
+ :style="[style]"
+ >
+ <view
+ :style="[stickyContent]"
+ class="u-sticky__content"
+ >
+ <slot />
+ </view>
+ </view>
+</template>
+
+<script>
+ import props from './props.js';;
+ /**
+ * sticky ������
+ * @description ������������CSS���position: sticky��������������������������������������������������������������������������� ������������������������������������������������������������������������������������������������������������������
+ * @tutorial https://www.uviewui.com/components/sticky.html
+ * @property {String ��� Number} offsetTop ������������������������������������px��������� 0 ���
+ * @property {String ��� Number} customNavHeight ��������������������������� ���h5 ������44 ������������ 0 ���
+ * @property {Boolean} disabled ������������������������ ��������� false ���
+ * @property {String} bgColor ��������������������������� '#ffffff' ���
+ * @property {String ��� Number} zIndex ������������z-index���
+ * @property {String ��� Number} index ������������������������������������������������
+ * @property {Object} customStyle ������������������������������
+ * @event {Function} fixed ���������������������
+ * @event {Function} unfixed ���������������������������
+ * @example <u-sticky offsetTop="200"><view>���������������������������������������������</view></u-sticky>
+ */
+ export default {
+ name: 'u-sticky',
+ mixins: [uni.$u.mpMixin, uni.$u.mixin, props],
+ data() {
+ return {
+ cssSticky: false, // ������������css���sticky������
+ stickyTop: 0, // ���������top���������������������������������������������������������������������offsetTop���
+ elId: uni.$u.guid(),
+ left: 0, // js���������������������������������������postition: fixed���������������������������������������������������������������������������������left���height���width������
+ width: 'auto',
+ height: 'auto',
+ fixed: false, // js������������������������������������
+ }
+ },
+ computed: {
+ style() {
+ const style = {}
+ if(!this.disabled) {
+ if (this.cssSticky) {
+ style.position = 'sticky'
+ style.zIndex = this.uZindex
+ style.top = uni.$u.addUnit(this.stickyTop)
+ } else {
+ style.height = this.fixed ? this.height + 'px' : 'auto'
+ }
+ } else {
+ // ������������������������������������relative(nvue)������nvue���static������������������
+ // #ifdef APP-NVUE
+ style.position = 'relative'
+ // #endif
+ // #ifndef APP-NVUE
+ style.position = 'static'
+ // #endif
+ }
+ style.backgroundColor = this.bgColor
+ return uni.$u.deepMerge(uni.$u.addStyle(this.customStyle), style)
+ },
+ // ���������������������
+ stickyContent() {
+ const style = {}
+ if (!this.cssSticky) {
+ style.position = this.fixed ? 'fixed' : 'static'
+ style.top = this.stickyTop + 'px'
+ style.left = this.left + 'px'
+ style.width = this.width == 'auto' ? 'auto' : this.width + 'px'
+ style.zIndex = this.uZindex
+ }
+ return style
+ },
+ uZindex() {
+ return this.zIndex ? this.zIndex : uni.$u.zIndex.sticky
+ }
+ },
+ mounted() {
+ this.init()
+ },
+ methods: {
+ init() {
+ this.getStickyTop()
+ // ���������������������
+ this.checkSupportCssSticky()
+ // ���������������css sticky������������js���������������������������������css������
+ if (!this.cssSticky) {
+ !this.disabled && this.initObserveContent()
+ }
+ },
+ initObserveContent() {
+ // ���������������������������������������js���������������������������������������������������������"������"
+ this.$uGetRect('#' + this.elId).then((res) => {
+ this.height = res.height
+ this.left = res.left
+ this.width = res.width
+ this.$nextTick(() => {
+ this.observeContent()
+ })
+ })
+ },
+ observeContent() {
+ // ������������������������
+ this.disconnectObserver('contentObserver')
+ const contentObserver = uni.createIntersectionObserver({
+ // ���������������������
+ thresholds: [0.95, 0.98, 1]
+ })
+ // ���������������������������������
+ contentObserver.relativeToViewport({
+ top: -this.stickyTop
+ })
+ // ���������������������
+ contentObserver.observe(`#${this.elId}`, res => {
+ this.setFixed(res.boundingClientRect.top)
+ })
+ this.contentObserver = contentObserver
+ },
+ setFixed(top) {
+ // ������������������������������������
+ const fixed = top <= this.stickyTop
+ this.fixed = fixed
+ },
+ disconnectObserver(observerName) {
+ // ���������������������������
+ const observer = this[observerName]
+ observer && observer.disconnect()
+ },
+ getStickyTop() {
+ this.stickyTop = uni.$u.getPx(this.offsetTop) + uni.$u.getPx(this.customNavHeight)
+ },
+ async checkSupportCssSticky() {
+ // #ifdef H5
+ // H5������������������������������������������css sticky���������������������������������������������������
+ if (this.checkCssStickyForH5()) {
+ this.cssSticky = true
+ }
+ // #endif
+
+ // ������������������������8.0������������������������css sticky���(������������7���������������������������������sticky)
+ if (uni.$u.os() === 'android' && Number(uni.$u.sys().system) > 8) {
+ this.cssSticky = true
+ }
+
+ // APP-Vue������������������������computedStyle������������������css sticky
+ // #ifdef APP-VUE || MP-WEIXIN
+ this.cssSticky = await this.checkComputedStyle()
+ // #endif
+
+ // ios���������ios6���������������������css sticky���
+ if (uni.$u.os() === 'ios') {
+ this.cssSticky = true
+ }
+
+ // nvue������������css sticky���
+ // #ifdef APP-NVUE
+ this.cssSticky = true
+ // #endif
+ },
+ // ���APP������������������������������uni.createSelectorQuery������������������������css sticky
+ checkComputedStyle() {
+ // ���������������������������������������������������������������
+ // #ifdef APP-VUE || MP-WEIXIN
+ return new Promise(resolve => {
+ uni.createSelectorQuery().in(this).select('.u-sticky').fields({
+ computedStyle: ["position"]
+ }).exec(e => {
+ resolve('sticky' === e[0].position)
+ })
+ })
+ // #endif
+ },
+ // H5���������������������������������������������css sticky
+ // ���������������������������sticky������
+ checkCssStickyForH5() {
+ // ���������������������������������������������������������������
+ // #ifdef H5
+ const vendorList = ['', '-webkit-', '-ms-', '-moz-', '-o-'],
+ vendorListLength = vendorList.length,
+ stickyElement = document.createElement('div')
+ for (let i = 0; i < vendorListLength; i++) {
+ stickyElement.style.position = vendorList[i] + 'sticky'
+ if (stickyElement.style.position !== '') {
+ return true
+ }
+ }
+ return false;
+ // #endif
+ }
+ },
+ beforeDestroy() {
+ this.disconnectObserver('contentObserver')
+ }
+ }
+</script>
+
+<style lang="scss" scoped>
+ .u-sticky {
+ /* #ifdef APP-VUE || MP-WEIXIN */
+ // ���������������sticky������������������������������APP������uni.createSelectorQuery������������������css sticky������
+ position: sticky;
+ /* #endif */
+ }
+</style>
diff --git a/uni_modules/uview-ui/components/u-subsection/props.js b/uni_modules/uview-ui/components/u-subsection/props.js
new file mode 100644
index 0000000..5675eaa
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-subsection/props.js
@@ -0,0 +1,49 @@
+export default {
+ props: {
+ // tab���������
+ list: {
+ type: Array,
+ default: uni.$u.props.subsection.list
+ },
+ // ���������������tab���index
+ current: {
+ type: [String, Number],
+ default: uni.$u.props.subsection.current
+ },
+ // ���������������
+ activeColor: {
+ type: String,
+ default: uni.$u.props.subsection.activeColor
+ },
+ // ������������������
+ inactiveColor: {
+ type: String,
+ default: uni.$u.props.subsection.inactiveColor
+ },
+ // ���������������mode=button������������������mode=subsection������������������
+ mode: {
+ type: String,
+ default: uni.$u.props.subsection.mode
+ },
+ // ������������
+ fontSize: {
+ type: [String, Number],
+ default: uni.$u.props.subsection.fontSize
+ },
+ // ������tab���������������������
+ bold: {
+ type: Boolean,
+ default: uni.$u.props.subsection.bold
+ },
+ // mode = button������������������������
+ bgColor: {
+ type: String,
+ default: uni.$u.props.subsection.bgColor
+ },
+ // ���list������������������������������
+ keyName: {
+ type: String,
+ default: uni.$u.props.subsection.keyName
+ }
+ }
+}
diff --git a/uni_modules/uview-ui/components/u-subsection/u-subsection.vue b/uni_modules/uview-ui/components/u-subsection/u-subsection.vue
new file mode 100644
index 0000000..cc4d540
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-subsection/u-subsection.vue
@@ -0,0 +1,299 @@
+<template>
+ <view
+ class="u-subsection"
+ ref="u-subsection"
+ :class="[`u-subsection--${mode}`]"
+ :style="[$u.addStyle(customStyle), wrapperStyle]"
+ >
+ <view
+ class="u-subsection__bar"
+ ref="u-subsection__bar"
+ :style="[barStyle]"
+ :class="[
+ mode === 'button' && 'u-subsection--button__bar',
+ current === 0 &&
+ mode === 'subsection' &&
+ 'u-subsection__bar--first',
+ current > 0 &&
+ current < list.length - 1 &&
+ mode === 'subsection' &&
+ 'u-subsection__bar--center',
+ current === list.length - 1 &&
+ mode === 'subsection' &&
+ 'u-subsection__bar--last',
+ ]"
+ ></view>
+ <view
+ class="u-subsection__item"
+ :class="[
+ `u-subsection__item--${index}`,
+ index < list.length - 1 &&
+ 'u-subsection__item--no-border-right',
+ index === 0 && 'u-subsection__item--first',
+ index === list.length - 1 && 'u-subsection__item--last',
+ ]"
+ :ref="`u-subsection__item--${index}`"
+ :style="[itemStyle(index)]"
+ @tap="clickHandler(index)"
+ v-for="(item, index) in list"
+ :key="index"
+ >
+ <text
+ class="u-subsection__item__text"
+ :style="[textStyle(index)]"
+ >{{ getText(item) }}</text
+ >
+ </view>
+ </view>
+</template>
+
+<script>
+// #ifdef APP-NVUE
+const dom = uni.requireNativePlugin("dom");
+const animation = uni.requireNativePlugin("animation");
+// #endif
+import props from "./props.js";
+/**
+ * Subsection ���������
+ * @description ������������������������������������������������������������������������
+ * @tutorial https://www.uviewui.com/components/subsection.html
+ * @property {Array} list tab���������
+ * @property {String ��� Number} current ���������������tab���index��������� 0 ���
+ * @property {String} activeColor ��������������������������� '#3c9cff' ���
+ * @property {String} inactiveColor ������������������������������ '#303133' ���
+ * @property {String} mode ���������������mode=button������������������mode=subsection��������������������������� 'button' ���
+ * @property {String ��� Number} fontSize ���������������������px��������� 12 ���
+ * @property {Boolean} bold ������������������������������������������ true ���
+ * @property {String} bgColor ���������������������mode���button������������������ '#eeeeef' ���
+ * @property {Object} customStyle ���������������������������������
+ * @property {String} keyName ���`list`��������������������������������������� 'name' ���
+ *
+ * @event {Function} change ������������������������������������ ������ index������������index���������������0������
+ * @example <u-subsection :list="list" :current="curNow" @change="sectionChange"></u-subsection>
+ */
+export default {
+ name: "u-subsection",
+ mixins: [uni.$u.mpMixin, uni.$u.mixin, props],
+ data() {
+ return {
+ // ������������
+ itemRect: {
+ width: 0,
+ height: 0,
+ },
+ };
+ },
+ watch: {
+ list(newValue, oldValue) {
+ this.init();
+ },
+ current: {
+ immediate: true,
+ handler(n) {
+ // #ifdef APP-NVUE
+ // ���������nvue������������������translateX���������������������������������������������������������������������
+ // ������animation������������������
+ const ref = this.$refs?.["u-subsection__bar"]?.ref;
+ // ���������ref���������(���������������������������������������������dom������������������������������ref)������������100ms������������������������������(���������������������������������)������������������
+ uni.$u.sleep(ref ? 0 : 100).then(() => {
+ animation.transition(this.$refs["u-subsection__bar"].ref, {
+ styles: {
+ transform: `translateX(${
+ n * this.itemRect.width
+ }px)`,
+ transformOrigin: "center center",
+ },
+ duration: 300,
+ });
+ });
+ // #endif
+ },
+ },
+ },
+ computed: {
+ wrapperStyle() {
+ const style = {};
+ // button���������������������������
+ if (this.mode === "button") {
+ style.backgroundColor = this.bgColor;
+ }
+ return style;
+ },
+ // ���������������
+ barStyle() {
+ const style = {};
+ style.width = `${this.itemRect.width}px`;
+ style.height = `${this.itemRect.height}px`;
+ // ������translateX������������������������������������������*item���������
+ // #ifndef APP-NVUE
+ style.transform = `translateX(${
+ this.current * this.itemRect.width
+ }px)`;
+ // #endif
+ if (this.mode === "subsection") {
+ // ���subsection������������������������������������������������������������������������������translateX������������������������������overflow: hidden���������������������
+ style.backgroundColor = this.activeColor;
+ }
+ return style;
+ },
+ // ���������item���������
+ itemStyle(index) {
+ return (index) => {
+ const style = {};
+ if (this.mode === "subsection") {
+ // ������border���������
+ style.borderColor = this.activeColor;
+ style.borderWidth = "1px";
+ style.borderStyle = "solid";
+ }
+ return style;
+ };
+ },
+ // ���������������������
+ textStyle(index) {
+ return (index) => {
+ const style = {};
+ style.fontWeight =
+ this.bold && this.current === index ? "bold" : "normal";
+ style.fontSize = uni.$u.addUnit(this.fontSize);
+ // subsection���������������������������������������������
+ if (this.mode === "subsection") {
+ style.color =
+ this.current === index ? "#fff" : this.inactiveColor;
+ } else {
+ // button������������������������������������������activeColor
+ style.color =
+ this.current === index
+ ? this.activeColor
+ : this.inactiveColor;
+ }
+ return style;
+ };
+ },
+ },
+ mounted() {
+ this.init();
+ },
+ methods: {
+ init() {
+ uni.$u.sleep().then(() => this.getRect());
+ },
+ // ������������������
+ getText(item) {
+ return typeof item === 'object' ? item[this.keyName] : item
+ },
+ // ���������������������
+ getRect() {
+ // #ifndef APP-NVUE
+ this.$uGetRect(".u-subsection__item--0").then((size) => {
+ this.itemRect = size;
+ });
+ // #endif
+
+ // #ifdef APP-NVUE
+ const ref = this.$refs["u-subsection__item--0"][0];
+ ref &&
+ dom.getComponentRect(ref, (res) => {
+ this.itemRect = res.size;
+ });
+ // #endif
+ },
+ clickHandler(index) {
+ this.$emit("change", index);
+ },
+ },
+};
+</script>
+
+<style lang="scss" scoped>
+@import "../../libs/css/components.scss";
+
+.u-subsection {
+ @include flex;
+ position: relative;
+ overflow: hidden;
+ /* #ifndef APP-NVUE */
+ width: 100%;
+ box-sizing: border-box;
+ /* #endif */
+
+ &--button {
+ height: 32px;
+ background-color: rgb(238, 238, 239);
+ padding: 3px;
+ border-radius: 3px;
+ align-items: stretch;
+
+ &__bar {
+ background-color: #ffffff;
+ border-radius: 3px !important;
+ }
+ }
+
+ &--subsection {
+ height: 30px;
+ }
+
+ &__bar {
+ position: absolute;
+ /* #ifndef APP-NVUE */
+ transition-property: transform, color;
+ transition-duration: 0.3s;
+ transition-timing-function: ease-in-out;
+ /* #endif */
+
+ &--first {
+ border-top-left-radius: 3px;
+ border-bottom-left-radius: 3px;
+ border-top-right-radius: 0px;
+ border-bottom-right-radius: 0px;
+ }
+
+ &--center {
+ border-top-left-radius: 0px;
+ border-bottom-left-radius: 0px;
+ border-top-right-radius: 0px;
+ border-bottom-right-radius: 0px;
+ }
+
+ &--last {
+ border-top-left-radius: 0px;
+ border-bottom-left-radius: 0px;
+ border-top-right-radius: 3px;
+ border-bottom-right-radius: 3px;
+ }
+ }
+
+ &__item {
+ @include flex;
+ flex: 1;
+ justify-content: center;
+ align-items: center;
+ // vue���������������������������������������������������������������������item������������������������
+ position: relative;
+
+ &--no-border-right {
+ border-right-width: 0 !important;
+ }
+
+ &--first {
+ border-top-left-radius: 3px;
+ border-bottom-left-radius: 3px;
+ }
+
+ &--last {
+ border-top-right-radius: 3px;
+ border-bottom-right-radius: 3px;
+ }
+
+ &__text {
+ font-size: 12px;
+ line-height: 12px;
+ @include flex;
+ align-items: center;
+ transition-property: color;
+ transition-duration: 0.3s;
+ }
+ }
+}
+</style>
diff --git a/uni_modules/uview-ui/components/u-swipe-action-item/index - backup.wxs b/uni_modules/uview-ui/components/u-swipe-action-item/index - backup.wxs
new file mode 100644
index 0000000..04cab92
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-swipe-action-item/index - backup.wxs
@@ -0,0 +1,256 @@
+/**
+ * ������wxs������������������APP-VUE������������QQ���������������H5������
+ * wxs���������������es6���������������������������var���������������������������������������������������
+ */
+
+// ������������
+function touchstart(event, ownerInstance) {
+ // ������������������������ComponentDescriptor������
+ var instance = event.instance
+ // wxs������������������������������������������������������������������touchstart���touchmove���������������������������������������
+ var state = instance.getState()
+ if (state.disable) return
+ var touches = event.touches
+ // ������������������������������������������������������
+ if (touches && touches.length > 1) return
+ // ������������������������������
+ state.moving = true
+ // ���������������������������������
+ state.startX = touches[0].pageX
+ state.startY = touches[0].pageY
+}
+
+// ������������
+function touchmove(event, ownerInstance) {
+ // ������������������������ComponentDescriptor������
+ var instance = event.instance
+ // wxs������������������������
+ var state = instance.getState()
+ if (state.disabled || !state.moving) return
+
+ var touches = event.touches
+ var pageX = touches[0].pageX
+ var pageY = touches[0].pageY
+ var moveX = pageX - state.startX
+ var moveY = pageY - state.startY
+ var buttonsWidth = state.buttonsWidth
+
+ // ���������X���������������Y���������������������������������������������������X���������������45���������������������������
+ if (Math.abs(moveX) > Math.abs(moveY) || Math.abs(moveX) > state.threshold) {
+ event.preventDefault()
+ event.stopPropagation()
+ }
+ // ���������������X���������������Y���������������������������������������������������������Y���������������45���������������������������������������������������������������������
+ if (Math.abs(moveX) < Math.abs(moveY)) return
+
+ // ���������������������������������������������������������������������������X������������������0������������������
+ // ������������������return������������������������������������������������������������������������������������������������
+ // ������������������������0
+ if (state.status === 'open') {
+ // ���������������������������������������������
+ if (moveX < 0) moveX = 0
+ // ������������������������������������������������������������������
+ if (moveX > buttonsWidth) moveX = buttonsWidth
+ // ������������������������������������������������������������������������
+ moveSwipeAction(-buttonsWidth + moveX, instance, ownerInstance)
+ } else {
+ // ������������������������������������
+ if (moveX > 0) moveX = 0
+ // ���������������������������������������������������������������������������������������������������������������������������������
+ if (Math.abs(moveX) > buttonsWidth) moveX = -buttonsWidth
+ // ������������������������������������������������������������������������������������������������������
+ moveSwipeAction(moveX, instance, ownerInstance)
+ }
+}
+
+// ������������
+function touchend(event, ownerInstance) {
+ // ������������������������ComponentDescriptor������
+ var instance = event.instance
+ // wxs������������������������
+ var state = instance.getState()
+ if (!state.moving || state.disabled) return
+ var touches = event.changedTouches ? event.changedTouches[0] : {}
+ var pageX = touches.pageX
+ var pageY = touches.pageY
+ var moveX = pageX - state.startX
+ if (state.status === 'open') {
+ // ���������������������������������������������������
+ if (moveX < 0) return
+ // ������������������������������������������������moveX���0������������������������������������������������������������
+ if (moveX === 0) {
+ return closeSwipeAction(instance, ownerInstance)
+ }
+ // ���������������������������������������������������������������������������������������������������������
+ if (Math.abs(moveX) < state.threshold) {
+ openSwipeAction(instance, ownerInstance)
+ } else {
+ // ������������������������������������������������������
+ closeSwipeAction(instance, ownerInstance)
+ }
+ } else {
+ // ���������������������������������������������
+ if (moveX > 0) return
+ // ������������
+ if (Math.abs(moveX) < state.threshold) {
+ closeSwipeAction(instance, ownerInstance)
+ } else {
+ openSwipeAction(instance, ownerInstance)
+ }
+ }
+}
+
+// ������������������
+function getDuration(value) {
+ if (value.toString().indexOf('s') >= 0) return value
+ return value > 30 ? value + 'ms' : value + 's'
+}
+
+// ������������������������������������
+function getMoveDirection(instance, ownerInstance) {
+ var state = instance.getState()
+}
+
+// ���������������������������������������������������������������������
+function moveSwipeAction(moveX, instance, ownerInstance) {
+ var state = instance.getState()
+ // ���������������������������������������������������������������������
+ var buttons = ownerInstance.selectAllComponents('.u-swipe-action-item__right__button')
+ var len = buttons.length
+ var previewButtonsMoveX = 0
+
+ // ���������������������������������
+ instance.requestAnimationFrame(function() {
+ instance.setStyle({
+ // ������translateX������
+ 'transition': 'none',
+ transform: 'translateX(' + moveX + 'px)',
+ '-webkit-transform': 'translateX(' + moveX + 'px)'
+ })
+ // ������������������
+ for (var i = len - 1; i >= 0; i--) {
+ // ���������������������������������������������������
+ var translateX = state.buttons[i].width / state.buttonsWidth * moveX
+ // ���������������������������������������������������������������������������������������������������������������������
+ var realTranslateX = translateX + previewButtonsMoveX
+ buttons[i].setStyle({
+ // ���������������������������������������������������������������������������������������������������������������������������������������������������
+ 'transition': 'none',
+ 'transform': 'translateX(' + realTranslateX + 'px)',
+ '-webkit-transform': 'translateX(' + realTranslateX + 'px)'
+ })
+ // ���������������������������������������������������������
+ previewButtonsMoveX += translateX
+ }
+ })
+}
+
+// ���������������������������
+function openSwipeAction(instance, ownerInstance) {
+ var state = instance.getState()
+ // ���������������������������������������������������������������������
+ var buttons = ownerInstance.selectAllComponents('.u-swipe-action-item__right__button')
+ var len = buttons.length
+ // ������duration������������
+ const duration = getDuration(state.duration)
+ // ������������������������������������������X������������������������
+ var buttonsWidth = -state.buttonsWidth
+ var previewButtonsMoveX = 0
+ instance.requestAnimationFrame(function() {
+ // ������������������������
+ instance.setStyle({
+ 'transition': 'transform ' + duration,
+ 'transform': 'translateX(' + buttonsWidth + 'px)',
+ '-webkit-transform': 'translateX(' + buttonsWidth + 'px)',
+ })
+ // ���������������������������������������������
+ for (var i = len - 1; i >= 0; i--) {
+ // ���������������������������������������������������
+ var translateX = state.buttons[i].width / state.buttonsWidth * buttonsWidth
+ // ���������������������������������������������������������������������������������������������������������������������
+ var realTranslateX = translateX + previewButtonsMoveX
+ buttons[i].setStyle({
+ // ������������������������������������������
+ 'transition': 'transform ' + duration,
+ 'transform': 'translateX(' + realTranslateX + 'px)',
+ '-webkit-transform': 'translateX(' + realTranslateX + 'px)'
+ })
+ // ���������������������������������������������������������
+ previewButtonsMoveX += translateX
+ }
+ })
+ setStatus('open', instance)
+}
+
+// ������������������������������open-���������������close-������������
+function setStatus(status, instance) {
+ var state = instance.getState()
+ state.status = status
+}
+
+// ���������������������������
+function closeSwipeAction(instance, ownerInstance) {
+ var state = instance.getState()
+ // ���������������������������������������������������������������������
+ var buttons = ownerInstance.selectAllComponents('.u-swipe-action-item__right__button')
+ var len = buttons.length
+ // ������duration������������
+ const duration = getDuration(state.duration)
+ instance.requestAnimationFrame(function() {
+ // ������������������������
+ instance.setStyle({
+ 'transition': 'transform ' + duration,
+ 'transform': 'translateX(0px)',
+ '-webkit-transform': 'translateX(0px)'
+ })
+ // ���������������������������������������������
+ for (var i = len - 1; i >= 0; i--) {
+ buttons[i].setStyle({
+ 'transition': 'transform ' + duration,
+ 'transform': 'translateX(0px)',
+ '-webkit-transform': 'translateX(0px)'
+ })
+ }
+ })
+ setStatus('close', instance)
+}
+
+// show���������������������
+function showChange(newValue, oldValue, ownerInstance, instance) {
+ var state = instance.getState()
+ if (state.disabled) return
+ // ������������������������
+ if (newValue) {
+ openSwipeAction(instance, ownerInstance)
+ } else {
+ closeSwipeAction(instance, ownerInstance)
+ }
+}
+
+// ������������������������
+function sizeChange(newValue, oldValue, ownerInstance, instance) {
+ // wxs������������������������
+ var state = instance.getState()
+ state.disabled = newValue.disabled
+ state.duration = newValue.duration
+ state.show = newValue.show
+ state.threshold = newValue.threshold
+ state.buttons = newValue.buttons
+
+ var len = state.buttons.length
+ if (len) {
+ var buttonsWidth = 0
+ var buttons = newValue.buttons
+ for (var i = 0; i < len; i++) {
+ buttonsWidth += buttons[i].width
+ }
+ }
+ state.buttonsWidth = buttonsWidth
+}
+
+module.exports = {
+ touchstart: touchstart,
+ touchmove: touchmove,
+ touchend: touchend,
+ sizeChange: sizeChange
+}
diff --git a/uni_modules/uview-ui/components/u-swipe-action-item/index.wxs b/uni_modules/uview-ui/components/u-swipe-action-item/index.wxs
new file mode 100644
index 0000000..728275f
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-swipe-action-item/index.wxs
@@ -0,0 +1,225 @@
+/**
+ * ������wxs������������������APP-VUE������������QQ���������������H5������
+ * wxs���������������es6���������������������������var���������������������������������������������������
+ */
+
+// ������������
+function touchstart(event, ownerInstance) {
+ // ������������������������ComponentDescriptor������
+ var instance = event.instance
+ // wxs������������������������������������������������������������������touchstart���touchmove���������������������������������������
+ var state = instance.getState()
+ if (state.disabled) return
+ var touches = event.touches
+ // ������������������������������������������������������
+ if (touches && touches.length > 1) return
+ // ������������������������������
+ state.moving = true
+ // ���������������������������������
+ state.startX = touches[0].pageX
+ state.startY = touches[0].pageY
+
+ ownerInstance.callMethod('closeOther')
+}
+
+// ������������
+function touchmove(event, ownerInstance) {
+ // ������������������������ComponentDescriptor������
+ var instance = event.instance
+ // wxs������������������������
+ var state = instance.getState()
+ if (state.disabled || !state.moving) return
+ var touches = event.touches
+ var pageX = touches[0].pageX
+ var pageY = touches[0].pageY
+ var moveX = pageX - state.startX
+ var moveY = pageY - state.startY
+ var buttonsWidth = state.buttonsWidth
+
+ // ���������X���������������Y���������������������������������������������������X���������������45���������������������������
+ if (Math.abs(moveX) > Math.abs(moveY) || Math.abs(moveX) > state.threshold) {
+ event.preventDefault && event.preventDefault()
+ event.stopPropagation && event.stopPropagation()
+ }
+ // ���������������X���������������Y���������������������������������������������������������Y���������������45���������������������������������������������������������������������
+ if (Math.abs(moveX) < Math.abs(moveY)) return
+
+ // ���������������������������������������������������������������������������X������������������0������������������
+ // ������������������return������������������������������������������������������������������������������������������������
+ // ������������������������0
+ if (state.status === 'open') {
+ // ���������������������������������������������
+ if (moveX < 0) moveX = 0
+ // ������������������������������������������������������������������
+ if (moveX > buttonsWidth) moveX = buttonsWidth
+ // ������������������������������������������������������������������������
+ moveSwipeAction(-buttonsWidth + moveX, instance, ownerInstance)
+ } else {
+ // ������������������������������������
+ if (moveX > 0) moveX = 0
+ // ���������������������������������������������������������������������������������������������������������������������������������
+ if (Math.abs(moveX) > buttonsWidth) moveX = -buttonsWidth
+ // ������������������������������������������������������������������������������������������������������
+ moveSwipeAction(moveX, instance, ownerInstance)
+ }
+}
+
+// ������������
+function touchend(event, ownerInstance) {
+ // ������������������������ComponentDescriptor������
+ var instance = event.instance
+ // wxs������������������������
+ var state = instance.getState()
+ if (!state.moving || state.disabled) return
+ var touches = event.changedTouches ? event.changedTouches[0] : {}
+ var pageX = touches.pageX
+ var pageY = touches.pageY
+ var moveX = pageX - state.startX
+ if (state.status === 'open') {
+ // ���������������������������������������������������
+ if (moveX < 0) return
+ // ������������������������������������������������moveX���0������������������������������������������������������������
+ if (moveX === 0) {
+ return closeSwipeAction(instance, ownerInstance)
+ }
+ // ���������������������������������������������������������������������������������������������������������
+ if (Math.abs(moveX) < state.threshold) {
+ openSwipeAction(instance, ownerInstance)
+ } else {
+ // ������������������������������������������������������
+ closeSwipeAction(instance, ownerInstance)
+ }
+ } else {
+ // ���������������������������������������������
+ if (moveX > 0) return
+ // ������������
+ if (Math.abs(moveX) < state.threshold) {
+ closeSwipeAction(instance, ownerInstance)
+ } else {
+ openSwipeAction(instance, ownerInstance)
+ }
+ }
+}
+
+// ������������������
+function getDuration(value) {
+ if (value.toString().indexOf('s') >= 0) return value
+ return value > 30 ? value + 'ms' : value + 's'
+}
+
+// ������������������������������������
+function getMoveDirection(instance, ownerInstance) {
+ var state = instance.getState()
+}
+
+// ���������������������������������������������������������������������
+function moveSwipeAction(moveX, instance, ownerInstance) {
+ var state = instance.getState()
+ // ���������������������������������������������������������������������
+ var buttons = ownerInstance.selectAllComponents('.u-swipe-action-item__right__button')
+
+ // ���������������������������������
+ instance.requestAnimationFrame(function() {
+ instance.setStyle({
+ // ������translateX������
+ 'transition': 'none',
+ transform: 'translateX(' + moveX + 'px)',
+ '-webkit-transform': 'translateX(' + moveX + 'px)'
+ })
+ })
+}
+
+// ���������������������������
+function openSwipeAction(instance, ownerInstance) {
+ var state = instance.getState()
+ // ���������������������������������������������������������������������
+ var buttons = ownerInstance.selectAllComponents('.u-swipe-action-item__right__button')
+ // ������duration������������
+ var duration = getDuration(state.duration)
+ // ������������������������������������������X������������������������
+ var buttonsWidth = -state.buttonsWidth
+ instance.requestAnimationFrame(function() {
+ // ������������������������
+ instance.setStyle({
+ 'transition': 'transform ' + duration,
+ 'transform': 'translateX(' + buttonsWidth + 'px)',
+ '-webkit-transform': 'translateX(' + buttonsWidth + 'px)',
+ })
+ })
+ setStatus('open', instance, ownerInstance)
+}
+
+// ������������������������������open-���������������close-������������
+function setStatus(status, instance, ownerInstance) {
+ var state = instance.getState()
+ state.status = status
+ ownerInstance.callMethod('setState', status)
+}
+
+// ���������������������������
+function closeSwipeAction(instance, ownerInstance) {
+ var state = instance.getState()
+ // ���������������������������������������������������������������������
+ var buttons = ownerInstance.selectAllComponents('.u-swipe-action-item__right__button')
+ var len = buttons.length
+ // ������duration������������
+ var duration = getDuration(state.duration)
+ instance.requestAnimationFrame(function() {
+ // ������������������������
+ instance.setStyle({
+ 'transition': 'transform ' + duration,
+ 'transform': 'translateX(0px)',
+ '-webkit-transform': 'translateX(0px)'
+ })
+ // ���������������������������������������������
+ for (var i = len - 1; i >= 0; i--) {
+ buttons[i].setStyle({
+ 'transition': 'transform ' + duration,
+ 'transform': 'translateX(0px)',
+ '-webkit-transform': 'translateX(0px)'
+ })
+ }
+ })
+ setStatus('close', instance, ownerInstance)
+}
+
+// status���������������������
+function statusChange(newValue, oldValue, ownerInstance, instance) {
+ var state = instance.getState()
+ if (state.disabled) return
+ // ������������������������
+ if (newValue === 'close' && state.status === 'open') {
+ closeSwipeAction(instance, ownerInstance)
+ } else if(newValue === 'open' && state.status === 'close') {
+ openSwipeAction(instance, ownerInstance)
+ }
+}
+
+// ������������������������
+function sizeChange(newValue, oldValue, ownerInstance, instance) {
+ // wxs������������������������
+ var state = instance.getState()
+ state.disabled = newValue.disabled
+ state.duration = newValue.duration
+ state.show = newValue.show
+ state.threshold = newValue.threshold
+ state.buttons = newValue.buttons
+
+ if (state.buttons) {
+ var len = state.buttons.length
+ var buttonsWidth = 0
+ var buttons = newValue.buttons
+ for (var i = 0; i < len; i++) {
+ buttonsWidth += buttons[i].width
+ }
+ }
+ state.buttonsWidth = buttonsWidth
+}
+
+module.exports = {
+ touchstart: touchstart,
+ touchmove: touchmove,
+ touchend: touchend,
+ sizeChange: sizeChange,
+ statusChange: statusChange
+}
diff --git a/uni_modules/uview-ui/components/u-swipe-action-item/nvue - backup.js b/uni_modules/uview-ui/components/u-swipe-action-item/nvue - backup.js
new file mode 100644
index 0000000..6b9f116
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-swipe-action-item/nvue - backup.js
@@ -0,0 +1,270 @@
+// nvue������dom���������������������dom���������������
+const dom = uni.requireNativePlugin('dom')
+// nvue���������������������������������������������uni.animation������������uni.animation������������nvue
+const animation = uni.requireNativePlugin('animation')
+
+export default {
+ data() {
+ return {
+ // ���������������
+ moving: false,
+ // ���������open-���������������close-������������
+ status: 'close',
+ // ������������������X���Y���������
+ startX: 0,
+ startY: 0,
+ // ���������������������������������������
+ buttons: [],
+ // ������������������������
+ buttonsWidth: 0,
+ // ���������������������������������
+ moveX: 0,
+ // ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������
+ lastX: 0
+ }
+ },
+ computed: {
+ // ������������������
+ getDuratin() {
+ let duration = String(this.duration)
+ // ������ms������������������ms���������������
+ if (duration.indexOf('ms') >= 0) return parseInt(duration)
+ // ������s������������������������ms������������������������1000
+ if (duration.indexOf('s') >= 0) return parseInt(duration) * 1000
+ // ���������������������������������30������������s������
+ duration = Number(duration)
+ return duration < 30 ? duration * 1000 : duration
+ }
+ },
+ watch: {
+ show: {
+ immediate: true,
+ handler(n) {
+ // if(n === true) {
+ // uni.$u.sleep(50).then(() => {
+ // this.openSwipeAction()
+ // })
+ // } else {
+ // this.closeSwipeAction()
+ // }
+ }
+ }
+ },
+ mounted() {
+ uni.$u.sleep(20).then(() => {
+ this.queryRect()
+ })
+ },
+ methods: {
+ close() {
+ this.closeSwipeAction()
+ },
+ // ���������������
+ touchstart(event) {
+ if (this.disabled) return
+ this.closeOther()
+ const { touches } = event
+ // ���������������������������������
+ this.startX = touches[0].pageX
+ this.startY = touches[0].pageY
+ },
+ // // ������������
+ touchmove(event) {
+ if (this.disabled) return
+ const { touches } = event
+ const { pageX } = touches[0]
+ const { pageY } = touches[0]
+ let moveX = pageX - this.startX
+ const moveY = pageY - this.startY
+ const { buttonsWidth } = this
+ const len = this.buttons.length
+
+ // ������������������������������������������������������������������������������������
+ if (Math.abs(pageX - this.lastX) < 0.3) return
+ this.lastX = pageX
+
+ // ���������X���������������Y���������������������������������������������������X���������������45���������������������������
+ if (Math.abs(moveX) > Math.abs(moveY) || Math.abs(moveX) > this.threshold) {
+ event.stopPropagation()
+ }
+ // ���������������X���������������Y���������������������������������������������������������Y���������������45���������������������������������������������������������������������
+ if (Math.abs(moveX) < Math.abs(moveY)) return
+
+ // ���������������������������������������������������������������������������X������������������0������������������
+ // ������������������return������������������������������������������������������������������������������������������������
+ // ������������������������0
+ if (this.status === 'open') {
+ // ���������������������������������������������
+ if (moveX < 0) moveX = 0
+ // ������������������������������������������������������������������
+ if (moveX > buttonsWidth) moveX = buttonsWidth
+ // ������������������������������������������������������������������������
+ this.moveSwipeAction(-buttonsWidth + moveX)
+ } else {
+ // ������������������������������������
+ if (moveX > 0) moveX = 0
+ // ���������������������������������������������������������������������������������������������������������������������������������
+ if (Math.abs(moveX) > buttonsWidth) moveX = -buttonsWidth
+ // ������������������������������������������������������������������������������������������������������
+ this.moveSwipeAction(moveX)
+ }
+ },
+ // ���������������������
+ touchend(event) {
+ if (this.disabled) return
+ const touches = event.changedTouches ? event.changedTouches[0] : {}
+ const { pageX } = touches
+ const { pageY } = touches
+ const { buttonsWidth } = this
+ this.moveX = pageX - this.startX
+ if (this.status === 'open') {
+ // ���������������������������������������������������
+ if (this.moveX < 0) this.moveX = 0
+ if (this.moveX > buttonsWidth) this.moveX = buttonsWidth
+ // ������������������������������������������������moveX���0������������������������������������������������������������
+ if (this.moveX === 0) {
+ return this.closeSwipeAction()
+ }
+ // ���������������������������������������������������������������������������������������������������������
+ if (Math.abs(this.moveX) < this.threshold) {
+ this.openSwipeAction()
+ } else {
+ // ������������������������������������������������������
+ this.closeSwipeAction()
+ }
+ } else {
+ // ���������������������������������������������
+ if (this.moveX >= 0) this.moveX = 0
+ if (this.moveX <= -buttonsWidth) this.moveX = -buttonsWidth
+ // ������������
+ if (Math.abs(this.moveX) < this.threshold) {
+ this.closeSwipeAction()
+ } else {
+ this.openSwipeAction()
+ }
+ }
+ },
+ // ���������������������������������������������������������������������
+ moveSwipeAction(moveX) {
+ if (this.moving) return
+ this.moving = true
+
+ let previewButtonsMoveX = 0
+ const len = this.buttons.length
+ animation.transition(this.$refs['u-swipe-action-item__content'].ref, {
+ styles: {
+ transform: `translateX(${moveX}px)`
+ },
+ timingFunction: 'linear'
+ }, () => {
+ this.moving = false
+ })
+ // ���������������������
+ for (let i = len - 1; i >= 0; i--) {
+ const buttonRef = this.$refs[`u-swipe-action-item__right__button-${i}`][0].ref
+ // ���������������������������������������������������
+ const translateX = this.buttons[i].width / this.buttonsWidth * moveX
+ // ���������������������������������������������������������������������������������������������������������������������
+ const realTranslateX = translateX + previewButtonsMoveX
+ animation.transition(buttonRef, {
+ styles: {
+ transform: `translateX(${realTranslateX}px)`
+ },
+ duration: 0,
+ delay: 0,
+ timingFunction: 'linear'
+ }, () => {})
+ // ���������������������������������������������������������
+ previewButtonsMoveX += translateX
+ }
+ },
+ // ������������
+ closeSwipeAction() {
+ if (this.status === 'close') return
+ this.moving = true
+ const { buttonsWidth } = this
+ animation.transition(this.$refs['u-swipe-action-item__content'].ref, {
+ styles: {
+ transform: 'translateX(0px)'
+ },
+ duration: this.getDuratin,
+ timingFunction: 'ease-in-out'
+ }, () => {
+ this.status = 'close'
+ this.moving = false
+ this.closeHandler()
+ })
+ // ���������������������
+ const len = this.buttons.length
+ for (let i = len - 1; i >= 0; i--) {
+ const buttonRef = this.$refs[`u-swipe-action-item__right__button-${i}`][0].ref
+ // ������������������������������������
+ if (this.buttons.length === 0 || !this.buttons[i] || !this.buttons[i].width) return
+
+ animation.transition(buttonRef, {
+ styles: {
+ transform: 'translateX(0px)'
+ },
+ duration: this.getDuratin,
+ timingFunction: 'ease-in-out'
+ }, () => {})
+ }
+ },
+ // ������������
+ openSwipeAction() {
+ if (this.status === 'open') return
+ this.moving = true
+ const buttonsWidth = -this.buttonsWidth
+ let previewButtonsMoveX = 0
+ animation.transition(this.$refs['u-swipe-action-item__content'].ref, {
+ styles: {
+ transform: `translateX(${buttonsWidth}px)`
+ },
+ duration: this.getDuratin,
+ timingFunction: 'ease-in-out'
+ }, () => {
+ this.status = 'open'
+ this.moving = false
+ this.openHandler()
+ })
+ // ���������������������
+ const len = this.buttons.length
+ for (let i = len - 1; i >= 0; i--) {
+ const buttonRef = this.$refs[`u-swipe-action-item__right__button-${i}`][0].ref
+ // ������������������������������������
+ if (this.buttons.length === 0 || !this.buttons[i] || !this.buttons[i].width) return
+ // ���������������������������������������������������
+ const translateX = this.buttons[i].width / this.buttonsWidth * buttonsWidth
+ // ���������������������������������������������������������������������������������������������������������������������
+ const realTranslateX = translateX + previewButtonsMoveX
+ animation.transition(buttonRef, {
+ styles: {
+ transform: `translateX(${realTranslateX}px)`
+ },
+ duration: this.getDuratin,
+ timingFunction: 'ease-in-out'
+ }, () => {})
+ previewButtonsMoveX += translateX
+ }
+ },
+ // ������������������������
+ queryRect() {
+ // ���������������������������������getRectByDom������������promise
+ const promiseAll = this.rightOptions.map((item, index) => this.getRectByDom(this.$refs[`u-swipe-action-item__right__button-${index}`][0]))
+ // ������promise.all������������������������������������������������������������������
+ Promise.all(promiseAll).then((sizes) => {
+ this.buttons = sizes
+ // ���������������������������
+ this.buttonsWidth = sizes.reduce((sum, cur) => sum + cur.width, 0)
+ })
+ },
+ // ������nvue���dom���������������������������
+ getRectByDom(ref) {
+ return new Promise((resolve) => {
+ dom.getComponentRect(ref, (res) => {
+ resolve(res.size)
+ })
+ })
+ }
+ }
+}
diff --git a/uni_modules/uview-ui/components/u-swipe-action-item/nvue.js b/uni_modules/uview-ui/components/u-swipe-action-item/nvue.js
new file mode 100644
index 0000000..118e4cf
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-swipe-action-item/nvue.js
@@ -0,0 +1,174 @@
+// nvue������dom���������������������dom���������������
+const dom = uni.requireNativePlugin('dom');
+const bindingX = uni.requireNativePlugin('bindingx');
+const animation = uni.requireNativePlugin('animation');
+
+export default {
+ data() {
+ return {
+ // ������������������������
+ buttonsWidth: 0,
+ // ���������������������
+ moving: false
+ }
+ },
+ computed: {
+ // ������������������
+ getDuratin() {
+ let duration = String(this.duration)
+ // ������ms������������������ms���������������
+ if (duration.indexOf('ms') >= 0) return parseInt(duration)
+ // ������s������������������������ms������������������������1000
+ if (duration.indexOf('s') >= 0) return parseInt(duration) * 1000
+ // ���������������������������������30������������s������
+ duration = Number(duration)
+ return duration < 30 ? duration * 1000 : duration
+ }
+ },
+ watch: {
+ show(n) {
+ if(n) {
+ this.moveCellByAnimation('open')
+ } else {
+ this.moveCellByAnimation('close')
+ }
+ }
+ },
+ mounted() {
+ this.initialize()
+ },
+ methods: {
+ initialize() {
+ this.queryRect()
+ },
+ // ���������������������������������������������������������������������������
+ closeHandler() {
+ if(this.status === 'open') {
+ // ���������������������������������������������������������������������
+ return this.moveCellByAnimation('close') && this.unbindBindingX()
+ }
+ },
+ // ���������������
+ clickHandler() {
+ // ������������������������������������������
+ if(this.moving) return
+ // ������������������������������������
+ this.parent && this.parent.closeOther(this)
+ if(this.status === 'open') {
+ // ���������������������������������������������������������������������
+ return this.moveCellByAnimation('close') && this.unbindBindingX()
+ }
+ },
+ // ���������������
+ onTouchstart(e) {
+ // ������������������������������������disabled������������������
+ if(this.moving || this.disabled) {
+ return this.unbindBindingX()
+ }
+ if(this.status === 'open') {
+ // ���������������������������������������������������������������������
+ return this.moveCellByAnimation('close') && this.unbindBindingX()
+ }
+ // ������������������e������������������������
+ e?.stopPropagation && e.stopPropagation()
+ e?.preventDefault && e.preventDefault()
+ this.moving = true
+ // ������������ref
+ const content = this.getContentRef()
+ let expression = `min(max(${-this.buttonsWidth}, x), 0)`
+ // ������������������������������������
+ this.parent && this.parent.closeOther(this)
+
+ // ������������KPI������������BindingX
+ this.panEvent = bindingX.bind({
+ anchor: content,
+ eventType: 'pan',
+ props: [{
+ element: content,
+ // ������width���������������������������
+ property: 'transform.translateX',
+ expression
+ }]
+ }, (res) => {
+ this.moving = false
+ if (res.state === 'end' || res.state === 'exit') {
+ const deltaX = res.deltaX
+ if(deltaX <= -this.buttonsWidth || deltaX >= 0) {
+ // ���������������������������������������������������������������������������0������������������������������������������������������������������
+ // ���������������������������������
+ this.$nextTick(() => {
+ this.status = deltaX <= -this.buttonsWidth ? 'open' : 'close'
+ })
+ } else if(Math.abs(deltaX) > uni.$u.getPx(this.threshold)) {
+ // ���������������������������������������������������������������������������������������
+ // ������������������0���������������������������������
+ if(Math.abs(deltaX) < this.buttonsWidth) {
+ this.moveCellByAnimation(deltaX > 0 ? 'close' : 'open')
+ }
+ } else {
+ // ���������������������������������������(������������������������������������������bindingX)
+ this.moveCellByAnimation('close')
+ }
+ }
+ })
+ },
+ // ������bindingX
+ unbindBindingX() {
+ // ������������������������
+ if (this?.panEvent?.token != 0) {
+ bindingX.unbind({
+ token: this.panEvent?.token,
+ // pan���������������
+ eventType: 'pan'
+ })
+ }
+ },
+ // ������������������������
+ queryRect() {
+ // ���������������������������������getRectByDom������������promise
+ const promiseAll = this.options.map((item, index) => {
+ return this.getRectByDom(this.$refs[`u-swipe-action-item__right__button-${index}`][0])
+ })
+ // ������promise.all������������������������������������������������������������������
+ Promise.all(promiseAll).then(sizes => {
+ this.buttons = sizes
+ // ���������������������������
+ this.buttonsWidth = sizes.reduce((sum, cur) => sum + cur.width, 0)
+ })
+ },
+ // ������nvue���dom���������������������������
+ getRectByDom(ref) {
+ return new Promise(resolve => {
+ dom.getComponentRect(ref, res => {
+ resolve(res.size)
+ })
+ })
+ },
+ // ������������������������������������������
+ moveCellByAnimation(status = 'open') {
+ if(this.moving) return
+ // ������������������
+ this.moveing = true
+ const content = this.getContentRef()
+ const x = status === 'open' ? -this.buttonsWidth : 0
+ animation.transition(content, {
+ styles: {
+ transform: `translateX(${x}px)`,
+ },
+ duration: uni.$u.getDuration(this.duration, false),
+ timingFunction: 'ease-in-out'
+ }, () => {
+ this.moving = false
+ this.status = status
+ this.unbindBindingX()
+ })
+ },
+ // ������������ref
+ getContentRef() {
+ return this.$refs['u-swipe-action-item__content'].ref
+ },
+ beforeDestroy() {
+ this.unbindBindingX()
+ }
+ }
+}
diff --git a/uni_modules/uview-ui/components/u-swipe-action-item/props.js b/uni_modules/uview-ui/components/u-swipe-action-item/props.js
new file mode 100644
index 0000000..ed82a42
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-swipe-action-item/props.js
@@ -0,0 +1,41 @@
+export default {
+ props: {
+ // ������������������������
+ show: {
+ type: Boolean,
+ default: uni.$u.props.swipeActionItem.show
+ },
+ // ���������������������v-for���������index���������
+ name: {
+ type: [String, Number],
+ default: uni.$u.props.swipeActionItem.name
+ },
+ // ������������
+ disabled: {
+ type: Boolean,
+ default: uni.$u.props.swipeActionItem.disabled
+ },
+ // ������������������������swipe���������
+ autoClose: {
+ type: Boolean,
+ default: uni.$u.props.swipeActionItem.autoClose
+ },
+ // ������������������������������������������������������������������������
+ threshold: {
+ type: Number,
+ default: uni.$u.props.swipeActionItem.threshold
+ },
+ // ������������������
+ options: {
+ type: Array,
+ default() {
+ return uni.$u.props.swipeActionItem.rightOptions
+ }
+ },
+ // ���������������������������ms
+ duration: {
+ type: [String, Number],
+ default: uni.$u.props.swipeActionItem.duration
+ }
+ }
+}
diff --git a/uni_modules/uview-ui/components/u-swipe-action-item/u-swipe-action-item.vue b/uni_modules/uview-ui/components/u-swipe-action-item/u-swipe-action-item.vue
new file mode 100644
index 0000000..1fab304
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-swipe-action-item/u-swipe-action-item.vue
@@ -0,0 +1,190 @@
+<template>
+ <view class="u-swipe-action-item" ref="u-swipe-action-item">
+ <view class="u-swipe-action-item__right">
+ <slot name="button">
+ <view v-for="(item,index) in options" :key="index" class="u-swipe-action-item__right__button"
+ :ref="`u-swipe-action-item__right__button-${index}`" :style="[{
+ alignItems: item.style && item.style.borderRadius ? 'center' : 'stretch'
+ }]" @tap="buttonClickHandler(item, index)">
+ <view class="u-swipe-action-item__right__button__wrapper" :style="[{
+ backgroundColor: item.style && item.style.backgroundColor ? item.style.backgroundColor : '#C7C6CD',
+ borderRadius: item.style && item.style.borderRadius ? item.style.borderRadius : '0',
+ padding: item.style && item.style.borderRadius ? '0' : '0 15px',
+ }, item.style]">
+ <u-icon v-if="item.icon" :name="item.icon"
+ :color="item.style && item.style.color ? item.style.color : '#ffffff'"
+ :size="item.iconSize ? $u.addUnit(item.iconSize) : item.style && item.style.fontSize ? $u.getPx(item.style.fontSize) * 1.2 : 17"
+ :customStyle="{
+ marginRight: item.text ? '2px' : 0
+ }"></u-icon>
+ <text v-if="item.text" class="u-swipe-action-item__right__button__wrapper__text u-line-1"
+ :style="[{
+ color: item.style && item.style.color ? item.style.color : '#ffffff',
+ fontSize: item.style && item.style.fontSize ? item.style.fontSize : '16px',
+ lineHeight: item.style && item.style.fontSize ? item.style.fontSize : '16px',
+ }]">{{ item.text }}</text>
+ </view>
+ </view>
+ </slot>
+ </view>
+ <!-- #ifdef APP-VUE || MP-WEIXIN || H5 || MP-QQ -->
+ <view class="u-swipe-action-item__content" @touchstart="wxs.touchstart" @touchmove="wxs.touchmove"
+ @touchend="wxs.touchend" :status="status" :change:status="wxs.statusChange" :size="size"
+ :change:size="wxs.sizeChange">
+ <!-- #endif -->
+ <!-- #ifdef APP-NVUE -->
+ <view class="u-swipe-action-item__content" ref="u-swipe-action-item__content" @panstart="onTouchstart"
+ @tap="clickHandler">
+ <!-- #endif -->
+ <slot />
+ </view>
+ </view>
+</template>
+<!-- #ifdef APP-VUE || MP-WEIXIN || H5 || MP-QQ -->
+<script src="./index.wxs" module="wxs" lang="wxs"></script>
+<!-- #endif -->
+<script>
+ import touch from '../../libs/mixin/touch.js'
+ import props from './props.js';
+ // #ifdef APP-NVUE
+ import nvue from './nvue.js';
+ // #endif
+ // #ifdef APP-VUE || MP-WEIXIN || H5 || MP-QQ
+ import wxs from './wxs.js';
+ // #endif
+ /**
+ * SwipeActionItem ������������������������
+ * @description ���������������������������������������������������������������������������������������������
+ * @tutorial https://www.uviewui.com/components/swipeAction.html
+ * @property {Boolean} show ��������������������������������� false ���
+ * @property {String | Number} index ���������������������v-for���������index������
+ * @property {Boolean} disabled ��������������������� false ���
+ * @property {Boolean} autoClose ������������������������swipe������������������ true ���
+ * @property {Number} threshold ��������������������������������������������������������������������������������� 30 ���
+ * @property {Array} options ������������������
+ * @property {String | Number} duration ���������������������������ms��������� 350 ���
+ * @event {Function(index)} open ���������������������
+ * @event {Function(index)} close ���������������������
+ * @example <u-swipe-action><u-swipe-action-item :options="options1" ></u-swipe-action-item></u-swipe-action>
+ */
+ export default {
+ name: 'u-swipe-action-item',
+ mixins: [uni.$u.mpMixin, uni.$u.mixin, props, touch],
+ // #ifdef APP-NVUE
+ mixins: [uni.$u.mpMixin, uni.$u.mixin, props, nvue, touch],
+ // #endif
+ // #ifdef APP-VUE || MP-WEIXIN || H5 || MP-QQ
+ mixins: [uni.$u.mpMixin, uni.$u.mixin, props, touch, wxs],
+ // #endif
+ data() {
+ return {
+ // ���������������������
+ size: {},
+ // ���������u-swipe-action���������
+ parentData: {
+ autoClose: true,
+ },
+ // ���������������open-���������close-������
+ status: 'close',
+ }
+ },
+ watch: {
+ // ������wxs���������������������������������������������������������������������������������������
+ wxsInit(newValue, oldValue) {
+ this.queryRect()
+ }
+ },
+ computed: {
+ wxsInit() {
+ return [this.disabled, this.autoClose, this.threshold, this.options, this.duration]
+ }
+ },
+ mounted() {
+ this.init()
+ },
+ methods: {
+ init() {
+ // ������������������������
+ this.updateParentData()
+ // #ifndef APP-NVUE
+ uni.$u.sleep().then(() => {
+ this.queryRect()
+ })
+ // #endif
+ },
+ updateParentData() {
+ // ������������mixin���
+ this.getParentData('u-swipe-action')
+ },
+ // #ifndef APP-NVUE
+ // ������������
+ queryRect() {
+ this.$uGetRect('.u-swipe-action-item__right__button', true).then(buttons => {
+ this.size = {
+ buttons,
+ show: this.show,
+ disabled: this.disabled,
+ threshold: this.threshold,
+ duration: this.duration
+ }
+ })
+ },
+ // #endif
+ // ���������������
+ buttonClickHandler(item, index) {
+ this.$emit('click', {
+ index,
+ name: this.name
+ })
+ }
+ },
+ }
+</script>
+
+<style lang="scss" scoped>
+ @import "../../libs/css/components.scss";
+
+ .u-swipe-action-item {
+ position: relative;
+ overflow: hidden;
+ /* #ifndef APP-NVUE || MP-WEIXIN */
+ touch-action: pan-y;
+ /* #endif */
+
+ &__content {
+ background-color: #FFFFFF;
+ z-index: 10;
+ }
+
+ &__right {
+ position: absolute;
+ top: 0;
+ bottom: 0;
+ right: 0;
+ @include flex;
+
+ &__button {
+ @include flex;
+ justify-content: center;
+ overflow: hidden;
+ align-items: center;
+
+ &__wrapper {
+ @include flex;
+ align-items: center;
+ justify-content: center;
+ padding: 0 15px;
+
+ &__text {
+ @include flex;
+ align-items: center;
+ color: #FFFFFF;
+ font-size: 15px;
+ text-align: center;
+ justify-content: center;
+ }
+ }
+ }
+ }
+ }
+</style>
diff --git a/uni_modules/uview-ui/components/u-swipe-action-item/wxs.js b/uni_modules/uview-ui/components/u-swipe-action-item/wxs.js
new file mode 100644
index 0000000..ee49c10
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-swipe-action-item/wxs.js
@@ -0,0 +1,15 @@
+export default {
+ methods: {
+ // ���������������
+ closeHandler() {
+ this.status = 'close'
+ },
+ setState(status) {
+ this.status = status
+ },
+ closeOther() {
+ // ������������������������������������
+ this.parent && this.parent.closeOther(this)
+ }
+ }
+}
diff --git a/uni_modules/uview-ui/components/u-swipe-action/props.js b/uni_modules/uview-ui/components/u-swipe-action/props.js
new file mode 100644
index 0000000..3a84536
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-swipe-action/props.js
@@ -0,0 +1,9 @@
+export default {
+ props: {
+ // ������������������������swipe���������
+ autoClose: {
+ type: Boolean,
+ default: uni.$u.props.swipeAction.autoClose
+ }
+ }
+}
diff --git a/uni_modules/uview-ui/components/u-swipe-action/u-swipe-action.vue b/uni_modules/uview-ui/components/u-swipe-action/u-swipe-action.vue
new file mode 100644
index 0000000..ad8f019
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-swipe-action/u-swipe-action.vue
@@ -0,0 +1,67 @@
+<template>
+ <view class="u-swipe-action">
+ <slot></slot>
+ </view>
+</template>
+
+<script>
+ import props from './props.js';
+ /**
+ * SwipeAction ���������������
+ * @description ���������������������������������������������������������������������������������������������
+ * @tutorial https://www.uviewui.com/components/swipeAction.html
+ * @property {Boolean} autoClose ������������������������swipe���������
+ * @event {Function(index)} click ���������������������
+ * @example <u-swipe-action><u-swipe-action-item :rightOptions="options1" ></u-swipe-action-item></u-swipe-action>
+ */
+ export default {
+ name: 'u-swipe-action',
+ mixins: [uni.$u.mpMixin, uni.$u.mixin, props],
+ data() {
+ return {}
+ },
+ provide() {
+ return {
+ swipeAction: this
+ }
+ },
+ computed: {
+ // ������computed���������������������������u-swipe-action-item���������������������������������������������������������������������������������������������������������������
+ // ������������������������������������������������������parentData������������watch���������������������������������������������������������������(u-swipe-action-item)
+ // ���������������������������������������
+ parentData() {
+ return [this.autoClose]
+ }
+ },
+ watch: {
+ // ���������������������������������������������������������������������������������������
+ parentData() {
+ if (this.children.length) {
+ this.children.map(child => {
+ // ���������������(u-swipe-action-item)���������updateParentData���������������������������(������������������������������������������������������������������)
+ typeof(child.updateParentData) === 'function' && child.updateParentData()
+ })
+ }
+ },
+ },
+ created() {
+ this.children = []
+ },
+ methods: {
+ closeOther(child) {
+ if (this.autoClose) {
+ // ������������������������������������������������������������������������������
+ this.children.map((item, index) => {
+ if (child !== item) {
+ item.closeHandler()
+ }
+ })
+ }
+ }
+ }
+ }
+</script>
+
+<style lang="scss" scoped>
+
+</style>
diff --git a/uni_modules/uview-ui/components/u-swiper-indicator/props.js b/uni_modules/uview-ui/components/u-swiper-indicator/props.js
new file mode 100644
index 0000000..302aca7
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-swiper-indicator/props.js
@@ -0,0 +1,29 @@
+export default {
+ props: {
+ // ���������������
+ length: {
+ type: [String, Number],
+ default: uni.$u.props.swiperIndicator.length
+ },
+ // ������������������������������������������
+ current: {
+ type: [String, Number],
+ default: uni.$u.props.swiperIndicator.current
+ },
+ // ������������������������
+ indicatorActiveColor: {
+ type: String,
+ default: uni.$u.props.swiperIndicator.indicatorActiveColor
+ },
+ // ������������������������
+ indicatorInactiveColor: {
+ type: String,
+ default: uni.$u.props.swiperIndicator.indicatorInactiveColor
+ },
+ // ������������������line-���������dot-������
+ indicatorMode: {
+ type: String,
+ default: uni.$u.props.swiperIndicator.indicatorMode
+ }
+ }
+}
diff --git a/uni_modules/uview-ui/components/u-swiper-indicator/u-swiper-indicator.vue b/uni_modules/uview-ui/components/u-swiper-indicator/u-swiper-indicator.vue
new file mode 100644
index 0000000..8923e13
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-swiper-indicator/u-swiper-indicator.vue
@@ -0,0 +1,110 @@
+<template>
+ <view class="u-swiper-indicator">
+ <view
+ class="u-swiper-indicator__wrapper"
+ v-if="indicatorMode === 'line'"
+ :class="[`u-swiper-indicator__wrapper--${indicatorMode}`]"
+ :style="{
+ width: $u.addUnit(lineWidth * length),
+ backgroundColor: indicatorInactiveColor
+ }"
+ >
+ <view
+ class="u-swiper-indicator__wrapper--line__bar"
+ :style="[lineStyle]"
+ ></view>
+ </view>
+ <view
+ class="u-swiper-indicator__wrapper"
+ v-if="indicatorMode === 'dot'"
+ >
+ <view
+ class="u-swiper-indicator__wrapper__dot"
+ v-for="(item, index) in length"
+ :key="index"
+ :class="[index === current && 'u-swiper-indicator__wrapper__dot--active']"
+ :style="[dotStyle(index)]"
+ >
+
+ </view>
+ </view>
+ </view>
+</template>
+
+<script>
+ import props from './props.js';
+ /**
+ * SwiperIndicator ������������������
+ * @description ���������������������������������������������������������,������������������
+ * @tutorial https://www.uviewui.com/components/swiper.html
+ * @property {String | Number} length ������������������������ 0 ���
+ * @property {String | Number} current ��������������������������������������������������� 0 ���
+ * @property {String} indicatorActiveColor ������������������������
+ * @property {String} indicatorInactiveColor ������������������������
+ * @property {String} indicatorMode ������������������������ 'line' ���
+ * @example <u-swiper :list="list4" indicator keyName="url" :autoplay="false"></u-swiper>
+ */
+ export default {
+ name: 'u-swiper-indicator',
+ mixins: [uni.$u.mpMixin, uni.$u.mixin, props],
+ data() {
+ return {
+ lineWidth: 22
+ }
+ },
+ computed: {
+ // ���������������������������
+ lineStyle() {
+ let style = {}
+ style.width = uni.$u.addUnit(this.lineWidth)
+ style.transform = `translateX(${ uni.$u.addUnit(this.current * this.lineWidth) })`
+ style.backgroundColor = this.indicatorActiveColor
+ return style
+ },
+ // ���������������������������
+ dotStyle() {
+ return index => {
+ let style = {}
+ style.backgroundColor = index === this.current ? this.indicatorActiveColor : this.indicatorInactiveColor
+ return style
+ }
+ }
+ },
+ }
+</script>
+
+<style lang="scss" scoped>
+ @import "../../libs/css/components.scss";
+
+ .u-swiper-indicator {
+
+ &__wrapper {
+ @include flex;
+
+ &--line {
+ border-radius: 100px;
+ height: 4px;
+
+ &__bar {
+ width: 22px;
+ height: 4px;
+ border-radius: 100px;
+ background-color: #FFFFFF;
+ transition: transform 0.3s;
+ }
+ }
+
+ &__dot {
+ width: 5px;
+ height: 5px;
+ border-radius: 100px;
+ margin: 0 4px;
+
+ &--active {
+ width: 12px;
+ }
+ }
+
+ }
+ }
+</style>
diff --git a/uni_modules/uview-ui/components/u-swiper/props.js b/uni_modules/uview-ui/components/u-swiper/props.js
new file mode 100644
index 0000000..bac6d31
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-swiper/props.js
@@ -0,0 +1,125 @@
+export default {
+ props: {
+ // ������������������������������������������������������������keyName���������������������
+ list: {
+ type: Array,
+ default: uni.$u.props.swiper.list
+ },
+ // ���������������������������
+ indicator: {
+ type: Boolean,
+ default: uni.$u.props.swiper.indicator
+ },
+ // ������������������������
+ indicatorActiveColor: {
+ type: String,
+ default: uni.$u.props.swiper.indicatorActiveColor
+ },
+ // ������������������������
+ indicatorInactiveColor: {
+ type: String,
+ default: uni.$u.props.swiper.indicatorInactiveColor
+ },
+ // ���������������������������bottom���left���right������������
+ indicatorStyle: {
+ type: [String, Object],
+ default: uni.$u.props.swiper.indicatorStyle
+ },
+ // ������������������line-���������dot-������
+ indicatorMode: {
+ type: String,
+ default: uni.$u.props.swiper.indicatorMode
+ },
+ // ������������������
+ autoplay: {
+ type: Boolean,
+ default: uni.$u.props.swiper.autoplay
+ },
+ // ��������������������� index
+ current: {
+ type: [String, Number],
+ default: uni.$u.props.swiper.current
+ },
+ // ��������������������� item-id ������������ current ���������������
+ currentItemId: {
+ type: String,
+ default: uni.$u.props.swiper.currentItemId
+ },
+ // ������������������������������
+ interval: {
+ type: [String, Number],
+ default: uni.$u.props.swiper.interval
+ },
+ // ������������������������������
+ duration: {
+ type: [String, Number],
+ default: uni.$u.props.swiper.duration
+ },
+ // ������������������������������������������
+ circular: {
+ type: Boolean,
+ default: uni.$u.props.swiper.circular
+ },
+ // ������������������������������������������������������nvue���������������������
+ previousMargin: {
+ type: [String, Number],
+ default: uni.$u.props.swiper.previousMargin
+ },
+ // ������������������������������������������������������nvue���������������������
+ nextMargin: {
+ type: [String, Number],
+ default: uni.$u.props.swiper.nextMargin
+ },
+ // ������������������������������������������������������������������������������
+ acceleration: {
+ type: Boolean,
+ default: uni.$u.props.swiper.acceleration
+ },
+ // ������������������������������nvue������������������������������
+ displayMultipleItems: {
+ type: Number,
+ default: uni.$u.props.swiper.displayMultipleItems
+ },
+ // ������swiper���������������������������������������default���linear���easeInCubic���easeOutCubic���easeInOutCubic
+ // ���������������������������
+ easingFunction: {
+ type: String,
+ default: uni.$u.props.swiper.easingFunction
+ },
+ // list���������������������������������������
+ keyName: {
+ type: String,
+ default: uni.$u.props.swiper.keyName
+ },
+ // ���������������������
+ imgMode: {
+ type: String,
+ default: uni.$u.props.swiper.imgMode
+ },
+ // ������������
+ height: {
+ type: [String, Number],
+ default: uni.$u.props.swiper.height
+ },
+ // ������������
+ bgColor: {
+ type: String,
+ default: uni.$u.props.swiper.bgColor
+ },
+ // ���������������������������������������������
+ radius: {
+ type: [String, Number],
+ default: uni.$u.props.swiper.radius
+ },
+ // ���������������
+ loading: {
+ type: Boolean,
+ default: uni.$u.props.swiper.loading
+ },
+ // ���������������������������������������������title������
+ showTitle: {
+ type: Boolean,
+ default: uni.$u.props.swiper.showTitle
+ }
+ }
+}
diff --git a/uni_modules/uview-ui/components/u-swiper/u-swiper.vue b/uni_modules/uview-ui/components/u-swiper/u-swiper.vue
new file mode 100644
index 0000000..0cfb229
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-swiper/u-swiper.vue
@@ -0,0 +1,255 @@
+<template>
+ <view
+ class="u-swiper"
+ :style="{
+ backgroundColor: bgColor,
+ height: $u.addUnit(height),
+ borderRadius: $u.addUnit(radius)
+ }"
+ >
+ <view
+ class="u-swiper__loading"
+ v-if="loading"
+ >
+ <u-loading-icon mode="circle"></u-loading-icon>
+ </view>
+ <swiper
+ v-else
+ class="u-swiper__wrapper"
+ :style="{
+ height: $u.addUnit(height),
+ }"
+ @change="change"
+ :circular="circular"
+ :interval="interval"
+ :duration="duration"
+ :autoplay="autoplay"
+ :current="current"
+ :currentItemId="currentItemId"
+ :previousMargin="$u.addUnit(previousMargin)"
+ :nextMargin="$u.addUnit(nextMargin)"
+ :acceleration="acceleration"
+ :displayMultipleItems="displayMultipleItems"
+ :easingFunction="easingFunction"
+ >
+ <swiper-item
+ class="u-swiper__wrapper__item"
+ v-for="(item, index) in list"
+ :key="index"
+ >
+ <view
+ class="u-swiper__wrapper__item__wrapper"
+ :style="[itemStyle(index)]"
+ >
+ <!-- ���nvue������image���������������������������������������������������flex:1��������������������������������������������������� -->
+ <image
+ class="u-swiper__wrapper__item__wrapper__image"
+ v-if="getItemType(item) === 'image'"
+ :src="getSource(item)"
+ :mode="imgMode"
+ @tap="clickHandler(index)"
+ :style="{
+ height: $u.addUnit(height),
+ borderRadius: $u.addUnit(radius)
+ }"
+ ></image>
+ <video
+ class="u-swiper__wrapper__item__wrapper__video"
+ v-if="getItemType(item) === 'video'"
+ :id="`video-${index}`"
+ :enable-progress-gesture="false"
+ :src="getSource(item)"
+ :poster="getPoster(item)"
+ :title="showTitle && $u.test.object(item) && item.title ? item.title : ''"
+ :style="{
+ height: $u.addUnit(height)
+ }"
+ controls
+ @tap="clickHandler(index)"
+ ></video>
+ <text
+ v-if="showTitle && $u.test.object(item) && item.title && $u.test.image(getSource(item))"
+ class="u-swiper__wrapper__item__wrapper__title u-line-1"
+ >{{ item.title }}</text>
+ </view>
+ </swiper-item>
+ </swiper>
+ <view class="u-swiper__indicator" :style="[$u.addStyle(indicatorStyle)]">
+ <slot name="indicator">
+ <u-swiper-indicator
+ v-if="!loading && indicator && !showTitle"
+ :indicatorActiveColor="indicatorActiveColor"
+ :indicatorInactiveColor="indicatorInactiveColor"
+ :length="list.length"
+ :current="currentIndex"
+ :indicatorMode="indicatorMode"
+ ></u-swiper-indicator>
+ </slot>
+ </view>
+ </view>
+</template>
+
+<script>
+ import props from './props.js';
+ /**
+ * Swiper ���������
+ * @description ���������������������������������������������������������,������������������
+ * @tutorial https://www.uviewui.com/components/swiper.html
+ * @property {Array} list ���������������
+ * @property {Boolean} indicator ������������������������������������ false ���
+ * @property {String} indicatorActiveColor ��������������������������������� '#FFFFFF' ���
+ * @property {String} indicatorInactiveColor ��������������������������������� 'rgba(255, 255, 255, 0.35)' ���
+ * @property {String | Object} indicatorStyle ���������������������������bottom���left���right������������
+ * @property {String} indicatorMode ������������������������ 'line' ���
+ * @property {Boolean} autoplay ��������������������������� true ���
+ * @property {String | Number} current ��������������������� index��������� 0 ���
+ * @property {String} currentItemId ��������������������� item-id ������������ current ���������������
+ * @property {String | Number} interval ���������������������������������ms������������ 3000 ���
+ * @property {String | Number} duration ���������������������������������ms������������ 300 ���
+ * @property {Boolean} circular ��������������������������������������������������� false ���
+ * @property {String | Number} previousMargin ������������������������������������������������������nvue������������������������������ 0 ���
+ * @property {String | Number} nextMargin ������������������������������������������������������nvue������������������������������ 0 ���
+ * @property {Boolean} acceleration ��������������������������������������������������������������������������������������� false ���
+ * @property {Number} displayMultipleItems ������������������������������nvue��������������������������������������� 1 ���
+ * @property {String} easingFunction ������swiper��������������������������� ������������������������������������ 'default' ���
+ * @property {String} keyName list������������������������������������������������ 'url' ���
+ * @property {String} imgMode ������������������������������ 'aspectFill' ���
+ * @property {String | Number} height ��������������������� 130 ���
+ * @property {String} bgColor ��������������������� '#f3f4f6' ���
+ * @property {String | Number} radius ������������������������������������������������������ 4 ���
+ * @property {Boolean} loading ������������������������ false ���
+ * @property {Boolean} showTitle ���������������������������������������������title��������������� false ���
+ * @event {Function(index)} click ������������������������ index���������������������������������0������
+ * @event {Function(index)} change ������������������������(������������������������) index������������������������������������0������
+ * @example <u-swiper :list="list4" keyName="url" :autoplay="false"></u-swiper>
+ */
+ export default {
+ name: 'u-swiper',
+ mixins: [uni.$u.mpMixin, uni.$u.mixin, props],
+ data() {
+ return {
+ currentIndex: 0
+ }
+ },
+ watch: {
+ current(val, preVal) {
+ if(val === preVal) return;
+ this.currentIndex = val; // ������������������������
+ }
+ },
+ computed: {
+ itemStyle() {
+ return index => {
+ const style = {}
+ // #ifndef APP-NVUE || MP-TOUTIAO
+ // ������������������������������������nvue���������
+ // ������������������������������������������������������������������
+ if (this.nextMargin && this.previousMargin) {
+ style.borderRadius = uni.$u.addUnit(this.radius)
+ if (index !== this.currentIndex) style.transform = 'scale(0.92)'
+ }
+ // #endif
+ return style
+ }
+ }
+ },
+ methods: {
+ getItemType(item) {
+ if (typeof item === 'string') return uni.$u.test.video(this.getSource(item)) ? 'video' : 'image'
+ if (typeof item === 'object' && this.keyName) {
+ if (!item.type) return uni.$u.test.video(this.getSource(item)) ? 'video' : 'image'
+ if (item.type === 'image') return 'image'
+ if (item.type === 'video') return 'video'
+ return 'image'
+ }
+ },
+ // ������������������������������������������������������������������������������������������������������������keyName
+ getSource(item) {
+ if (typeof item === 'string') return item
+ if (typeof item === 'object' && this.keyName) return item[this.keyName]
+ else uni.$u.error('������������������������������')
+ return ''
+ },
+ // ������������������
+ change(e) {
+ // ���������������������
+ const {
+ current
+ } = e.detail
+ this.pauseVideo(this.currentIndex)
+ this.currentIndex = current
+ this.$emit('change', e.detail)
+ },
+ // ������������������������������������
+ pauseVideo(index) {
+ const lastItem = this.getSource(this.list[index])
+ if (uni.$u.test.video(lastItem)) {
+ // ���������������������������������
+ const video = uni.createVideoContext(`video-${index}`, this)
+ video.pause()
+ }
+ },
+ // ���������������item���������������������������������������
+ getPoster(item) {
+ return typeof item === 'object' && item.poster ? item.poster : ''
+ },
+ // ������������item
+ clickHandler(index) {
+ this.$emit('click', index)
+ }
+ },
+ }
+</script>
+
+<style lang="scss" scoped>
+ @import "../../libs/css/components.scss";
+
+ .u-swiper {
+ @include flex;
+ justify-content: center;
+ align-items: center;
+ position: relative;
+ overflow: hidden;
+
+ &__wrapper {
+ flex: 1;
+
+ &__item {
+ flex: 1;
+
+ &__wrapper {
+ @include flex;
+ position: relative;
+ overflow: hidden;
+ transition: transform 0.3s;
+ flex: 1;
+
+ &__image {
+ flex: 1;
+ }
+
+ &__video {
+ flex: 1;
+ }
+
+ &__title {
+ position: absolute;
+ background-color: rgba(0, 0, 0, 0.3);
+ bottom: 0;
+ left: 0;
+ right: 0;
+ font-size: 28rpx;
+ padding: 12rpx 24rpx;
+ color: #FFFFFF;
+ flex: 1;
+ }
+ }
+ }
+ }
+
+ &__indicator {
+ position: absolute;
+ bottom: 10px;
+ }
+ }
+</style>
diff --git a/uni_modules/uview-ui/components/u-switch/props.js b/uni_modules/uview-ui/components/u-switch/props.js
new file mode 100644
index 0000000..4eef963
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-switch/props.js
@@ -0,0 +1,54 @@
+export default {
+ props: {
+ // ������������������������
+ loading: {
+ type: Boolean,
+ default: uni.$u.props.switch.loading
+ },
+ // ���������������������
+ disabled: {
+ type: Boolean,
+ default: uni.$u.props.switch.disabled
+ },
+ // ���������������������px
+ size: {
+ type: [String, Number],
+ default: uni.$u.props.switch.size
+ },
+ // ������������������������
+ activeColor: {
+ type: String,
+ default: uni.$u.props.switch.activeColor
+ },
+ // ������������������������
+ inactiveColor: {
+ type: String,
+ default: uni.$u.props.switch.inactiveColor
+ },
+ // ������v-model������������������
+ value: {
+ type: [Boolean, String, Number],
+ default: uni.$u.props.switch.value
+ },
+ // switch���������������
+ activeValue: {
+ type: [String, Number, Boolean],
+ default: uni.$u.props.switch.activeValue
+ },
+ // switch���������������
+ inactiveValue: {
+ type: [String, Number, Boolean],
+ default: uni.$u.props.switch.inactiveValue
+ },
+ // ���������������������������������������������������������������
+ asyncChange: {
+ type: Boolean,
+ default: uni.$u.props.switch.asyncChange
+ },
+ // ���������������������������
+ space: {
+ type: [String, Number],
+ default: uni.$u.props.switch.space
+ }
+ }
+}
diff --git a/uni_modules/uview-ui/components/u-switch/u-switch.vue b/uni_modules/uview-ui/components/u-switch/u-switch.vue
new file mode 100644
index 0000000..6f8577b
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-switch/u-switch.vue
@@ -0,0 +1,177 @@
+<template>
+ <view
+ class="u-switch"
+ :class="[disabled && 'u-switch--disabled']"
+ :style="[switchStyle, $u.addStyle(customStyle)]"
+ @tap="clickHandler"
+ >
+ <view
+ class="u-switch__bg"
+ :style="[bgStyle]"
+ >
+ </view>
+ <view
+ class="u-switch__node"
+ :class="[value && 'u-switch__node--on']"
+ :style="[nodeStyle]"
+ ref="u-switch__node"
+ >
+ <u-loading-icon
+ :show="loading"
+ mode="circle"
+ timingFunction='linear'
+ :color="value ? activeColor : '#AAABAD'"
+ :size="size * 0.6"
+ />
+ </view>
+ </view>
+</template>
+
+<script>
+ import props from './props.js';
+ /**
+ * switch ���������������
+ * @description ���������������������������������������������������������������������������
+ * @tutorial https://www.uviewui.com/components/switch.html
+ * @property {Boolean} loading ������������������������������ false ���
+ * @property {Boolean} disabled ��������������������� false ���
+ * @property {String | Number} size ���������������������px ��������� 25 ���
+ * @property {String} activeColor ��������������������� ��������� '#2979ff' ���
+ * @property {String} inactiveColor ��������������������� ��������� '#ffffff' ���
+ * @property {Boolean | String | Number} value ������v-model������������������ ��������� false ���
+ * @property {Boolean | String | Number} activeValue ������������������������change������������������ ��������� true ���
+ * @property {Boolean | String | Number} inactiveValue ������������������������change������������������ ��������� false ���
+ * @property {Boolean} asyncChange ��������������������������������������������������������������� ��������� false ���
+ * @property {String | Number} space ��������������������������� ��������� 0 ���
+ * @property {Object} customStyle ���������������������������������
+ *
+ * @event {Function} change ���switch������������������������
+ * @example <u-switch v-model="checked" active-color="red" inactive-color="#eee"></u-switch>
+ */
+ export default {
+ name: "u-switch",
+ mixins: [uni.$u.mpMixin, uni.$u.mixin,props],
+ watch: {
+ value: {
+ immediate: true,
+ handler(n) {
+ if(n !== this.inactiveValue && n !== this.activeValue) {
+ uni.$u.error('v-model���������������������inactiveValue���activeValue������������')
+ }
+ }
+ }
+ },
+ data() {
+ return {
+ bgColor: '#ffffff'
+ }
+ },
+ computed: {
+ isActive(){
+ return this.value === this.activeValue;
+ },
+ switchStyle() {
+ let style = {}
+ // ���������������2������������������������������������������������node������������������������������
+ style.width = uni.$u.addUnit(this.size * 2 + 2)
+ style.height = uni.$u.addUnit(Number(this.size) + 2)
+ // style.borderColor = this.value ? 'rgba(0, 0, 0, 0)' : 'rgba(0, 0, 0, 0.12)'
+ // ������������������������������������������name���������������������������(������������������������)
+ // ������������������������������������������������������������������������������������������������������������
+ if(this.customInactiveColor) {
+ style.borderColor = 'rgba(0, 0, 0, 0)'
+ }
+ style.backgroundColor = this.isActive ? this.activeColor : this.inactiveColor
+ return style;
+ },
+ nodeStyle() {
+ let style = {}
+ // ������������������������������������node������������������������������������������������������������������������
+ style.width = uni.$u.addUnit(this.size - this.space)
+ style.height = uni.$u.addUnit(this.size - this.space)
+ const translateX = this.isActive ? uni.$u.addUnit(this.space) : uni.$u.addUnit(this.size);
+ style.transform = `translateX(-${translateX})`
+ return style
+ },
+ bgStyle() {
+ let style = {}
+ // ������������������������������������HTML������������������switch������������������������������������������������(���������������)
+ style.width = uni.$u.addUnit(Number(this.size) * 2 - this.size / 2)
+ style.height = uni.$u.addUnit(this.size)
+ style.backgroundColor = this.inactiveColor
+ // ���������������������������������������������
+ style.transform = `scale(${this.isActive ? 0 : 1})`
+ return style
+ },
+ customInactiveColor() {
+ // ���������������������������������������������������������������������������node���������������������������������������
+ return this.inactiveColor !== '#fff' && this.inactiveColor !== '#ffffff'
+ }
+ },
+ methods: {
+ clickHandler() {
+ if (!this.disabled && !this.loading) {
+ const oldValue = this.isActive ? this.inactiveValue : this.activeValue
+ if(!this.asyncChange) {
+ this.$emit('input', oldValue)
+ }
+ // ���������������������������������������������������value���������������������������������������������������
+ this.$nextTick(() => {
+ this.$emit('change', oldValue)
+ })
+ }
+ }
+ }
+ };
+</script>
+
+<style lang="scss" scoped>
+ @import "../../libs/css/components.scss";
+
+ .u-switch {
+ @include flex(row);
+ /* #ifndef APP-NVUE */
+ box-sizing: border-box;
+ /* #endif */
+ position: relative;
+ background-color: #fff;
+ border-width: 1px;
+ border-radius: 100px;
+ transition: background-color 0.4s;
+ border-color: rgba(0, 0, 0, 0.12);
+ border-style: solid;
+ justify-content: flex-end;
+ align-items: center;
+ // ������weex���������������������KPI���������������bug������������������������������������
+ // ���������iOS���������������������������������������������switch���������������
+ overflow: hidden;
+
+ &__node {
+ @include flex(row);
+ align-items: center;
+ justify-content: center;
+ border-radius: 100px;
+ background-color: #fff;
+ border-radius: 100px;
+ box-shadow: 1px 1px 1px 0 rgba(0, 0, 0, 0.25);
+ transition-property: transform;
+ transition-duration: 0.4s;
+ transition-timing-function: cubic-bezier(0.3, 1.05, 0.4, 1.05);
+ }
+
+ &__bg {
+ position: absolute;
+ border-radius: 100px;
+ background-color: #FFFFFF;
+ transition-property: transform;
+ transition-duration: 0.4s;
+ border-top-left-radius: 0;
+ border-bottom-left-radius: 0;
+ transition-timing-function: ease;
+ }
+
+ &--disabled {
+ opacity: 0.6;
+ }
+ }
+</style>
diff --git a/uni_modules/uview-ui/components/u-tabbar-item/props.js b/uni_modules/uview-ui/components/u-tabbar-item/props.js
new file mode 100644
index 0000000..a2e6a24
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-tabbar-item/props.js
@@ -0,0 +1,35 @@
+export default {
+ props: {
+ // item���������������������������u-tabbar���value������������������������
+ name: {
+ type: [String, Number, null],
+ default: uni.$u.props.tabbarItem.name
+ },
+ // uView���������������������������������������
+ icon: {
+ icon: String,
+ default: uni.$u.props.tabbarItem.icon
+ },
+ // ������������������������������
+ badge: {
+ type: [String, Number, null],
+ default: uni.$u.props.tabbarItem.badge
+ },
+ // ���������������������������������badge������
+ dot: {
+ type: Boolean,
+ default: uni.$u.props.tabbarItem.dot
+ },
+ // ������������
+ text: {
+ type: String,
+ default: uni.$u.props.tabbarItem.text
+ },
+ // ������������������������������������������������������������������top���right������
+ badgeStyle: {
+ type: [Object, String],
+ default: uni.$u.props.tabbarItem.badgeStyle
+ }
+
+ }
+}
diff --git a/uni_modules/uview-ui/components/u-tabbar-item/u-tabbar-item.vue b/uni_modules/uview-ui/components/u-tabbar-item/u-tabbar-item.vue
new file mode 100644
index 0000000..8ee00cf
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-tabbar-item/u-tabbar-item.vue
@@ -0,0 +1,142 @@
+<template>
+ <view
+ class="u-tabbar-item"
+ :style="[$u.addStyle(customStyle)]"
+ @tap="clickHandler"
+ >
+ <view class="u-tabbar-item__icon">
+ <u-icon
+ v-if="icon"
+ :name="icon"
+ :color="isActive? parentData.activeColor : parentData.inactiveColor"
+ :size="20"
+ ></u-icon>
+ <template v-else>
+ <slot
+ v-if="isActive"
+ name="active-icon"
+ />
+ <slot
+ v-else
+ name="inactive-icon"
+ />
+ </template>
+ <u-badge
+ absolute
+ :offset="[0, dot ? '34rpx' : badge > 9 ? '14rpx' : '20rpx']"
+ :customStyle="badgeStyle"
+ :isDot="dot"
+ :value="badge || (dot ? 1 : null)"
+ :show="dot || badge > 0"
+ ></u-badge>
+ </view>
+
+ <slot name="text">
+ <text
+ class="u-tabbar-item__text"
+ :style="{
+ color: isActive? parentData.activeColor : parentData.inactiveColor
+ }"
+ >{{ text }}</text>
+ </slot>
+ </view>
+</template>
+
+<script>
+ import props from './props.js';
+ /**
+ * TabbarItem ������������������������
+ * @description ���������������������������tabbar������������
+ * @tutorial https://www.uviewui.com/components/tabbar.html
+ * @property {String | Number} name item���������������������������u-tabbar���value������������������������
+ * @property {String} icon uView���������������������������������������
+ * @property {String | Number} badge ������������������������������
+ * @property {Boolean} dot ���������������������������������badge��������������� false ���
+ * @property {String} text ������������
+ * @property {Object | String} badgeStyle ������������������������������������������������������������������top���right��������������� 'top: 6px;right:2px;' ���
+ * @property {Object} customStyle ���������������������������������
+ *
+ * @example <u-tabbar :value="value2" :placeholder="false" @change="name => value2 = name" :fixed="false" :safeAreaInsetBottom="false"><u-tabbar-item text="������" icon="home" dot ></u-tabbar-item></u-tabbar>
+ */
+ export default {
+ name: 'u-tabbar-item',
+ mixins: [uni.$u.mpMixin, uni.$u.mixin,props],
+ data() {
+ return {
+ isActive: false, // ������������������������
+ parentData: {
+ value: null,
+ activeColor: '',
+ inactiveColor: ''
+ }
+ }
+ },
+ created() {
+ this.init()
+ },
+ methods: {
+ init() {
+ // ���������������������������provide/inject������������������������������������������������������created���������������������������
+ this.updateParentData()
+ if (!this.parent) {
+ uni.$u.error('u-tabbar-item������������u-tabbar������������')
+ }
+ // ���������������u-tabbar���children������������������
+ const index = this.parent.children.indexOf(this)
+ // ������������������name(������������������name���������index������)������������������������value������
+ this.isActive = (this.name || index) === this.parentData.value
+ },
+ updateParentData() {
+ // ������������mixin���
+ this.getParentData('u-tabbar')
+ },
+ // ���������������������������u-tabbar������
+ updateFromParent() {
+ // ���������������
+ this.init()
+ },
+ clickHandler() {
+ this.$nextTick(() => {
+ const index = this.parent.children.indexOf(this)
+ const name = this.name || index
+ // ���������item���������������item���������change������
+ if (name !== this.parent.value) {
+ this.parent.$emit('change', name)
+ }
+ this.$emit('click', name)
+ })
+ }
+ },
+ }
+</script>
+
+<style lang="scss" scoped>
+ @import "../../libs/css/components.scss";
+
+ .u-tabbar-item {
+ @include flex(column);
+ align-items: center;
+ justify-content: center;
+ flex: 1;
+
+ &__icon {
+ @include flex;
+ position: relative;
+ width: 150rpx;
+ justify-content: center;
+ }
+
+ &__text {
+ margin-top: 2px;
+ font-size: 12px;
+ color: $u-content-color;
+ }
+ }
+
+ /* #ifdef MP */
+ // ������������������������shadow DOM������������������������������������������flex: 1������������������
+ :host {
+ flex: 1
+ }
+ /* #endif */
+</style>
diff --git a/uni_modules/uview-ui/components/u-tabbar/props.js b/uni_modules/uview-ui/components/u-tabbar/props.js
new file mode 100644
index 0000000..7f8171c
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-tabbar/props.js
@@ -0,0 +1,44 @@
+export default {
+ props: {
+ // ������������������name
+ value: {
+ type: [String, Number, null],
+ default: uni.$u.props.tabbar.value
+ },
+ // ���������iPhoneX������������������������
+ safeAreaInsetBottom: {
+ type: Boolean,
+ default: uni.$u.props.tabbar.safeAreaInsetBottom
+ },
+ // ������������������������
+ border: {
+ type: Boolean,
+ default: uni.$u.props.tabbar.border
+ },
+ // ������������z-index
+ zIndex: {
+ type: [String, Number],
+ default: uni.$u.props.tabbar.zIndex
+ },
+ // ���������������������
+ activeColor: {
+ type: String,
+ default: uni.$u.props.tabbar.activeColor
+ },
+ // ������������������������
+ inactiveColor: {
+ type: String,
+ default: uni.$u.props.tabbar.inactiveColor
+ },
+ // ���������������������
+ fixed: {
+ type: Boolean,
+ default: uni.$u.props.tabbar.fixed
+ },
+ // fixed���������������������������������������������������������������������
+ placeholder: {
+ type: Boolean,
+ default: uni.$u.props.tabbar.placeholder
+ }
+ }
+}
diff --git a/uni_modules/uview-ui/components/u-tabbar/u-tabbar.vue b/uni_modules/uview-ui/components/u-tabbar/u-tabbar.vue
new file mode 100644
index 0000000..953f33a
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-tabbar/u-tabbar.vue
@@ -0,0 +1,141 @@
+<template>
+ <view class="u-tabbar">
+ <view
+ class="u-tabbar__content"
+ ref="u-tabbar__content"
+ @touchmove.stop.prevent="noop"
+ :class="[border && 'u-border-top', fixed && 'u-tabbar--fixed']"
+ :style="[tabbarStyle]"
+ >
+ <view class="u-tabbar__content__item-wrapper">
+ <slot />
+ </view>
+ <u-safe-bottom v-if="safeAreaInsetBottom"></u-safe-bottom>
+ </view>
+ <view
+ class="u-tabbar__placeholder"
+ v-if="placeholder"
+ :style="{
+ height: placeholderHeight + 'px',
+ }"
+ ></view>
+ </view>
+</template>
+
+<script>
+ import props from './props.js';
+ // #ifdef APP-NVUE
+ const dom = uni.requireNativePlugin('dom')
+ // #endif
+ /**
+ * Tabbar ���������������
+ * @description ���������������������������tabbar������������
+ * @tutorial https://www.uviewui.com/components/tabbar.html
+ * @property {String | Number} value ������������������name
+ * @property {Boolean} safeAreaInsetBottom ���������iPhoneX��������������������������������� true ���
+ * @property {Boolean} border ��������������������������������� true ���
+ * @property {String | Number} zIndex ������������z-index��������� 1 ���
+ * @property {String} activeColor ������������������������������ '#1989fa' ���
+ * @property {String} inactiveColor ��������������������������������� '#7d7e80' ���
+ * @property {Boolean} fixed ������������������������������ true ���
+ * @property {Boolean} placeholder fixed������������������������������������������������������������������������������ true ���
+ * @property {Object} customStyle ���������������������������������
+ *
+ * @example <u-tabbar :value="value2" :placeholder="false" @change="name => value2 = name" :fixed="false" :safeAreaInsetBottom="false"><u-tabbar-item text="������" icon="home" dot ></u-tabbar-item></u-tabbar>
+ */
+ export default {
+ name: 'u-tabbar',
+ mixins: [uni.$u.mpMixin, uni.$u.mixin,props],
+ data() {
+ return {
+ placeholderHeight: 0
+ }
+ },
+ computed: {
+ tabbarStyle() {
+ const style = {
+ zIndex: this.zIndex
+ }
+ // ������������������������customStyle������
+ return uni.$u.deepMerge(style, uni.$u.addStyle(this.customStyle))
+ },
+ // ���������������������������������������computed���������������������
+ updateChild() {
+ return [this.value, this.activeColor, this.inactiveColor]
+ },
+ updatePlaceholder() {
+ return [this.fixed, this.placeholder]
+ }
+ },
+ watch: {
+ updateChild() {
+ // ������updateChildren���������������������������������������������������������������
+ this.updateChildren()
+ },
+ updatePlaceholder() {
+ // ������fixed���placeholder���������������������������������������������������������
+ this.setPlaceholderHeight()
+ }
+ },
+ created() {
+ this.children = []
+ },
+ mounted() {
+ this.setPlaceholderHeight()
+ },
+ methods: {
+ updateChildren() {
+ // ���������������������������������������������updateFromParent������������������
+ this.children.length && this.children.map(child => child.updateFromParent())
+ },
+ // ���������������������������������������
+ async setPlaceholderHeight() {
+ if (!this.fixed || !this.placeholder) return
+ // ������������������
+ await uni.$u.sleep(20)
+ // #ifndef APP-NVUE
+ this.$uGetRect('.u-tabbar__content').then(({height = 50}) => {
+ // ������IOS safearea bottom ���������������
+ this.placeholderHeight = height
+ })
+ // #endif
+
+ // #ifdef APP-NVUE
+ dom.getComponentRect(this.$refs['u-tabbar__content'], (res) => {
+ const {
+ size
+ } = res
+ this.placeholderHeight = size.height
+ })
+ // #endif
+ }
+ }
+ }
+</script>
+
+<style lang="scss" scoped>
+ @import "../../libs/css/components.scss";
+
+ .u-tabbar {
+ @include flex(column);
+ flex: 1;
+ justify-content: center;
+
+ &__content {
+ @include flex(column);
+ background-color: #fff;
+
+ &__item-wrapper {
+ height: 50px;
+ @include flex(row);
+ }
+ }
+
+ &--fixed {
+ position: fixed;
+ bottom: 0;
+ left: 0;
+ right: 0;
+ }
+ }
+</style>
diff --git a/uni_modules/uview-ui/components/u-table/props.js b/uni_modules/uview-ui/components/u-table/props.js
new file mode 100644
index 0000000..7c11331
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-table/props.js
@@ -0,0 +1,5 @@
+export default {
+ props: {
+
+ }
+}
diff --git a/uni_modules/uview-ui/components/u-table/u-table.vue b/uni_modules/uview-ui/components/u-table/u-table.vue
new file mode 100644
index 0000000..b64ce69
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-table/u-table.vue
@@ -0,0 +1,29 @@
+<template>
+ <view class="u-table">
+
+ </view>
+</template>
+
+<script>
+ import props from './props.js';
+ /**
+ * Table ������
+ * @description ������������������������������������������������������������ ���������������������HTML���table������������table���tr���th���td������������������
+ * @tutorial https://www.uviewui.com/components/table.html
+ * @example <u-table><u-tr><u-th>������</u-th </u-tr> <u-tr><u-td>������������</u-td> </u-tr> <u-tr><u-td>������������</u-td> </u-tr></u-table>
+ */
+ export default {
+ name: 'u-table',
+ mixins: [uni.$u.mpMixin, uni.$u.mixin,props],
+ data() {
+ return {
+
+ }
+ }
+ }
+</script>
+
+<style lang="scss" scoped>
+ @import "../../libs/css/components.scss";
+
+</style>
diff --git a/uni_modules/uview-ui/components/u-tabs-item/props.js b/uni_modules/uview-ui/components/u-tabs-item/props.js
new file mode 100644
index 0000000..7c11331
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-tabs-item/props.js
@@ -0,0 +1,5 @@
+export default {
+ props: {
+
+ }
+}
diff --git a/uni_modules/uview-ui/components/u-tabs-item/u-tabs-item.vue b/uni_modules/uview-ui/components/u-tabs-item/u-tabs-item.vue
new file mode 100644
index 0000000..effb796
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-tabs-item/u-tabs-item.vue
@@ -0,0 +1,29 @@
+<template>
+ <swiper-item>
+ <slot />
+ </swiper-item>
+</template>
+
+<script>
+ import props from './props.js';
+ /**
+ * TabsItem tabs������������������������
+ * @description tabs��������������������������������������������������������������������������������������������������������������� ���������������������������������������������������������������tab������������������������������������������
+ * @tutorial https://www.uviewui.com/components/tabs.html
+ * @property {type} prop_name
+ * @event {Function()}
+ * @example
+ */
+ export default {
+ name: 'u-tabs-item',
+ mixins: [uni.$u.mpMixin, uni.$u.mixin,props],
+ data() {
+ return {
+
+ }
+ }
+ }
+</script>
+
+<style>
+</style>
diff --git a/uni_modules/uview-ui/components/u-tabs/props.js b/uni_modules/uview-ui/components/u-tabs/props.js
new file mode 100644
index 0000000..2cfa41f
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-tabs/props.js
@@ -0,0 +1,64 @@
+export default {
+ props: {
+ // ������������������������������������ms
+ duration: {
+ type: Number,
+ default: uni.$u.props.tabs.duration
+ },
+ // tabs������������
+ list: {
+ type: Array,
+ default: uni.$u.props.tabs.list
+ },
+ // ������������
+ lineColor: {
+ type: String,
+ default: uni.$u.props.tabs.lineColor
+ },
+ // ���������������������������
+ activeStyle: {
+ type: [String, Object],
+ default: uni.$u.props.tabs.activeStyle
+ },
+ // ���������������������������
+ inactiveStyle: {
+ type: [String, Object],
+ default: uni.$u.props.tabs.inactiveStyle
+ },
+ // ������������
+ lineWidth: {
+ type: [String, Number],
+ default: uni.$u.props.tabs.lineWidth
+ },
+ // ������������
+ lineHeight: {
+ type: [String, Number],
+ default: uni.$u.props.tabs.lineHeight
+ },
+ // ������������������������������������������������������������������
+ lineBgSize: {
+ type: String,
+ default: uni.$u.props.tabs.lineBgSize
+ },
+ // ������item���������
+ itemStyle: {
+ type: [String, Object],
+ default: uni.$u.props.tabs.itemStyle
+ },
+ // ���������������������
+ scrollable: {
+ type: Boolean,
+ default: uni.$u.props.tabs.scrollable
+ },
+ // ���������������������������
+ current: {
+ type: [Number, String],
+ default: uni.$u.props.tabs.current
+ },
+ // ���������������������
+ keyName: {
+ type: String,
+ default: uni.$u.props.tabs.keyName
+ }
+ }
+}
diff --git a/uni_modules/uview-ui/components/u-tabs/u-tabs.vue b/uni_modules/uview-ui/components/u-tabs/u-tabs.vue
new file mode 100644
index 0000000..9c54cc1
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-tabs/u-tabs.vue
@@ -0,0 +1,354 @@
+<template>
+ <view class="u-tabs">
+ <view class="u-tabs__wrapper">
+ <slot name="left" />
+ <view class="u-tabs__wrapper__scroll-view-wrapper">
+ <scroll-view
+ :scroll-x="scrollable"
+ :scroll-left="scrollLeft"
+ scroll-with-animation
+ class="u-tabs__wrapper__scroll-view"
+ :show-scrollbar="false"
+ ref="u-tabs__wrapper__scroll-view"
+ >
+ <view
+ class="u-tabs__wrapper__nav"
+ ref="u-tabs__wrapper__nav"
+ >
+ <view
+ class="u-tabs__wrapper__nav__item"
+ v-for="(item, index) in list"
+ :key="index"
+ @tap="clickHandler(item, index)"
+ :ref="`u-tabs__wrapper__nav__item-${index}`"
+ :style="[$u.addStyle(itemStyle), {flex: scrollable ? '' : 1}]"
+ :class="[`u-tabs__wrapper__nav__item-${index}`, item.disabled && 'u-tabs__wrapper__nav__item--disabled']"
+ >
+ <text
+ :class="[item.disabled && 'u-tabs__wrapper__nav__item__text--disabled']"
+ class="u-tabs__wrapper__nav__item__text"
+ :style="[textStyle(index)]"
+ >{{ item[keyName] }}</text>
+ <u-badge
+ :show="!!(item.badge && (item.badge.show || item.badge.isDot || item.badge.value))"
+ :isDot="item.badge && item.badge.isDot || propsBadge.isDot"
+ :value="item.badge && item.badge.value || propsBadge.value"
+ :max="item.badge && item.badge.max || propsBadge.max"
+ :type="item.badge && item.badge.type || propsBadge.type"
+ :showZero="item.badge && item.badge.showZero || propsBadge.showZero"
+ :bgColor="item.badge && item.badge.bgColor || propsBadge.bgColor"
+ :color="item.badge && item.badge.color || propsBadge.color"
+ :shape="item.badge && item.badge.shape || propsBadge.shape"
+ :numberType="item.badge && item.badge.numberType || propsBadge.numberType"
+ :inverted="item.badge && item.badge.inverted || propsBadge.inverted"
+ customStyle="margin-left: 4px;"
+ ></u-badge>
+ </view>
+ <!-- #ifdef APP-NVUE -->
+ <view
+ class="u-tabs__wrapper__nav__line"
+ ref="u-tabs__wrapper__nav__line"
+ :style="[{
+ width: $u.addUnit(lineWidth),
+ height: $u.addUnit(lineHeight),
+ background: lineColor,
+ backgroundSize: lineBgSize,
+ }]"
+ >
+ <!-- #endif -->
+ <!-- #ifndef APP-NVUE -->
+ <view
+ class="u-tabs__wrapper__nav__line"
+ ref="u-tabs__wrapper__nav__line"
+ :style="[{
+ width: $u.addUnit(lineWidth),
+ transform: `translate(${lineOffsetLeft}px)`,
+ transitionDuration: `${firstTime ? 0 : duration}ms`,
+ height: $u.addUnit(lineHeight),
+ background: lineColor,
+ backgroundSize: lineBgSize,
+ }]"
+ >
+ <!-- #endif -->
+ </view>
+ </view>
+ </scroll-view>
+ </view>
+ <slot name="right" />
+ </view>
+ </view>
+</template>
+
+<script>
+ // #ifdef APP-NVUE
+ const animation = uni.requireNativePlugin('animation')
+ const dom = uni.requireNativePlugin('dom')
+ // #endif
+ import props from './props.js';
+ /**
+ * Tabs ������
+ * @description tabs��������������������������������������������������������������������������������������������������������������� ���������������������������������������������������������������tab������������������������������������������
+ * @tutorial https://www.uviewui.com/components/tabs.html
+ * @property {String | Number} duration ������������������������������������������������������ 200 ���
+ * @property {String | Number} swierWidth swiper������������������ '750rpx' ���
+ * @property {String} keyName ���`list`��������������������������������������� 'name' ���
+ * @event {Function(index)} change ��������������������� index: ������������������tab������������0������
+ * @event {Function(index)} click ��������������������� index: ������������������tab������������0������
+ * @example <u-tabs :list="list" :is-scroll="false" :current="current" @change="change"></u-tabs>
+ */
+ export default {
+ name: 'u-tabs',
+ mixins: [uni.$u.mpMixin, uni.$u.mixin, props],
+ data() {
+ return {
+ firstTime: true,
+ scrollLeft: 0,
+ scrollViewWidth: 0,
+ lineOffsetLeft: 0,
+ tabsRect: {
+ left: 0
+ },
+ innerCurrent: 0,
+ moving: false,
+ }
+ },
+ watch: {
+ current: {
+ immediate: true,
+ handler (newValue, oldValue) {
+ // ������������������������������������������������
+ if (newValue !== this.innerCurrent) {
+ this.innerCurrent = newValue
+ this.$nextTick(() => {
+ this.resize()
+ })
+ }
+ }
+ },
+ // list������������������������list������������
+ list() {
+ this.$nextTick(() => {
+ this.resize()
+ })
+ }
+ },
+ computed: {
+ textStyle() {
+ return index => {
+ const style = {}
+ // ������������������������������
+ const customeStyle = index === this.innerCurrent ? uni.$u.addStyle(this.activeStyle) : uni.$u
+ .addStyle(
+ this.inactiveStyle)
+ // ���������������������������������������������������������������������������������������nvue���������������style���������������!import���������������������������
+ if (this.list[index].disabled) {
+ style.color = '#c8c9cc'
+ }
+ return uni.$u.deepMerge(customeStyle, style)
+ }
+ },
+ propsBadge() {
+ return uni.$u.props.badge
+ }
+ },
+ async mounted() {
+ this.init()
+ },
+ methods: {
+ setLineLeft() {
+ const tabItem = this.list[this.innerCurrent];
+ if (!tabItem) {
+ return;
+ }
+ // ������������������������������
+ let lineOffsetLeft = this.list
+ .slice(0, this.innerCurrent)
+ .reduce((total, curr) => total + curr.rect.width, 0);
+ // ������������������������px���������
+ const lineWidth = uni.$u.getPx(this.lineWidth);
+ this.lineOffsetLeft = lineOffsetLeft + (tabItem.rect.width - lineWidth) / 2
+ // #ifdef APP-NVUE
+ // ������������������������������������������
+ this.animation(this.lineOffsetLeft, this.firstTime ? 0 : parseInt(this.duration))
+ // #endif
+
+ // ���������������������������������������������������������������������������������������tab item���������
+ // ������������������������������������������nvue���������������������style���������������������������������������������������������������false(������������������������)
+ if (this.firstTime) {
+ setTimeout(() => {
+ this.firstTime = false
+ }, 10);
+ }
+ },
+ // nvue������������������������
+ animation(x, duration = 0) {
+ // #ifdef APP-NVUE
+ const ref = this.$refs['u-tabs__wrapper__nav__line']
+ animation.transition(ref, {
+ styles: {
+ transform: `translateX(${x}px)`
+ },
+ duration
+ })
+ // #endif
+ },
+ // ���������������������
+ clickHandler(item, index) {
+ // ���������������������disabled���������������click������������������������������change���������������������������������������
+ this.$emit('click', {
+ ...item,
+ index
+ })
+ // ������disabled���������������
+ if (item.disabled) return
+ this.innerCurrent = index
+ this.resize()
+ this.$emit('change', {
+ ...item,
+ index
+ })
+ },
+ init() {
+ uni.$u.sleep().then(() => {
+ this.resize()
+ })
+ },
+ setScrollLeft() {
+ // ������������tab���������������������tab���������width���left(������������������������������������������������)���������
+ const tabRect = this.list[this.innerCurrent]
+ // ������������������item������������������
+ const offsetLeft = this.list
+ .slice(0, this.innerCurrent)
+ .reduce((total, curr) => {
+ return total + curr.rect.width
+ }, 0)
+ // ���������������������
+ const windowWidth = uni.$u.sys().windowWidth
+ // ������������tabs-item������������������������������������������scroll-view���������
+ let scrollLeft = offsetLeft - (this.tabsRect.width - tabRect.rect.width) / 2 - (windowWidth - this.tabsRect
+ .right) / 2 + this.tabsRect.left / 2
+ // ������������������������������scrollLeft���������������������scroll-view������������tabs���������������
+ scrollLeft = Math.min(scrollLeft, this.scrollViewWidth - this.tabsRect.width)
+ this.scrollLeft = Math.max(0, scrollLeft)
+ },
+ // ���������������������������
+ resize() {
+ // ���������������list���������������
+ if(this.list.length === 0) {
+ return
+ }
+ Promise.all([this.getTabsRect(), this.getAllItemRect()]).then(([tabsRect, itemRect = []]) => {
+ this.tabsRect = tabsRect
+ this.scrollViewWidth = 0
+ itemRect.map((item, index) => {
+ // ������scroll-view������������������
+ this.scrollViewWidth += item.width
+ // ���������������������item������������X���������
+ this.list[index].rect = item
+ })
+ // ���������tabs���������������������������������������
+ this.setLineLeft()
+ this.setScrollLeft()
+ })
+ },
+ // ���������������������������
+ getTabsRect() {
+ return new Promise(resolve => {
+ this.queryRect('u-tabs__wrapper__scroll-view').then(size => resolve(size))
+ })
+ },
+ // ���������������������������
+ getAllItemRect() {
+ return new Promise(resolve => {
+ const promiseAllArr = this.list.map((item, index) => this.queryRect(
+ `u-tabs__wrapper__nav__item-${index}`, true))
+ Promise.all(promiseAllArr).then(sizes => resolve(sizes))
+ })
+ },
+ // ���������������������������
+ queryRect(el, item) {
+ // #ifndef APP-NVUE
+ // $uGetRect���uView���������������������������������������������������������https://www.uviewui.com/js/getRect.html
+ // ���������������������this.$uGetRect���������������uni.$u.getRect������������������������������������
+ return new Promise(resolve => {
+ this.$uGetRect(`.${el}`).then(size => {
+ resolve(size)
+ })
+ })
+ // #endif
+
+ // #ifdef APP-NVUE
+ // nvue������������dom������������������������
+ // ������������promise���������������������������������������then������
+ return new Promise(resolve => {
+ dom.getComponentRect(item ? this.$refs[el][0] : this.$refs[el], res => {
+ resolve(res.size)
+ })
+ })
+ // #endif
+ },
+ },
+ }
+</script>
+
+<style lang="scss" scoped>
+ @import "../../libs/css/components.scss";
+
+ .u-tabs {
+
+ &__wrapper {
+ @include flex;
+ align-items: center;
+
+ &__scroll-view-wrapper {
+ flex: 1;
+ /* #ifndef APP-NVUE */
+ overflow: auto hidden;
+ /* #endif */
+ }
+
+ &__scroll-view {
+ @include flex;
+ flex: 1;
+ }
+
+ &__nav {
+ @include flex;
+ position: relative;
+
+ &__item {
+ padding: 0 11px;
+ @include flex;
+ align-items: center;
+ justify-content: center;
+
+ &--disabled {
+ /* #ifndef APP-NVUE */
+ cursor: not-allowed;
+ /* #endif */
+ }
+
+ &__text {
+ font-size: 15px;
+ color: $u-content-color;
+
+ &--disabled {
+ color: $u-disabled-color !important;
+ }
+ }
+ }
+
+ &__line {
+ height: 3px;
+ background: $u-primary;
+ width: 30px;
+ position: absolute;
+ bottom: 2px;
+ border-radius: 100px;
+ transition-property: transform;
+ transition-duration: 300ms;
+ }
+ }
+ }
+ }
+</style>
diff --git a/uni_modules/uview-ui/components/u-tag/props.js b/uni_modules/uview-ui/components/u-tag/props.js
new file mode 100644
index 0000000..6bffaa2
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-tag/props.js
@@ -0,0 +1,84 @@
+export default {
+ props: {
+ // ������������info���primary���success���warning���error
+ type: {
+ type: String,
+ default: uni.$u.props.tag.type
+ },
+ // ���������
+ disabled: {
+ type: [Boolean, String],
+ default: uni.$u.props.tag.disabled
+ },
+ // ������������������large���medium���mini
+ size: {
+ type: String,
+ default: uni.$u.props.tag.size
+ },
+ // tag������������circle���������������������, square������������������������
+ shape: {
+ type: String,
+ default: uni.$u.props.tag.shape
+ },
+ // ������������
+ text: {
+ type: [String, Number],
+ default: uni.$u.props.tag.text
+ },
+ // ���������������������������������������������������
+ bgColor: {
+ type: String,
+ default: uni.$u.props.tag.bgColor
+ },
+ // ���������������������������������������������������������
+ color: {
+ type: String,
+ default: uni.$u.props.tag.color
+ },
+ // ���������������������
+ borderColor: {
+ type: String,
+ default: uni.$u.props.tag.borderColor
+ },
+ // ���������������������������
+ closeColor: {
+ type: String,
+ default: uni.$u.props.tag.closeColor
+ },
+ // ���������������������������������������������������������������������������������
+ name: {
+ type: [String, Number],
+ default: uni.$u.props.tag.name
+ },
+ // // ���������������dark|light|plain
+ // mode: {
+ // type: String,
+ // default: 'light'
+ // },
+ // ������������������������������
+ plainFill: {
+ type: Boolean,
+ default: uni.$u.props.tag.plainFill
+ },
+ // ������������
+ plain: {
+ type: Boolean,
+ default: uni.$u.props.tag.plain
+ },
+ // ���������������
+ closable: {
+ type: Boolean,
+ default: uni.$u.props.tag.closable
+ },
+ // ������������
+ show: {
+ type: Boolean,
+ default: uni.$u.props.tag.show
+ },
+ // ���������������������������������������
+ icon: {
+ type: String,
+ default: uni.$u.props.tag.icon
+ }
+ }
+}
diff --git a/uni_modules/uview-ui/components/u-tag/u-tag.vue b/uni_modules/uview-ui/components/u-tag/u-tag.vue
new file mode 100644
index 0000000..95f33c4
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-tag/u-tag.vue
@@ -0,0 +1,358 @@
+<template>
+ <u-transition
+ mode="fade"
+ :show="show"
+ >
+ <view class="u-tag-wrapper">
+ <view
+ class="u-tag"
+ :class="[`u-tag--${shape}`, !plain && `u-tag--${type}`, plain && `u-tag--${type}--plain`, `u-tag--${size}`, plain && plainFill && `u-tag--${type}--plain--fill`]"
+ @tap.stop="clickHandler"
+ :style="[{
+ marginRight: closable ? '10px' : 0,
+ marginTop: closable ? '10px' : 0,
+ }, style]"
+ >
+ <slot name="icon">
+ <view
+ class="u-tag__icon"
+ v-if="icon"
+ >
+ <image
+ v-if="$u.test.image(icon)"
+ :src="icon"
+ :style="[imgStyle]"
+ ></image>
+ <u-icon
+ v-else
+ :color="elIconColor"
+ :name="icon"
+ :size="iconSize"
+ ></u-icon>
+ </view>
+ </slot>
+ <text
+ class="u-tag__text"
+ :style="[textColor]"
+ :class="[`u-tag__text--${type}`, plain && `u-tag__text--${type}--plain`, `u-tag__text--${size}`]"
+ >{{ text }}</text>
+ </view>
+ <view
+ class="u-tag__close"
+ :class="[`u-tag__close--${size}`]"
+ v-if="closable"
+ @tap.stop="closeHandler"
+ :style="{backgroundColor: closeColor}"
+ >
+ <u-icon
+ name="close"
+ :size="closeSize"
+ color="#ffffff"
+ ></u-icon>
+ </view>
+ </view>
+ </u-transition>
+</template>
+
+<script>
+ import props from './props.js';
+ /**
+ * Tag ������
+ * @description tag���������������������������������������������������������������������������������������������������������������������������
+ * @tutorial https://www.uviewui.com/components/tag.html
+ * @property {String} type ������������info���primary���success���warning���error ��������� 'primary' ���
+ * @property {Boolean | String} disabled ������������������ false ���
+ * @property {String} size ������������������large���medium���mini ��������� 'medium' ���
+ * @property {String} shape tag������������circle���������������������, square��������������������������������� 'square' ���
+ * @property {String | Number} text ���������������������
+ * @property {String} bgColor ���������������������������������������������������
+ * @property {String} color ���������������������������������������������������������
+ * @property {String} borderColor ���������������������������������
+ * @property {String} closeColor ������������������������������������ #C6C7CB���
+ * @property {String | Number} name ���������������������������������������������������������������������������������
+ * @property {Boolean} plainFill ��������������������������������������� false ���
+ * @property {Boolean} plain ��������������������� false ���
+ * @property {Boolean} closable ���������������������������true��������������������������������������������������� false ���
+ * @property {Boolean} show ��������������������������� true ���
+ * @property {String} icon ���������������������������������������
+ * @event {Function(index)} click ��������������������� index: ���������index���������
+ * @event {Function(index)} close closable���true������������������������������������ index: ���������index���������
+ * @example <u-tag text="������" type="error" plain plainFill></u-tag>
+ */
+ export default {
+ name: 'u-tag',
+ mixins: [uni.$u.mpMixin, uni.$u.mixin, props],
+ data() {
+ return {
+
+ }
+ },
+ computed: {
+ style() {
+ const style = {}
+ if (this.bgColor) {
+ style.backgroundColor = this.bgColor
+ }
+ if (this.color) {
+ style.color = this.color
+ }
+ if(this.borderColor) {
+ style.borderColor = this.borderColor
+ }
+ return style
+ },
+ // nvue���������������������������������������
+ textColor() {
+ const style = {}
+ if (this.color) {
+ style.color = this.color
+ }
+ return style
+ },
+ imgStyle() {
+ const width = this.size === 'large' ? '17px' : this.size === 'medium' ? '15px' : '13px'
+ return {
+ width,
+ height: width
+ }
+ },
+ // ���������������
+ closeSize() {
+ const size = this.size === 'large' ? 15 : this.size === 'medium' ? 13 : 12
+ return size
+ },
+ // ������������
+ iconSize() {
+ const size = this.size === 'large' ? 21 : this.size === 'medium' ? 19 : 16
+ return size
+ },
+ // ������������
+ elIconColor() {
+ return this.iconColor ? this.iconColor : this.plain ? this.type : '#ffffff'
+ }
+ },
+ methods: {
+ // ������������������
+ closeHandler() {
+ this.$emit('close', this.name)
+ },
+ // ������������
+ clickHandler() {
+ this.$emit('click', this.name)
+ }
+ }
+ }
+</script>
+
+<style
+ lang="scss"
+ scoped
+>
+ @import "../../libs/css/components.scss";
+
+ .u-tag-wrapper {
+ position: relative;
+ }
+
+ .u-tag {
+ @include flex;
+ align-items: center;
+ border-style: solid;
+
+ &--circle {
+ border-radius: 100px;
+ }
+
+ &--square {
+ border-radius: 3px;
+ }
+
+ &__icon {
+ margin-right: 4px;
+ }
+
+ &__text {
+ &--mini {
+ font-size: 12px;
+ line-height: 12px;
+ }
+
+ &--medium {
+ font-size: 13px;
+ line-height: 13px;
+ }
+
+ &--large {
+ font-size: 15px;
+ line-height: 15px;
+ }
+ }
+
+ &--mini {
+ height: 22px;
+ line-height: 22px;
+ padding: 0 5px;
+ }
+
+ &--medium {
+ height: 26px;
+ line-height: 22px;
+ padding: 0 10px;
+ }
+
+ &--large {
+ height: 32px;
+ line-height: 32px;
+ padding: 0 15px;
+ }
+
+ &--primary {
+ background-color: $u-primary;
+ border-width: 1px;
+ border-color: $u-primary;
+ }
+
+ &--primary--plain {
+ border-width: 1px;
+ border-color: $u-primary;
+ }
+
+ &--primary--plain--fill {
+ background-color: #ecf5ff;
+ }
+
+ &__text--primary {
+ color: #FFFFFF;
+ }
+
+ &__text--primary--plain {
+ color: $u-primary;
+ }
+
+ &--error {
+ background-color: $u-error;
+ border-width: 1px;
+ border-color: $u-error;
+ }
+
+ &--error--plain {
+ border-width: 1px;
+ border-color: $u-error;
+ }
+
+ &--error--plain--fill {
+ background-color: #fef0f0;
+ }
+
+ &__text--error {
+ color: #FFFFFF;
+ }
+
+ &__text--error--plain {
+ color: $u-error;
+ }
+
+ &--warning {
+ background-color: $u-warning;
+ border-width: 1px;
+ border-color: $u-warning;
+ }
+
+ &--warning--plain {
+ border-width: 1px;
+ border-color: $u-warning;
+ }
+
+ &--warning--plain--fill {
+ background-color: #fdf6ec;
+ }
+
+ &__text--warning {
+ color: #FFFFFF;
+ }
+
+ &__text--warning--plain {
+ color: $u-warning;
+ }
+
+ &--success {
+ background-color: $u-success;
+ border-width: 1px;
+ border-color: $u-success;
+ }
+
+ &--success--plain {
+ border-width: 1px;
+ border-color: $u-success;
+ }
+
+ &--success--plain--fill {
+ background-color: #f5fff0;
+ }
+
+ &__text--success {
+ color: #FFFFFF;
+ }
+
+ &__text--success--plain {
+ color: $u-success;
+ }
+
+ &--info {
+ background-color: $u-info;
+ border-width: 1px;
+ border-color: $u-info;
+ }
+
+ &--info--plain {
+ border-width: 1px;
+ border-color: $u-info;
+ }
+
+ &--info--plain--fill {
+ background-color: #f4f4f5;
+ }
+
+ &__text--info {
+ color: #FFFFFF;
+ }
+
+ &__text--info--plain {
+ color: $u-info;
+ }
+
+ &__close {
+ position: absolute;
+ z-index: 999;
+ top: 10px;
+ right: 10px;
+ border-radius: 100px;
+ background-color: #C6C7CB;
+ @include flex(row);
+ align-items: center;
+ justify-content: center;
+ /* #ifndef APP-NVUE */
+ transform: scale(0.6) translate(80%, -80%);
+ /* #endif */
+ /* #ifdef APP-NVUE */
+ transform: scale(0.6) translate(50%, -50%);
+ /* #endif */
+
+ &--mini {
+ width: 18px;
+ height: 18px;
+ }
+
+ &--medium {
+ width: 22px;
+ height: 22px;
+ }
+
+ &--large {
+ width: 25px;
+ height: 25px;
+ }
+ }
+
+ }
+</style>
diff --git a/uni_modules/uview-ui/components/u-td/props.js b/uni_modules/uview-ui/components/u-td/props.js
new file mode 100644
index 0000000..7c11331
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-td/props.js
@@ -0,0 +1,5 @@
+export default {
+ props: {
+
+ }
+}
diff --git a/uni_modules/uview-ui/components/u-td/u-td.vue b/uni_modules/uview-ui/components/u-td/u-td.vue
new file mode 100644
index 0000000..600dce5
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-td/u-td.vue
@@ -0,0 +1,31 @@
+<template>
+ <view class="u-td">
+
+ </view>
+</template>
+
+<script>
+ import props from './props.js';
+ /**
+ * Td ���������������������
+ * @description
+ * @tutorial url
+ * @property {String | Number}
+ * @event {Function}
+ * @example
+ */
+ export default {
+ name: 'u-td',
+ mixins: [uni.$u.mpMixin, uni.$u.mixin,props],
+ data() {
+ return {
+
+ }
+ }
+ }
+</script>
+
+<style lang="scss" scoped>
+ @import "../../libs/css/components.scss";
+
+</style>
diff --git a/uni_modules/uview-ui/components/u-text/props.js b/uni_modules/uview-ui/components/u-text/props.js
new file mode 100644
index 0000000..d330075
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-text/props.js
@@ -0,0 +1,110 @@
+export default {
+ props: {
+ // ������������
+ type: {
+ type: String,
+ default: uni.$u.props.text.type
+ },
+ // ������������
+ show: {
+ type: Boolean,
+ default: uni.$u.props.text.show
+ },
+ // ������������
+ text: {
+ type: [String, Number],
+ default: uni.$u.props.text.text
+ },
+ // ������������
+ prefixIcon: {
+ type: String,
+ default: uni.$u.props.text.prefixIcon
+ },
+ // ������������
+ suffixIcon: {
+ type: String,
+ default: uni.$u.props.text.suffixIcon
+ },
+ // ���������������������������
+ // text-���������������price-���������phone-������������name-���������date-���������link-���������
+ mode: {
+ type: String,
+ default: uni.$u.props.text.mode
+ },
+ // mode=link���������������������
+ href: {
+ type: String,
+ default: uni.$u.props.text.href
+ },
+ // ���������������
+ format: {
+ type: [String, Function],
+ default: uni.$u.props.text.format
+ },
+ // mode=phone������������������������������������
+ call: {
+ type: Boolean,
+ default: uni.$u.props.text.call
+ },
+ // ������������������������
+ openType: {
+ type: String,
+ default: uni.$u.props.text.openType
+ },
+ // ���������������������normal
+ bold: {
+ type: Boolean,
+ default: uni.$u.props.text.bold
+ },
+ // ������������
+ block: {
+ type: Boolean,
+ default: uni.$u.props.text.block
+ },
+ // ������������������������������������������������������������������������������
+ lines: {
+ type: [String, Number],
+ default: uni.$u.props.text.lines
+ },
+ // ������������
+ color: {
+ type: String,
+ default: uni.$u.props.text.color
+ },
+ // ������������
+ size: {
+ type: [String, Number],
+ default: uni.$u.props.text.size
+ },
+ // ���������������
+ iconStyle: {
+ type: [Object, String],
+ default: uni.$u.props.text.iconStyle
+ },
+ // ��������������������������������������������������� none|underline|line-through
+ decoration: {
+ type: String,
+ default: uni.$u.props.text.decoration
+ },
+ // ���������������������������������������������������
+ margin: {
+ type: [Object, String, Number],
+ default: uni.$u.props.text.margin
+ },
+ // ������������
+ lineHeight: {
+ type: [String, Number],
+ default: uni.$u.props.text.lineHeight
+ },
+ // ������������������������������left|center|right
+ align: {
+ type: String,
+ default: uni.$u.props.text.align
+ },
+ // ������������������������break-word|normal|anywhere
+ wordWrap: {
+ type: String,
+ default: uni.$u.props.text.wordWrap
+ }
+ }
+}
diff --git a/uni_modules/uview-ui/components/u-text/u-text.vue b/uni_modules/uview-ui/components/u-text/u-text.vue
new file mode 100644
index 0000000..99d0809
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-text/u-text.vue
@@ -0,0 +1,223 @@
+<template>
+ <view
+ class="u-text"
+ :class="[]"
+ v-if="show"
+ :style="{
+ margin: margin,
+ justifyContent: align === 'left' ? 'flex-start' : align === 'center' ? 'center' : 'flex-end'
+ }"
+ @tap="clickHandler"
+ >
+ <text
+ :class="['u-text__price', type && `u-text__value--${type}`]"
+ v-if="mode === 'price'"
+ :style="[valueStyle]"
+ >���</text
+ >
+ <view class="u-text__prefix-icon" v-if="prefixIcon">
+ <u-icon
+ :name="prefixIcon"
+ :customStyle="$u.addStyle(iconStyle)"
+ ></u-icon>
+ </view>
+ <u-link
+ v-if="mode === 'link'"
+ :text="value"
+ :href="href"
+ underLine
+ ></u-link>
+ <template v-else-if="openType && isMp">
+ <button
+ class="u-reset-button u-text__value"
+ :style="[valueStyle]"
+ :data-index="index"
+ :openType="openType"
+ @getuserinfo="onGetUserInfo"
+ @contact="onContact"
+ @getphonenumber="onGetPhoneNumber"
+ @error="onError"
+ @launchapp="onLaunchApp"
+ @opensetting="onOpenSetting"
+ :lang="lang"
+ :session-from="sessionFrom"
+ :send-message-title="sendMessageTitle"
+ :send-message-path="sendMessagePath"
+ :send-message-img="sendMessageImg"
+ :show-message-card="showMessageCard"
+ :app-parameter="appParameter"
+ >
+ {{ value }}
+ </button>
+ </template>
+ <text
+ v-else
+ class="u-text__value"
+ :style="[valueStyle]"
+ :class="[
+ type && `u-text__value--${type}`,
+ lines && `u-line-${lines}`
+ ]"
+ >{{ value }}</text
+ >
+ <view class="u-text__suffix-icon" v-if="suffixIcon">
+ <u-icon
+ :name="suffixIcon"
+ :customStyle="$u.addStyle(iconStyle)"
+ ></u-icon>
+ </view>
+ </view>
+</template>
+
+<script>
+import value from './value.js'
+import button from '../../libs/mixin/button.js'
+import openType from '../../libs/mixin/openType.js'
+import props from './props.js'
+/**
+ * Text ������
+ * @description ���������������������������������������������������������������������������������������������������������*������������������...������������ ������������������������������������������������������text���������������������������������������������������
+ * @tutorial https://www.uviewui.com/components/loading.html
+ * @property {String} type ������������
+ * @property {Boolean} show ��������������������� true ���
+ * @property {String | Number} text ������������
+ * @property {String} prefixIcon ������������
+ * @property {String} suffixIcon ������������
+ * @property {String} mode ��������������������������� text-���������������price-���������phone-������������name-���������date-���������link-���������
+ * @property {String} href mode=link���������������������
+ * @property {String | Function} format ���������������
+ * @property {Boolean} call mode=phone��������������������������������������������� false ���
+ * @property {String} openType ������������������������
+ * @property {Boolean} bold ���������������������normal��������� false ���
+ * @property {Boolean} block ��������������������� false ���
+ * @property {String | Number} lines ������������������������������������������������������������������������������
+ * @property {String} color ��������������������� '#303133' ���
+ * @property {String | Number} size ��������������������� 15 ���
+ * @property {Object | String} iconStyle ��������������� ��������� {fontSize: '15px'} ���
+ * @property {String} decoration ��������������������������������������������������� none|underline|line-through��������� 'none' ���
+ * @property {Object | String | Number} margin ������������������������������������������������������������ 0 ���
+ * @property {String | Number} lineHeight ������������
+ * @property {String} align ������������������������������left|center|right��������� 'left' ���
+ * @property {String} wordWrap ������������������������break-word|normal|anywhere��������� 'normal' ���
+ * @event {Function} click ������������������
+ * @example <u--text text="������������������,������������������"></u--text>
+ */
+export default {
+ name: 'u--text',
+ // #ifdef MP
+ mixins: [uni.$u.mpMixin, uni.$u.mixin, value, button, openType, props],
+ // #endif
+ // #ifndef MP
+ mixins: [uni.$u.mpMixin, uni.$u.mixin, value, props],
+ // #endif
+ computed: {
+ valueStyle() {
+ const style = {
+ textDecoration: this.decoration,
+ fontWeight: this.bold ? 'bold' : 'normal',
+ wordWrap: this.wordWrap,
+ fontSize: uni.$u.addUnit(this.size)
+ }
+ !this.type && (style.color = this.color)
+ this.isNvue && this.lines && (style.lines = this.lines)
+ this.lineHeight &&
+ (style.lineHeight = uni.$u.addUnit(this.lineHeight))
+ !this.isNvue && this.block && (style.display = 'block')
+ return uni.$u.deepMerge(style, uni.$u.addStyle(this.customStyle))
+ },
+ isNvue() {
+ let nvue = false
+ // #ifdef APP-NVUE
+ nvue = true
+ // #endif
+ return nvue
+ },
+ isMp() {
+ let mp = false
+ // #ifdef MP
+ mp = true
+ // #endif
+ return mp
+ }
+ },
+ data() {
+ return {}
+ },
+ methods: {
+ clickHandler() {
+ // ���������������������������������������
+ if (this.call && this.mode === 'phone') {
+ uni.makePhoneCall({
+ phoneNumber: this.text
+ })
+ }
+ this.$emit('click')
+ }
+ }
+}
+</script>
+
+<style lang="scss" scoped>
+@import '../../libs/css/components.scss';
+
+.u-text {
+ @include flex(row);
+ align-items: center;
+ flex-wrap: nowrap;
+ flex: 1;
+ /* #ifndef APP-NVUE */
+ width: 100%;
+ /* #endif */
+
+ &__price {
+ font-size: 14px;
+ color: $u-content-color;
+ }
+
+ &__value {
+ font-size: 14px;
+ @include flex;
+ color: $u-content-color;
+ flex-wrap: wrap;
+ // flex: 1;
+ text-overflow: ellipsis;
+ align-items: center;
+
+ &--primary {
+ color: $u-primary;
+ }
+
+ &--warning {
+ color: $u-warning;
+ }
+
+ &--success {
+ color: $u-success;
+ }
+
+ &--info {
+ color: $u-info;
+ }
+
+ &--error {
+ color: $u-error;
+ }
+
+ &--main {
+ color: $u-main-color;
+ }
+
+ &--content {
+ color: $u-content-color;
+ }
+
+ &--tips {
+ color: $u-tips-color;
+ }
+
+ &--light {
+ color: $u-light-color;
+ }
+ }
+}
+</style>
diff --git a/uni_modules/uview-ui/components/u-text/value.js b/uni_modules/uview-ui/components/u-text/value.js
new file mode 100644
index 0000000..9859bbb
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-text/value.js
@@ -0,0 +1,85 @@
+export default {
+ computed: {
+ // ������������������������������
+ value() {
+ const {
+ text,
+ mode,
+ format,
+ href
+ } = this
+ // ������������
+ if (mode === 'price') {
+ // ������text������������������������
+ if (!/^\d+(\.\d+)?$/.test(text)) {
+ uni.$u.error('������������������text���������������������������');
+ }
+ // ���������������������������������������format���������������������������������������������������format������������������������������������������
+ if (uni.$u.test.func(format)) {
+ // ������������������������������������������������������
+ return format(text)
+ }
+ // ������format���������������������������������������������������������������������������
+ return uni.$u.priceFormat(text, 2)
+ } if (mode === 'date') {
+ // ������������������������������������������
+ !uni.$u.test.date(text) && uni.$u.error('������������������text���������������������������������������')
+ // ���������������������������������������format���������������������������������������������������format������������������������������������
+ if (uni.$u.test.func(format)) {
+ // ������������������������������������������������������
+ return format(text)
+ } if (format) {
+ // ������format���������������������������������������������������������������������������
+ return uni.$u.timeFormat(text, format)
+ }
+ // ������������������format���������������������������������������������
+ return uni.$u.timeFormat(text, 'yyyy-mm-dd')
+ } if (mode === 'phone') {
+ // ������������������������������
+ // !uni.$u.test.mobile(text) && uni.$u.error('���������������������text���������������������������������')
+ if (uni.$u.test.func(format)) {
+ // ������������������������������������������������������
+ return format(text)
+ } if (format === 'encrypt') {
+ // ������format���encrypt������������������������������������������
+ return `${text.substr(0, 3)}****${text.substr(7)}`
+ }
+ return text
+ } if (mode === 'name') {
+ // ������������������������������
+ !(typeof (text) === 'string') && uni.$u.error('������������������text������������������������������')
+ if (uni.$u.test.func(format)) {
+ // ������������������������������������������������������
+ return format(text)
+ } if (format === 'encrypt') {
+ // ������format���encrypt���������������������������������������
+ return this.formatName(text)
+ }
+ return text
+ } if (mode === 'link') {
+ // ������������������������������
+ !uni.$u.test.url(href) && uni.$u.error('���������������������href���������������URL������')
+ return text
+ }
+ return text
+ }
+ },
+ methods: {
+ // ���������������������������
+ formatName(name) {
+ let value = ''
+ if (name.length === 2) {
+ value = name.substr(0, 1) + '*'
+ } else if (name.length > 2) {
+ let char = ''
+ for (let i = 0, len = name.length - 2; i < len; i++) {
+ char += '*'
+ }
+ value = name.substr(0, 1) + char + name.substr(-1, 1)
+ } else {
+ value = name
+ }
+ return value
+ }
+ }
+}
diff --git a/uni_modules/uview-ui/components/u-textarea/props.js b/uni_modules/uview-ui/components/u-textarea/props.js
new file mode 100644
index 0000000..d0e16d5
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-textarea/props.js
@@ -0,0 +1,119 @@
+export default {
+ props: {
+ // ������������������
+ value: {
+ type: [String, Number],
+ default: uni.$u.props.textarea.value
+ },
+ // ���������������������������
+ placeholder: {
+ type: [String, Number],
+ default: uni.$u.props.textarea.placeholder
+ },
+ // ������placeholder���������������������������������������style���������scoped���������������������������/deep/
+ placeholderClass: {
+ type: String,
+ default: uni.$u.props.input.placeholderClass
+ },
+ // ������placeholder���������
+ placeholderStyle: {
+ type: [String, Object],
+ default: uni.$u.props.input.placeholderStyle
+ },
+ // ���������������
+ height: {
+ type: [String, Number],
+ default: uni.$u.props.textarea.height
+ },
+ // ������������������������������������������������������������App-vue���H5������
+ confirmType: {
+ type: String,
+ default: uni.$u.props.textarea.confirmType
+ },
+ // ������������
+ disabled: {
+ type: Boolean,
+ default: uni.$u.props.textarea.disabled
+ },
+ // ������������������������
+ count: {
+ type: Boolean,
+ default: uni.$u.props.textarea.count
+ },
+ // ���������������������������nvue������������H5���������������������������
+ focus: {
+ type: Boolean,
+ default: uni.$u.props.textarea.focus
+ },
+ // ������������������������
+ autoHeight: {
+ type: Boolean,
+ default: uni.$u.props.textarea.autoHeight
+ },
+ // ������textarea������������position:fixed������������������������������������fixed���true
+ fixed: {
+ type: Boolean,
+ default: uni.$u.props.textarea.fixed
+ },
+ // ������������������������������
+ cursorSpacing: {
+ type: Number,
+ default: uni.$u.props.textarea.cursorSpacing
+ },
+ // ������focus������������������
+ cursor: {
+ type: [String, Number],
+ default: uni.$u.props.textarea.cursor
+ },
+ // ������������������������������������������������������������
+ showConfirmBar: {
+ type: Boolean,
+ default: uni.$u.props.textarea.showConfirmBar
+ },
+ // ���������������������������������������������������selection-end������������
+ selectionStart: {
+ type: Number,
+ default: uni.$u.props.textarea.selectionStart
+ },
+ // ���������������������������������������������������selection-start������������
+ selectionEnd: {
+ type: Number,
+ default: uni.$u.props.textarea.selectionEnd
+ },
+ // ������������������������������������������
+ adjustPosition: {
+ type: Boolean,
+ default: uni.$u.props.textarea.adjustPosition
+ },
+ // ������������ iOS ������������������������������������������������
+ disableDefaultPadding: {
+ type: Boolean,
+ default: uni.$u.props.textarea.disableDefaultPadding
+ },
+ // focus���������������������������������������������������������������������
+ holdKeyboard: {
+ type: Boolean,
+ default: uni.$u.props.textarea.holdKeyboard
+ },
+ // ������������������������������ -1 ������������������������������
+ maxlength: {
+ type: [String, Number],
+ default: uni.$u.props.textarea.maxlength
+ },
+ // ���������������surround-���������������bottom-������������
+ border: {
+ type: String,
+ default: uni.$u.props.textarea.border
+ },
+ // ������������������������������������������������
+ formatter: {
+ type: [Function, null],
+ default: uni.$u.props.textarea.formatter
+ },
+ // ���������������������������������������������������������
+ ignoreCompositionEvent: {
+ type: Boolean,
+ default: true
+ }
+ }
+}
diff --git a/uni_modules/uview-ui/components/u-textarea/u-textarea.vue b/uni_modules/uview-ui/components/u-textarea/u-textarea.vue
new file mode 100644
index 0000000..2cd5fdc
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-textarea/u-textarea.vue
@@ -0,0 +1,239 @@
+<template>
+ <view class="u-textarea" :class="textareaClass" :style="[textareaStyle]">
+ <textarea
+ class="u-textarea__field"
+ :value="innerValue"
+ :style="{ height: $u.addUnit(height) }"
+ :placeholder="placeholder"
+ :placeholder-style="$u.addStyle(placeholderStyle, 'string')"
+ :placeholder-class="placeholderClass"
+ :disabled="disabled"
+ :focus="focus"
+ :autoHeight="autoHeight"
+ :fixed="fixed"
+ :cursorSpacing="cursorSpacing"
+ :cursor="cursor"
+ :showConfirmBar="showConfirmBar"
+ :selectionStart="selectionStart"
+ :selectionEnd="selectionEnd"
+ :adjustPosition="adjustPosition"
+ :disableDefaultPadding="disableDefaultPadding"
+ :holdKeyboard="holdKeyboard"
+ :maxlength="maxlength"
+ :confirmType="confirmType"
+ :ignoreCompositionEvent="ignoreCompositionEvent"
+ @focus="onFocus"
+ @blur="onBlur"
+ @linechange="onLinechange"
+ @input="onInput"
+ @confirm="onConfirm"
+ @keyboardheightchange="onKeyboardheightchange"
+ ></textarea>
+ <text
+ class="u-textarea__count"
+ :style="{
+ 'background-color': disabled ? 'transparent' : '#fff',
+ }"
+ v-if="count"
+ >{{ innerValue.length }}/{{ maxlength }}</text
+ >
+ </view>
+</template>
+
+<script>
+import props from "./props.js";
+/**
+ * Textarea ���������
+ * @description ������������������������������������������������������������������������������������������������������������������������
+ * @tutorial https://www.uviewui.com/components/textarea.html
+ *
+ * @property {String | Number} value ������������������
+ * @property {String | Number} placeholder ���������������������������
+ * @property {String} placeholderClass ������placeholder���������������������������������������style���������scoped���������������������������/deep/ ��� ������ 'input-placeholder' ���
+ * @property {String | Object} placeholderStyle ������placeholder���������������������/������������������"color: red;"
+ * @property {String | Number} height ������������������������ 70 ���
+ * @property {String} confirmType ������������������������������������������������������������App-vue���H5��������������� 'done' ���
+ * @property {Boolean} disabled ��������������������� false ���
+ * @property {Boolean} count ��������������������������������� false ���
+ * @property {Boolean} focus ���������������������������nvue������������H5������������������������������������ false ���
+ * @property {Boolean | Function} autoHeight ��������������������������������� false ���
+ * @property {Boolean} fixed ������textarea������������position:fixed������������������������������������fixed���true��������� false ���
+ * @property {Number} cursorSpacing ��������������������������������������� 0 ���
+ * @property {String | Number} cursor ������focus������������������
+ * @property {Function} formatter ������������������
+ * @property {Boolean} showConfirmBar ��������������������������������������������������������������������� true ���
+ * @property {Number} selectionStart ���������������������������������������������������selection-end������������������������ -1 ���
+ * @property {Number | Number} selectionEnd ���������������������������������������������������selection-start��������������������� -1 ���
+ * @property {Boolean} adjustPosition ��������������������������������������������������� true ���
+ * @property {Boolean | Number} disableDefaultPadding ������������ iOS ��������������������������������������������������������� false ���
+ * @property {Boolean} holdKeyboard focus������������������������������������������������������������������������������ false ���
+ * @property {String | Number} maxlength ������������������������������ -1 ��������������������������������������� 140 ���
+ * @property {String} border ���������������surround-���������������none-������������bottom-��������������������� 'surround' ���
+ * @property {Boolean} ignoreCompositionEvent ���������������������������������������������������������
+ *
+ * @event {Function(e)} focus ���������������������������event.detail = { value, height }���height ���������������
+ * @event {Function(e)} blur ���������������������������������event.detail = {value, cursor}
+ * @event {Function(e)} linechange ���������������������������������event.detail = {height: 0, heightRpx: 0, lineCount: 0}
+ * @event {Function(e)} input ��������������������������� input ������
+ * @event {Function(e)} confirm ������������������ ������ confirm ������
+ * @event {Function(e)} keyboardheightchange ������������������������������������������������
+ * @example <u--textarea v-model="value1" placeholder="���������������" ></u--textarea>
+ */
+export default {
+ name: "u-textarea",
+ mixins: [uni.$u.mpMixin, uni.$u.mixin, props],
+ data() {
+ return {
+ // ���������������
+ innerValue: "",
+ // ������������������������������
+ focused: false,
+ // value���������������������������watch������������������immediate������������������������������������������������������value���������������
+ firstChange: true,
+ // value���������������������������������������������������
+ changeFromInner: false,
+ // ������������������
+ innerFormatter: value => value
+ }
+ },
+ watch: {
+ value: {
+ immediate: true,
+ handler(newVal, oldVal) {
+ this.innerValue = newVal;
+ /* #ifdef H5 */
+ // ���H5������������value������������������input������������������������@input������������������������������������������
+ if (
+ this.firstChange === false &&
+ this.changeFromInner === false
+ ) {
+ this.valueChange();
+ }
+ /* #endif */
+ this.firstChange = false;
+ // ������changeFromInner���������false������������������������������������������������
+ this.changeFromInner = false;
+ },
+ },
+ },
+ computed: {
+ // ���������������
+ textareaClass() {
+ let classes = [],
+ { border, disabled, shape } = this;
+ border === "surround" &&
+ (classes = classes.concat(["u-border", "u-textarea--radius"]));
+ border === "bottom" &&
+ (classes = classes.concat([
+ "u-border-bottom",
+ "u-textarea--no-radius",
+ ]));
+ disabled && classes.push("u-textarea--disabled");
+ return classes.join(" ");
+ },
+ // ���������������
+ textareaStyle() {
+ const style = {};
+ // #ifdef APP-NVUE
+ // ������textarea���������nvue���������������������������������������������������
+ if (uni.$u.os() === "android") {
+ style.paddingTop = "6px";
+ style.paddingLeft = "9px";
+ style.paddingBottom = "3px";
+ style.paddingRight = "6px";
+ }
+ // #endif
+ return uni.$u.deepMerge(style, uni.$u.addStyle(this.customStyle));
+ },
+ },
+ methods: {
+ // ������������������������������������������������props������������������������ref������������
+ setFormatter(e) {
+ this.innerFormatter = e
+ },
+ onFocus(e) {
+ this.$emit("focus", e);
+ },
+ onBlur(e) {
+ this.$emit("blur", e);
+ // ������������u-form���������������
+ uni.$u.formValidate(this, "blur");
+ },
+ onLinechange(e) {
+ this.$emit("linechange", e);
+ },
+ onInput(e) {
+ let { value = "" } = e.detail || {};
+ // ���������������������
+ const formatter = this.formatter || this.innerFormatter
+ const formatValue = formatter(value)
+ // ������������props���������������������������������������innerValue������������������������������$nextTick���������������������������������������
+ this.innerValue = value
+ this.$nextTick(() => {
+ this.innerValue = formatValue;
+ this.valueChange();
+ })
+ },
+ // ���������������������������������
+ valueChange() {
+ const value = this.innerValue;
+ this.$nextTick(() => {
+ this.$emit("input", value);
+ // ������value���������������������������������
+ this.changeFromInner = true;
+ this.$emit("change", value);
+ // ������������u-form���������������
+ uni.$u.formValidate(this, "change");
+ });
+ },
+ onConfirm(e) {
+ this.$emit("confirm", e);
+ },
+ onKeyboardheightchange(e) {
+ this.$emit("keyboardheightchange", e);
+ },
+ },
+};
+</script>
+
+<style lang="scss" scoped>
+@import "../../libs/css/components.scss";
+
+.u-textarea {
+ border-radius: 4px;
+ background-color: #fff;
+ position: relative;
+ @include flex;
+ flex: 1;
+ padding: 9px;
+
+ &--radius {
+ border-radius: 4px;
+ }
+
+ &--no-radius {
+ border-radius: 0;
+ }
+
+ &--disabled {
+ background-color: #f5f7fa;
+ }
+
+ &__field {
+ flex: 1;
+ font-size: 15px;
+ color: $u-content-color;
+ width: 100%;
+ }
+
+ &__count {
+ position: absolute;
+ right: 5px;
+ bottom: 2px;
+ font-size: 12px;
+ color: $u-tips-color;
+ background-color: #ffffff;
+ padding: 1px 4px;
+ }
+}
+</style>
diff --git a/uni_modules/uview-ui/components/u-toast/u-toast.vue b/uni_modules/uview-ui/components/u-toast/u-toast.vue
new file mode 100644
index 0000000..f194830
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-toast/u-toast.vue
@@ -0,0 +1,291 @@
+<template>
+ <view class="u-toast">
+ <u-overlay
+ :show="isShow"
+ :custom-style="overlayStyle"
+ >
+ <view
+ class="u-toast__content"
+ :style="[contentStyle]"
+ :class="['u-type-' + tmpConfig.type, (tmpConfig.type === 'loading' || tmpConfig.loading) ? 'u-toast__content--loading' : '']"
+ >
+ <u-loading-icon
+ v-if="tmpConfig.type === 'loading'"
+ mode="circle"
+ color="rgb(255, 255, 255)"
+ inactiveColor="rgb(120, 120, 120)"
+ size="25"
+ ></u-loading-icon>
+ <u-icon
+ v-else-if="tmpConfig.type !== 'defalut' && iconName"
+ :name="iconName"
+ size="17"
+ :color="tmpConfig.type"
+ :customStyle="iconStyle"
+ ></u-icon>
+ <u-gap
+ v-if="tmpConfig.type === 'loading' || tmpConfig.loading"
+ height="12"
+ bgColor="transparent"
+ ></u-gap>
+ <text
+ class="u-toast__content__text"
+ :class="['u-toast__content__text--' + tmpConfig.type]"
+ style="max-width: 400rpx;"
+ >{{ tmpConfig.message }}</text>
+ </view>
+ </u-overlay>
+ </view>
+</template>
+
+<script>
+ /**
+ * toast ������������
+ * @description ���������������������������uni���uni.showToastAPI������������������������������
+ * @tutorial https://www.uviewui.com/components/toast.html
+ * @property {String | Number} zIndex toast������������zIndex��� (������ 10090 )
+ * @property {Boolean} loading ��������������� ��������� false ���
+ * @property {String | Number} message ���������������������
+ * @property {String} icon ������������������������������������
+ * @property {String} type ������������ ��������� default���
+ * @property {Boolean} show ��������������������� ��������� false���
+ * @property {Boolean} overlay ��������������������������������������������� ��������� false ���
+ * @property {String} position ������ ��������� 'center' ���
+ * @property {Object} params ���������������
+ * @property {String | Number} duration ���������������������ms ��������� 2000 ���
+ * @property {Boolean} isTab ������������������tab������ ��������� false ���
+ * @property {String} url toast������������������������������������������������������������back������
+ * @property {Function} complete ���������������������������
+ * @property {Boolean} back ������toast��������������������������� ��������� false ���
+ * @property {Object} customStyle ������������������������������
+ * @event {Function} show ������toast���������������������������������toast���������onReady������������������
+ * @example <u-toast ref="uToast" />
+ */
+ export default {
+ name: 'u-toast',
+ mixins: [uni.$u.mpMixin, uni.$u.mixin],
+ data() {
+ return {
+ isShow: false,
+ timer: null, // ���������
+ config: {
+ message: '', // ������������
+ type: '', // ���������������primary���success���error���warning���black
+ duration: 2000, // ������������������������
+ icon: true, // ���������������
+ position: 'center', // toast���������������
+ complete: null, // ���������������������������
+ overlay: false, // ������������������������
+ loading: false, // ���������������������
+ },
+ tmpConfig: {}, // ������������������������������������������������������������
+ }
+ },
+ computed: {
+ iconName() {
+ // ������������none���������type���error|warning|succes|info������������������������
+ if(!this.tmpConfig.icon || this.tmpConfig.icon == 'none') {
+ return '';
+ }
+ if (['error', 'warning', 'success', 'primary'].includes(this.tmpConfig.type)) {
+ return uni.$u.type2icon(this.tmpConfig.type)
+ } else {
+ return ''
+ }
+ },
+ overlayStyle() {
+ const style = {
+ justifyContent: 'center',
+ alignItems: 'center',
+ display: 'flex'
+ }
+ // ������������������100%������������������������������������
+ style.backgroundColor = 'rgba(0, 0, 0, 0)'
+ return style
+ },
+ iconStyle() {
+ const style = {}
+ // ���������������������������������������������������������������������
+ style.marginRight = '4px'
+ // #ifdef APP-NVUE
+ // iOSAPP���������������1px������������������������������������
+ if (uni.$u.os() === 'ios') {
+ style.marginTop = '-1px'
+ }
+ // #endif
+ return style
+ },
+ loadingIconColor() {
+ let color = 'rgb(255, 255, 255)'
+ if (['error', 'warning', 'success', 'primary'].includes(this.tmpConfig.type)) {
+ // loading-icon������������������color���������������������������������������������������������������������
+ // ���������rgb���������������������������������������
+ color = uni.$u.hexToRgb(uni.$u.color[this.tmpConfig.type])
+ }
+ return color
+ },
+ // ���������������������
+ contentStyle() {
+ const windowHeight = uni.$u.sys().windowHeight, style = {}
+ let value = 0
+ // ������top���bottom������Y���������������������������������������
+ if(this.tmpConfig.position === 'top') {
+ value = - windowHeight * 0.25
+ } else if(this.tmpConfig.position === 'bottom') {
+ value = windowHeight * 0.25
+ }
+ style.transform = `translateY(${value}px)`
+ return style
+ }
+ },
+ created() {
+ // ���������������������������toast���������������������������
+ ['primary', 'success', 'error', 'warning', 'default', 'loading'].map(item => {
+ this[item] = message => this.show({
+ type: item,
+ message
+ })
+ })
+ },
+ methods: {
+ // ������toast���������������������������this.$refs.xxx.show(options)������������
+ show(options) {
+ // ���������������������this.config���������������������������u-toast������������������������������
+ this.tmpConfig = uni.$u.deepMerge(this.config, options)
+ // ���������������
+ this.clearTimer()
+ this.isShow = true
+ this.timer = setTimeout(() => {
+ // ������������������������������������������toast������
+ this.clearTimer()
+ // ������������������callback������������������������������
+ typeof(this.tmpConfig.complete) === 'function' && this.tmpConfig.complete()
+ }, this.tmpConfig.duration)
+ },
+ // ������toast���������������������������this.$refs.xxx.hide()������������
+ hide() {
+ this.clearTimer()
+ },
+ clearTimer() {
+ this.isShow = false
+ // ���������������
+ clearTimeout(this.timer)
+ this.timer = null
+ }
+ },
+ beforeDestroy() {
+ this.clearTimer()
+ }
+ }
+</script>
+
+<style lang="scss" scoped>
+ @import "../../libs/css/components.scss";
+
+ $u-toast-color:#fff !default;
+ $u-toast-border-radius:4px !default;
+ $u-toast-border-background-color:#585858 !default;
+ $u-toast-border-font-size:14px !default;
+ $u-toast-border-padding:12px 20px !default;
+ $u-toast-loading-border-padding: 20px 20px !default;
+ $u-toast-content-text-color:#fff !default;
+ $u-toast-content-text-font-size:15px !default;
+ $u-toast-u-icon:10rpx !default;
+ $u-toast-u-type-primary-color:$u-primary !default;
+ $u-toast-u-type-primary-background-color:#ecf5ff !default;
+ $u-toast-u-type-primary-border-color:rgb(215, 234, 254) !default;
+ $u-toast-u-type-primary-border-width:1px !default;
+ $u-toast-u-type-success-color: $u-success !default;
+ $u-toast-u-type-success-background-color: #dbf1e1 !default;
+ $u-toast-u-type-success-border-color: #BEF5C8 !default;
+ $u-toast-u-type-success-border-width: 1px !default;
+ $u-toast-u-type-error-color:$u-error !default;
+ $u-toast-u-type-error-background-color:#fef0f0 !default;
+ $u-toast-u-type-error-border-color:#fde2e2 !default;
+ $u-toast-u-type-error-border-width: 1px !default;
+ $u-toast-u-type-warning-color:$u-warning !default;
+ $u-toast-u-type-warning-background-color:#fdf6ec !default;
+ $u-toast-u-type-warning-border-color:#faecd8 !default;
+ $u-toast-u-type-warning-border-width: 1px !default;
+ $u-toast-u-type-default-color:#fff !default;
+ $u-toast-u-type-default-background-color:#585858 !default;
+
+ .u-toast {
+ &__content {
+ @include flex;
+ padding: $u-toast-border-padding;
+ border-radius: $u-toast-border-radius;
+ background-color: $u-toast-border-background-color;
+ color: $u-toast-color;
+ align-items: center;
+ /* #ifndef APP-NVUE */
+ max-width: 600rpx;
+ /* #endif */
+ position: relative;
+
+ &--loading {
+ flex-direction: column;
+ padding: $u-toast-loading-border-padding;
+ }
+
+ &__text {
+ color: $u-toast-content-text-color;
+ font-size: $u-toast-content-text-font-size;
+ line-height: $u-toast-content-text-font-size;
+
+ &--default {
+ color: $u-toast-content-text-color;
+ }
+
+ &--error {
+ color: $u-error;
+ }
+
+ &--primary {
+ color: $u-primary;
+ }
+
+ &--success {
+ color: $u-success;
+ }
+
+ &--warning {
+ color: $u-warning;
+ }
+ }
+ }
+ }
+
+ .u-type-primary {
+ color: $u-toast-u-type-primary-color;
+ background-color: $u-toast-u-type-primary-background-color;
+ border-color: $u-toast-u-type-primary-border-color;
+ border-width: $u-toast-u-type-primary-border-width;
+ }
+
+ .u-type-success {
+ color: $u-toast-u-type-success-color;
+ background-color: $u-toast-u-type-success-background-color;
+ border-color: $u-toast-u-type-success-border-color;
+ border-width: 1px;
+ }
+
+ .u-type-error {
+ color: $u-toast-u-type-error-color;
+ background-color: $u-toast-u-type-error-background-color;
+ border-color: $u-toast-u-type-error-border-color;
+ border-width: $u-toast-u-type-error-border-width;
+ }
+
+ .u-type-warning {
+ color: $u-toast-u-type-warning-color;
+ background-color: $u-toast-u-type-warning-background-color;
+ border-color: $u-toast-u-type-warning-border-color;
+ border-width: 1px;
+ }
+
+ .u-type-default {
+ color: $u-toast-u-type-default-color;
+ background-color: $u-toast-u-type-default-background-color;
+ }
+</style>
diff --git a/uni_modules/uview-ui/components/u-toolbar/props.js b/uni_modules/uview-ui/components/u-toolbar/props.js
new file mode 100644
index 0000000..1b72966
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-toolbar/props.js
@@ -0,0 +1,34 @@
+export default {
+ props: {
+ // ���������������������
+ show: {
+ type: Boolean,
+ default: uni.$u.props.toolbar.show
+ },
+ // ���������������������
+ cancelText: {
+ type: String,
+ default: uni.$u.props.toolbar.cancelText
+ },
+ // ���������������������
+ confirmText: {
+ type: String,
+ default: uni.$u.props.toolbar.confirmText
+ },
+ // ���������������������
+ cancelColor: {
+ type: String,
+ default: uni.$u.props.toolbar.cancelColor
+ },
+ // ���������������������
+ confirmColor: {
+ type: String,
+ default: uni.$u.props.toolbar.confirmColor
+ },
+ // ������������
+ title: {
+ type: String,
+ default: uni.$u.props.toolbar.title
+ }
+ }
+}
diff --git a/uni_modules/uview-ui/components/u-toolbar/u-toolbar.vue b/uni_modules/uview-ui/components/u-toolbar/u-toolbar.vue
new file mode 100644
index 0000000..290b771
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-toolbar/u-toolbar.vue
@@ -0,0 +1,102 @@
+<template>
+ <view
+ class="u-toolbar"
+ @touchmove.stop.prevent="noop"
+ v-if="show"
+ >
+ <view
+ class="u-toolbar__cancel__wrapper"
+ hover-class="u-hover-class"
+ >
+ <text
+ class="u-toolbar__wrapper__cancel"
+ @tap="cancel"
+ :style="{
+ color: cancelColor
+ }"
+ >{{ cancelText }}</text>
+ </view>
+ <text
+ class="u-toolbar__title u-line-1"
+ v-if="title"
+ >{{ title }}</text>
+ <view
+ class="u-toolbar__confirm__wrapper"
+ hover-class="u-hover-class"
+ >
+ <text
+ class="u-toolbar__wrapper__confirm"
+ @tap="confirm"
+ :style="{
+ color: confirmColor
+ }"
+ >{{ confirmText }}</text>
+ </view>
+ </view>
+</template>
+
+<script>
+ import props from './props.js';
+ /**
+ * Toolbar ���������
+ * @description
+ * @tutorial https://www.uviewui.com/components/toolbar.html
+ * @property {Boolean} show ������������������������������ true ���
+ * @property {String} cancelText ������������������������������ '������' ���
+ * @property {String} confirmText ������������������������������ '������' ���
+ * @property {String} cancelColor ������������������������������ '#909193' ���
+ * @property {String} confirmColor ������������������������������ '#3c9cff' ���
+ * @property {String} title ������������
+ * @event {Function}
+ * @example
+ */
+ export default {
+ name: 'u-toolbar',
+ mixins: [uni.$u.mpMixin, uni.$u.mixin,props],
+ methods: {
+ // ������������������
+ cancel() {
+ this.$emit('cancel')
+ },
+ // ������������������
+ confirm() {
+ this.$emit('confirm')
+ }
+ },
+ }
+</script>
+
+<style lang="scss" scoped>
+ @import "../../libs/css/components.scss";
+
+ .u-toolbar {
+ height: 42px;
+ @include flex;
+ justify-content: space-between;
+ align-items: center;
+
+ &__wrapper {
+ &__cancel {
+ color: $u-tips-color;
+ font-size: 15px;
+ padding: 0 15px;
+ }
+ }
+
+ &__title {
+ color: $u-main-color;
+ padding: 0 60rpx;
+ font-size: 16px;
+ flex: 1;
+ text-align: center;
+ }
+
+ &__wrapper {
+ &__confirm {
+ color: $u-primary;
+ font-size: 15px;
+ padding: 0 15px;
+ }
+ }
+ }
+</style>
diff --git a/uni_modules/uview-ui/components/u-tooltip/clipboard.min.js b/uni_modules/uview-ui/components/u-tooltip/clipboard.min.js
new file mode 100644
index 0000000..b7bff12
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-tooltip/clipboard.min.js
@@ -0,0 +1,58 @@
+/*!
+ * clipboard.js v1.6.1
+ * https://zenorocha.github.io/clipboard.js
+ *
+ * Licensed MIT �� Zeno Rocha
+ */
+!(function (e) { if (typeof exports === 'object' && typeof module !== 'undefined')module.exports = e(); else if (typeof define === 'function' && define.amd)define([], e); else { let t; t = typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : this, t.Clipboard = e() } }(() => {
+ let e; let t; let n; return (function e(t, n, o) { function i(a, c) { if (!n[a]) { if (!t[a]) { const l = typeof require === 'function' && require; if (!c && l) return l(a, !0); if (r) return r(a, !0); const u = new Error(`Cannot find module '${a}'`); throw u.code = 'MODULE_NOT_FOUND', u } const s = n[a] = { exports: {} }; t[a][0].call(s.exports, (e) => { const n = t[a][1][e]; return i(n || e) }, s, s.exports, e, t, n, o) } return n[a].exports } for (var r = typeof require === 'function' && require, a = 0; a < o.length; a++)i(o[a]); return i }({
+ 1: [function (e, t, n) { function o(e, t) { for (;e && e.nodeType !== i;) { if (e.matches(t)) return e; e = e.parentNode } } var i = 9; if (typeof Element !== 'undefined' && !Element.prototype.matches) { const r = Element.prototype; r.matches = r.matchesSelector || r.mozMatchesSelector || r.msMatchesSelector || r.oMatchesSelector || r.webkitMatchesSelector }t.exports = o }, {}],
+ 2: [function (e, t, n) { function o(e, t, n, o, r) { const a = i.apply(this, arguments); return e.addEventListener(n, a, r), { destroy() { e.removeEventListener(n, a, r) } } } function i(e, t, n, o) { return function (n) { n.delegateTarget = r(n.target, t), n.delegateTarget && o.call(e, n) } } var r = e('./closest'); t.exports = o }, { './closest': 1 }],
+ 3: [function (e, t, n) { n.node = function (e) { return void 0 !== e && e instanceof HTMLElement && e.nodeType === 1 }, n.nodeList = function (e) { const t = Object.prototype.toString.call(e); return void 0 !== e && (t === '[object NodeList]' || t === '[object HTMLCollection]') && 'length' in e && (e.length === 0 || n.node(e[0])) }, n.string = function (e) { return typeof e === 'string' || e instanceof String }, n.fn = function (e) { const t = Object.prototype.toString.call(e); return t === '[object Function]' } }, {}],
+ 4: [function (e, t, n) { function o(e, t, n) { if (!e && !t && !n) throw new Error('Missing required arguments'); if (!c.string(t)) throw new TypeError('Second argument must be a String'); if (!c.fn(n)) throw new TypeError('Third argument must be a Function'); if (c.node(e)) return i(e, t, n); if (c.nodeList(e)) return r(e, t, n); if (c.string(e)) return a(e, t, n); throw new TypeError('First argument must be a String, HTMLElement, HTMLCollection, or NodeList') } function i(e, t, n) { return e.addEventListener(t, n), { destroy() { e.removeEventListener(t, n) } } } function r(e, t, n) { return Array.prototype.forEach.call(e, (e) => { e.addEventListener(t, n) }), { destroy() { Array.prototype.forEach.call(e, (e) => { e.removeEventListener(t, n) }) } } } function a(e, t, n) { return l(document.body, e, t, n) } var c = e('./is'); var l = e('delegate'); t.exports = o }, { './is': 3, delegate: 2 }],
+ 5: [function (e, t, n) { function o(e) { let t; if (e.nodeName === 'SELECT')e.focus(), t = e.value; else if (e.nodeName === 'INPUT' || e.nodeName === 'TEXTAREA') { const n = e.hasAttribute('readonly'); n || e.setAttribute('readonly', ''), e.select(), e.setSelectionRange(0, e.value.length), n || e.removeAttribute('readonly'), t = e.value } else { e.hasAttribute('contenteditable') && e.focus(); const o = window.getSelection(); const i = document.createRange(); i.selectNodeContents(e), o.removeAllRanges(), o.addRange(i), t = o.toString() } return t }t.exports = o }, {}],
+ 6: [function (e, t, n) {
+ function o() {}o.prototype = {
+ on(e, t, n) { const o = this.e || (this.e = {}); return (o[e] || (o[e] = [])).push({ fn: t, ctx: n }), this }, once(e, t, n) { function o() { i.off(e, o), t.apply(n, arguments) } var i = this; return o._ = t, this.on(e, o, n) }, emit(e) { const t = [].slice.call(arguments, 1); const n = ((this.e || (this.e = {}))[e] || []).slice(); let o = 0; const i = n.length; for (o; o < i; o++)n[o].fn.apply(n[o].ctx, t); return this }, off(e, t) { const n = this.e || (this.e = {}); const o = n[e]; const i = []; if (o && t) for (let r = 0, a = o.length; r < a; r++)o[r].fn !== t && o[r].fn._ !== t && i.push(o[r]); return i.length ? n[e] = i : delete n[e], this }
+ }, t.exports = o
+ }, {}],
+ 7: [function (t, n, o) {
+ !(function (i, r) { if (typeof e === 'function' && e.amd)e(['module', 'select'], r); else if (typeof o !== 'undefined')r(n, t('select')); else { const a = { exports: {} }; r(a, i.select), i.clipboardAction = a.exports } }(this, (e, t) => {
+ 'use strict'
+
+ function n(e) { return e && e.__esModule ? e : { default: e } } function o(e, t) { if (!(e instanceof t)) throw new TypeError('Cannot call a class as a function') } const i = n(t); const r = typeof Symbol === 'function' && typeof Symbol.iterator === 'symbol' ? function (e) { return typeof e } : function (e) { return e && typeof Symbol === 'function' && e.constructor === Symbol && e !== Symbol.prototype ? 'symbol' : typeof e }; const a = (function () { function e(e, t) { for (let n = 0; n < t.length; n++) { const o = t[n]; o.enumerable = o.enumerable || !1, o.configurable = !0, 'value' in o && (o.writable = !0), Object.defineProperty(e, o.key, o) } } return function (t, n, o) { return n && e(t.prototype, n), o && e(t, o), t } }()); const c = (function () {
+ function e(t) { o(this, e), this.resolveOptions(t), this.initSelection() } return a(e, [{ key: 'resolveOptions', value: function e() { const t = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : {}; this.action = t.action, this.emitter = t.emitter, this.target = t.target, this.text = t.text, this.trigger = t.trigger, this.selectedText = '' } }, { key: 'initSelection', value: function e() { this.text ? this.selectFake() : this.target && this.selectTarget() } }, { key: 'selectFake', value: function e() { const t = this; const n = document.documentElement.getAttribute('dir') == 'rtl'; this.removeFake(), this.fakeHandlerCallback = function () { return t.removeFake() }, this.fakeHandler = document.body.addEventListener('click', this.fakeHandlerCallback) || !0, this.fakeElem = document.createElement('textarea'), this.fakeElem.style.fontSize = '12pt', this.fakeElem.style.border = '0', this.fakeElem.style.padding = '0', this.fakeElem.style.margin = '0', this.fakeElem.style.position = 'absolute', this.fakeElem.style[n ? 'right' : 'left'] = '-9999px'; const o = window.pageYOffset || document.documentElement.scrollTop; this.fakeElem.style.top = `${o}px`, this.fakeElem.setAttribute('readonly', ''), this.fakeElem.value = this.text, document.body.appendChild(this.fakeElem), this.selectedText = (0, i.default)(this.fakeElem), this.copyText() } }, { key: 'removeFake', value: function e() { this.fakeHandler && (document.body.removeEventListener('click', this.fakeHandlerCallback), this.fakeHandler = null, this.fakeHandlerCallback = null), this.fakeElem && (document.body.removeChild(this.fakeElem), this.fakeElem = null) } }, { key: 'selectTarget', value: function e() { this.selectedText = (0, i.default)(this.target), this.copyText() } }, { key: 'copyText', value: function e() { let t = void 0; try { t = document.execCommand(this.action) } catch (e) { t = !1 } this.handleResult(t) } }, {
+ key: 'handleResult',
+ value: function e(t) {
+ this.emitter.emit(t ? 'success' : 'error', {
+ action: this.action, text: this.selectedText, trigger: this.trigger, clearSelection: this.clearSelection.bind(this)
+ })
+ }
+ }, { key: 'clearSelection', value: function e() { this.target && this.target.blur(), window.getSelection().removeAllRanges() } }, { key: 'destroy', value: function e() { this.removeFake() } }, { key: 'action', set: function e() { const t = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : 'copy'; if (this._action = t, this._action !== 'copy' && this._action !== 'cut') throw new Error('Invalid "action" value, use either "copy" or "cut"') }, get: function e() { return this._action } }, { key: 'target', set: function e(t) { if (void 0 !== t) { if (!t || (typeof t === 'undefined' ? 'undefined' : r(t)) !== 'object' || t.nodeType !== 1) throw new Error('Invalid "target" value, use a valid Element'); if (this.action === 'copy' && t.hasAttribute('disabled')) throw new Error('Invalid "target" attribute. Please use "readonly" instead of "disabled" attribute'); if (this.action === 'cut' && (t.hasAttribute('readonly') || t.hasAttribute('disabled'))) throw new Error('Invalid "target" attribute. You can\'t cut text from elements with "readonly" or "disabled" attributes'); this._target = t } }, get: function e() { return this._target } }]), e
+ }()); e.exports = c
+ }))
+ }, { select: 5 }],
+ 8: [function (t, n, o) {
+ !(function (i, r) { if (typeof e === 'function' && e.amd)e(['module', './clipboard-action', 'tiny-emitter', 'good-listener'], r); else if (typeof o !== 'undefined')r(n, t('./clipboard-action'), t('tiny-emitter'), t('good-listener')); else { const a = { exports: {} }; r(a, i.clipboardAction, i.tinyEmitter, i.goodListener), i.clipboard = a.exports } }(this, (e, t, n, o) => {
+ 'use strict'
+
+ function i(e) { return e && e.__esModule ? e : { default: e } } function r(e, t) { if (!(e instanceof t)) throw new TypeError('Cannot call a class as a function') } function a(e, t) { if (!e) throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); return !t || typeof t !== 'object' && typeof t !== 'function' ? e : t } function c(e, t) {
+ if (typeof t !== 'function' && t !== null) throw new TypeError(`Super expression must either be null or a function, not ${typeof t}`); e.prototype = Object.create(t && t.prototype, {
+ constructor: {
+ value: e, enumerable: !1, writable: !0, configurable: !0
+ }
+ }), t && (Object.setPrototypeOf ? Object.setPrototypeOf(e, t) : e.__proto__ = t)
+ } function l(e, t) { const n = `data-clipboard-${e}`; if (t.hasAttribute(n)) return t.getAttribute(n) } const u = i(t); const s = i(n); const f = i(o); const d = (function () { function e(e, t) { for (let n = 0; n < t.length; n++) { const o = t[n]; o.enumerable = o.enumerable || !1, o.configurable = !0, 'value' in o && (o.writable = !0), Object.defineProperty(e, o.key, o) } } return function (t, n, o) { return n && e(t.prototype, n), o && e(t, o), t } }()); const h = (function (e) {
+ function t(e, n) { r(this, t); const o = a(this, (t.__proto__ || Object.getPrototypeOf(t)).call(this)); return o.resolveOptions(n), o.listenClick(e), o } return c(t, e), d(t, [{ key: 'resolveOptions', value: function e() { const t = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : {}; this.action = typeof t.action === 'function' ? t.action : this.defaultAction, this.target = typeof t.target === 'function' ? t.target : this.defaultTarget, this.text = typeof t.text === 'function' ? t.text : this.defaultText } }, { key: 'listenClick', value: function e(t) { const n = this; this.listener = (0, f.default)(t, 'click', (e) => n.onClick(e)) } }, {
+ key: 'onClick',
+ value: function e(t) {
+ const n = t.delegateTarget || t.currentTarget; this.clipboardAction && (this.clipboardAction = null), this.clipboardAction = new u.default({
+ action: this.action(n), target: this.target(n), text: this.text(n), trigger: n, emitter: this
+ })
+ }
+ }, { key: 'defaultAction', value: function e(t) { return l('action', t) } }, { key: 'defaultTarget', value: function e(t) { const n = l('target', t); if (n) return document.querySelector(n) } }, { key: 'defaultText', value: function e(t) { return l('text', t) } }, { key: 'destroy', value: function e() { this.listener.destroy(), this.clipboardAction && (this.clipboardAction.destroy(), this.clipboardAction = null) } }], [{ key: 'isSupported', value: function e() { const t = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : ['copy', 'cut']; const n = typeof t === 'string' ? [t] : t; let o = !!document.queryCommandSupported; return n.forEach((e) => { o = o && !!document.queryCommandSupported(e) }), o } }]), t
+ }(s.default)); e.exports = h
+ }))
+ }, { './clipboard-action': 7, 'good-listener': 4, 'tiny-emitter': 6 }]
+ }, {}, [8]))(8)
+}))
diff --git a/uni_modules/uview-ui/components/u-tooltip/props.js b/uni_modules/uview-ui/components/u-tooltip/props.js
new file mode 100644
index 0000000..16aecbc
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-tooltip/props.js
@@ -0,0 +1,59 @@
+export default {
+ props: {
+ // ���������������������������
+ text: {
+ type: [String, Number],
+ default: uni.$u.props.tooltip.text
+ },
+ // ���������������������������������������������������������text���
+ copyText: {
+ type: [String, Number],
+ default: uni.$u.props.tooltip.copyText
+ },
+ // ������������
+ size: {
+ type: [String, Number],
+ default: uni.$u.props.tooltip.size
+ },
+ // ������������
+ color: {
+ type: String,
+ default: uni.$u.props.tooltip.color
+ },
+ // ���������������������������������������
+ bgColor: {
+ type: String,
+ default: uni.$u.props.tooltip.bgColor
+ },
+ // ������������������������top-���������bottom-������
+ direction: {
+ type: String,
+ default: uni.$u.props.tooltip.direction
+ },
+ // ���������������z-index���nvue������
+ zIndex: {
+ type: [String, Number],
+ default: uni.$u.props.tooltip.zIndex
+ },
+ // ������������������������
+ showCopy: {
+ type: Boolean,
+ default: uni.$u.props.tooltip.showCopy
+ },
+ // ������������������
+ buttons: {
+ type: Array,
+ default: uni.$u.props.tooltip.buttons
+ },
+ // ���������������������������������������������
+ overlay: {
+ type: Boolean,
+ default: uni.$u.props.tooltip.overlay
+ },
+ // ���������������������������������������toast
+ showToast: {
+ type: Boolean,
+ default: uni.$u.props.tooltip.showToast
+ }
+ }
+}
diff --git a/uni_modules/uview-ui/components/u-tooltip/u-tooltip.vue b/uni_modules/uview-ui/components/u-tooltip/u-tooltip.vue
new file mode 100644
index 0000000..4bd8fc9
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-tooltip/u-tooltip.vue
@@ -0,0 +1,365 @@
+<template>
+ <view
+ class="u-tooltip"
+ :style="[$u.addStyle(customStyle)]"
+ >
+ <u-overlay
+ :show="showTooltip && tooltipTop !== -10000 && overlay"
+ customStyle="backgroundColor: rgba(0, 0, 0, 0)"
+ @click="overlayClickHandler"
+ ></u-overlay>
+ <view class="u-tooltip__wrapper">
+ <text
+ class="u-tooltip__wrapper__text"
+ :id="textId"
+ :ref="textId"
+ :userSelect="false"
+ :selectable="false"
+ @longpress.stop="longpressHandler"
+ :style="{
+ color: color,
+ backgroundColor: bgColor && showTooltip && tooltipTop !== -10000 ? bgColor : 'transparent'
+ }"
+ >{{ text }}</text>
+ <u-transition
+ mode="fade"
+ :show="showTooltip"
+ duration="300"
+ :customStyle="{
+ position: 'absolute',
+ top: $u.addUnit(tooltipTop),
+ zIndex: zIndex,
+ ...tooltipStyle
+ }"
+ >
+ <view
+ class="u-tooltip__wrapper__popup"
+ :id="tooltipId"
+ :ref="tooltipId"
+ >
+ <view
+ class="u-tooltip__wrapper__popup__indicator"
+ hover-class="u-tooltip__wrapper__popup__indicator--hover"
+ v-if="showCopy || buttons.length"
+ :style="[indicatorStyle, {
+ width: $u.addUnit(indicatorWidth),
+ height: $u.addUnit(indicatorWidth),
+ }]"
+ >
+ <!-- ������nvue������������������������������������������������������������������45deg������������������������������ -->
+ </view>
+ <view class="u-tooltip__wrapper__popup__list">
+ <view
+ v-if="showCopy"
+ class="u-tooltip__wrapper__popup__list__btn"
+ hover-class="u-tooltip__wrapper__popup__list__btn--hover"
+ @tap="setClipboardData"
+ >
+ <text
+ class="u-tooltip__wrapper__popup__list__btn__text"
+ >������</text>
+ </view>
+ <u-line
+ direction="column"
+ color="#8d8e90"
+ v-if="showCopy && buttons.length > 0"
+ length="18"
+ ></u-line>
+ <block v-for="(item , index) in buttons" :key="index">
+ <view
+ class="u-tooltip__wrapper__popup__list__btn"
+ hover-class="u-tooltip__wrapper__popup__list__btn--hover"
+ >
+ <text
+ class="u-tooltip__wrapper__popup__list__btn__text"
+ @tap="btnClickHandler(index)"
+ >{{ item }}</text>
+ </view>
+ <u-line
+ direction="column"
+ color="#8d8e90"
+ v-if="index < buttons.length - 1"
+ length="18"
+ ></u-line>
+ </block>
+ </view>
+ </view>
+ </u-transition>
+ </view>
+ </view>
+</template>
+
+<script>
+ import props from './props.js';
+ // #ifdef APP-NVUE
+ const dom = uni.requireNativePlugin('dom')
+ // #endif
+ // #ifdef H5
+ import ClipboardJS from "./clipboard.min.js"
+ // #endif
+ /**
+ * Tooltip
+ * @description
+ * @tutorial https://www.uviewui.com/components/tooltip.html
+ * @property {String | Number} text ���������������������������
+ * @property {String | Number} copyText ���������������������������������������������������������text���
+ * @property {String | Number} size ��������������������� 14 ���
+ * @property {String} color ��������������������� '#606266' ���
+ * @property {String} bgColor ������������������������������������������������ 'transparent' ���
+ * @property {String} direction ������������������������top-���������bottom-��������������� 'top' ���
+ * @property {String | Number} zIndex ���������������z-index���nvue��������������� 10071 ���
+ * @property {Boolean} showCopy ��������������������������������� true ���
+ * @property {Array} buttons ������������������
+ * @property {Boolean} overlay ������������������������������������������������������ true ���
+ * @property {Object} customStyle ���������������������������������
+ *
+ * @event {Function}
+ * @example
+ */
+ export default {
+ name: 'u-tooltip',
+ mixins: [uni.$u.mpMixin, uni.$u.mixin, props],
+ data() {
+ return {
+ // ������������������
+ showTooltip: true,
+ // ������������id������������������������������������������������
+ textId: uni.$u.guid(),
+ tooltipId: uni.$u.guid(),
+ // ���������������������������������������������������������������������������������������
+ tooltipTop: -10000,
+ // ���������������������
+ tooltipInfo: {
+ width: 0,
+ left: 0
+ },
+ // ���������������������
+ textInfo: {
+ width: 0,
+ left: 0
+ },
+ // ���������������������������
+ indicatorStyle: {},
+ // ������������������������������������������������������������������������������������������
+ screenGap: 12,
+ // ���������������������������������������������������������������������������������������������������������������������������������
+ indicatorWidth: 14,
+ }
+ },
+ watch: {
+ propsChange() {
+ this.getElRect()
+ }
+ },
+ computed: {
+ // ������������H5������������������H5���������������������������������������������H5������
+ // ������������������������������������������������������������������������������������
+ propsChange() {
+ return [this.text, this.buttons]
+ },
+ // ���������������������������������������
+ tooltipStyle() {
+ const style = {
+ transform: `translateY(${this.direction === 'top' ? '-100%' : '100%'})`,
+ },
+ sys = uni.$u.sys(),
+ getPx = uni.$u.getPx,
+ addUnit = uni.$u.addUnit
+ if (this.tooltipInfo.width / 2 > this.textInfo.left + this.textInfo.width / 2 - this.screenGap) {
+ this.indicatorStyle = {}
+ style.left = `-${addUnit(this.textInfo.left - this.screenGap)}`
+ this.indicatorStyle.left = addUnit(this.textInfo.width / 2 - getPx(style.left) - this.indicatorWidth /
+ 2)
+ } else if (this.tooltipInfo.width / 2 > sys.windowWidth - this.textInfo.right + this.textInfo.width / 2 -
+ this.screenGap) {
+ this.indicatorStyle = {}
+ style.right = `-${addUnit(sys.windowWidth - this.textInfo.right - this.screenGap)}`
+ this.indicatorStyle.right = addUnit(this.textInfo.width / 2 - getPx(style.right) - this
+ .indicatorWidth / 2)
+ } else {
+ const left = Math.abs(this.textInfo.width / 2 - this.tooltipInfo.width / 2)
+ style.left = this.textInfo.width > this.tooltipInfo.width ? addUnit(left) : -addUnit(left)
+ this.indicatorStyle = {}
+ }
+ if (this.direction === 'top') {
+ style.marginTop = '-10px'
+ this.indicatorStyle.bottom = '-4px'
+ } else {
+ style.marginBottom = '-10px'
+ this.indicatorStyle.top = '-4px'
+ }
+ return style
+ }
+ },
+ mounted() {
+ this.init()
+ },
+ methods: {
+ init() {
+ this.getElRect()
+ },
+ // ������������������
+ async longpressHandler() {
+ this.tooltipTop = 0
+ this.showTooltip = true
+ },
+ // ������������������
+ overlayClickHandler() {
+ this.showTooltip = false
+ },
+ // ������������������
+ btnClickHandler(index) {
+ this.showTooltip = false
+ // ���������������������������������������index���������1���������������������������������������
+ this.$emit('click', this.showCopy ? index + 1 : index)
+ },
+ // ������������������
+ queryRect(ref) {
+ // #ifndef APP-NVUE
+ // $uGetRect���uView���������������������������������������������������������https://www.uviewui.com/js/getRect.html
+ // ���������������������this.$uGetRect���������������uni.$u.getRect������������������������������������
+ return new Promise(resolve => {
+ this.$uGetRect(`#${ref}`).then(size => {
+ resolve(size)
+ })
+ })
+ // #endif
+
+ // #ifdef APP-NVUE
+ // nvue������������dom������������������������
+ // ������������promise���������������������������������������then������
+ return new Promise(resolve => {
+ dom.getComponentRect(this.$refs[ref], res => {
+ resolve(res.size)
+ })
+ })
+ // #endif
+ },
+ // ������������
+ getElRect() {
+ // ���������������������������������������������������������������������
+ this.showTooltip = true
+ this.tooltipTop = -10000
+ uni.$u.sleep(500).then(() => {
+ this.queryRect(this.tooltipId).then(size => {
+ this.tooltipInfo = size
+ // ������������������������������������������������������������������������������������������������������������������
+ this.showTooltip = false
+ })
+ this.queryRect(this.textId).then(size => {
+ this.textInfo = size
+ })
+ })
+ },
+ // ������������������������
+ setClipboardData() {
+ // ������������
+ this.showTooltip = false
+ this.$emit('click', 0)
+ // #ifndef H5
+ uni.setClipboardData({
+ // ������������copyText���������������������������������������text���������������������������
+ data: this.copyText || this.text,
+ success: () => {
+ this.showToast && uni.$u.toast('������������')
+ },
+ fail: () => {
+ this.showToast && uni.$u.toast('������������')
+ },
+ complete: () => {
+ this.showTooltip = false
+ }
+ })
+ // #endif
+
+ // #ifdef H5
+ let event = window.event || e || {}
+ let clipboard = new ClipboardJS('', {
+ text: () => this.copyText || this.text
+ })
+ clipboard.on('success', (e) => {
+ this.showToast && uni.$u.toast('������������')
+ clipboard.off('success')
+ clipboard.off('error')
+ // ���������������������������������DOM���������
+ clipboard.destroy()
+ })
+ clipboard.on('error', (e) => {
+ this.showToast && uni.$u.toast('������������')
+ clipboard.off('success')
+ clipboard.off('error')
+ // ���������������������������������DOM���������
+ clipboard.destroy()
+ })
+ clipboard.onClick(event)
+ // #endif
+ }
+ }
+ }
+</script>
+
+<style lang="scss" scoped>
+ @import "../../libs/css/components.scss";
+
+ .u-tooltip {
+ position: relative;
+ @include flex;
+
+ &__wrapper {
+ @include flex;
+ justify-content: center;
+ /* #ifndef APP-NVUE */
+ white-space: nowrap;
+ /* #endif */
+
+ &__text {
+ font-size: 14px;
+ }
+
+ &__popup {
+ @include flex;
+ justify-content: center;
+
+ &__list {
+ background-color: #060607;
+ position: relative;
+ flex: 1;
+ border-radius: 5px;
+ padding: 0px 0;
+ @include flex(row);
+ align-items: center;
+ overflow: hidden;
+
+ &__btn {
+ padding: 11px 13px;
+
+ &--hover {
+ background-color: #58595B;
+ }
+
+ &__text {
+ line-height: 12px;
+ font-size: 13px;
+ color: #FFFFFF;
+ }
+ }
+ }
+
+ &__indicator {
+ position: absolute;
+ background-color: #060607;
+ width: 14px;
+ height: 14px;
+ bottom: -4px;
+ transform: rotate(45deg);
+ border-radius: 2px;
+ z-index: -1;
+
+ &--hover {
+ background-color: #58595B;
+ }
+ }
+ }
+ }
+ }
+</style>
diff --git a/uni_modules/uview-ui/components/u-tr/props.js b/uni_modules/uview-ui/components/u-tr/props.js
new file mode 100644
index 0000000..7c11331
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-tr/props.js
@@ -0,0 +1,5 @@
+export default {
+ props: {
+
+ }
+}
diff --git a/uni_modules/uview-ui/components/u-tr/u-tr.vue b/uni_modules/uview-ui/components/u-tr/u-tr.vue
new file mode 100644
index 0000000..dbbca08
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-tr/u-tr.vue
@@ -0,0 +1,31 @@
+<template>
+ <view class="u-tr">
+
+ </view>
+</template>
+
+<script>
+ import props from './props.js';
+ /**
+ * Tr
+ * @description
+ * @tutorial url
+ * @property {String}
+ * @event {Function}
+ * @example
+ */
+ export default {
+ name: 'u-tr',
+ mixins: [uni.$u.mpMixin, uni.$u.mixin,props],
+ data() {
+ return {
+
+ }
+ }
+ }
+</script>
+
+<style lang="scss" scoped>
+ @import "../../libs/css/components.scss";
+
+</style>
diff --git a/uni_modules/uview-ui/components/u-transition/nvue.ani-map.js b/uni_modules/uview-ui/components/u-transition/nvue.ani-map.js
new file mode 100644
index 0000000..b86b962
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-transition/nvue.ani-map.js
@@ -0,0 +1,68 @@
+export default {
+ fade: {
+ enter: { opacity: 0 },
+ 'enter-to': { opacity: 1 },
+ leave: { opacity: 1 },
+ 'leave-to': { opacity: 0 }
+ },
+ 'fade-up': {
+ enter: { opacity: 0, transform: 'translateY(100%)' },
+ 'enter-to': { opacity: 1, transform: 'translateY(0)' },
+ leave: { opacity: 1, transform: 'translateY(0)' },
+ 'leave-to': { opacity: 0, transform: 'translateY(100%)' }
+ },
+ 'fade-down': {
+ enter: { opacity: 0, transform: 'translateY(-100%)' },
+ 'enter-to': { opacity: 1, transform: 'translateY(0)' },
+ leave: { opacity: 1, transform: 'translateY(0)' },
+ 'leave-to': { opacity: 0, transform: 'translateY(-100%)' }
+ },
+ 'fade-left': {
+ enter: { opacity: 0, transform: 'translateX(-100%)' },
+ 'enter-to': { opacity: 1, transform: 'translateY(0)' },
+ leave: { opacity: 1, transform: 'translateY(0)' },
+ 'leave-to': { opacity: 0, transform: 'translateX(-100%)' }
+ },
+ 'fade-right': {
+ enter: { opacity: 0, transform: 'translateX(100%)' },
+ 'enter-to': { opacity: 1, transform: 'translateY(0)' },
+ leave: { opacity: 1, transform: 'translateY(0)' },
+ 'leave-to': { opacity: 0, transform: 'translateX(100%)' }
+ },
+ 'slide-up': {
+ enter: { transform: 'translateY(100%)' },
+ 'enter-to': { transform: 'translateY(0)' },
+ leave: { transform: 'translateY(0)' },
+ 'leave-to': { transform: 'translateY(100%)' }
+ },
+ 'slide-down': {
+ enter: { transform: 'translateY(-100%)' },
+ 'enter-to': { transform: 'translateY(0)' },
+ leave: { transform: 'translateY(0)' },
+ 'leave-to': { transform: 'translateY(-100%)' }
+ },
+ 'slide-left': {
+ enter: { transform: 'translateX(-100%)' },
+ 'enter-to': { transform: 'translateY(0)' },
+ leave: { transform: 'translateY(0)' },
+ 'leave-to': { transform: 'translateX(-100%)' }
+ },
+ 'slide-right': {
+ enter: { transform: 'translateX(100%)' },
+ 'enter-to': { transform: 'translateY(0)' },
+ leave: { transform: 'translateY(0)' },
+ 'leave-to': { transform: 'translateX(100%)' }
+ },
+ zoom: {
+ enter: { transform: 'scale(0.95)' },
+ 'enter-to': { transform: 'scale(1)' },
+ leave: { transform: 'scale(1)' },
+ 'leave-to': { transform: 'scale(0.95)' }
+ },
+ 'fade-zoom': {
+ enter: { opacity: 0, transform: 'scale(0.95)' },
+ 'enter-to': { opacity: 1, transform: 'scale(1)' },
+ leave: { opacity: 1, transform: 'scale(1)' },
+ 'leave-to': { opacity: 0, transform: 'scale(0.95)' }
+ }
+}
diff --git a/uni_modules/uview-ui/components/u-transition/props.js b/uni_modules/uview-ui/components/u-transition/props.js
new file mode 100644
index 0000000..f7b1c22
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-transition/props.js
@@ -0,0 +1,24 @@
+export default {
+ props: {
+ // ������������������
+ show: {
+ type: Boolean,
+ default: uni.$u.props.transition.show
+ },
+ // ���������������������
+ mode: {
+ type: String,
+ default: uni.$u.props.transition.mode
+ },
+ // ������������������������������ms
+ duration: {
+ type: [String, Number],
+ default: uni.$u.props.transition.duration
+ },
+ // ���������������������������
+ timingFunction: {
+ type: String,
+ default: uni.$u.props.transition.timingFunction
+ }
+ }
+}
diff --git a/uni_modules/uview-ui/components/u-transition/transition.js b/uni_modules/uview-ui/components/u-transition/transition.js
new file mode 100644
index 0000000..92e5681
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-transition/transition.js
@@ -0,0 +1,157 @@
+// ������������������������������������������promise������������nextTick���������������������������then������
+const nextTick = () => new Promise(resolve => setTimeout(resolve, 1000 / 50))
+// nvue���������������������������������������������
+import animationMap from './nvue.ani-map.js'
+
+// #ifndef APP-NVUE
+// ������������������������������������������������������������������������css������������
+const getClassNames = (name) => ({
+ enter: `u-${name}-enter u-${name}-enter-active`,
+ 'enter-to': `u-${name}-enter-to u-${name}-enter-active`,
+ leave: `u-${name}-leave u-${name}-leave-active`,
+ 'leave-to': `u-${name}-leave-to u-${name}-leave-active`
+})
+// #endif
+
+// #ifdef APP-NVUE
+// ������nvue(weex)���animation���������������������������
+// https://weex.apache.org/zh/docs/modules/animation.html#transition
+const animation = uni.requireNativePlugin('animation')
+const getStyle = (name) => animationMap[name]
+// #endif
+
+export default {
+ methods: {
+ // ���������������������������
+ clickHandler() {
+ this.$emit('click')
+ },
+ // #ifndef APP-NVUE
+ // vue���������������������������
+ vueEnter() {
+ // ������������������������
+ const classNames = getClassNames(this.mode)
+ // ������������������������������������������
+ this.status = 'enter'
+ this.$emit('beforeEnter')
+ this.inited = true
+ this.display = true
+ this.classes = classNames.enter
+ this.$nextTick(async () => {
+ // #ifdef H5
+ await uni.$u.sleep(20)
+ // #endif
+ // ������������������������
+ this.$emit('enter')
+ this.transitionEnded = false
+ // ������������������������������������
+ this.$emit('afterEnter')
+ // ������������enter-to������
+ this.classes = classNames['enter-to']
+ })
+ },
+ // ������������������
+ vueLeave() {
+ // ���������������������������������������������
+ if (!this.display) return
+ const classNames = getClassNames(this.mode)
+ // ���������������������������������
+ this.status = 'leave'
+ this.$emit('beforeLeave')
+ // ������������
+ this.classes = classNames.leave
+
+ this.$nextTick(() => {
+ // ���������������������������
+ this.transitionEnded = false
+ this.$emit('leave')
+ // ������������������������������������������������������������������������������
+ setTimeout(this.onTransitionEnd, this.duration)
+ this.classes = classNames['leave-to']
+ })
+ },
+ // #endif
+ // #ifdef APP-NVUE
+ // nvue������������������
+ nvueEnter() {
+ // ���������������������
+ const currentStyle = getStyle(this.mode)
+ // ���������������������������������
+ this.status = 'enter'
+ this.$emit('beforeEnter')
+ // ������������������������
+ this.inited = true
+ this.display = true
+ // ���nvue���������������������������������������������������������������������������������������������������������������
+ // ���������������������������������������������������������������������������������������������������������������������������������������������������������
+ this.viewStyle = {
+ opacity: 0
+ }
+ // ������������������������������
+ this.$nextTick(() => {
+ // ������������
+ this.viewStyle = currentStyle.enter
+ Promise.resolve()
+ .then(nextTick)
+ .then(() => {
+ // ������������������������������
+ this.$emit('enter')
+ // nvue���transition������������������������ref������������������������������ref���������vue���this.$refs['u-transition']������
+ animation.transition(this.$refs['u-transition'].ref, {
+ styles: currentStyle['enter-to'],
+ duration: this.duration,
+ timingFunction: this.timingFunction,
+ needLayout: false,
+ delay: 0
+ }, () => {
+ // ���������������������������������
+ this.$emit('afterEnter')
+ })
+ })
+ .catch(() => {})
+ })
+ },
+ nvueLeave() {
+ if (!this.display) {
+ return
+ }
+ const currentStyle = getStyle(this.mode)
+ // ���������������������
+ this.status = 'leave'
+ this.$emit('beforeLeave')
+ // ������������
+ this.viewStyle = currentStyle.leave
+ // ������promise���������������������
+ Promise.resolve()
+ .then(nextTick) // ������������ms
+ .then(() => {
+ this.transitionEnded = false
+ // ���������������������������
+ this.$emit('leave')
+ animation.transition(this.$refs['u-transition'].ref, {
+ styles: currentStyle['leave-to'],
+ duration: this.duration,
+ timingFunction: this.timingFunction,
+ needLayout: false,
+ delay: 0
+ }, () => {
+ this.onTransitionEnd()
+ })
+ })
+ .catch(() => {})
+ },
+ // #endif
+ // ���������������������
+ onTransitionEnd() {
+ // ������������������������������������������������
+ if (this.transitionEnded) return
+ this.transitionEnded = true
+ // ������������������������������������
+ this.$emit(this.status === 'leave' ? 'afterLeave' : 'afterEnter')
+ if (!this.show && this.display) {
+ this.display = false
+ this.inited = false
+ }
+ }
+ }
+}
diff --git a/uni_modules/uview-ui/components/u-transition/u-transition.vue b/uni_modules/uview-ui/components/u-transition/u-transition.vue
new file mode 100644
index 0000000..22831dc
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-transition/u-transition.vue
@@ -0,0 +1,92 @@
+<template>
+ <view
+ v-if="inited"
+ class="u-transition"
+ ref="u-transition"
+ @tap="clickHandler"
+ :class="classes"
+ :style="[mergeStyle]"
+ @touchmove="noop"
+ >
+ <slot />
+ </view>
+</template>
+
+<script>
+import props from './props.js';
+// ���������methods���������������������������������������������������������mixin������
+import transition from "./transition.js";
+/**
+ * transition ������������
+ * @description
+ * @tutorial
+ * @property {String} show ������������������ ��������� false ���
+ * @property {String} mode ��������������������� ��������� 'fade' ���
+ * @property {String | Number} duration ������������������������������ms ��������� '300' ���
+ * @property {String} timingFunction ��������������������������� ��������� 'ease-out' ���
+ * @property {Object} customStyle ���������������
+ * @event {Function} before-enter ���������������
+ * @event {Function} enter ���������������
+ * @event {Function} after-enter ���������������
+ * @event {Function} before-leave ���������������
+ * @event {Function} leave ���������������
+ * @event {Function} after-leave ���������������
+ * @example
+ */
+export default {
+ name: 'u-transition',
+ data() {
+ return {
+ inited: false, // ������������/������������
+ viewStyle: {}, // ���������������������
+ status: '', // ���������������������������
+ transitionEnded: false, // ���������������������������
+ display: false, // ������������������
+ classes: '', // ���������������
+ }
+ },
+ computed: {
+ mergeStyle() {
+ const { viewStyle, customStyle } = this
+ return {
+ // #ifndef APP-NVUE
+ transitionDuration: `${this.duration}ms`,
+ // display: `${this.display ? '' : 'none'}`,
+ transitionTimingFunction: this.timingFunction,
+ // #endif
+ // ���������������������������������������������������������viewStyle������
+ ...uni.$u.addStyle(customStyle),
+ ...viewStyle
+ }
+ }
+ },
+ // ���mixin���������������������uni.$u.mixin������������������vue������������
+ mixins: [uni.$u.mpMixin, uni.$u.mixin, transition, props],
+ watch: {
+ show: {
+ handler(newVal) {
+ // vue���nvue���������������������������
+ // #ifdef APP-NVUE
+ newVal ? this.nvueEnter() : this.nvueLeave()
+ // #endif
+ // #ifndef APP-NVUE
+ newVal ? this.vueEnter() : this.vueLeave()
+ // #endif
+ },
+ // ���������������������������������props���show���������
+ immediate: true
+ }
+ }
+}
+</script>
+
+<style lang="scss" scoped>
+@import '../../libs/css/components.scss';
+
+/* #ifndef APP-NVUE */
+// vue������������������������������������������������
+@import './vue.ani-style.scss';
+/* #endif */
+
+.u-transition {}
+</style>
diff --git a/uni_modules/uview-ui/components/u-transition/vue.ani-style.scss b/uni_modules/uview-ui/components/u-transition/vue.ani-style.scss
new file mode 100644
index 0000000..a31d88b
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-transition/vue.ani-style.scss
@@ -0,0 +1,113 @@
+/**
+ * vue���������������������������������������������
+ * fade���������
+ * zoom���������
+ * fade-zoom���������������
+ * fade-up���������������
+ * fade-down���������������
+ * fade-left���������������
+ * fade-right���������������
+ * slide-up���������������
+ * slide-down���������������
+ * slide-left���������������
+ * slide-right���������������
+ */
+
+$u-zoom-scale: scale(0.95);
+
+.u-fade-enter-active,
+.u-fade-leave-active {
+ transition-property: opacity;
+}
+
+.u-fade-enter,
+.u-fade-leave-to {
+ opacity: 0
+}
+
+.u-fade-zoom-enter,
+.u-fade-zoom-leave-to {
+ transform: $u-zoom-scale;
+ opacity: 0;
+}
+
+.u-fade-zoom-enter-active,
+.u-fade-zoom-leave-active {
+ transition-property: transform, opacity;
+}
+
+.u-fade-down-enter-active,
+.u-fade-down-leave-active,
+.u-fade-left-enter-active,
+.u-fade-left-leave-active,
+.u-fade-right-enter-active,
+.u-fade-right-leave-active,
+.u-fade-up-enter-active,
+.u-fade-up-leave-active {
+ transition-property: opacity, transform;
+}
+
+.u-fade-up-enter,
+.u-fade-up-leave-to {
+ transform: translate3d(0, 100%, 0);
+ opacity: 0
+}
+
+.u-fade-down-enter,
+.u-fade-down-leave-to {
+ transform: translate3d(0, -100%, 0);
+ opacity: 0
+}
+
+.u-fade-left-enter,
+.u-fade-left-leave-to {
+ transform: translate3d(-100%, 0, 0);
+ opacity: 0
+}
+
+.u-fade-right-enter,
+.u-fade-right-leave-to {
+ transform: translate3d(100%, 0, 0);
+ opacity: 0
+}
+
+.u-slide-down-enter-active,
+.u-slide-down-leave-active,
+.u-slide-left-enter-active,
+.u-slide-left-leave-active,
+.u-slide-right-enter-active,
+.u-slide-right-leave-active,
+.u-slide-up-enter-active,
+.u-slide-up-leave-active {
+ transition-property: transform;
+}
+
+.u-slide-up-enter,
+.u-slide-up-leave-to {
+ transform: translate3d(0, 100%, 0)
+}
+
+.u-slide-down-enter,
+.u-slide-down-leave-to {
+ transform: translate3d(0, -100%, 0)
+}
+
+.u-slide-left-enter,
+.u-slide-left-leave-to {
+ transform: translate3d(-100%, 0, 0)
+}
+
+.u-slide-right-enter,
+.u-slide-right-leave-to {
+ transform: translate3d(100%, 0, 0)
+}
+
+.u-zoom-enter-active,
+.u-zoom-leave-active {
+ transition-property: transform
+}
+
+.u-zoom-enter,
+.u-zoom-leave-to {
+ transform: $u-zoom-scale
+}
diff --git a/uni_modules/uview-ui/components/u-upload/mixin.js b/uni_modules/uview-ui/components/u-upload/mixin.js
new file mode 100644
index 0000000..410c775
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-upload/mixin.js
@@ -0,0 +1,21 @@
+export default {
+ watch: {
+ // ������accept���������������������������������������������
+ // ���������������������������������������������������������������������������������������������
+ accept: {
+ immediate: true,
+ handler(val) {
+ // #ifndef MP-WEIXIN
+ if (val === 'all' || val === 'media') {
+ uni.$u.error('���������������������������������accept���������all���media������')
+ }
+ // #endif
+ // #ifndef H5 || MP-WEIXIN
+ if (val === 'file') {
+ uni.$u.error('������������������������H5(HX2.9.9)������������accept���������file')
+ }
+ // #endif
+ }
+ }
+ }
+}
diff --git a/uni_modules/uview-ui/components/u-upload/props.js b/uni_modules/uview-ui/components/u-upload/props.js
new file mode 100644
index 0000000..b106ae7
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-upload/props.js
@@ -0,0 +1,124 @@
+export default {
+ props: {
+ // ���������������������, ������������all media image file video
+ accept: {
+ type: String,
+ default: uni.$u.props.upload.accept
+ },
+ // ���������������������������������accept���image���������������capture������������camera���������������������������
+ capture: {
+ type: [String, Array],
+ default: uni.$u.props.upload.capture
+ },
+ // ���accept���video������������������������������������������true
+ compressed: {
+ type: Boolean,
+ default: uni.$u.props.upload.compressed
+ },
+ // ���accept���video������������������������back���front
+ camera: {
+ type: String,
+ default: uni.$u.props.upload.camera
+ },
+ // ���accept���video������������������������������������������������������
+ maxDuration: {
+ type: Number,
+ default: uni.$u.props.upload.maxDuration
+ },
+ // ������������������������������������������
+ uploadIcon: {
+ type: String,
+ default: uni.$u.props.upload.uploadIcon
+ },
+ // ���������������������������������������
+ uploadIconColor: {
+ type: String,
+ default: uni.$u.props.upload.uploadIconColor
+ },
+ // ���������������������������������
+ useBeforeRead: {
+ type: Boolean,
+ default: uni.$u.props.upload.useBeforeRead
+ },
+ // ������������������������
+ afterRead: {
+ type: Function,
+ default: null
+ },
+ // ������������������������
+ beforeRead: {
+ type: Function,
+ default: null
+ },
+ // ���������������������������������������������
+ previewFullImage: {
+ type: Boolean,
+ default: uni.$u.props.upload.previewFullImage
+ },
+ // ������������������
+ maxCount: {
+ type: [String, Number],
+ default: uni.$u.props.upload.maxCount
+ },
+ // ������������
+ disabled: {
+ type: Boolean,
+ default: uni.$u.props.upload.disabled
+ },
+ // ���������������������������������������������image������mode������������
+ imageMode: {
+ type: String,
+ default: uni.$u.props.upload.imageMode
+ },
+ // ������������������������������������������������������������
+ name: {
+ type: String,
+ default: uni.$u.props.upload.name
+ },
+ // ������������������������, ������������original compressed
+ sizeType: {
+ type: Array,
+ default: uni.$u.props.upload.sizeType
+ },
+ // ������������������������������������������������������
+ multiple: {
+ type: Boolean,
+ default: uni.$u.props.upload.multiple
+ },
+ // ������������������������
+ deletable: {
+ type: Boolean,
+ default: uni.$u.props.upload.deletable
+ },
+ // ������������������������������byte
+ maxSize: {
+ type: [String, Number],
+ default: uni.$u.props.upload.maxSize
+ },
+ // ������������������������������
+ fileList: {
+ type: Array,
+ default: uni.$u.props.upload.fileList
+ },
+ // ���������������������������
+ uploadText: {
+ type: String,
+ default: uni.$u.props.upload.uploadText
+ },
+ // ������������������������������������������������������������
+ width: {
+ type: [String, Number],
+ default: uni.$u.props.upload.width
+ },
+ // ������������������������������������������������������������
+ height: {
+ type: [String, Number],
+ default: uni.$u.props.upload.height
+ },
+ // ���������������������������������������
+ previewImage: {
+ type: Boolean,
+ default: uni.$u.props.upload.previewImage
+ }
+ }
+}
diff --git a/uni_modules/uview-ui/components/u-upload/u-upload.vue b/uni_modules/uview-ui/components/u-upload/u-upload.vue
new file mode 100644
index 0000000..1dac8a7
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-upload/u-upload.vue
@@ -0,0 +1,558 @@
+<template>
+ <view class="u-upload" :style="[$u.addStyle(customStyle)]">
+ <view class="u-upload__wrap" >
+ <template v-if="previewImage">
+ <view
+ class="u-upload__wrap__preview"
+ v-for="(item, index) in lists"
+ :key="index"
+ >
+ <image
+ v-if="item.isImage || (item.type && item.type === 'image')"
+ :src="item.thumb || item.url"
+ :mode="imageMode"
+ class="u-upload__wrap__preview__image"
+ @tap="onPreviewImage(item)"
+ :style="[{
+ width: $u.addUnit(width),
+ height: $u.addUnit(height)
+ }]"
+ />
+ <view
+ v-else
+ class="u-upload__wrap__preview__other"
+ >
+ <u-icon
+ color="#80CBF9"
+ size="26"
+ :name="item.isVideo || (item.type && item.type === 'video') ? 'movie' : 'folder'"
+ ></u-icon>
+ <text class="u-upload__wrap__preview__other__text">{{item.isVideo || (item.type && item.type === 'video') ? '������' : '������'}}</text>
+ </view>
+ <view
+ class="u-upload__status"
+ v-if="item.status === 'uploading' || item.status === 'failed'"
+ >
+ <view class="u-upload__status__icon">
+ <u-icon
+ v-if="item.status === 'failed'"
+ name="close-circle"
+ color="#ffffff"
+ size="25"
+ />
+ <u-loading-icon
+ size="22"
+ mode="circle"
+ color="#ffffff"
+ v-else
+ />
+ </view>
+ <text
+ v-if="item.message"
+ class="u-upload__status__message"
+ >{{ item.message }}</text>
+ </view>
+ <view
+ class="u-upload__deletable"
+ v-if="item.status !== 'uploading' && (deletable || item.deletable)"
+ @tap.stop="deleteItem(index)"
+ >
+ <view class="u-upload__deletable__icon">
+ <u-icon
+ name="close"
+ color="#ffffff"
+ size="10"
+ ></u-icon>
+ </view>
+ </view>
+ <view
+ class="u-upload__success"
+ v-if="item.status === 'success'"
+ >
+ <!-- #ifdef APP-NVUE -->
+ <image
+ :src="successIcon"
+ class="u-upload__success__icon"
+ ></image>
+ <!-- #endif -->
+ <!-- #ifndef APP-NVUE -->
+ <view class="u-upload__success__icon">
+ <u-icon
+ name="checkmark"
+ color="#ffffff"
+ size="12"
+ ></u-icon>
+ </view>
+ <!-- #endif -->
+ </view>
+ </view>
+
+ </template>
+
+ <template v-if="isInCount">
+ <view
+ v-if="$slots.default || $slots.$default"
+ @tap="chooseFile"
+ >
+ <slot />
+ </view>
+ <view
+ v-else
+ class="u-upload__button"
+ :hover-class="!disabled ? 'u-upload__button--hover' : ''"
+ hover-stay-time="150"
+ @tap="chooseFile"
+ :class="[disabled && 'u-upload__button--disabled']"
+ :style="[{
+ width: $u.addUnit(width),
+ height: $u.addUnit(height)
+ }]"
+ >
+ <u-icon
+ :name="uploadIcon"
+ size="26"
+ :color="uploadIconColor"
+ ></u-icon>
+ <text
+ v-if="uploadText"
+ class="u-upload__button__text"
+ >{{ uploadText }}</text>
+ </view>
+ </template>
+ </view>
+
+ </view>
+</template>
+
+<script>
+ import {
+ chooseFile
+ } from './utils';
+ import mixin from './mixin.js';
+ import props from './props.js';
+
+ /**
+ * upload ������
+ * @description ���������������������������������
+ * @tutorial https://uviewui.com/components/upload.html
+ * @property {String} accept ���������������������, ������������all media image file video ��������� 'image' ���
+ * @property {String | Array} capture ���������������������������������accept���image���������������capture������������camera������������������������������������ ['album', 'camera'] ���
+ * @property {Boolean} compressed ���accept���video������������������������������������������true��������� true ���
+ * @property {String} camera ���accept���video������������������������back���front��������� 'back' ���
+ * @property {Number} maxDuration ���accept���video��������������������������������������������������������������� 60 ���
+ * @property {String} uploadIcon ��������������������������������������������������� 'camera-fill' ���
+ * @property {String} uploadIconColor ������������������������������������������������������������������ #D3D4D6 ���
+ * @property {Boolean} useBeforeRead ������������������������������������������ false ���
+ * @property {Boolean} previewFullImage ������������������������������������������������������ true ���
+ * @property {String | Number} maxCount ��������������������������� 52 ���
+ * @property {Boolean} disabled ��������������������� false ���
+ * @property {String} imageMode ���������������������������������������������image������mode��������������������� 'aspectFill' ���
+ * @property {String} name ������������������������������������������������������������
+ * @property {Array} sizeType ������������������������, ������������original compressed��������� ['original', 'compressed'] ���
+ * @property {Boolean} multiple ������������������������������������������������������ ��������� false ���
+ * @property {Boolean} deletable ��������������������������������� true ���
+ * @property {String | Number} maxSize ������������������������������byte ��������� Number.MAX_VALUE ���
+ * @property {Array} fileList ������������������������������
+ * @property {String} uploadText ���������������������������
+ * @property {String | Number} width ��������������������������������������������������������������������� 80 ���
+ * @property {String | Number} height ��������������������������������������������������������������������� 80 ���
+ * @property {Object} customStyle ������������������������������
+ * @event {Function} afterRead ������������������������
+ * @event {Function} beforeRead ������������������������
+ * @event {Function} oversize ������������������������
+ * @event {Function} clickPreview ������������������
+ * @event {Function} delete ������������
+ * @example <u-upload :action="action" :fileList="fileList" ></u-upload>
+ */
+ export default {
+ name: "u-upload",
+ mixins: [uni.$u.mpMixin, uni.$u.mixin, mixin,props],
+ data() {
+ return {
+ // #ifdef APP-NVUE
+ successIcon: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAYAAACM/rhtAAAAAXNSR0IArs4c6QAAAERlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAA6ABAAMAAAABAAEAAKACAAQAAAABAAAAKKADAAQAAAABAAAAKAAAAAB65masAAACP0lEQVRYCc3YXygsURwH8K/dpcWyG3LF5u/6/+dKVylSypuUl6uUPMifKMWL8oKEB1EUT1KeUPdR3uTNUsSLxb2udG/cbvInNuvf2rVnazZ/ZndmZ87snjM1Z+Z3zpzfp9+Z5mEAhlvjRtZgCKs+gnPAOcAkkMOR4jEHfItjDvgRxxSQD8cM0BuOCaAvXNCBQrigAsXgggYUiwsK0B9cwIH+4gIKlIILGFAqLiBAOTjFgXJxigJp4BQD0sIpAqSJow6kjSNAFTnRaHJwLenD6Mud52VQAcrBfTd2oyq+HtGaGGWAcnAVcXWoM3bCZrdi+ncPfaAcXE5UKVpdW/vitGPqqAtn98d0gXJwX7Qp6MmegUYVhvmTIezdmHlxJCjpHRTCFerLkRRu4k0aqdajN3sWOo0BK//msHa+xDuPC/oNFMKRhTtM4xjIX0SCNpXL4+7VIaHuyiWEp2L7ahWLf8fejfPdqPmC3mJicORZUp1CQzm+GiphvljGk+PBvWRbxii+xVTj5M6CiZ/tsDufvaXyxEUDxeLIyvu3m0iOyEFWVAkydcVYdyFrE9tQk9iMq6f/GNlvwt3LjQfh60LUrw9/cFyyMJUW/XkLSNMV4Mi6C5ML+ui4x5ClAX9sB9w0wV6wglJwJCv5fOxcr6EstgbGiEw4XcfUry4cWrcEUW8n+ARKxXEJHhw2WG43UKSvwI/TSZgvl7kh0b3XLZaLEy0QmMgLZAVH7J+ALOE+AVnDvQOyiPMAWcW5gSzjCPAV+78S5WE0GrQAAAAASUVORK5CYII=',
+ // #endif
+ lists: [],
+ isInCount: true,
+ }
+ },
+ watch: {
+ // ������������������������������������������������������
+ fileList: {
+ immediate: true,
+ handler() {
+ this.formatFileList()
+ }
+ },
+ },
+ methods: {
+ formatFileList() {
+ const {
+ fileList = [], maxCount
+ } = this;
+ const lists = fileList.map((item) =>
+ Object.assign(Object.assign({}, item), {
+ // ������item.url������������������blob���������������������������������video������image���������������������accept���������������
+ isImage: this.accept === 'image' || uni.$u.test.image(item.url || item.thumb),
+ isVideo: this.accept === 'video' || uni.$u.test.video(item.url || item.thumb),
+ deletable: typeof(item.deletable) === 'boolean' ? item.deletable : this.deletable,
+ })
+ );
+ this.lists = lists
+ this.isInCount = lists.length < maxCount
+ },
+ chooseFile() {
+ const {
+ maxCount,
+ multiple,
+ lists,
+ disabled
+ } = this;
+ if (disabled) return;
+ // ������������������������������������������������������������
+ let capture;
+ try {
+ capture = uni.$u.test.array(this.capture) ? this.capture : this.capture.split(',');
+ }catch(e) {
+ capture = [];
+ }
+ chooseFile(
+ Object.assign({
+ accept: this.accept,
+ multiple: this.multiple,
+ capture: capture,
+ compressed: this.compressed,
+ maxDuration: this.maxDuration,
+ sizeType: this.sizeType,
+ camera: this.camera,
+ }, {
+ maxCount: maxCount - lists.length,
+ })
+ )
+ .then((res) => {
+ this.onBeforeRead(multiple ? res : res[0]);
+ })
+ .catch((error) => {
+ this.$emit('error', error);
+ });
+ },
+ // ������������������
+ onBeforeRead(file) {
+ const {
+ beforeRead,
+ useBeforeRead,
+ } = this;
+ let res = true
+ // beforeRead���������������������
+ if (uni.$u.test.func(beforeRead)) {
+ // ���������������������������������������������������������������������������������������
+ res = beforeRead(file, this.getDetail());
+ }
+ if (useBeforeRead) {
+ res = new Promise((resolve, reject) => {
+ this.$emit(
+ 'beforeRead',
+ Object.assign(Object.assign({
+ file
+ }, this.getDetail()), {
+ callback: (ok) => {
+ ok ? resolve() : reject();
+ },
+ })
+ );
+ });
+ }
+ if (!res) {
+ return;
+ }
+ if (uni.$u.test.promise(res)) {
+ res.then((data) => this.onAfterRead(data || file));
+ } else {
+ this.onAfterRead(file);
+ }
+ },
+ getDetail(index) {
+ return {
+ name: this.name,
+ index: index == null ? this.fileList.length : index,
+ };
+ },
+ onAfterRead(file) {
+ const {
+ maxSize,
+ afterRead
+ } = this;
+ const oversize = Array.isArray(file) ?
+ file.some((item) => item.size > maxSize) :
+ file.size > maxSize;
+ if (oversize) {
+ this.$emit('oversize', Object.assign({
+ file
+ }, this.getDetail()));
+ return;
+ }
+ if (typeof afterRead === 'function') {
+ afterRead(file, this.getDetail());
+ }
+ this.$emit('afterRead', Object.assign({
+ file
+ }, this.getDetail()));
+ },
+ deleteItem(index) {
+ this.$emit(
+ 'delete',
+ Object.assign(Object.assign({}, this.getDetail(index)), {
+ file: this.fileList[index],
+ })
+ );
+ },
+ // ������������
+ onPreviewImage(item) {
+ if (!item.isImage || !this.previewFullImage) return
+ uni.previewImage({
+ // ���filter������������������item������������filter������������������url
+ urls: this.lists.filter((item) => this.accept === 'image' || uni.$u.test.image(item.url || item.thumb)).map((item) => item.url || item.thumb),
+ current: item.url || item.thumb,
+ fail() {
+ uni.$u.toast('������������������')
+ },
+ });
+ },
+ onPreviewVideo(event) {
+ if (!this.data.previewFullImage) return;
+ const {
+ index
+ } = event.currentTarget.dataset;
+ const {
+ lists
+ } = this.data;
+ wx.previewMedia({
+ sources: lists
+ .filter((item) => isVideoFile(item))
+ .map((item) =>
+ Object.assign(Object.assign({}, item), {
+ type: 'video'
+ })
+ ),
+ current: index,
+ fail() {
+ uni.$u.toast('������������������')
+ },
+ });
+ },
+ onClickPreview(event) {
+ const {
+ index
+ } = event.currentTarget.dataset;
+ const item = this.data.lists[index];
+ this.$emit(
+ 'clickPreview',
+ Object.assign(Object.assign({}, item), this.getDetail(index))
+ );
+ }
+ }
+ }
+</script>
+
+<style lang="scss" scoped>
+ @import '../../libs/css/components.scss';
+ $u-upload-preview-border-radius: 2px !default;
+ $u-upload-preview-margin: 0 8px 8px 0 !default;
+ $u-upload-image-width:80px !default;
+ $u-upload-image-height:$u-upload-image-width;
+ $u-upload-other-bgColor: rgb(242, 242, 242) !default;
+ $u-upload-other-flex:1 !default;
+ $u-upload-text-font-size:11px !default;
+ $u-upload-text-color:$u-tips-color !default;
+ $u-upload-text-margin-top:2px !default;
+ $u-upload-deletable-right:0 !default;
+ $u-upload-deletable-top:0 !default;
+ $u-upload-deletable-bgColor:rgb(55, 55, 55) !default;
+ $u-upload-deletable-height:14px !default;
+ $u-upload-deletable-width:$u-upload-deletable-height;
+ $u-upload-deletable-boder-bottom-left-radius:100px !default;
+ $u-upload-deletable-zIndex:3 !default;
+ $u-upload-success-bottom:0 !default;
+ $u-upload-success-right:0 !default;
+ $u-upload-success-border-style:solid !default;
+ $u-upload-success-border-top-color:transparent !default;
+ $u-upload-success-border-left-color:transparent !default;
+ $u-upload-success-border-bottom-color: $u-success !default;
+ $u-upload-success-border-right-color:$u-upload-success-border-bottom-color;
+ $u-upload-success-border-width:9px !default;
+ $u-upload-icon-top:0px !default;
+ $u-upload-icon-right:0px !default;
+ $u-upload-icon-h5-top:1px !default;
+ $u-upload-icon-h5-right:0 !default;
+ $u-upload-icon-width:16px !default;
+ $u-upload-icon-height:$u-upload-icon-width;
+ $u-upload-success-icon-bottom:-10px !default;
+ $u-upload-success-icon-right:-10px !default;
+ $u-upload-status-right:0 !default;
+ $u-upload-status-left:0 !default;
+ $u-upload-status-bottom:0 !default;
+ $u-upload-status-top:0 !default;
+ $u-upload-status-bgColor:rgba(0, 0, 0, 0.5) !default;
+ $u-upload-status-icon-Zindex:1 !default;
+ $u-upload-message-font-size:12px !default;
+ $u-upload-message-color:#FFFFFF !default;
+ $u-upload-message-margin-top:5px !default;
+ $u-upload-button-width:80px !default;
+ $u-upload-button-height:$u-upload-button-width;
+ $u-upload-button-bgColor:rgb(244, 245, 247) !default;
+ $u-upload-button-border-radius:2px !default;
+ $u-upload-botton-margin: 0 8px 8px 0 !default;
+ $u-upload-text-font-size:11px !default;
+ $u-upload-text-color:$u-tips-color !default;
+ $u-upload-text-margin-top: 2px !default;
+ $u-upload-hover-bgColor:rgb(230, 231, 233) !default;
+ $u-upload-disabled-opacity:.5 !default;
+
+ .u-upload {
+ @include flex(column);
+ flex: 1;
+
+ &__wrap {
+ @include flex;
+ flex-wrap: wrap;
+ flex: 1;
+
+ &__preview {
+ border-radius: $u-upload-preview-border-radius;
+ margin: $u-upload-preview-margin;
+ position: relative;
+ overflow: hidden;
+ @include flex;
+
+ &__image {
+ width: $u-upload-image-width;
+ height: $u-upload-image-height;
+ }
+
+ &__other {
+ width: $u-upload-image-width;
+ height: $u-upload-image-height;
+ background-color: $u-upload-other-bgColor;
+ flex: $u-upload-other-flex;
+ @include flex(column);
+ justify-content: center;
+ align-items: center;
+
+ &__text {
+ font-size: $u-upload-text-font-size;
+ color: $u-upload-text-color;
+ margin-top: $u-upload-text-margin-top;
+ }
+ }
+ }
+ }
+
+ &__deletable {
+ position: absolute;
+ top: $u-upload-deletable-top;
+ right: $u-upload-deletable-right;
+ background-color: $u-upload-deletable-bgColor;
+ height: $u-upload-deletable-height;
+ width: $u-upload-deletable-width;
+ @include flex;
+ border-bottom-left-radius: $u-upload-deletable-boder-bottom-left-radius;
+ align-items: center;
+ justify-content: center;
+ z-index: $u-upload-deletable-zIndex;
+
+ &__icon {
+ position: absolute;
+ transform: scale(0.7);
+ top: $u-upload-icon-top;
+ right: $u-upload-icon-right;
+ /* #ifdef H5 */
+ top: $u-upload-icon-h5-top;
+ right: $u-upload-icon-h5-right;
+ /* #endif */
+ }
+ }
+
+ &__success {
+ position: absolute;
+ bottom: $u-upload-success-bottom;
+ right: $u-upload-success-right;
+ @include flex;
+ // ������weex(nvue)������������������KPI(������������������)���laji������������������css���������������
+ // ���������nvue���������������������nvue���������css������
+ /* #ifndef APP-NVUE */
+ border-style: $u-upload-success-border-style;
+ border-top-color: $u-upload-success-border-top-color;
+ border-left-color: $u-upload-success-border-left-color;
+ border-bottom-color: $u-upload-success-border-bottom-color;
+ border-right-color: $u-upload-success-border-right-color;
+ border-width: $u-upload-success-border-width;
+ align-items: center;
+ justify-content: center;
+ /* #endif */
+
+ &__icon {
+ /* #ifndef APP-NVUE */
+ position: absolute;
+ transform: scale(0.7);
+ bottom: $u-upload-success-icon-bottom;
+ right: $u-upload-success-icon-right;
+ /* #endif */
+ /* #ifdef APP-NVUE */
+ width: $u-upload-icon-width;
+ height: $u-upload-icon-height;
+ /* #endif */
+ }
+ }
+
+ &__status {
+ position: absolute;
+ top: $u-upload-status-top;
+ bottom: $u-upload-status-bottom;
+ left: $u-upload-status-left;
+ right: $u-upload-status-right;
+ background-color: $u-upload-status-bgColor;
+ @include flex(column);
+ align-items: center;
+ justify-content: center;
+
+ &__icon {
+ position: relative;
+ z-index: $u-upload-status-icon-Zindex;
+ }
+
+ &__message {
+ font-size: $u-upload-message-font-size;
+ color: $u-upload-message-color;
+ margin-top: $u-upload-message-margin-top;
+ }
+ }
+
+ &__button {
+ @include flex(column);
+ align-items: center;
+ justify-content: center;
+ width: $u-upload-button-width;
+ height: $u-upload-button-height;
+ background-color: $u-upload-button-bgColor;
+ border-radius: $u-upload-button-border-radius;
+ margin: $u-upload-botton-margin;
+ /* #ifndef APP-NVUE */
+ box-sizing: border-box;
+ /* #endif */
+
+ &__text {
+ font-size: $u-upload-text-font-size;
+ color: $u-upload-text-color;
+ margin-top: $u-upload-text-margin-top;
+ }
+
+ &--hover {
+ background-color: $u-upload-hover-bgColor;
+ }
+
+ &--disabled {
+ opacity: $u-upload-disabled-opacity;
+ }
+ }
+ }
+</style>
diff --git a/uni_modules/uview-ui/components/u-upload/utils.js b/uni_modules/uview-ui/components/u-upload/utils.js
new file mode 100644
index 0000000..88cb602
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-upload/utils.js
@@ -0,0 +1,151 @@
+function pickExclude(obj, keys) {
+ // ������������������type������������
+ if (!['[object Object]', '[object File]'].includes(Object.prototype.toString.call(obj))) {
+ return {}
+ }
+ return Object.keys(obj).reduce((prev, key) => {
+ if (!keys.includes(key)) {
+ prev[key] = obj[key]
+ }
+ return prev
+ }, {})
+}
+
+function formatImage(res) {
+ return res.tempFiles.map((item) => ({
+ ...pickExclude(item, ['path']),
+ type: 'image',
+ url: item.path,
+ thumb: item.path,
+ size: item.size,
+ // #ifdef H5
+ name: item.name
+ // #endif
+ }))
+}
+
+function formatVideo(res) {
+ return [
+ {
+ ...pickExclude(res, ['tempFilePath', 'thumbTempFilePath', 'errMsg']),
+ type: 'video',
+ url: res.tempFilePath,
+ thumb: res.thumbTempFilePath,
+ size: res.size,
+ // #ifdef H5
+ name: res.name
+ // #endif
+ }
+ ]
+}
+
+function formatMedia(res) {
+ return res.tempFiles.map((item) => ({
+ ...pickExclude(item, ['fileType', 'thumbTempFilePath', 'tempFilePath']),
+ type: res.type,
+ url: item.tempFilePath,
+ thumb: res.type === 'video' ? item.thumbTempFilePath : item.tempFilePath,
+ size: item.size
+ }))
+}
+
+function formatFile(res) {
+ return res.tempFiles.map((item) => ({
+ ...pickExclude(item, ['path']),
+ url: item.path,
+ size:item.size,
+ // #ifdef H5
+ name: item.name,
+ type: item.type
+ // #endif
+ }))
+}
+export function chooseFile({
+ accept,
+ multiple,
+ capture,
+ compressed,
+ maxDuration,
+ sizeType,
+ camera,
+ maxCount
+}) {
+ return new Promise((resolve, reject) => {
+ switch (accept) {
+ case 'image':
+ uni.chooseImage({
+ count: multiple ? Math.min(maxCount, 9) : 1,
+ sourceType: capture,
+ sizeType,
+ success: (res) => resolve(formatImage(res)),
+ fail: reject
+ })
+ break
+ // #ifdef MP-WEIXIN
+ // ������������������������������chooseMedia������
+ case 'media':
+ wx.chooseMedia({
+ count: multiple ? Math.min(maxCount, 9) : 1,
+ sourceType: capture,
+ maxDuration,
+ sizeType,
+ camera,
+ success: (res) => resolve(formatMedia(res)),
+ fail: reject
+ })
+ break
+ // #endif
+ case 'video':
+ uni.chooseVideo({
+ sourceType: capture,
+ compressed,
+ maxDuration,
+ camera,
+ success: (res) => resolve(formatVideo(res)),
+ fail: reject
+ })
+ break
+ // #ifdef MP-WEIXIN || H5
+ // ������������������������������chooseMessageFile������
+ case 'file':
+ // #ifdef MP-WEIXIN
+ wx.chooseMessageFile({
+ count: multiple ? maxCount : 1,
+ type: accept,
+ success: (res) => resolve(formatFile(res)),
+ fail: reject
+ })
+ // #endif
+ // #ifdef H5
+ // ������hx2.9.9���������������uni.chooseFile
+ uni.chooseFile({
+ count: multiple ? maxCount : 1,
+ type: accept,
+ success: (res) => resolve(formatFile(res)),
+ fail: reject
+ })
+ // #endif
+ break
+ // #endif
+ default:
+ // ������������������������accept���������������������������������������������������
+ // #ifdef MP-WEIXIN
+ wx.chooseMessageFile({
+ count: multiple ? maxCount : 1,
+ type: 'all',
+ success: (res) => resolve(formatFile(res)),
+ fail: reject
+ })
+ // #endif
+ // #ifdef H5
+ // ������hx2.9.9���������������uni.chooseFile
+ uni.chooseFile({
+ count: multiple ? maxCount : 1,
+ type: 'all',
+ success: (res) => resolve(formatFile(res)),
+ fail: reject
+ })
+ // #endif
+ }
+ })
+}
diff --git a/uni_modules/uview-ui/components/uview-ui/uview-ui.vue b/uni_modules/uview-ui/components/uview-ui/uview-ui.vue
new file mode 100644
index 0000000..bcd3662
--- /dev/null
+++ b/uni_modules/uview-ui/components/uview-ui/uview-ui.vue
@@ -0,0 +1,15 @@
+<template>
+</template>
+
+<template>
+ <view></view>
+</template>
+
+<script>
+ export default {
+
+ }
+</script>
+
+<style>
+</style>
diff --git a/uni_modules/uview-ui/index.js b/uni_modules/uview-ui/index.js
new file mode 100644
index 0000000..651c090
--- /dev/null
+++ b/uni_modules/uview-ui/index.js
@@ -0,0 +1,79 @@
+// ���������������������������������������vue.config.js������transpileDependencies���������������https://www.uviewui.com/components/npmSetting.html#_5-cli������������������
+const pleaseSetTranspileDependencies = {}, babelTest = pleaseSetTranspileDependencies?.test
+
+
+
+// ������������mixin
+import mixin from './libs/mixin/mixin.js'
+// ������������������mixin
+import mpMixin from './libs/mixin/mpMixin.js'
+// ������������������http������������������������
+import Request from './libs/luch-request'
+
+// ������������
+import route from './libs/util/route.js'
+// ������������������,colorGradient-������������,hexToRgb-���������������������rgb������,rgbToHex-rgb���������������
+import colorGradient from './libs/function/colorGradient.js'
+
+// ������������
+import test from './libs/function/test.js'
+// ������������
+import debounce from './libs/function/debounce.js'
+// ������������
+import throttle from './libs/function/throttle.js'
+// ���������������������������
+import index from './libs/function/index.js'
+
+// ������������
+import config from './libs/config/config.js'
+// props������������
+import props from './libs/config/props.js'
+// ������������fixed������������z-index������������
+import zIndex from './libs/config/zIndex.js'
+// ������������������������������������������
+import color from './libs/config/color.js'
+// ������
+import platform from './libs/function/platform'
+
+const $u = {
+ route,
+ date: index.timeFormat, // ������date
+ colorGradient: colorGradient.colorGradient,
+ hexToRgb: colorGradient.hexToRgb,
+ rgbToHex: colorGradient.rgbToHex,
+ colorToRgba: colorGradient.colorToRgba,
+ test,
+ type: ['primary', 'success', 'error', 'warning', 'info'],
+ http: new Request(),
+ config, // uView������������������������������������
+ zIndex,
+ debounce,
+ throttle,
+ mixin,
+ mpMixin,
+ props,
+ ...index,
+ color,
+ platform
+}
+
+// $u���������uni���������
+uni.$u = $u
+
+const install = (Vue) => {
+ // ���������������������������������������date���timeFormat
+ Vue.filter('timeFormat', (timestamp, format) => uni.$u.timeFormat(timestamp, format))
+ Vue.filter('date', (timestamp, format) => uni.$u.timeFormat(timestamp, format))
+ // ���������������������������������������������������
+ Vue.filter('timeFrom', (timestamp, format) => uni.$u.timeFrom(timestamp, format))
+ // ���������������uni���Vue.prototype���
+ // #ifndef APP-NVUE
+ // ������vue������������Vue.prototype���������������������nvue���������Vue.prototype���Vue.mixin������������
+ Vue.prototype.$u = $u
+ Vue.mixin(mixin)
+ // #endif
+}
+
+export default {
+ install
+}
diff --git a/uni_modules/uview-ui/index.scss b/uni_modules/uview-ui/index.scss
new file mode 100644
index 0000000..8fcfa83
--- /dev/null
+++ b/uni_modules/uview-ui/index.scss
@@ -0,0 +1,23 @@
+// ���������������������
+@import "./libs/css/common.scss";
+@import "./libs/css/color.scss";
+
+// ���nvue���������
+/* #ifndef APP-NVUE */
+@import "./libs/css/vue.scss";
+/* #endif */
+
+// nvue���������������
+/* #ifdef APP-NVUE */
+@import "./libs/css/nvue.scss";
+/* #endif */
+
+// ������������������������
+/* #ifdef MP */
+@import "./libs/css/mp.scss";
+/* #endif */
+
+// H5���������������
+/* #ifdef H5 */
+@import "./libs/css/h5.scss";
+/* #endif */
\ No newline at end of file
diff --git a/uni_modules/uview-ui/libs/config/color.js b/uni_modules/uview-ui/libs/config/color.js
new file mode 100644
index 0000000..56b4187
--- /dev/null
+++ b/uni_modules/uview-ui/libs/config/color.js
@@ -0,0 +1,17 @@
+// ���������������������������������������������������������������������������������css������
+// ������������������������������������������������������������������������(2020-06-20)
+const color = {
+ primary: '#3c9cff',
+ info: '#909399',
+ default: '#909399',
+ warning: '#f9ae3d',
+ error: '#f56c6c',
+ success: '#5ac725',
+ mainColor: '#303133',
+ contentColor: '#606266',
+ tipsColor: '#909399',
+ lightColor: '#c0c4cc',
+ borderColor: '#e4e7ed'
+}
+
+export default color
diff --git a/uni_modules/uview-ui/libs/config/config.js b/uni_modules/uview-ui/libs/config/config.js
new file mode 100644
index 0000000..a3a784e
--- /dev/null
+++ b/uni_modules/uview-ui/libs/config/config.js
@@ -0,0 +1,34 @@
+// ������������������2023-03-27
+const version = '2.0.36'
+
+// ������������������������������������������������
+if (process.env.NODE_ENV === 'development') {
+ console.log(`\n %c uView V${version} %c https://uviewui.com/ \n\n`, 'color: #ffffff; background: #3c9cff; padding:5px 0; border-radius: 5px;');
+}
+
+export default {
+ v: version,
+ version,
+ // ������������
+ type: [
+ 'primary',
+ 'success',
+ 'info',
+ 'error',
+ 'warning'
+ ],
+ // ���������������������������������scss���:export���������js���������������������nvue���������
+ color: {
+ 'u-primary': '#2979ff',
+ 'u-warning': '#ff9900',
+ 'u-success': '#19be6b',
+ 'u-error': '#fa3534',
+ 'u-info': '#909399',
+ 'u-main-color': '#303133',
+ 'u-content-color': '#606266',
+ 'u-tips-color': '#909399',
+ 'u-light-color': '#c0c4cc'
+ },
+ // ������������������������������������rpx���������������������������������������������������������������������rpx
+ unit: 'px'
+}
diff --git a/uni_modules/uview-ui/libs/config/props.js b/uni_modules/uview-ui/libs/config/props.js
new file mode 100644
index 0000000..6930d48
--- /dev/null
+++ b/uni_modules/uview-ui/libs/config/props.js
@@ -0,0 +1,190 @@
+/**
+ * ������������������������������������������������props������
+ * ���������������������������������������props���������
+ * ������������������������������������������������������
+ */
+import config from './config'
+
+import actionSheet from './props/actionSheet.js'
+import album from './props/album.js'
+import alert from './props/alert.js'
+import avatar from './props/avatar'
+import avatarGroup from './props/avatarGroup'
+import backtop from './props/backtop'
+import badge from './props/badge'
+import button from './props/button'
+import calendar from './props/calendar'
+import carKeyboard from './props/carKeyboard'
+import cell from './props/cell'
+import cellGroup from './props/cellGroup'
+import checkbox from './props/checkbox'
+import checkboxGroup from './props/checkboxGroup'
+import circleProgress from './props/circleProgress'
+import code from './props/code'
+import codeInput from './props/codeInput'
+import col from './props/col'
+import collapse from './props/collapse'
+import collapseItem from './props/collapseItem'
+import columnNotice from './props/columnNotice'
+import countDown from './props/countDown'
+import countTo from './props/countTo'
+import datetimePicker from './props/datetimePicker'
+import divider from './props/divider'
+import empty from './props/empty'
+import form from './props/form'
+import formItem from './props/formItem'
+import gap from './props/gap'
+import grid from './props/grid'
+import gridItem from './props/gridItem'
+import icon from './props/icon'
+import image from './props/image'
+import indexAnchor from './props/indexAnchor'
+import indexList from './props/indexList'
+import input from './props/input'
+import keyboard from './props/keyboard'
+import line from './props/line'
+import lineProgress from './props/lineProgress'
+import link from './props/link'
+import list from './props/list'
+import listItem from './props/listItem'
+import loadingIcon from './props/loadingIcon'
+import loadingPage from './props/loadingPage'
+import loadmore from './props/loadmore'
+import modal from './props/modal'
+import navbar from './props/navbar'
+import noNetwork from './props/noNetwork'
+import noticeBar from './props/noticeBar'
+import notify from './props/notify'
+import numberBox from './props/numberBox'
+import numberKeyboard from './props/numberKeyboard'
+import overlay from './props/overlay'
+import parse from './props/parse'
+import picker from './props/picker'
+import popup from './props/popup'
+import radio from './props/radio'
+import radioGroup from './props/radioGroup'
+import rate from './props/rate'
+import readMore from './props/readMore'
+import row from './props/row'
+import rowNotice from './props/rowNotice'
+import scrollList from './props/scrollList'
+import search from './props/search'
+import section from './props/section'
+import skeleton from './props/skeleton'
+import slider from './props/slider'
+import statusBar from './props/statusBar'
+import steps from './props/steps'
+import stepsItem from './props/stepsItem'
+import sticky from './props/sticky'
+import subsection from './props/subsection'
+import swipeAction from './props/swipeAction'
+import swipeActionItem from './props/swipeActionItem'
+import swiper from './props/swiper'
+import swipterIndicator from './props/swipterIndicator'
+import _switch from './props/switch'
+import tabbar from './props/tabbar'
+import tabbarItem from './props/tabbarItem'
+import tabs from './props/tabs'
+import tag from './props/tag'
+import text from './props/text'
+import textarea from './props/textarea'
+import toast from './props/toast'
+import toolbar from './props/toolbar'
+import tooltip from './props/tooltip'
+import transition from './props/transition'
+import upload from './props/upload'
+
+const {
+ color
+} = config
+
+export default {
+ ...actionSheet,
+ ...album,
+ ...alert,
+ ...avatar,
+ ...avatarGroup,
+ ...backtop,
+ ...badge,
+ ...button,
+ ...calendar,
+ ...carKeyboard,
+ ...cell,
+ ...cellGroup,
+ ...checkbox,
+ ...checkboxGroup,
+ ...circleProgress,
+ ...code,
+ ...codeInput,
+ ...col,
+ ...collapse,
+ ...collapseItem,
+ ...columnNotice,
+ ...countDown,
+ ...countTo,
+ ...datetimePicker,
+ ...divider,
+ ...empty,
+ ...form,
+ ...formItem,
+ ...gap,
+ ...grid,
+ ...gridItem,
+ ...icon,
+ ...image,
+ ...indexAnchor,
+ ...indexList,
+ ...input,
+ ...keyboard,
+ ...line,
+ ...lineProgress,
+ ...link,
+ ...list,
+ ...listItem,
+ ...loadingIcon,
+ ...loadingPage,
+ ...loadmore,
+ ...modal,
+ ...navbar,
+ ...noNetwork,
+ ...noticeBar,
+ ...notify,
+ ...numberBox,
+ ...numberKeyboard,
+ ...overlay,
+ ...parse,
+ ...picker,
+ ...popup,
+ ...radio,
+ ...radioGroup,
+ ...rate,
+ ...readMore,
+ ...row,
+ ...rowNotice,
+ ...scrollList,
+ ...search,
+ ...section,
+ ...skeleton,
+ ...slider,
+ ...statusBar,
+ ...steps,
+ ...stepsItem,
+ ...sticky,
+ ...subsection,
+ ...swipeAction,
+ ...swipeActionItem,
+ ...swiper,
+ ...swipterIndicator,
+ ..._switch,
+ ...tabbar,
+ ...tabbarItem,
+ ...tabs,
+ ...tag,
+ ...text,
+ ...textarea,
+ ...toast,
+ ...toolbar,
+ ...tooltip,
+ ...transition,
+ ...upload
+}
diff --git a/uni_modules/uview-ui/libs/config/props/actionSheet.js b/uni_modules/uview-ui/libs/config/props/actionSheet.js
new file mode 100644
index 0000000..d8061a7
--- /dev/null
+++ b/uni_modules/uview-ui/libs/config/props/actionSheet.js
@@ -0,0 +1,25 @@
+/*
+ * @Author : LQ
+ * @Description :
+ * @version : 1.0
+ * @Date : 2021-08-20 16:44:21
+ * @LastAuthor : LQ
+ * @lastTime : 2021-08-20 16:44:35
+ * @FilePath : /u-view2.0/uview-ui/libs/config/props/actionSheet.js
+ */
+export default {
+ // action-sheet������
+ actionSheet: {
+ show: false,
+ title: '',
+ description: '',
+ actions: () => [],
+ index: '',
+ cancelText: '',
+ closeOnClickAction: true,
+ safeAreaInsetBottom: true,
+ openType: '',
+ closeOnClickOverlay: true,
+ round: 0
+ }
+}
diff --git a/uni_modules/uview-ui/libs/config/props/album.js b/uni_modules/uview-ui/libs/config/props/album.js
new file mode 100644
index 0000000..8877326
--- /dev/null
+++ b/uni_modules/uview-ui/libs/config/props/album.js
@@ -0,0 +1,25 @@
+/*
+ * @Author : LQ
+ * @Description :
+ * @version : 1.0
+ * @Date : 2021-08-20 16:44:21
+ * @LastAuthor : LQ
+ * @lastTime : 2021-08-20 16:47:24
+ * @FilePath : /u-view2.0/uview-ui/libs/config/props/album.js
+ */
+export default {
+ // album ������
+ album: {
+ urls: () => [],
+ keyName: '',
+ singleSize: 180,
+ multipleSize: 70,
+ space: 6,
+ singleMode: 'scaleToFill',
+ multipleMode: 'aspectFill',
+ maxCount: 9,
+ previewFullImage: true,
+ rowCount: 3,
+ showMore: true
+ }
+}
diff --git a/uni_modules/uview-ui/libs/config/props/alert.js b/uni_modules/uview-ui/libs/config/props/alert.js
new file mode 100644
index 0000000..8f8182c
--- /dev/null
+++ b/uni_modules/uview-ui/libs/config/props/alert.js
@@ -0,0 +1,22 @@
+/*
+ * @Author : LQ
+ * @Description :
+ * @version : 1.0
+ * @Date : 2021-08-20 16:44:21
+ * @LastAuthor : LQ
+ * @lastTime : 2021-08-20 16:48:53
+ * @FilePath : /u-view2.0/uview-ui/libs/config/props/alert.js
+ */
+export default {
+ // alert������������
+ alert: {
+ title: '',
+ type: 'warning',
+ description: '',
+ closable: false,
+ showIcon: false,
+ effect: 'light',
+ center: false,
+ fontSize: 14
+ }
+}
diff --git a/uni_modules/uview-ui/libs/config/props/avatar.js b/uni_modules/uview-ui/libs/config/props/avatar.js
new file mode 100644
index 0000000..c097d4e
--- /dev/null
+++ b/uni_modules/uview-ui/libs/config/props/avatar.js
@@ -0,0 +1,28 @@
+/*
+ * @Author : LQ
+ * @Description :
+ * @version : 1.0
+ * @Date : 2021-08-20 16:44:21
+ * @LastAuthor : LQ
+ * @lastTime : 2021-08-20 16:49:22
+ * @FilePath : /u-view2.0/uview-ui/libs/config/props/avatar.js
+ */
+export default {
+ // avatar ������
+ avatar: {
+ src: '',
+ shape: 'circle',
+ size: 40,
+ mode: 'scaleToFill',
+ text: '',
+ bgColor: '#c0c4cc',
+ color: '#ffffff',
+ fontSize: 18,
+ icon: '',
+ mpAvatar: false,
+ randomBgColor: false,
+ defaultUrl: '',
+ colorIndex: '',
+ name: ''
+ }
+}
diff --git a/uni_modules/uview-ui/libs/config/props/avatarGroup.js b/uni_modules/uview-ui/libs/config/props/avatarGroup.js
new file mode 100644
index 0000000..f4a66c3
--- /dev/null
+++ b/uni_modules/uview-ui/libs/config/props/avatarGroup.js
@@ -0,0 +1,23 @@
+/*
+ * @Author : LQ
+ * @Description :
+ * @version : 1.0
+ * @Date : 2021-08-20 16:44:21
+ * @LastAuthor : LQ
+ * @lastTime : 2021-08-20 16:49:55
+ * @FilePath : /u-view2.0/uview-ui/libs/config/props/avatarGroup.js
+ */
+export default {
+ // avatarGroup ������
+ avatarGroup: {
+ urls: () => [],
+ maxCount: 5,
+ shape: 'circle',
+ mode: 'scaleToFill',
+ showMore: true,
+ size: 40,
+ keyName: '',
+ gap: 0.5,
+ extraValue: 0
+ }
+}
diff --git a/uni_modules/uview-ui/libs/config/props/backtop.js b/uni_modules/uview-ui/libs/config/props/backtop.js
new file mode 100644
index 0000000..80f17d0
--- /dev/null
+++ b/uni_modules/uview-ui/libs/config/props/backtop.js
@@ -0,0 +1,27 @@
+/*
+ * @Author : LQ
+ * @Description :
+ * @version : 1.0
+ * @Date : 2021-08-20 16:44:21
+ * @LastAuthor : LQ
+ * @lastTime : 2021-08-20 16:50:18
+ * @FilePath : /u-view2.0/uview-ui/libs/config/props/backtop.js
+ */
+export default {
+ // backtop������
+ backtop: {
+ mode: 'circle',
+ icon: 'arrow-upward',
+ text: '',
+ duration: 100,
+ scrollTop: 0,
+ top: 400,
+ bottom: 100,
+ right: 20,
+ zIndex: 9,
+ iconStyle: () => ({
+ color: '#909399',
+ fontSize: '19px'
+ })
+ }
+}
diff --git a/uni_modules/uview-ui/libs/config/props/badge.js b/uni_modules/uview-ui/libs/config/props/badge.js
new file mode 100644
index 0000000..44ee7cc
--- /dev/null
+++ b/uni_modules/uview-ui/libs/config/props/badge.js
@@ -0,0 +1,27 @@
+/*
+ * @Author : LQ
+ * @Description :
+ * @version : 1.0
+ * @Date : 2021-08-20 16:44:21
+ * @LastAuthor : LQ
+ * @lastTime : 2021-08-23 19:51:50
+ * @FilePath : /u-view2.0/uview-ui/libs/config/props/badge.js
+ */
+export default {
+ // ���������������
+ badge: {
+ isDot: false,
+ value: '',
+ show: true,
+ max: 999,
+ type: 'error',
+ showZero: false,
+ bgColor: null,
+ color: null,
+ shape: 'circle',
+ numberType: 'overflow',
+ offset: () => [],
+ inverted: false,
+ absolute: false
+ }
+}
diff --git a/uni_modules/uview-ui/libs/config/props/button.js b/uni_modules/uview-ui/libs/config/props/button.js
new file mode 100644
index 0000000..acd65fc
--- /dev/null
+++ b/uni_modules/uview-ui/libs/config/props/button.js
@@ -0,0 +1,42 @@
+/*
+ * @Author : LQ
+ * @Description :
+ * @version : 1.0
+ * @Date : 2021-08-20 16:44:21
+ * @LastAuthor : LQ
+ * @lastTime : 2021-08-20 16:51:27
+ * @FilePath : /u-view2.0/uview-ui/libs/config/props/button.js
+ */
+export default {
+ // button������
+ button: {
+ hairline: false,
+ type: 'info',
+ size: 'normal',
+ shape: 'square',
+ plain: false,
+ disabled: false,
+ loading: false,
+ loadingText: '',
+ loadingMode: 'spinner',
+ loadingSize: 15,
+ openType: '',
+ formType: '',
+ appParameter: '',
+ hoverStopPropagation: true,
+ lang: 'en',
+ sessionFrom: '',
+ sendMessageTitle: '',
+ sendMessagePath: '',
+ sendMessageImg: '',
+ showMessageCard: false,
+ dataName: '',
+ throttleTime: 0,
+ hoverStartTime: 0,
+ hoverStayTime: 200,
+ text: '',
+ icon: '',
+ iconColor: '',
+ color: ''
+ }
+}
diff --git a/uni_modules/uview-ui/libs/config/props/calendar.js b/uni_modules/uview-ui/libs/config/props/calendar.js
new file mode 100644
index 0000000..bfd2bd6
--- /dev/null
+++ b/uni_modules/uview-ui/libs/config/props/calendar.js
@@ -0,0 +1,42 @@
+/*
+ * @Author : LQ
+ * @Description :
+ * @version : 1.0
+ * @Date : 2021-08-20 16:44:21
+ * @LastAuthor : LQ
+ * @lastTime : 2021-08-20 16:52:43
+ * @FilePath : /u-view2.0/uview-ui/libs/config/props/calendar.js
+ */
+export default {
+ // calendar ������
+ calendar: {
+ title: '������������',
+ showTitle: true,
+ showSubtitle: true,
+ mode: 'single',
+ startText: '������',
+ endText: '������',
+ customList: () => [],
+ color: '#3c9cff',
+ minDate: 0,
+ maxDate: 0,
+ defaultDate: null,
+ maxCount: Number.MAX_SAFE_INTEGER, // Infinity
+ rowHeight: 56,
+ formatter: null,
+ showLunar: false,
+ showMark: true,
+ confirmText: '������',
+ confirmDisabledText: '������',
+ show: false,
+ closeOnClickOverlay: false,
+ readonly: false,
+ showConfirm: true,
+ maxRange: Number.MAX_SAFE_INTEGER, // Infinity
+ rangePrompt: '',
+ showRangePrompt: true,
+ allowSameDay: false,
+ round: 0,
+ monthNum: 3
+ }
+}
diff --git a/uni_modules/uview-ui/libs/config/props/carKeyboard.js b/uni_modules/uview-ui/libs/config/props/carKeyboard.js
new file mode 100644
index 0000000..af1baa0
--- /dev/null
+++ b/uni_modules/uview-ui/libs/config/props/carKeyboard.js
@@ -0,0 +1,15 @@
+/*
+ * @Author : LQ
+ * @Description :
+ * @version : 1.0
+ * @Date : 2021-08-20 16:44:21
+ * @LastAuthor : LQ
+ * @lastTime : 2021-08-20 16:53:20
+ * @FilePath : /u-view2.0/uview-ui/libs/config/props/carKeyboard.js
+ */
+export default {
+ // ���������������
+ carKeyboard: {
+ random: false
+ }
+}
diff --git a/uni_modules/uview-ui/libs/config/props/cell.js b/uni_modules/uview-ui/libs/config/props/cell.js
new file mode 100644
index 0000000..425ea3f
--- /dev/null
+++ b/uni_modules/uview-ui/libs/config/props/cell.js
@@ -0,0 +1,35 @@
+/*
+ * @Author : LQ
+ * @Description :
+ * @version : 1.0
+ * @Date : 2021-08-20 16:44:21
+ * @LastAuthor : LQ
+ * @lastTime : 2021-08-23 20:53:09
+ * @FilePath : /u-view2.0/uview-ui/libs/config/props/cell.js
+ */
+export default {
+ // cell���������props
+ cell: {
+ customClass: '',
+ title: '',
+ label: '',
+ value: '',
+ icon: '',
+ disabled: false,
+ border: true,
+ center: false,
+ url: '',
+ linkType: 'navigateTo',
+ clickable: false,
+ isLink: false,
+ required: false,
+ arrowDirection: '',
+ iconStyle: {},
+ rightIconStyle: {},
+ rightIcon: 'arrow-right',
+ titleStyle: {},
+ size: '',
+ stop: true,
+ name: ''
+ }
+}
diff --git a/uni_modules/uview-ui/libs/config/props/cellGroup.js b/uni_modules/uview-ui/libs/config/props/cellGroup.js
new file mode 100644
index 0000000..d48a9cd
--- /dev/null
+++ b/uni_modules/uview-ui/libs/config/props/cellGroup.js
@@ -0,0 +1,17 @@
+/*
+ * @Author : LQ
+ * @Description :
+ * @version : 1.0
+ * @Date : 2021-08-20 16:44:21
+ * @LastAuthor : LQ
+ * @lastTime : 2021-08-20 16:54:16
+ * @FilePath : /u-view2.0/uview-ui/libs/config/props/cellGroup.js
+ */
+export default {
+ // cell-group���������props
+ cellGroup: {
+ title: '',
+ border: true,
+ customStyle: {}
+ }
+}
diff --git a/uni_modules/uview-ui/libs/config/props/checkbox.js b/uni_modules/uview-ui/libs/config/props/checkbox.js
new file mode 100644
index 0000000..2310901
--- /dev/null
+++ b/uni_modules/uview-ui/libs/config/props/checkbox.js
@@ -0,0 +1,27 @@
+/*
+ * @Author : LQ
+ * @Description :
+ * @version : 1.0
+ * @Date : 2021-08-20 16:44:21
+ * @LastAuthor : LQ
+ * @lastTime : 2021-08-23 21:06:59
+ * @FilePath : /u-view2.0/uview-ui/libs/config/props/checkbox.js
+ */
+export default {
+ // checkbox������
+ checkbox: {
+ name: '',
+ shape: '',
+ size: '',
+ checkbox: false,
+ disabled: '',
+ activeColor: '',
+ inactiveColor: '',
+ iconSize: '',
+ iconColor: '',
+ label: '',
+ labelSize: '',
+ labelColor: '',
+ labelDisabled: ''
+ }
+}
diff --git a/uni_modules/uview-ui/libs/config/props/checkboxGroup.js b/uni_modules/uview-ui/libs/config/props/checkboxGroup.js
new file mode 100644
index 0000000..8798fa4
--- /dev/null
+++ b/uni_modules/uview-ui/libs/config/props/checkboxGroup.js
@@ -0,0 +1,29 @@
+/*
+ * @Author : LQ
+ * @Description :
+ * @version : 1.0
+ * @Date : 2021-08-20 16:44:21
+ * @LastAuthor : LQ
+ * @lastTime : 2021-08-20 16:54:47
+ * @FilePath : /u-view2.0/uview-ui/libs/config/props/checkboxGroup.js
+ */
+export default {
+ // checkbox-group������
+ checkboxGroup: {
+ name: '',
+ value: () => [],
+ shape: 'square',
+ disabled: false,
+ activeColor: '#2979ff',
+ inactiveColor: '#c8c9cc',
+ size: 18,
+ placement: 'row',
+ labelSize: 14,
+ labelColor: '#303133',
+ labelDisabled: false,
+ iconColor: '#ffffff',
+ iconSize: 12,
+ iconPlacement: 'left',
+ borderBottom: false
+ }
+}
diff --git a/uni_modules/uview-ui/libs/config/props/circleProgress.js b/uni_modules/uview-ui/libs/config/props/circleProgress.js
new file mode 100644
index 0000000..b3a9b43
--- /dev/null
+++ b/uni_modules/uview-ui/libs/config/props/circleProgress.js
@@ -0,0 +1,15 @@
+/*
+ * @Author : LQ
+ * @Description :
+ * @version : 1.0
+ * @Date : 2021-08-20 16:44:21
+ * @LastAuthor : LQ
+ * @lastTime : 2021-08-20 16:55:02
+ * @FilePath : /u-view2.0/uview-ui/libs/config/props/circleProgress.js
+ */
+export default {
+ // circleProgress ������
+ circleProgress: {
+ percentage: 30
+ }
+}
diff --git a/uni_modules/uview-ui/libs/config/props/code.js b/uni_modules/uview-ui/libs/config/props/code.js
new file mode 100644
index 0000000..693417a
--- /dev/null
+++ b/uni_modules/uview-ui/libs/config/props/code.js
@@ -0,0 +1,21 @@
+/*
+ * @Author : LQ
+ * @Description :
+ * @version : 1.0
+ * @Date : 2021-08-20 16:44:21
+ * @LastAuthor : LQ
+ * @lastTime : 2021-08-20 16:55:27
+ * @FilePath : /u-view2.0/uview-ui/libs/config/props/code.js
+ */
+
+export default {
+ // code ������
+ code: {
+ seconds: 60,
+ startText: '���������������',
+ changeText: 'X���������������',
+ endText: '������������',
+ keepRunning: false,
+ uniqueKey: ''
+ }
+}
diff --git a/uni_modules/uview-ui/libs/config/props/codeInput.js b/uni_modules/uview-ui/libs/config/props/codeInput.js
new file mode 100644
index 0000000..cac9265
--- /dev/null
+++ b/uni_modules/uview-ui/libs/config/props/codeInput.js
@@ -0,0 +1,29 @@
+/*
+ * @Author : LQ
+ * @Description :
+ * @version : 1.0
+ * @Date : 2021-08-20 16:44:21
+ * @LastAuthor : LQ
+ * @lastTime : 2021-08-20 16:55:58
+ * @FilePath : /u-view2.0/uview-ui/libs/config/props/codeInput.js
+ */
+export default {
+ // codeInput ������
+ codeInput: {
+ adjustPosition: true,
+ maxlength: 6,
+ dot: false,
+ mode: 'box',
+ hairline: false,
+ space: 10,
+ value: '',
+ focus: false,
+ bold: false,
+ color: '#606266',
+ fontSize: 18,
+ size: 35,
+ disabledKeyboard: false,
+ borderColor: '#c9cacc',
+ disabledDot: true
+ }
+}
diff --git a/uni_modules/uview-ui/libs/config/props/col.js b/uni_modules/uview-ui/libs/config/props/col.js
new file mode 100644
index 0000000..7621653
--- /dev/null
+++ b/uni_modules/uview-ui/libs/config/props/col.js
@@ -0,0 +1,19 @@
+/*
+ * @Author : LQ
+ * @Description :
+ * @version : 1.0
+ * @Date : 2021-08-20 16:44:21
+ * @LastAuthor : LQ
+ * @lastTime : 2021-08-20 16:56:12
+ * @FilePath : /u-view2.0/uview-ui/libs/config/props/col.js
+ */
+export default {
+ // col ������
+ col: {
+ span: 12,
+ offset: 0,
+ justify: 'start',
+ align: 'stretch',
+ textAlign: 'left'
+ }
+}
diff --git a/uni_modules/uview-ui/libs/config/props/collapse.js b/uni_modules/uview-ui/libs/config/props/collapse.js
new file mode 100644
index 0000000..c2b9fdd
--- /dev/null
+++ b/uni_modules/uview-ui/libs/config/props/collapse.js
@@ -0,0 +1,17 @@
+/*
+ * @Author : LQ
+ * @Description :
+ * @version : 1.0
+ * @Date : 2021-08-20 16:44:21
+ * @LastAuthor : LQ
+ * @lastTime : 2021-08-20 16:56:30
+ * @FilePath : /u-view2.0/uview-ui/libs/config/props/collapse.js
+ */
+export default {
+ // collapse ������
+ collapse: {
+ value: null,
+ accordion: false,
+ border: true
+ }
+}
diff --git a/uni_modules/uview-ui/libs/config/props/collapseItem.js b/uni_modules/uview-ui/libs/config/props/collapseItem.js
new file mode 100644
index 0000000..74ce682
--- /dev/null
+++ b/uni_modules/uview-ui/libs/config/props/collapseItem.js
@@ -0,0 +1,25 @@
+/*
+ * @Author : LQ
+ * @Description :
+ * @version : 1.0
+ * @Date : 2021-08-20 16:44:21
+ * @LastAuthor : LQ
+ * @lastTime : 2021-08-20 16:56:42
+ * @FilePath : /u-view2.0/uview-ui/libs/config/props/collapseItem.js
+ */
+export default {
+ // collapseItem ������
+ collapseItem: {
+ title: '',
+ value: '',
+ label: '',
+ disabled: false,
+ isLink: true,
+ clickable: true,
+ border: true,
+ align: 'left',
+ name: '',
+ icon: '',
+ duration: 300
+ }
+}
diff --git a/uni_modules/uview-ui/libs/config/props/columnNotice.js b/uni_modules/uview-ui/libs/config/props/columnNotice.js
new file mode 100644
index 0000000..147c0aa
--- /dev/null
+++ b/uni_modules/uview-ui/libs/config/props/columnNotice.js
@@ -0,0 +1,24 @@
+/*
+ * @Author : LQ
+ * @Description :
+ * @version : 1.0
+ * @Date : 2021-08-20 16:44:21
+ * @LastAuthor : LQ
+ * @lastTime : 2021-08-20 16:57:16
+ * @FilePath : /u-view2.0/uview-ui/libs/config/props/columnNotice.js
+ */
+export default {
+ // columnNotice ������
+ columnNotice: {
+ text: '',
+ icon: 'volume',
+ mode: '',
+ color: '#f9ae3d',
+ bgColor: '#fdf6ec',
+ fontSize: 14,
+ speed: 80,
+ step: false,
+ duration: 1500,
+ disableTouch: true
+ }
+}
diff --git a/uni_modules/uview-ui/libs/config/props/countDown.js b/uni_modules/uview-ui/libs/config/props/countDown.js
new file mode 100644
index 0000000..81e33b1
--- /dev/null
+++ b/uni_modules/uview-ui/libs/config/props/countDown.js
@@ -0,0 +1,18 @@
+/*
+ * @Author : LQ
+ * @Description :
+ * @version : 1.0
+ * @Date : 2021-08-20 16:44:21
+ * @LastAuthor : LQ
+ * @lastTime : 2021-08-20 17:11:29
+ * @FilePath : /u-view2.0/uview-ui/libs/config/props/countDown.js
+ */
+export default {
+ // u-count-down ���������������
+ countDown: {
+ time: 0,
+ format: 'HH:mm:ss',
+ autoStart: true,
+ millisecond: false
+ }
+}
diff --git a/uni_modules/uview-ui/libs/config/props/countTo.js b/uni_modules/uview-ui/libs/config/props/countTo.js
new file mode 100644
index 0000000..a536cde
--- /dev/null
+++ b/uni_modules/uview-ui/libs/config/props/countTo.js
@@ -0,0 +1,25 @@
+/*
+ * @Author : LQ
+ * @Description :
+ * @version : 1.0
+ * @Date : 2021-08-20 16:44:21
+ * @LastAuthor : LQ
+ * @lastTime : 2021-08-20 16:57:32
+ * @FilePath : /u-view2.0/uview-ui/libs/config/props/countTo.js
+ */
+export default {
+ // countTo ������
+ countTo: {
+ startVal: 0,
+ endVal: 0,
+ duration: 2000,
+ autoplay: true,
+ decimals: 0,
+ useEasing: true,
+ decimal: '.',
+ color: '#606266',
+ fontSize: 22,
+ bold: false,
+ separator: ''
+ }
+}
diff --git a/uni_modules/uview-ui/libs/config/props/datetimePicker.js b/uni_modules/uview-ui/libs/config/props/datetimePicker.js
new file mode 100644
index 0000000..4f90966
--- /dev/null
+++ b/uni_modules/uview-ui/libs/config/props/datetimePicker.js
@@ -0,0 +1,36 @@
+/*
+ * @Author : LQ
+ * @Description :
+ * @version : 1.0
+ * @Date : 2021-08-20 16:44:21
+ * @LastAuthor : LQ
+ * @lastTime : 2021-08-20 16:57:48
+ * @FilePath : /u-view2.0/uview-ui/libs/config/props/datetimePicker.js
+ */
+export default {
+ // datetimePicker ������
+ datetimePicker: {
+ show: false,
+ showToolbar: true,
+ value: '',
+ title: '',
+ mode: 'datetime',
+ maxDate: new Date(new Date().getFullYear() + 10, 0, 1).getTime(),
+ minDate: new Date(new Date().getFullYear() - 10, 0, 1).getTime(),
+ minHour: 0,
+ maxHour: 23,
+ minMinute: 0,
+ maxMinute: 59,
+ filter: null,
+ formatter: null,
+ loading: false,
+ itemHeight: 44,
+ cancelText: '������',
+ confirmText: '������',
+ cancelColor: '#909193',
+ confirmColor: '#3c9cff',
+ visibleItemCount: 5,
+ closeOnClickOverlay: false,
+ defaultIndex: () => []
+ }
+}
diff --git a/uni_modules/uview-ui/libs/config/props/divider.js b/uni_modules/uview-ui/libs/config/props/divider.js
new file mode 100644
index 0000000..55a8ce4
--- /dev/null
+++ b/uni_modules/uview-ui/libs/config/props/divider.js
@@ -0,0 +1,23 @@
+/*
+ * @Author : LQ
+ * @Description :
+ * @version : 1.0
+ * @Date : 2021-08-20 16:44:21
+ * @LastAuthor : LQ
+ * @lastTime : 2021-08-20 16:58:03
+ * @FilePath : /u-view2.0/uview-ui/libs/config/props/divider.js
+ */
+export default {
+ // divider������
+ divider: {
+ dashed: false,
+ hairline: true,
+ dot: false,
+ textPosition: 'center',
+ text: '',
+ textSize: 14,
+ textColor: '#909399',
+ lineColor: '#dcdfe6'
+ }
+
+}
diff --git a/uni_modules/uview-ui/libs/config/props/empty.js b/uni_modules/uview-ui/libs/config/props/empty.js
new file mode 100644
index 0000000..fe20445
--- /dev/null
+++ b/uni_modules/uview-ui/libs/config/props/empty.js
@@ -0,0 +1,26 @@
+/*
+ * @Author : LQ
+ * @Description :
+ * @version : 1.0
+ * @Date : 2021-08-20 16:44:21
+ * @LastAuthor : LQ
+ * @lastTime : 2021-08-20 17:03:27
+ * @FilePath : /u-view2.0/uview-ui/libs/config/props/empty.js
+ */
+export default {
+ // empty������
+ empty: {
+ icon: '',
+ text: '',
+ textColor: '#c0c4cc',
+ textSize: 14,
+ iconColor: '#c0c4cc',
+ iconSize: 90,
+ mode: 'data',
+ width: 160,
+ height: 160,
+ show: true,
+ marginTop: 0
+ }
+
+}
diff --git a/uni_modules/uview-ui/libs/config/props/form.js b/uni_modules/uview-ui/libs/config/props/form.js
new file mode 100644
index 0000000..41b122e
--- /dev/null
+++ b/uni_modules/uview-ui/libs/config/props/form.js
@@ -0,0 +1,22 @@
+/*
+ * @Author : LQ
+ * @Description :
+ * @version : 1.0
+ * @Date : 2021-08-20 16:44:21
+ * @LastAuthor : LQ
+ * @lastTime : 2021-08-20 17:03:49
+ * @FilePath : /u-view2.0/uview-ui/libs/config/props/form.js
+ */
+export default {
+ // form ������
+ form: {
+ model: () => ({}),
+ rules: () => ({}),
+ errorType: 'message',
+ borderBottom: true,
+ labelPosition: 'left',
+ labelWidth: 45,
+ labelAlign: 'left',
+ labelStyle: () => ({})
+ }
+}
diff --git a/uni_modules/uview-ui/libs/config/props/formItem.js b/uni_modules/uview-ui/libs/config/props/formItem.js
new file mode 100644
index 0000000..4b7c90a
--- /dev/null
+++ b/uni_modules/uview-ui/libs/config/props/formItem.js
@@ -0,0 +1,23 @@
+/*
+ * @Author : LQ
+ * @Description :
+ * @version : 1.0
+ * @Date : 2021-08-20 16:44:21
+ * @LastAuthor : LQ
+ * @lastTime : 2021-08-20 17:04:32
+ * @FilePath : /u-view2.0/uview-ui/libs/config/props/formItem.js
+ */
+export default {
+ // formItem ������
+ formItem: {
+ label: '',
+ prop: '',
+ borderBottom: '',
+ labelPosition: '',
+ labelWidth: '',
+ rightIcon: '',
+ leftIcon: '',
+ required: false,
+ leftIconStyle: '',
+ }
+}
diff --git a/uni_modules/uview-ui/libs/config/props/gap.js b/uni_modules/uview-ui/libs/config/props/gap.js
new file mode 100644
index 0000000..60a21af
--- /dev/null
+++ b/uni_modules/uview-ui/libs/config/props/gap.js
@@ -0,0 +1,19 @@
+/*
+ * @Author : LQ
+ * @Description :
+ * @version : 1.0
+ * @Date : 2021-08-20 16:44:21
+ * @LastAuthor : LQ
+ * @lastTime : 2021-08-20 17:05:25
+ * @FilePath : /u-view2.0/uview-ui/libs/config/props/gap.js
+ */
+export default {
+ // gap������
+ gap: {
+ bgColor: 'transparent',
+ height: 20,
+ marginTop: 0,
+ marginBottom: 0,
+ customStyle: {}
+ }
+}
diff --git a/uni_modules/uview-ui/libs/config/props/grid.js b/uni_modules/uview-ui/libs/config/props/grid.js
new file mode 100644
index 0000000..60abeb7
--- /dev/null
+++ b/uni_modules/uview-ui/libs/config/props/grid.js
@@ -0,0 +1,17 @@
+/*
+ * @Author : LQ
+ * @Description :
+ * @version : 1.0
+ * @Date : 2021-08-20 16:44:21
+ * @LastAuthor : LQ
+ * @lastTime : 2021-08-20 17:05:57
+ * @FilePath : /u-view2.0/uview-ui/libs/config/props/grid.js
+ */
+export default {
+ // grid������
+ grid: {
+ col: 3,
+ border: false,
+ align: 'left'
+ }
+}
diff --git a/uni_modules/uview-ui/libs/config/props/gridItem.js b/uni_modules/uview-ui/libs/config/props/gridItem.js
new file mode 100644
index 0000000..1b747f4
--- /dev/null
+++ b/uni_modules/uview-ui/libs/config/props/gridItem.js
@@ -0,0 +1,16 @@
+/*
+ * @Author : LQ
+ * @Description :
+ * @version : 1.0
+ * @Date : 2021-08-20 16:44:21
+ * @LastAuthor : LQ
+ * @lastTime : 2021-08-20 17:06:13
+ * @FilePath : /u-view2.0/uview-ui/libs/config/props/gridItem.js
+ */
+export default {
+ // grid-item������
+ gridItem: {
+ name: null,
+ bgColor: 'transparent'
+ }
+}
diff --git a/uni_modules/uview-ui/libs/config/props/icon.js b/uni_modules/uview-ui/libs/config/props/icon.js
new file mode 100644
index 0000000..1d81d2d
--- /dev/null
+++ b/uni_modules/uview-ui/libs/config/props/icon.js
@@ -0,0 +1,36 @@
+/*
+ * @Author : LQ
+ * @Description :
+ * @version : 1.0
+ * @Date : 2021-08-20 16:44:21
+ * @LastAuthor : LQ
+ * @lastTime : 2021-08-20 18:00:14
+ * @FilePath : /u-view2.0/uview-ui/libs/config/props/icon.js
+ */
+import config from '../config'
+
+const {
+ color
+} = config
+export default {
+ // icon������
+ icon: {
+ name: '',
+ color: color['u-content-color'],
+ size: '16px',
+ bold: false,
+ index: '',
+ hoverClass: '',
+ customPrefix: 'uicon',
+ label: '',
+ labelPos: 'right',
+ labelSize: '15px',
+ labelColor: color['u-content-color'],
+ space: '3px',
+ imgMode: '',
+ width: '',
+ height: '',
+ top: 0,
+ stop: false
+ }
+}
diff --git a/uni_modules/uview-ui/libs/config/props/image.js b/uni_modules/uview-ui/libs/config/props/image.js
new file mode 100644
index 0000000..2552db6
--- /dev/null
+++ b/uni_modules/uview-ui/libs/config/props/image.js
@@ -0,0 +1,30 @@
+/*
+ * @Author : LQ
+ * @Description :
+ * @version : 1.0
+ * @Date : 2021-08-20 16:44:21
+ * @LastAuthor : LQ
+ * @lastTime : 2021-08-20 17:01:51
+ * @FilePath : /u-view2.0/uview-ui/libs/config/props/image.js
+ */
+export default {
+ // image������
+ image: {
+ src: '',
+ mode: 'aspectFill',
+ width: '300',
+ height: '225',
+ shape: 'square',
+ radius: 0,
+ lazyLoad: true,
+ showMenuByLongpress: true,
+ loadingIcon: 'photo',
+ errorIcon: 'error-circle',
+ showLoading: true,
+ showError: true,
+ fade: true,
+ webp: false,
+ duration: 500,
+ bgColor: '#f3f4f6'
+ }
+}
diff --git a/uni_modules/uview-ui/libs/config/props/indexAnchor.js b/uni_modules/uview-ui/libs/config/props/indexAnchor.js
new file mode 100644
index 0000000..bb20d46
--- /dev/null
+++ b/uni_modules/uview-ui/libs/config/props/indexAnchor.js
@@ -0,0 +1,19 @@
+/*
+ * @Author : LQ
+ * @Description :
+ * @version : 1.0
+ * @Date : 2021-08-20 16:44:21
+ * @LastAuthor : LQ
+ * @lastTime : 2021-08-20 17:13:15
+ * @FilePath : /u-view2.0/uview-ui/libs/config/props/indexAnchor.js
+ */
+export default {
+ // indexAnchor ������
+ indexAnchor: {
+ text: '',
+ color: '#606266',
+ size: 14,
+ bgColor: '#dedede',
+ height: 32
+ }
+}
diff --git a/uni_modules/uview-ui/libs/config/props/indexList.js b/uni_modules/uview-ui/libs/config/props/indexList.js
new file mode 100644
index 0000000..dc6ce94
--- /dev/null
+++ b/uni_modules/uview-ui/libs/config/props/indexList.js
@@ -0,0 +1,19 @@
+/*
+ * @Author : LQ
+ * @Description :
+ * @version : 1.0
+ * @Date : 2021-08-20 16:44:21
+ * @LastAuthor : LQ
+ * @lastTime : 2021-08-20 17:13:35
+ * @FilePath : /u-view2.0/uview-ui/libs/config/props/indexList.js
+ */
+export default {
+ // indexList ������
+ indexList: {
+ inactiveColor: '#606266',
+ activeColor: '#5677fc',
+ indexList: () => [],
+ sticky: true,
+ customNavHeight: 0
+ }
+}
diff --git a/uni_modules/uview-ui/libs/config/props/input.js b/uni_modules/uview-ui/libs/config/props/input.js
new file mode 100644
index 0000000..4f0edc6
--- /dev/null
+++ b/uni_modules/uview-ui/libs/config/props/input.js
@@ -0,0 +1,48 @@
+/*
+ * @Author : LQ
+ * @Description :
+ * @version : 1.0
+ * @Date : 2021-08-20 16:44:21
+ * @LastAuthor : LQ
+ * @lastTime : 2021-08-20 17:13:55
+ * @FilePath : /u-view2.0/uview-ui/libs/config/props/input.js
+ */
+export default {
+ // index ������
+ input: {
+ value: '',
+ type: 'text',
+ fixed: false,
+ disabled: false,
+ disabledColor: '#f5f7fa',
+ clearable: false,
+ password: false,
+ maxlength: -1,
+ placeholder: null,
+ placeholderClass: 'input-placeholder',
+ placeholderStyle: 'color: #c0c4cc',
+ showWordLimit: false,
+ confirmType: 'done',
+ confirmHold: false,
+ holdKeyboard: false,
+ focus: false,
+ autoBlur: false,
+ disableDefaultPadding: false,
+ cursor: -1,
+ cursorSpacing: 30,
+ selectionStart: -1,
+ selectionEnd: -1,
+ adjustPosition: true,
+ inputAlign: 'left',
+ fontSize: '15px',
+ color: '#303133',
+ prefixIcon: '',
+ prefixIconStyle: '',
+ suffixIcon: '',
+ suffixIconStyle: '',
+ border: 'surround',
+ readonly: false,
+ shape: 'square',
+ formatter: null
+ }
+}
diff --git a/uni_modules/uview-ui/libs/config/props/keyboard.js b/uni_modules/uview-ui/libs/config/props/keyboard.js
new file mode 100644
index 0000000..57182bd
--- /dev/null
+++ b/uni_modules/uview-ui/libs/config/props/keyboard.js
@@ -0,0 +1,30 @@
+/*
+ * @Author : LQ
+ * @Description :
+ * @version : 1.0
+ * @Date : 2021-08-20 16:44:21
+ * @LastAuthor : LQ
+ * @lastTime : 2021-08-20 17:07:49
+ * @FilePath : /u-view2.0/uview-ui/libs/config/props/keyboard.js
+ */
+export default {
+ // ������������
+ keyboard: {
+ mode: 'number',
+ dotDisabled: false,
+ tooltip: true,
+ showTips: true,
+ tips: '',
+ showCancel: true,
+ showConfirm: true,
+ random: false,
+ safeAreaInsetBottom: true,
+ closeOnClickOverlay: true,
+ show: false,
+ overlay: true,
+ zIndex: 10075,
+ cancelText: '������',
+ confirmText: '������',
+ autoChange: false
+ }
+}
diff --git a/uni_modules/uview-ui/libs/config/props/line.js b/uni_modules/uview-ui/libs/config/props/line.js
new file mode 100644
index 0000000..2c87af2
--- /dev/null
+++ b/uni_modules/uview-ui/libs/config/props/line.js
@@ -0,0 +1,20 @@
+/*
+ * @Author : LQ
+ * @Description :
+ * @version : 1.0
+ * @Date : 2021-08-20 16:44:21
+ * @LastAuthor : LQ
+ * @lastTime : 2021-08-20 17:04:49
+ * @FilePath : /u-view2.0/uview-ui/libs/config/props/line.js
+ */
+export default {
+ // line������
+ line: {
+ color: '#d6d7d9',
+ length: '100%',
+ direction: 'row',
+ hairline: true,
+ margin: 0,
+ dashed: false
+ }
+}
diff --git a/uni_modules/uview-ui/libs/config/props/lineProgress.js b/uni_modules/uview-ui/libs/config/props/lineProgress.js
new file mode 100644
index 0000000..cdfcb0e
--- /dev/null
+++ b/uni_modules/uview-ui/libs/config/props/lineProgress.js
@@ -0,0 +1,19 @@
+/*
+ * @Author : LQ
+ * @Description :
+ * @version : 1.0
+ * @Date : 2021-08-20 16:44:21
+ * @LastAuthor : LQ
+ * @lastTime : 2021-08-20 17:14:11
+ * @FilePath : /u-view2.0/uview-ui/libs/config/props/lineProgress.js
+ */
+export default {
+ // lineProgress ������
+ lineProgress: {
+ activeColor: '#19be6b',
+ inactiveColor: '#ececec',
+ percentage: 0,
+ showText: true,
+ height: 12
+ }
+}
diff --git a/uni_modules/uview-ui/libs/config/props/link.js b/uni_modules/uview-ui/libs/config/props/link.js
new file mode 100644
index 0000000..6c4c883
--- /dev/null
+++ b/uni_modules/uview-ui/libs/config/props/link.js
@@ -0,0 +1,26 @@
+/*
+ * @Author : LQ
+ * @Description :
+ * @version : 1.0
+ * @Date : 2021-08-20 16:44:21
+ * @LastAuthor : LQ
+ * @lastTime : 2021-08-20 17:45:36
+ * @FilePath : /u-view2.0/uview-ui/libs/config/props/link.js
+ */
+import config from '../config'
+
+const {
+ color
+} = config
+export default {
+ // link���������������props������
+ link: {
+ color: color['u-primary'],
+ fontSize: 15,
+ underLine: false,
+ href: '',
+ mpTips: '���������������������������������������',
+ lineColor: '',
+ text: ''
+ }
+}
diff --git a/uni_modules/uview-ui/libs/config/props/list.js b/uni_modules/uview-ui/libs/config/props/list.js
new file mode 100644
index 0000000..a830c32
--- /dev/null
+++ b/uni_modules/uview-ui/libs/config/props/list.js
@@ -0,0 +1,28 @@
+/*
+ * @Author : LQ
+ * @Description :
+ * @version : 1.0
+ * @Date : 2021-08-20 16:44:21
+ * @LastAuthor : LQ
+ * @lastTime : 2021-08-20 17:14:53
+ * @FilePath : /u-view2.0/uview-ui/libs/config/props/list.js
+ */
+export default {
+ // list ������
+ list: {
+ showScrollbar: false,
+ lowerThreshold: 50,
+ upperThreshold: 0,
+ scrollTop: 0,
+ offsetAccuracy: 10,
+ enableFlex: false,
+ pagingEnabled: false,
+ scrollable: true,
+ scrollIntoView: '',
+ scrollWithAnimation: false,
+ enableBackToTop: false,
+ height: 0,
+ width: 0,
+ preLoadScreen: 1
+ }
+}
diff --git a/uni_modules/uview-ui/libs/config/props/listItem.js b/uni_modules/uview-ui/libs/config/props/listItem.js
new file mode 100644
index 0000000..7fe2166
--- /dev/null
+++ b/uni_modules/uview-ui/libs/config/props/listItem.js
@@ -0,0 +1,15 @@
+/*
+ * @Author : LQ
+ * @Description :
+ * @version : 1.0
+ * @Date : 2021-08-20 16:44:21
+ * @LastAuthor : LQ
+ * @lastTime : 2021-08-20 17:15:40
+ * @FilePath : /u-view2.0/uview-ui/libs/config/props/listItem.js
+ */
+export default {
+ // listItem ������
+ listItem: {
+ anchor: ''
+ }
+}
diff --git a/uni_modules/uview-ui/libs/config/props/loadingIcon.js b/uni_modules/uview-ui/libs/config/props/loadingIcon.js
new file mode 100644
index 0000000..f4739c4
--- /dev/null
+++ b/uni_modules/uview-ui/libs/config/props/loadingIcon.js
@@ -0,0 +1,30 @@
+/*
+ * @Author : LQ
+ * @Description :
+ * @version : 1.0
+ * @Date : 2021-08-20 16:44:21
+ * @LastAuthor : LQ
+ * @lastTime : 2021-08-20 17:45:47
+ * @FilePath : /u-view2.0/uview-ui/libs/config/props/loadingIcon.js
+ */
+import config from '../config'
+
+const {
+ color
+} = config
+export default {
+ // loading-icon���������������������
+ loadingIcon: {
+ show: true,
+ color: color['u-tips-color'],
+ textColor: color['u-tips-color'],
+ vertical: false,
+ mode: 'spinner',
+ size: 24,
+ textSize: 15,
+ text: '',
+ timingFunction: 'ease-in-out',
+ duration: 1200,
+ inactiveColor: ''
+ }
+}
diff --git a/uni_modules/uview-ui/libs/config/props/loadingPage.js b/uni_modules/uview-ui/libs/config/props/loadingPage.js
new file mode 100644
index 0000000..dc53109
--- /dev/null
+++ b/uni_modules/uview-ui/libs/config/props/loadingPage.js
@@ -0,0 +1,23 @@
+/*
+ * @Author : LQ
+ * @Description :
+ * @version : 1.0
+ * @Date : 2021-08-20 16:44:21
+ * @LastAuthor : LQ
+ * @lastTime : 2021-08-20 17:00:23
+ * @FilePath : /u-view2.0/uview-ui/libs/config/props/loadingPage.js
+ */
+export default {
+ // loading-page������
+ loadingPage: {
+ loadingText: '������������',
+ image: '',
+ loadingMode: 'circle',
+ loading: false,
+ bgColor: '#ffffff',
+ color: '#C8C8C8',
+ fontSize: 19,
+ iconSize: 28,
+ loadingColor: '#C8C8C8'
+ }
+}
diff --git a/uni_modules/uview-ui/libs/config/props/loadmore.js b/uni_modules/uview-ui/libs/config/props/loadmore.js
new file mode 100644
index 0000000..67c1160
--- /dev/null
+++ b/uni_modules/uview-ui/libs/config/props/loadmore.js
@@ -0,0 +1,32 @@
+/*
+ * @Author : LQ
+ * @Description :
+ * @version : 1.0
+ * @Date : 2021-08-20 16:44:21
+ * @LastAuthor : LQ
+ * @lastTime : 2021-08-20 17:15:26
+ * @FilePath : /u-view2.0/uview-ui/libs/config/props/loadmore.js
+ */
+export default {
+ // loadmore ������
+ loadmore: {
+ status: 'loadmore',
+ bgColor: 'transparent',
+ icon: true,
+ fontSize: 14,
+ iconSize: 17,
+ color: '#606266',
+ loadingIcon: 'spinner',
+ loadmoreText: '������������',
+ loadingText: '������������...',
+ nomoreText: '���������������',
+ isDot: false,
+ iconColor: '#b7b7b7',
+ marginTop: 10,
+ marginBottom: 10,
+ height: 'auto',
+ line: false,
+ lineColor: '#E6E8EB',
+ dashed: false,
+ }
+}
diff --git a/uni_modules/uview-ui/libs/config/props/modal.js b/uni_modules/uview-ui/libs/config/props/modal.js
new file mode 100644
index 0000000..2ae3fff
--- /dev/null
+++ b/uni_modules/uview-ui/libs/config/props/modal.js
@@ -0,0 +1,30 @@
+/*
+ * @Author : LQ
+ * @Description :
+ * @version : 1.0
+ * @Date : 2021-08-20 16:44:21
+ * @LastAuthor : LQ
+ * @lastTime : 2021-08-20 17:15:59
+ * @FilePath : /u-view2.0/uview-ui/libs/config/props/modal.js
+ */
+export default {
+ // modal ������
+ modal: {
+ show: false,
+ title: '',
+ content: '',
+ confirmText: '������',
+ cancelText: '������',
+ showConfirmButton: true,
+ showCancelButton: false,
+ confirmColor: '#2979ff',
+ cancelColor: '#606266',
+ buttonReverse: false,
+ zoom: true,
+ asyncClose: false,
+ closeOnClickOverlay: false,
+ negativeTop: 0,
+ width: '650rpx',
+ confirmButtonShape: ''
+ }
+}
diff --git a/uni_modules/uview-ui/libs/config/props/navbar.js b/uni_modules/uview-ui/libs/config/props/navbar.js
new file mode 100644
index 0000000..614a99d
--- /dev/null
+++ b/uni_modules/uview-ui/libs/config/props/navbar.js
@@ -0,0 +1,32 @@
+/*
+ * @Author : LQ
+ * @Description :
+ * @version : 1.0
+ * @Date : 2021-08-20 16:44:21
+ * @LastAuthor : LQ
+ * @lastTime : 2021-08-20 17:16:18
+ * @FilePath : /u-view2.0/uview-ui/libs/config/props/navbar.js
+ */
+import color from '../color'
+export default {
+ // navbar ������
+ navbar: {
+ safeAreaInsetTop: true,
+ placeholder: false,
+ fixed: true,
+ border: false,
+ leftIcon: 'arrow-left',
+ leftText: '',
+ rightText: '',
+ rightIcon: '',
+ title: '',
+ bgColor: '#ffffff',
+ titleWidth: '400rpx',
+ height: '44px',
+ leftIconSize: 20,
+ leftIconColor: color.mainColor,
+ autoBack: false,
+ titleStyle: ''
+ }
+
+}
diff --git a/uni_modules/uview-ui/libs/config/props/noNetwork.js b/uni_modules/uview-ui/libs/config/props/noNetwork.js
new file mode 100644
index 0000000..74dba1b
--- /dev/null
+++ b/uni_modules/uview-ui/libs/config/props/noNetwork.js
@@ -0,0 +1,18 @@
+/*
+ * @Author : LQ
+ * @Description :
+ * @version : 1.0
+ * @Date : 2021-08-20 16:44:21
+ * @LastAuthor : LQ
+ * @lastTime : 2021-08-20 17:16:39
+ * @FilePath : /u-view2.0/uview-ui/libs/config/props/noNetwork.js
+ */
+export default {
+ // noNetwork
+ noNetwork: {
+ tips: '���������������������������',
+ zIndex: '',
+ image: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAASwAAAEsCAYAAAB5fY51AAAAAXNSR0IArs4c6QAAAERlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAA6ABAAMAAAABAAEAAKACAAQAAAABAAABLKADAAQAAAABAAABLAAAAADYYILnAABAAElEQVR4Ae29CZhkV3kefNeq6m2W7tn3nl0aCbHIAgmQPGB+sLCNzSID9g9PYrAf57d/+4+DiW0cy8QBJ06c2In/PLFDHJ78+MGCGNsYgyxwIwktwEijAc1ohtmnZ+2Z7p5eq6vu9r/vuXWrq25VdVV1V3dXVX9Hmj73nv285963vvOd75yraeIEAUFAEBAEBAFBQBAQBAQBQUAQEAQEAUFAEBAEBAFBQBAQBAQBQUAQEAQEAUFAEBAEBAFBQBAQBAQBQUAQEAQEAUFAEBAEBAFBQBAQBAQBQUAQEAQEAUFAEBAEBAFBQBAQBAQBQUAQEAQEAUFAEBAEBAFBQBAQBAQBQUAQEAQEAUFAEBAEBAFBQBAQBAQBQUAQEAQEAUFAEBAEBAFBQBAQBAQBQUAQEAQEAUFAEBAEBAFBQBAQBAQBQUAQEAQEAUFAEBAEBAFBQBAQBAQBQUAQEAQEAUFAEBAEBAFBQBAQBAQBQUAQEAQEAUFAEBAEBAFBQBAQBAQBQUAQEAQEAUFAEBAEBAFBQBAQBAQBQUAQEAQEAUFAEBAEBAFBQBAQBAQBQUAQEAQEAUFAEBAEBAFBQBAQBAQBQUAQEAQEAUFAEBAEBAFBQBAQBAQBQUAQEAQEAUFAEBAEBAFBQBAQBAQBQUAQaD8E9PbrkvRopSMwMBBYRs+5O/yJS68cPnzYXel4tFP/jXbqjPRFEAiCQNe6Bw/6gdFn9Oy9Q90LLG2DgBBW2wyldIQIPPPCte2a5q3jtR+4ff/4wuBuXotrDwSEsNpjHKUXQODppy+udYJMEUEZgbd94DvnNwlA7YGAEFZ7jOOK78Xp06eTTkq7sxwQhmXuf/754VXl4iSstRAQwmqt8ZLWlkHg0UcD49qYfUjXfLtMtOZ7npExJu4iqZWLl7DWQUAIq3XGSlpaAYHD77q8xwuCOSUoXw8Sl0eMux977DGzQjES3AIICGG1wCBJEysj8PXnz230XXdr5RQFMYbRvWnv6w8UhMhliyGwYghr4Pjg3oEXL34ey9zyC9tiD2ml5h47dr1LN7S6CMjz/A3PvHh1Z6UyJby5EVgRhKUe7Kz/JU0LfvrJo5f+Y3MPibSuFgQGBgasYSd9l6GDsup0WS/T/9RTp9fXmU2SNwECdQ92E7S57iaMeJnPQLK6ixkDLfjlb7546RfrLkQyNBcC3dsP6oHWMd9G+V3JgwPHh7rnm1/yLQ8CbU9Y33zp0j+nZFUMb/DHmB7+SHGY3LUKAk8cObtD00xlHDrfNge+Z2ozU3c9dvx4Yr5lSL6lR6CtCWvg6OAPw9z538ZhhZRl6XrwhW8du1KX/iNejtwvPQIDR8+vSRqJ/obU7GupjdNdh2gW0ZDypJBFR6BtB2rg2OVtuub9JcmpHIpBoK1xfffLzx4f7C0XL2HNiYDp6bs9z23Ypn1fC1Y/9PCFDc3ZW2lVHIG2JKzTp4Ok7nv/G6Q054MIvda+bNb74pEgKGtwGAdL7pcfAa8vOKEZ2kyjWuLr7uDh+/qvN6o8KWdxEWhLwroyeek/g4zuqwU6kNrhyZcu/UktaSXN8iNwuL9/RuvVXtJ9PbPQ1vhmcP6t9+47u9ByJP/SIdB2hDVw9MJHQFYfrQdCph84evFX68kjaZcPAZJWwjMXRFpJ2zr91tfuvrh8vZCa54NA2xGWrunvmg8QWCJ/N4ir7fCYDxatkOeBB7an501agXbygVdvv9IK/ZQ2FiPQdi9osGbH+zRNf7y4m9Xu9Me7N9nv0HXdr5ZS4psHgXpJC9P/wDRTx0Vn1TxjWG9LGrbaUm/Fi5meSvcrkxf/Cg/ow9XqAUk91v3qHT97r6471dJKfHMi8Oyzgx1Z03t1YAQVT2MwgsC3u+yXHzi0faQ5eyGtqgWBtpOw2Ol9+/TM+sTOn8L08MtzgQCy+tOHXr3jA0JWc6HU/HF5Scssr4jXcYqfP6V/T8iq+ceyWgvbUsKKOn38eJAYyl56TAuCEr2WYei//9Crd/5GlFb81kdASVopSFrerKRlaoZj9HR+700H10+0fg+lB21NWBxe2lhNHsUpDZr27mi4dV379R9+za4/iO7Fbx8ECknLCPTsTDJ17O33bJpqnx6u7J60PWFxeAcCbMV56dJfQKf1bkMLfuGh1+76zMoe9vbuPUnLsb2DtmOe5HSxvXsrvWtLBEhaTx29+Ma27Jx0ShAQBAQBQUAQEAQEAUFAEBAEBAFBQBAQBAQBQUAQEAQEAUFAEBAEBAFBQBAQBAQBQUAQaEsEVoQdVluO3BJ06ptHL34b1XRjp4Ch6Rq24+kmjG4Nwwg+9uA9u/73EjRBqhAEihAoe3xwUQq5WTYEzp0b3ZnV/Ncf6O/9AvY9wlh/6dy3X7ncN512Zw9BVLXjuAP4np44vnQtkZoEgVkEhLBmsWiKqwsXpjbPBOn3gRfenwnc+7GBe+zsjclvonFDS9nA9Iy/u3x9+vAP3735VPk4CRUEFhcBIazFxbfm0k9fHD7k+v4nQFaPQIrx8Gmyx/GJ0J/t7ez7mw0b9MmaC2pQQgh0/ZSm4g5TwueWWtqLt0HuVy4CQljLPPYnB0depTn+b3t+8B4t0AdBUv93h2H9xc6da0aXs2m+r1WQsLRnl7NdUvfKRkAIa5nG//r1oGtsZvjTgev/kqYHF/TA+AXoqv4npJemOEiQU1Eo2l+G0movBK1UBBPU7s9E1+ILAkuNgKwSLjXiqO/khVtvARH8dxDBRkMzPrF/V+9/BlG5y9CUqlXinHv9mRPXtvuus88L9H3JPv2zD2yXExCqAicJBIFWRwAvv3Xqwq0/Pnn+lv/K+ZvfPH3p9p5W75O0fxaBp793ce3AwIDMWmYhafiVgNtwSMsXeHp4eNXJC8Nf0PAdRCiuf/XgrnWUqsqotcvnl9DmRkCdweX4b9N7+m/ih+mbMraLM14yJVwcXItKpT1VRve+ArC3Qqn+3gM7132jKEGZm6tXg86J7OhDfuA/iHwPUpfUZSfu2L59tXxEoQxeyxkEgjKeOnLxHb4RqC+NY5H3+2953d4XlrNN7Vq3ENYij+yZwbG9jpt9GkBPQ5H9zgP9607OVeWp87cOQtn9zwJf+xDMNFfj+jryPqXpxj8c2Nn7P+SXey70lidu4IXzb0DNB4tr9751+HV7zxSHyd1CERDCWiiCc+QPjUCnsaqmZ62O5IN7N/VUNP48ee7mAZDTf4Tt049iUG4Guv4ZfNLos9UIbo7qJWoJEHjy+bP7fNsoOcnW0A0/aacef8PdG28sQTNWTBVCWIs01OfPj66BpfqTmq732UnjgT1bei+Vq4pTv7HM8Ceg2/o1qLQug7T+FaaM3IqTLZdewpoHgYEjV9fphvOj+OShWa5V+CxvZtpzv/LwG/aNl4uXsPoRwI+4uEYjAJ2GmdG8L0FK2mYa+tsrkdXZy+P7x2ZuHdW14P+BLdank9q6Qwd3rf+ckFWjR6Tx5Q2cP58K9Jm3VCIr1ogt48lO237r3//96YofeG18y9q7RFklXITxPXV+5DchKb3ZDMy37Nu5tuxG4R9cHH6b42QfAzlds+3EPXu2rfrBIjRFilwkBIIR7SHoJDurFU89ZOd680Gke6JaWomvjoBIWNUxqivFD87fej0e0n8Fwvr0/t1rnyqX+QfnRz7g+8FX8Rv8vL3auF/IqhxKzR2WCPxXqKeq3krDTdj2ierpJEUtCIgOqxaUakwzNBR0D09yiqePHOjveyOkpxLr9VMXb73V97S/h3nDXx7Y2fdPkAYbncW1IgIDxy5vM7LZt/hgrnLtxyaBrJNxv/72N+6tuNhSLp+EVUZACKsyNnXHvHL+1qcgNf2KbSXu2bt9dcmS9qlzo/fARgcmCtpzB3b1/Vg5QiuslLowENyDWDn8cSjl98PgdBviu03N+rl9/WufLEwr18uDwLdevLTF1YK3xnVZ2HI1bUxrT7z5zTuXdRP78qCyeLUKYTUI25OXbm4JPO00TBj+6I7+db8ZL3ZwMOiYdG4dA1lN9HWte2iuI2NAVPapC8O/CGPR34Ip/AZIbIMo7yX8G9QMbcS09P+2b1vf5XgdrXaPfiYns9oeLLEd8D1/B7Dp0E1jGP042pXQj7RKf546cmGzp+tv1TRf6YQD35/QO3seP3xow5IfC9QqmM23naJ0ny9ysXwgq98BWc0kVhv/Nhalbqe8kd/Fr8MOSEr3zEVWrwyO3I29hl+E9LUHGf+nAXI6sGPdd8uV2YphIKnE5IyL6bLxk7cn3bdkHHefrpvJAExMZ1uBZmqeNzXtfzUzk/m/ens7LjV7Px+8d9e1579/44l0duZtge+Np5zEEw8c2pBu9na3YvtEwmrAqNE8IZvNHsep5//yjl3r/0O8yFOXbv0QCO05gP0JGIL+fjw+uj91YeRh/Dp/PtCDM7Zpfmjvjt6Xo7hW9ycmJjaYduf7Hdf/8HTGfa3rG9rYxLSWnsloPg7fijZV8oFM2Ja2a9t6EJd7bCztvHP7us4rrdD/r3/7ct9I99jEI4cOiQ3dIg2YEFYDgOUJDFj1e8TqX7cT4kImXuQr5279A4DeBEX8ayvprU4N3rovcALot/TH13T0fXDTJn0qXk4r3k9OTm4y7a6PzjjORzOOvn1kbEqbnEprPhRzwAKzwFLHk05hv6Yd6N+o3R6beG50aPSdr3qV6IJKkVp5ITIlXOCYn4Yexr0w/DO6YXymHFlR0e5r7tsM3fxgJbI6fW1ivTeT+SsYmr54cFff+5Cu5X+hb94Merp6/J/PusGvTE6724eGJ7RpSFOkKPCUZvBPBccoHBet3Rwe13rX9tw/PjXzZ5hKvr8SfhWKkeA2REAIa4GD6p0feRdWBnvxjv2PckVhVfBf4A29uG/X2i+Ui2eYn8n8NryuDr3jPfWSFV5k44UT137eshIP2K7/64cObbheqZ6lCp+Ydt8TBO7vTM5od1+/NR4SFVhoLpKKt410lnE8LTMzo3V2dLznxLkhYgQ9obiVjEDln7mVjEodfYcpw+MAsftg/7qSDbAnb97sCSb0Yei2fqOcbovVqKNnNO8HmAE9Cv3Wp+uoWjt27HpXNqH9WTKR+kBHKqEFbvo5y3N/avfu4g23R45f3WGa1k9ZicTd0zPTf/f6O7f8dT311Jp2fHzmgJlI/N70jPPe4bEZ6Kg4qw0lqlrLiNKBiLWerpTW25PUbkPXZViW62ecHz+4d8PXojTirzwEyhq8rTwYFtRjvpX/rlwJ+iSXugPbMuyKBOHo3geRJtuT7PujcmVUCuPJlhnL/9NUqvMD2eyM5sxMaIlE4n7XML907tyNjcxHQjty4sZv66Z1xEok/xNW5n4uZSf+8sT5m++vVO58wkEu5sR09pd9w/rWyET2vReujiqygrSopn/zKZN5qMeirotKeTyolm7p/+X06Wvr51ue5Gt9BISwFjiGsLl6N6SrvylXDNTK70D4mX071pwtF88w6Jd/DG/1E1u26NOV0pQL71y3/8PJVOcHMzPTWkcCH2YGOaTTaS2RTN6f1fQvvvDK1bdnbO2JZCr1SeRfn05Pa1PTU0gXJBKW+ecnzlxvCGndhFQ1NRP8bcY1/vjS9bF1V26MwHwsVKiXa3etYVw1TNhYJ3TDjQCO42jJVMcez7J+t9YyJF37ISCEtahjGjxkGDr2DJZ31D8h5vUQJL5RPkXlUMM07u3qSGidICvkzzuSlmlZb0olrK9hD9v9JCrPC196JoPMAolFg6CV+PPj54YeyWecx8Vk2v1Q0rSfhFT18LnBmzBRyNalp5qrSuq7kiAsh4SFa7oZ9M0wzI+cPHOjZPo9V1kS1z4ICGEt4lhiCvZrSa2jol7qzPXJPk6nIGbVbWfUvcr7hO9MP97ZVXpggOu6ajplYStj7l1XvbRMXbPAbp6HzSSBlkraNknrvfVCcPt2sHYi7f3pTDb47KUbYxuvKqkKpYBXKBnV869c3WgbDEixAck0FGFFfEzJzbIsO9C1TyrcymWWsLZGIHoW2rqTzdo5dXyykz0NC8l779i5vu4zwM+eHVntGP5jqVTq/6AkVc5NZ3wNH2lVxNWZNIukMSjiNd9z0+CHp5DXAdX4SAg203w8GB5IATtODHzdK8C15kEjhXvNS9rWA11dnfcMDY9prscss48RySakrOLWqODCoIKAgkuVgsS0urtD60haeV1YYVbbtjUn6/74HXvW/11huFy3PwKzT1r797Upe3jq4sib9u9Y+wxe+vh7W1N7jx49v6ZzbffnQD4/Cj1Pfjx54XiBls6GVuTUc9mQsOIO9mPQFdkIRlz4fy5JLm2ZMOqTcJaXIqpcqnixVe+rdbZ3dbc2OT0D0wZIibHSksmklslknvx+//q3PiKnXcTQae/b+LPQ3r1t0969cOL6G7o6E09qgZegdMJBpVQ1DbKCpyUt6oPKz/4NEJalCAuZFIuEVBJd+jgLh4rvAiFqUVGkhJZMWFp3Z0obGSu/d5gSnWmavuO6h+/cvYHSobgVgoAYjrb4QPMUiGtj1/79jBMkLBwiTlMASlYzTkhWCJyTrGAyMOFkst/BoYMmuIIyGJYcMXMMdNwHPhYN1qWS1t6ZLGaKZL8yzFXTr15BooLLMugHMBRNKgW+It8y9TEcJGt4rvcRFCCEVQbFdg0Swmrxkb0+cf2XOzq73kgdFieEXF2jdEUJKQH6SVWQrNjtZDKlpTPp38U58iUbthk/Ph7sN6zg/xudSGvD4xkq6otcnnjyF0XRRTflkyC0IIJE1JG0QbqGNpMNp5xFhRTcZDNoj66988SFm5vv3LX+WkGUXLYxAuXnCW3c4XbqGs9hwjv+a9lsuN+ahOJSCoLjNDAFvVUll0p1aNPp6adTweSflEszPO48oFn+4yOTmR+6enOshKyYhzWpf/jDuuf6x2aV/qNRaPG/1d0gUXWCA0uu7GhMmkqmerEc8KOVU0lMuyFQ+Ylut562YX9Sncmf7Ojo3BDZWbGLtMkiUVXSWTFNuMqWuYG530f7+/tnGFboxsfdd9mm8XdDo9O7rg6NFq0CFqZr5DWlK9qV0fZqGvZchSuPlevB2VmG/hOV4yWm3RAQwmrhEcW64qu4ykfJho52Vp3J8quBYQooqWDKADftBd6HD+5efyoKj/zR8ew/hWXY56/cnFh7a3RCTTGjuMX0SVB9qzu1qfQM+jO3dBW1g6uVSHv/qVNX10Vh4rc3AkJYLTy+WA/8ou9kJjo7bOh+DLVFZ64TEbCyBktxI5PJZj56R//Gx+NdH5vM4vuI+p8NXh9LjU1iw3EZhXc8TyPuuV9wDaaCfBjTM06N0hVWQmHBDzvSDZ5tvqYR7ZAymh8BIazmH6OKLbzv0KZvJEz3ZzEFnEolaEtV2XEaCLKadrIz//TQnk1/EU85NuH8th8Yf4j9gMZUOrNkZEVZCnsbtTU9KW18GqcKFyjh420sd2+j33pg3F8uTsLaDwEhrBYf04O7N/2t7/o/C2FoGnsIy/YGlvAwSfCvZzLOe+8oR1ZT3u/5uvHJC9dGtJlMrfqjslXVHwjpat2aLi2rjFFLjUSrFUjlO0juddXSSXx7ICCE1QbjiHO0/hofbPgwpnDTOR2V6hWNQqGUx34890noet5yaO+Gko3Y45PO7/uB/lvnrwxrWdha1absbgxo1FWtwplXqYSJY5Nn5lU3bLHQmGA/yko0plVSSjMjIITVzKNTR9sO7dv8RSeb/T9BWmMkKv4D+YzBXuljV7yxd+zfte6VeHGKrHTz4+cv38JWmyUmKzSGG5z7VndoE7kz3uPtq+Welvhwm39weVjOyaoFsBZPI4TV4gNY2Pw79mz8KyebeRIH+VEZTaX0sf27+v794TKmCxNTzr/2NOPj5wZBVjjdYSklq6jN69dyKuhqmWztivYob+RTSkPbe/xMdlMUJn77IiCE1W5jq+s4dYEO6mzsYAmvi/+CrH7LDYxPcBq4HGTFVcG1ULLT5orS1ULIkoSFI2cMHKG8obiXcteOCAhhtdmo6gaOh4EWWlkyYU9gvHswXfgV19d/7+LVkSWfBrItJJhObL/p7elQR8fUZnEV70XxPc01sM+xrzhU7toRgZIHuh07uZL6xA3LBaYB+Ar8rBsfz34YX1j+D5eu317QNGy2xPquSE4mDuXb2IujY2AgytNE67RiKFshzuwCR5s9ZSMlsK0QEMJqq+GkBKOF5yFzRoidK5BoFCeMjM/8mG+a//Xy0Li55KYLBRiTrGjwOQ1br4VMBQuKVJeQKVPxMLlvPwSEsNpsTEECmBLSgbHUpwD1YGwse59l2p+9fmuig4fiNZIowrqq/6Xeqm9Vh9JbjcOKvqFtACX7gV8kTVZvkaRoRQSEsFpx1OZoM2iKxxuHLtDcsZlgLzYZfv7m7XSv+r7fIm234XSP/8o5ktWqzqSyZr89PoXPYDTYkZvziw0NLluKayoEyq4iNVULpTF1IaDjHHZmoAW4aep9geN8fiLt998cGYdtVp7K6iqzXGJFUCAi7jdkuapsBJKcPBwgyP8YRyV7B04Q3dDbpY3jg6gupoMNla5U41BbUN9n0sr1ScKaHwEhrOYfo7paCAW0WiWknihhW/0Tabf/6tDtxpIVSIhGnz1dSXUkDL8fSHKi4/lWPId9Kp3Vxqegp8J/m9f14D6DQ/nmb281FwgkZ1Dj7bnSSFx7ICCE1R7jmO8FJJr8jCvjeNrIxFjDJBpKVaSlXhwDw384MyucBoLAGEfHI5ptO6n1YAq4FjorH9IWjUOnFlF3pj62aui3whbI33ZGQAir/UY3XCVEvzgdw/8NcSyGUhSlpVWQrFg2p39xp0JYLyIohaXxdZ2FGofG6yi85/QS32F0Asu8URgu1+2JgCjd22xcsVElPC85169Gaa1YTkRWJKpSqooBiQQzONvq9sRULKKxtzzAEJw1api2EFZjoW3K0oSwmnJY5tcoSD09HanEDztubnfO/IopyUWC6sUmZUpW5aSqkgwgK04DxxaZrFivacCaIdAuH9zaM1rSDgloOwSEsNpoSMenvU93dXb+EE5taFivKElRqd67qrNmsqIF+yjMF/i56MV2JqadYKxXMDXM6+4Wu04pf/kQEMJaPuwbWvPticwj4Il/NnTrdl7JrqaDC5wTUle1GmdWWVCw1+JotjA6PgnThsIdQrXknF8arkJi/+R355dbcrUaArU9ha3WqxXW3tHR9C5dN//T9eEJ3aGdUwP7T0V7F86Mr0VW4mF6o2NTS/ilaB2HDmb8wA2+08AuS1FNjIAQVhMPTi1NgwRkGKbxRxMz3uaJSRzVUkumOtLwo6Zc7aOkVdEhynN9NQ1cyuNqeEqD67mX9TXGyxXbJhFthYAQVosP58S0909czfqJqzdGODVqaG/IUbCWr2p0yukfp4FUtDfeir1yl8IPUGjPHFy/fqJyKolpJwSEsFp4NEfT6Z3YBvOp8MvMc0hAi9hHNQ1cBrJil5TUZxhfXsTuSdFNhoAQVpMNSD3NMTzzU1PZYAM/ProYkg3UV5rHT8lXmA7SwnwEq4FLLVkRI04HM+n0LdvzvlEPZpK2tREQwmrR8ZucCd7hePr7rw2N5PfxLUZXON1zHKz4kb0KnIttP6Njk8tyaimbwXPrsW/yq3v3bhoqaJZctjkCQlgtOMCYCnU4GedTI+NpQ32XbxH7QOmKG5nzdIWZJz8HNkKygqI9TmSL2JSiovGVn0A39c8WBcpN2yMghNWCQ4zPc0HRbr6GEs6chJFnmfl3knZO4/hmII1B6fiFG9br0s6qAeXPp2WUrhzHeXH/jr6n5pNf8rQuAkJYLTZ2kK7Wul7w6zeGx9DyUsZovOodOizosTg1TM9k1Wogpa7lIisOF+w48E/7E5B1Y/cgtdizsBKbK6c1tNioT6X9n3MDcyePOo7OoJqrC6S0+ZIYV+GSOHxvc18PJCxXG4ed13I727axqTp9yk9rX1jutkj9S4+ASFhLj/m8axwdDdbgELxfGsLpoZyqVXPVU1QugVJUV0dC27p+FaaBWWxknq6ceAljTNMiAf/BoUMbJpewWqmqSRAQCatJBqKWZpgJ731Zx9pJM4aK0hXe5vlKVFEbKFlxs3PvqpSSqpbzKztRm+gnEkktnU6/2GFMfa4wXK5XDgJCWC0y1iAR6/Z49iOjY7C5qkG6mk+3SFQGlEP8FFdnygrNFqBsn1OxP5+K5pGHbcBhqhT8fqu/v39mHkVIljZAQAirRQYx7Wj3Zj3tddQjVVJ4l50CMjHe8mqOTJCCvmoTyIrENXx7Uinbm4Gs2PZUqkObnp76i0N7N36tWl8kvn0RaGnCGhgILKPn3B3+xKVXDh8+nPseX3sOlpt13+P4uonv71WeDqLr1ampFB8S1JrulNaHc9rTMxltcpofOeWns0rTLkeIZUHRnpm5YibMf7kc9UudzYNAyyrd8ZLpWvfgQT8w+oyevXeo++bBtaEtQd9s1/ffRsV3I6eDJCp+nourgH04UZQnhIYfWm1o8xdUGCU8/E/bil89sH3dlQUVJplbHoGWJaxnXri2HTvd1nEEcCBS3z++MLi75UejQgcmJjL92ax/gNJPo6QekhVXAbdvXI3D+XQ1Bcxiu02zTAEjKFIdHTQS/S8Hd2/4YhQm/spFoCUJ6+mnL651gkwRQRmBt33gO+c3teNQYin/oG6aKX5rcKEukqqoWN+Ij5vy81v8UATDG0WGC21jlJ96K6wKPpWd8H8jChN/ZSPQcoR1+vTppJPS7iw3bIZl7n/++eFV5eJaOczX9Z2YvM1LPxWpocBHKv8qHHdMqSphGUqqahaThfj40ITBcbLnsDj6oXvu2bS4n96JVy73TYtASxHWo48GxrUx+5Cu+XY5RH3PMzLGxF0ktXLxrRoGNVPPfNtOolIrgElLGYH2wbZqcipdIFVFlDbfGhqfj9bskCaHHS/7gTt3r73Y+BqkxFZFoKUI6/C7Lu/Bl1jmlKB8PUhcHjHufuyxx/g5lbZw+BL7bX4EoiZqyS0T0uM0j1+82QSl+ua+bhxj7GjD2LicwWkLzaarigbKsmDJ7gcTmezMBw/t3ixntUfAiK8QaBmzhq8/f26j77pbaxo3w+jetPf1B5D2RE3pmzyR4/nH+Mti4Wx1dUrCHO0lSVGqskFUnakkpn6mhu086jgYHkWTW3Wbo4Tli6L5gqYHE47vfeDufVv+YflaIjU3KwItIWEdO3a9Szc0ElDNDqcLbHjmxas7a87QxAnX9ljfxcr+Mzs29ykpi1O8iJjoR/cm5o7dnUl89LRLW93dyWmVIip+Kp7pmlWqIvQ8Mga9Gslm3Efu3LX+K008HNK0ZUSgplnGMrZPGxgYsIKeXa/TA61jPu0w0+7xBx/cd3M+eZspD0wbDgWm+RXP13cODY/jWGKuGAb48jG+agNpilbqlKZoWDqDY2AyjtNUlupzYZlKpXgaxIVMNv0zd+/d+uxcaSVuZSPQ/IT13TN34QRvZW81n6HSDdMLUqmjh9tgd//Fi8OHEl3JL3Z2dh3MzGA7XU664llVWRz/QhLjNYmsmaWp/DjCjqIDdlaZTOZZ1/A+fGj7hjP5OLkQBMog0NSE9cSRszuswNhdpt31BRnazM3U9IuPHDrUuG+419eChqU+cvzqjp7u5P9KJpMPpqc51Zv9QntLkFQBEqZluVCw/7nhaP9i376+8YIouRQEyiLQtIQ1cPT8GjOw7vE8tyFtxBrb2MBXdh579FF99g0vC0nzB548ebNHT2l/aFmJj1BPBYyav9EFLaQ+jdPAVNL8/pZ13a8qiJLLOhAAjvrTRy/d0enbF+69d0tzHFhWR/vnk7Rple6mp+9uFFkRGF8LVj/08IUN8wGp2fIcPLh+4sCu9R+F3ucj0MLf4vaVVnChqYWmdaQS2jpY2vd0djh86Vqh7c3Yxm8dudTPxaW0lrn7yJEjZW0Tm7HdC2lT0xKW1xecgHE3FDWNcb7uDh6+r/96Y0prjlIO7ur7TOD5b3ayzt9ylY0Gl83qKFXZsCXrXdOlrV3djf2LBr556JOshLDmMWhPPXV6vav5O5jVxYLUhNl3iIbV8yiqpbI0bQcP85C2Xu0l3dczC0XUN4Pzb71339mFltOM+Q/0rzu5f2fvu1zH+QDOt3uZ0pbVRMRFouJK5qqeTkhVqyBdtdUmhGV5JI4cudrpd5kHiyp3tTU/8s6r+4rC2vCmaQmLWJO0Ep65INJK2tbpt75298U2HLuiLh3oX/95L+0/kHUyvwTieiUJHVEimVzy1UKeWMqv2pCoKEVFRNXT1aHawnBx80eAZj7TwcxdAc5Gi5fiaNnNT37nCk4xaV/X1IRF2B94YHt63qQVaCcfePX2K+07fMU9U7qtHev+xE/7r3cc70O+6w1gxuV0dHZiusgvJS/O7IskRXLs6KCxqj+B26t9a3uUREWi4plbQlTFYzXvu+7tB3EIUGel/L6e3TNw5NS8zYAqldss4YvzBC9C7559drAja3qvDoyg6pwCP+KBZaVOPPjazS1vMLpQKE9fuPnawDB+EqehPwzWuAuSl8LPg90WVxhJJPWQCUmPBAWTBEz1TFUGpqO3wYYvIPgr2az35a2b1/50V6f1e1NTlVcvEzB0xRekj67usu5FmS2/crvQcaol/zeeObfTSOj91dIq28PxiaOHDx9quy8LtQxhcZBqIS0Dhkl2l/3yA4e2j1Qb2JUUD1Iyz1waOQib0vsxKXsAFvH3wMB0JySwtZC+DBPTN5BOCEnhrI1BuKe9l6tIzsVCiD6E0DOabrwI2elZ09aP7N3aNxjheXvK+a1OENa0EFYEyYL9rz072Ju03ZpNQKj7Xd899cKhNrA9LASvZTY/s9GcHoK0XsrakLS8UklLxyl+/rj+/Qfu2367sJNyTS7SuZfneO7ffweBGScu3NwAqWgrTvTc5jjBZmw87tMCfRXYKQWOgula4OiBOQUZ7DZuhrAGdQXxV0zPuCaGnkv3VPGHOpPw7+QPR62OM5HhdNddGOeX2kmCbSnC4mDlSStVTFr4eLljdHV+702vWz9R66Cu5HS5h5hmHvz3QiOxwJTRo2BGgY06dm7OVhewYGAY6s75oD+ZDs4JPY9JyqSCQ7ABqftd5VFM3/j2Ja4mtsWpJQSq6ZXu5UZTKeJnsHpohiYPRqBn04nkS2+CQWW59BK2dAjwS0Y4IHDz2ERWG8Gnwm7iK9W3sFmbvrqGPzw6gW8eTmvTM07XmTPX28KYd7EQ3rjnvv1QFHbPt3zT9DcMPHd+13zzN1s+/hC2rKOo7NjeQdsxT5LEWrYjbdLw05eHtwWe9jl0542u62HZHZIVpalY/yIlP5X3MHYddLLZfy4fmYiBhNuB509vw+rG3tKY+kOwGHLi7W/cS91jS7v4s9TSnZHGLx8CICH9lXNDX+zpWfXuycnaBV2e3e567nAm4973qv0bzy1fD5qr5oEB7KXt0u7B3Loh7yhWVfypbOalh9+wr6U3mbfklLC5Hi1pDRE4ef7Wj+EEiZ+amqpvJT2bzWjJRLIPR3n9riA5i4DZg720DSIrlsrvHXSZ9p7ZGlrzSgirNcetqVp9/vz5FJTqj6JRejTdq6eBMzNpHP9s//QrF4bvrydfO6f1JrCX1mvcXlo98Kembjotr3wXwmrnp36J+pYNeh5JdqRem83O77gxkpxtW3bgOZ/g1HKJmt3U1Rw+3D+zrc89aunagnWzpq6PdxujLz388L4F78tdbtCEsJZ7BFq8/sHBoMPX/I9hyrGgnuDUUZzrnnz7yQu3HlxQQW2Ued++fZmJ1e5LoPB5k5ZpWCPXz+08du+99zrtAI0QVjuM4jL2YcIZeh+2+9wF49MFtYJSlgmHE0g/JlLWLJQPg7RmhtyXsJ18eja0tivsXhj6xy9ve/mRR5TRcG2ZmjyViN9NPkDN3Dz1FW5z9XM4i+s1ME1YcFNpUIrVLHzJzHnwjl0bn1twgW1UwPHjxxPXpztejR0HFTc+F3YXRwxdfdM9W08D0zrs4wtLaM5rkbCac1xaolWOvurhZIPIih0OdVm2haNTfqUlAFjCRnJP4HBn+iUqz6tVa2nGpTe/etsP2o2s2G8hrGqjL/FlEQC5GHghfplSUSMdvwaEA/9+4vjpa3c2stx2KIsfUek2dr+EuXNF2xEjSJx98w/tbFt7NiGsdniSl6EPp84O3W/Z1oPzXRms1GRKWdCJdeCIlJ+vlGYlh997r+70+EPH8NHJEtLCauCph+7bmj81ox1xEsJqx1Fdij4Zxi9AT2KSYBrtslgxhOD2gWOyz7AstFzx6zFHj1mGobYUYAgC9cHge3ddK5uhjQKFsNpoMJeqK6+8cm0X6noXiWUxHA8WxAdWNyQM45HFKL8dyiRpueM7jllmMGpnjO+1w9fNaxmXxiogaqlR0jQdAkeOBPjczrnOiQ6jw88ESSOA6KT7iQzOHEvavu1pZsLQg4QPP/DdZG9Xx/vWrOr+mfR03SvtNffdxleAQIgvTzjBT0w409Mpu2faufZy+vDhw5WPMa25dEnYqggIYbXqyNXY7i/jCyvdfmaVb5hdVsLp9LJGp43j1/1A7/RdvdMwPRzEboRnLVHe9vEvL3eXBOB4ZMta22H+TiqV2LJQ26u5u6Bju44Z3J7O/Lvp6cwPmBanOwQ4uNHRTWMK21bSvh1Mm642nTWCtKkH07rnTE72aOO0XZq7bIltVQSEsFp15HLthg5J/+aJE12m3tVjOPYq1/dW4cTjHnwMYhXOce8xDd3y/PJW6OpMdsTRVy4iK/rKMR/jwvz825VIHFzT3fkx13UW/dnhRy3GJyeeHEs7n1XNibUPFvY6vtGDw5vV9w0Vofn81qGhZfDhi3HX8SfQ/3HPMse9CWcCX0gel2OIFJIt+2fRH7qWRaYJG85NxldGzV4tGayFSLQ24+q9ULyu9gJfMU5ELTn6wUISTl03NHz1KzyiJLqmX657OLLdSJgoXTO7cBxyN172blier4YCvBsFdSNXV2dC35tKJrbzfPfFdjwvC/qs9MSMxxNRsSqmT6LhUDQHE+jUBE7UnATXTuLsrRn01K2l/x6+qItiR3TNG8V59KNB0DGSfNXGUXwJY2Gm+osNhpSvEBDCasIHgVLTt75/aQ0MnXpBNb2QgNYEntfr4wu/nBYpKQLtxtdwAh0SBX3VDe7nM/Ha5vf1Fb/CURS2bCTAWWuxR229qRsbQQQbUed61LfW14JVKKsTJ5sk8WUcHbtlNANyTOhgcmAGKH7p3m1FWpqtuZCu+LByVdKHVMjpKEQrBwIW9tnpXOIH+QTDSH/D9f0bmCLewDn1I4HmwtAypPDZ/oe9oXKf/aMPsWxSs/RR13FHrURiZE1gDR86tKHEdCDMKX+XCwEhrOVCvqBeHNaW6ui11/mWDtLQ1kEiWodXE4rwYgepAPssTPCMOjIdAk94TZ8pMZjch8HjDorGFUTUAwlkh64be0A9/ZCatiDZWtOyE7ClQmIdJICJFYhA+TRV4Fo5/QIHiUvrTEbkVRCxiJfsSBbfYk87OTExXxdazY5yUgiRKfpHQ1YSkONmAZY+gV4NIeVFfCXoLNA5h/Plb5LzWAyzF+IVXdNnvO/6GcsyhjC1vmWZ7s2pO3fdOqzriy9asnJxZREoerDLppDAhiIAEtCfO3F5rW0a6z1PX4/nf53nG5RqqrpieSnULEVh8cx4E7ugH78H8tG9eP/24oVezY+pkpA8b/abhPF8le75BqdsXUtaFeaTlTI2IByEoU1l8oq1mkokcZHElIRoWmpejMMCMyCvQXyy7JjjuUcgOl4tLCzCMpTHgFpcgkViX/dH/ax2Szf8m2Yqc/MN+1r7BM/C/rfCtRDWEozSkbMjq7NTY5t13dqE6dhG3wsSqlp+C9DDi0ifLrqmT1f6BgUaPjiHN0lJAGAfvpWcI4XjiHIMF6ocO/EjmMa9HeelQ1LT1PRpoce/sJwOTCQtc+kfGQp6Uxl+9JWtmL+jNEaJ0gKBgbsygR58B4sHfwV5aliVWg3vCHv6ymHcdG868IzrVsK6pnd71+/dsmXxbD3m3/W2ybn0T1/bQFe5I8euX+9ybuqbXMPbDA7ZCKV4uMOecyz+9OfmWvj9x9zEw6JW+JuOX298WhE6qtwLEV3TL1tb/AWj7sqwfqaro/sdmcyM+vBp2XzzDEzaBiQsNH+e+eeTjQ+ohwqnG0BYhfVzNYKrkOmpyauYYH8KvD8G6RPBszrC6Jq+ystl0ghzXEZjR5+O4+iZwTh+eG7Yqa5rq/3hGzzTSkXKn4YgIITVABjBP+ZzP7i8ydasrZCetuCHvIvFRs92SEdlpnCYE2LOQi12OA7RNf1yjrphHIyE9yOXPnfNMDg70DpdTf8DWDKs5rRvMVwChAWrUgh21HzllD0NrigqlxKVC7bKQuOOWeGiuI7OTkhb6T8C/Xw3xkel9cXxj6eIxiY3Hhx3X9dHsWJwDaa3l1+zd9Mt/F4tUk/ijWnP+/DBb8++LWqvnh0c7NDGta0pO7kl6zpb8AJzEUr91kYEFdeBRCt69Nm4+AsSl6jwjVGckY6VwPwUpLhLURx9xliWvxFHi/w+zB0SWCnLsVpxnoXesSI2ngp4zmRJXPgf/0IleGH51R6uwjeX5MR76qtITh7+8N9Cp4GF7Sm8Zl1s35pVXVomm/5c1vG+Wm284njHJeJq44/FjixUAld8w7uijW6+xo3MhW2S6+oIVHumqpewglJ87+LFtcFUcqur+1vxwPcZJqYPMOyhXw6GKI4+4/GwQpjCBhe+6XDIpFb06PM+np5hhS5eXzw9bLJ2pBLGv4Fe36BU4kA6IQGw8MUY6MJywVeqDs54Z69zrWdY7jI3G1ZtUiSV6zzDI3IqLLew/wu9jspl+yywrA1pEed5QceXPT3jBb/DLrA5ua5UHZ/4eMTbFx+fwvE3DJO8fANrjlctL7giJhRx9MrfR89R+VgJ1Y6currONuwd0FNsxwtV02mPlWGLy1TxlPHf6Hh8PH9xesvw9yRM+5PIRT2ZIgVKKZxWUY/PT8aTFPji0i3m4Ed1hDWV/7uY9bNGtiGqAyorJRWSqCgdkrQiR5KddrwPlsq8xfhG6efvx8dvtiQczDdmmPaldDBxSVYeZ3GJXxUMWzxq5d4fPz7Ym7X1HTAL2A7NqtJHEQ3qtCPjw3LoxB/v+OMZ5VVzR5aHWRuErYA+y4uu6fM+Xl9J/lh7bFvbY+vmv0bWos9tsXAWSLIiaSnyApHxJz6SbFSFuXTw8i86r5vVRW1m+6IHmUREAuI0lcREP5q2ztWPrO9/YK54xsXHI56+cePvj3qBfimZNS+J5FWMcrjptThsRd4dPX9+DcwEd5iQphwozfkCwJKaLv9ewHYKeicfSudwShcnJDBBOD3MTwGRO0cqLIj73jQTaejDBYaPHTBgJ/i5+HyYijd95sFhRzkzB7yL2IrCtGwezj9nOQVTUlfPwiicifnu5J0qHHd8mXHIG6ZD7JQqIk9kJK6QwAokMWRUhMaSeJ0vcfaiXNhs7PyuwpYV51Vh+EM/Pu2M9GckpyiOuZm2Wvtom+Y4me8xPbvIIujzPu6Wbvyt1ejL3U7Sv/v754ZHsORwaX3KGdwiJhO5pzY+Mivk/urVq52jTnIXlEc78LKu8qAMx/G8kHhyOicosz0ovM3IrIDKb15HSvDoOoqv+hMLYCOWI8ash0vmufryZVcqLz4u8fym3ov1xT/EVp4UDUTn4/iS0xW+sZTMojASmLqGp64iH4FRXJQ2TKj+lv7JVRTVxwQkm9APyaboGnGMzSVR6VR87ipsVT645ovOzi5tamb6zzB1/nqzjz+s9YetwLioZW5C8jq08K9+1IxS8yQsfF6ap1WL2BK8VOaJc6NbPcPrx7wJ++hmHQUPvOaQgMJ3ETtVlERDP0wVsQ19uPgcLQyt/Dc+p4jlL6k/1xa2qVyh5ApEzEoErm/DsPOTXV3de6anq36roFyRdYWVbVSshHJEMt98saIXfIu9koplYZL6m/hUz7kS/Jt0/PE8+Jj6X/Y6k+fv2tA1BKIvB/OC8WnGAmp5dpqx3XW36fjgYK/upXbhFd+BrRlqn16MfkrspkoC4hnirYjbUVWzs4rHx8uL3cerjwt0TA4RcBcsuX8Rn97q54okVsCKJJ9YkSvy1gJR4aOtnAr6OJP+L13d+BKBKMEzHhAfgDh6yzD+vqHjTDDvYpAxLqwEfVdbE9bpIEi6V27tdLP+LnzPrWS/XrRTnz5d4e79+LNY7r4kP+Z7Jv7z1LyPL0B4Tb+ci9cXLy+eJ54e8Rw//rqqcUR+HOrgYVprJbBl5E2w63oI64J7k8mUDZLGhmAXs19ucVkxP8gKQu4ptCxbMy2TW3KAGI4u1P207ztH3CDx/7bL+Cdse8h1Zy5ev7Dp8uHD7blJuy0J69TV8XW6l92Dl3cbLG6g98idbhDgdANcY1ZY9o2N4mpNr96GRf1Da3Wui0RW69F1bWslvp81LD2xDTOGu9DhQzBc7AcYfYlkAqo6A6ozqHNBYJTESGitTGShsp0qQSxT4AcoPJQw0LBlEPhBFakHDjoLvY+XgVIyg7WK77tG8n9pvpHXBbXL+OMBd7FN6KLu+uf27esbX9RHdIkLbxvCGhgYsDb3v2a7obt7YHakpKmYiqgE2ioqJbzIOszXcSov/DAzRRNehyJKvPx4+igv/ZLKEaCkoZxUFMYXE1I8f7Xyq/UHp9CkAlfbCF3NdlhS7IQguA0N2wiJYy1ktC5IISb1Okr5jSYruy2SGlYkIkKLSC3yy/WrUWGzSnjaTUX/QEhYQuNewLCdwBFKRkpOuAfr4sBnwwfDg6B0MHagORhBHNqHw5WxTwYav6lAt/42MBLfrYZXHO9w3Ftr/B0Hp0pY+tkD29ddAz5ln8NGjddSlNPyhHV8aKjbzAS7Dd3egRcvgRHJWyrHASw9Pyp+vlSxEluH0jWAGQF9VVZMpxHVRZ/xSKQU4PR5Xy0+/sLQZCFS9DN/XKtSeh5WrL2x+sMyZv+W67+vwz5eC7oDx12rm9pakNg639B68XL3Qh+2Bm94DySxHhg0daBHSQhiCbyyyMS9SDi8RhEHyYP1qD9qak0S4VGn5VYrSTRKEkKHWYYiHuQmCYb/YKYLqS+3H5LYckxJmz6qhSYJ5yNgzgtuclESpncBfN8Fj3lgJdCSGpHcGECoxrouMoHjzO+4evLLMB1VKxJV8Wyj8Q80Ix043jnTu32hlTdkh08Yn7UWcnio9Qs3pzZm0lN7LCOxIdIZxbuQ1+lAVFFxJB7aMeUIiPkiPRPjo2v6dPF4FVjHnxi/oQK0Az/bymf5uI7ayGLj6eM63nrbF5VNXzV7nv3HViQL3JAEaSV1z0iBNJIgJBCYkSKJYbdjEiSHw7a0BI5s6QBBbINUswMUsQ6E11UojZGccA9dcZDBdQY+TgyFTgkiEKYyIBvstAQzIRk8cBJ+A2j4gZFDFWAqjAp3V5IhQYYwwUJ57ByS0QINzMYK8FyrRxt3KNbXb2qG/UVNT5wDyCt6/A0boGbdqzPA4tD21SPquWihPy1FWHjQzYs3xnZkM95ePIZd8RccBx1xez/UPowp46I4+uVcLD9/8Plq0Gfy6Jp+uez5uqPyY+UtNN5DuVQc06drpv4bIDXsjtsMpdkOSC79QK4Xog3PzwF4IBNCBiIhpBSpoE8jioqWaM2KCRuOqwLXgIQItKIe0lCYD/lZjoqgGIo0+J++SsmMKA8eqQ21qHuUh2PfzQHN6vgG6vVK8GfmQhcbr3Yff+AEi3rtdCtNF8u/eIWD2ATXx4Mg0XH1Vr/hm7sDQw8PvyvTrriKWocEE0C6oM/kJRJHrAykgj6WGlq+JUifu6YfS6pu4/UVa6AgQcXKi78ApekhcWFBwMstEkTX9MvVHw+Lt2ex+4+Pg62CxgsHEwZbAdgWIJfA+ICkfDRYtyAwWWB7Ay8F8VT/KB0bOJ4Gx/CQfUKSwZGrJJs8iZHYgB0zMB+zk8hopQ8hEcEog2ERASIBAOL5fIrVIKLxXKtzKPZLgZUckvGf+/nH5HsK0+Uz3316zeAjj3D23Lwu90w0ZwNpiZ72UnvwfO/AXIFnXfLBxLOsHn6yiLqmr3oQ04LHX9hq6TFHI6txrlYWkHj98UT1lh8vryR/rIKq6aO204drdP8hRWF3itmLUw42QnW1CSTSA2IAIXkWOBYKLWw8wjVqNkEaFqjFwLQNJhWI4ZiFoiq6QX0SbsEo6HMoWVFCYprwjw6FP65BXCSoXJwiOwpnFK9A6yiWkQhRDwA9XAfpwLS/AqnqSKP7jwapquiznXFXMn6x8Yg/X/HySvLHKqiaPlZfvf0H6BloAM/v3tpzHkJwUx59Uxb4GE5Lfnt2ZGS16SX3+F5mq4llfegtwnaSR6J5EC8hPUV6IDaS6aDnoZ5DpYe6AtdgOr4pyhXLNPH0KKCo/DDP7N+S+mI6qHzbQr7AbdgW+iylWn0l5cf6E29ftfSN6L9lGl04x30tOtMHklmLhxpClW9BL4S1T+i2uNPRp+0FflD0AN9A9LHnmHGBBfJCE3QL9ALiguoJqiu+64gDzWGIIAlhzhaSDsMV/yjJi3BxyY9khP9BXBSzEMY/AFORGMmM1yyKZfmm+ZKuJf4uMHV1THEj+o+S864E7zYd/8Dliqp2MamvPbt9uw4dY/M4DnXTuMuXx/scK9iHLcbryzfKwvOJBSGNPl10Tb8WV0xYyMFymDdXXv46Kq+ueChJQI4WlSUqf8StOf5CNdXqr9afxe8/Gm6AoLAqGKyCGLSG350ACFzKM2FvaeOseEhFOsjItdQ2S6wYYmkOdl2+CfLBvmpIV55vYY2Qn6uAxAWC40zbhxSmWArcQj0TSIiSU37mx0kgVesgLereOSz8E5EWJa6Qzyh1hZEcO7xY4Ct9WLfNvwa+5xA2h6uGP6vMPxMsZ8WNf0Gf+cOCw9usq51a5+kNG9Sn1IjJsjoO0LI7EpVra/vxhPdFs7JyjYriohlbTAKGxO1C6oJEljseOLqmTxfPX66OucJK66OUNzuDjK7p05UIbGwX25I/vrj4BYrnD0uZ/Rtvfzz9fPsPIkgkbL0DZNMFRVEHFEY2ZCBTcwMLdfCsCCVN4SwpE9YG+ARNgD24IDHYSYB1yNCYDkLRFoC8oOUG40AKQx5IYyAmlQ6SF7dDoSof0hbJiApzqLs43aPc5UG+AvVQ/4T7nGQFQiJ5kdbAkmgH2Sz0FaWB4gLrad22v4nmuvPt/yzCc1+V4t0e4z93r8PYwDCvNANxLSthkai0jmCf5+jq6y6Y4SkjTfoKprgWufj9Dg3AozBmiK7pl3H8WDH3u0YfLY6u6c/HVS2vSvsxoygyTF2q/qNenEyjJ5NJPYGPRidME1M1/JYqwyoNq32Ihu4J0z5M+WA2DoqwEI9wfmEaEhQJzPNsKNOh0jJwrfRVJqbnNOrC6IGwQFzgHiKrpCuq2kE+FizrMXWE7IWCEKemg7hSiimOQchNIC3EchqpHlBO95TshQThkwF5TL9k+Mm/MZLGzVo3AlQdLzagDle1vCYd/wU9/5Z5ZcyZPnNow/J8ZHZZCGtsbKw3rdn7nIzTx42o0WfP1cPKuYJ6XPFs5q7p8zmKx5v8cdcxDeMPOR1fj+gh4X10TV/dukiC+nJPeLy8eH1hrtm/UVvpKxcrP2oL/dlcs1eQ9PCeo73wGcp+R2Xyvlp74vH19B9EkoA2CYKUlcQqJCQj6vkoyBjh/IurcJiy4Zxy2FMptRBO7sK3kClR0UYUZAX+wMqfC1ICiYHMYBsKSQsSFKaAUEqZLoiK00ASFsgpN0UEUWE6yOkiiArE6NmUb91OWwAAEuNJREFUszCNxA0c/uBoF04W86YOarWQAYjGmHBBEIkUiXEqib025hNmInWknv6zKo77Sh3/RvcfSx5Xl4O4yr5Y7NxiuEEQFT4uvs8yrF5VvosX28LLS185vsiRHkc9YPiJtrCbJIzHyx3gJdfpl80flZWPR6qIxJghus7xjSqj4E9UNn2VvN76Csqq6XIR+48OYEeGlcAaXhLfQwxNQcgQEI9IErOOxBUuCuDLz9Arm5iyOTaYy7Jty8hAb2VCm43ZmwnwQTbgFpAWyA4SGEKhaMdgYNpngKAcpeMCAfFjYGE4yAqco3RZ0LorUqOkxVkf6AgzvFBPFbISSsOUD+WRrWijpcwbmI4Gomj4yxAIv4bPVU+q9sfxk/EP36UlfP49N3vNWr/m9CZdX/zzjDDofAoW3XHVr9NPHdB8p2+uORl/mjFLUktMbBTtkSJbpLCRxYyD5OpJps/4+DJuvq5IIgoLqfi3pLzcRuloM7QSzKImsBSWG80LVKkxkSvOkFHaCjL5QvrPN9rwvaSVtEg2ICmQCNRQkGjwnlOpNktMxdds+GxcRFrIyCmhTQMEUJjl4qwtzPbAOVC8o0DUZroGiMmBpEUfRBZ4DvRUJC4/1GOpij1ML9XU0PJdFxIZGsOpJkkOQ0YdFh5CPodKl0WfRqQkVUhTIEf1iN4GkdJU4Rx/xsJfHkpfMv4cd+IAUJb1+YdkfSU7NXp6+/bti7qquKiEdfVq0Gl2TO2DonYzAcUTCv0slCB8FuGia/q8j7iAPl30aNIPHVKq55w+00MvjFLo05WmV8H5P9XLzydVF/H0xbGl9UGfjm226B98po2u6fO+0f3H9M7SbT1h+FoS00ybSmm+5/RZHxzbwWvVHtSvNuLRR4BKl0vPtHRhWh1SESUsNBkH0qjvNiAx4MA1JDBc4yBmTPmwJArJCFM+dA1SE5XsmFIqRTzKUrZYkMio78IUkauFoW6Mcbin1GWrOR8nqOEUEUQFmuK3ZdEw6NFg92s9j3XLp0CIsAuS8VdPkcKhCZ9/KAc81x/c3NdzFjy6KHZc0YPNh7VhDg9jYnh4co9n2dvx1nLalys7Rimx2xLGigfEJBQ0Xr149FkBVb04BQiTlPAFbTiDxRGKM1pJf5AgarPKG0sQu413N07hkCANO5m0fSebtCwziW5DqMISHTRMJCDF23inYbmsauNCHq+Vn1ta5dErzKN8psP/RiIXVpAegKJQ30Y06AQSEXdAIpdL0wbTNsLpoSIeCwRJHZYBpTusIFAIlPC0iqL5AxoCcmLPQkkLdITRCc0dSFqQD1A51g4pLOXmhZCwDMO2BpH9q6ZtDoU4oKQIy5yEynFnv+mzw+0+/q3Sf5yT4aYs89zq1alLIK7wYeQANcCpgW5AOaqIARzxcudrXrMTz+cuFAxBI1Rw06eLKz3xsnDikt+Mmr9mWBlXrbySeJAlTt8MXJImXHRNv0zx2GpWZ3r0KKqzXHlRHH26+fQf+mkbg56ADjppUuihMJl7BEhGtmnj+4Phj1lEUAzjaQcgJkzcqPPmlI/yjdJV8Trf/+hbeYyP0uMS0zSVF8SEaSELxkhR6a7IC1IVHkNMBWEkCljxYQ7YXgWKrDCHw2ohJDDKSkr5Tst3TANBp7DdgkTFKSOpxYMtV2i3hXQoJjwbBo3L4oibAajdXmSbCl01PEvi6x3PetMvwfi3cv+xHpPRk8GZvo6Oq5y5FvZlvtfqQZ5v5igfH7iRdHqrn/H24McyEb6ejCUxkCwqEATi8JDNKtWRIxI6wrLj+aOyQgIqLT/KTZ+OLYnCFGHE60PdSgzIgVmcfrbt5evjYkB97VeNyv8plx/UYoChElhYgB7KtD3PAUWRpejIVNzNAjNzyDuYRqnrMF5dIx4CkTrlAJQRps2FhZIX5lqYwfFLOygTBeSmkUhDEgNvIC7MR5ML6JhozoCpn+858G1utbH4j7BRT0Z9VlZzbTyOKJCKeCjkqYbkFBJh+DXCPVcKuXKIFURlm8WBoZSFOBCYmk6i33ioT+Kw1CegEMspcFfe+M8+rRySNum/YUwm9I7TPT04NWOBDg/nwtz16xMbEp3mPswIOuI6G7wBSlynz1pQWZEIP0smIcEEWN3QsfJDn+nj9FFSPh73wilgdE2f+eOumo4pPqWI2kI/LKu4RVXLq7H/kJopRUFhnkj4joNT9KC/BlZgAIVD1I+cwASVUBgCIsF1KEQxJLpGPKHGP5LYrAs5ikREnmJ61KF4K5cG1+REVS6HC1JauGroYYcOrLWUEp6MSF0UpoZgK5hV2dgEzeNLYbMBnRQZEUPnOwGMT6GOp57Kg/0WTCMYjnsQHpDmlJFTR5IcNt/alvV1PdF5NsKcLSpGG03L6QcjnWDpeIXqgFYb//A9wGi1+fMPDeqY7nae6uvT530KKp+JebkhHJyX6Fqz33X83tCgRr1d6gXBH+XnFtEwDmEVMBfAtbK7UvHxVTb1gGLQokbFVBZMDtUJHmT+dsPxmqSRU2nkrxkWxhfbOfEVwLov4sIaonSRr1qZy6vy8xliPbn+qPjYHxSm6mJwdB357DfaVtJ/BMLeW0/ayVQSR6TA5AB7h8kwmFeRrFBUSFYkJk7GsM+F5SuiCQmFBEriCskHYcxfEM9ozBjBS/yaKD//rBzndjD3BHswAcmqwFdhOWGugCw5owwpEt9sxMlVGWQEK4GlcAOi1XAcL6eLICfdcMFmNDnH7xdO/YTCHTkxM2B6EiSPbuXmHrZO5eJy4Iu6lfo2Gu8orFfA+PM9UMjnHpBIx9v+/Q9Wm8nMfcMTE1d7u7vP4Ec6fzy1wqOGP3xI63JHjgT2/rsy/boTbMP0pe78dVUWS5wjK0VUjIqNN3kA62ZYeIcfxofXDFNFUZBTT4W6m71mWBlXrb4yWSoEYWh0jVIUdJEmzA6o18mRDN7dCplCEkK8IiP4WRAU9OO8j5wimZB3SAhKYlJEphLkJCaSEP7PEdxsfVG5UWFxP6qPPngTlvBED6IWLN8dTPmg8ocFPPRXWBdlFWqqCEmLlhAgLRtKdLaAkpQNfRUM6DUQGOUiTimNEaT7FvRVw/F6K91XG4/mHf9KPaovvJ36jzfSS1mpc6mUdhnvhZL4a0GjZsKBKK+n0+kt0AHvztCAsIzjeeAeUKVPF1l101cBWCICxcGmcPalUeHRnyguIsJYej79fFnpKxdjrKhu+spVK69Ke+OW6SXlh7Xk/8b7D5umJKY6nUiQAEmp5ZKoD5Ay8kTFzcAsJIrL+ZREYCWAaU4ubXRNP8wfpuSuGubHMwCJhSuGPCiYJIMw5GV6xkfY0Wd+WoPiBAlEhvnzNluw3SKZYTkQHIQ5J1RQDg7Lw/QQGUIdFp4wcC9KgQ/7KkxjucEHROVmc3ZaCFfEjMxUvlPvBZ0WhT1Q1zG06hQKyGPA9qEh4bPRJuO/0p//WvoPyXpa77BPr9L1mn64QiJRT0vlP3jg1oyn0/th1dnN6VOkQyh8wVRuPpLUH9GHi+sckD4vLaj43NSHLwfv8cKjbGxdgc97JUpFpIRbpovKYHTUltkpHYkyEqNYf1gWfZU+Vn+JiMZERS4qKyTAMv1hmwoItLT/aL6OL9cn8A4mknhDkR5CUuh43ExhAXjnIQVxRQ9UwnU1JM73meHISINzlY/1Ir3jwNQBtui5IpU3K2mFZbEUEhgJiHlZhkqI8rws7hPFxBHlZ5romu1CGRSv2HyQEQiLPkwefJcSk2o0mU+F8Z46KswbKd8qvRUWiq7BsuoYlF/q+Jd839p4/KNnFHhw+Fbc819r/y3dHO7qsk9D2lLPBvEq59SLXC6CYSCq1OTk5F48g+FxLyQSvvyzhFK8taaYL1ACiYdkkSOg/HVO4irmAySLlR8+yHy5wnaWysTF7YmnRxdyecMXFDcxx3KjNCUEGUtb2r4Iixwh5qebxEG58v2Hkh0ERqlLp5kClNLkngLSyF8XExrZi089SYbFm9DRg1FCbEKyoxQE8sqFkTOgTwrDVIPCP/k8qpRcGrxMEXmxnpwjUeXbhjpgA2bBNsp0HPQWOiwNOnddw5YcNIdSFyzTlUKehEbrLDxDNn7osjCXPw5FO22qgPfKHn/pf8XxxxetvSvYlX8BxBVKCdGDmPPDhz0W+Oijjxof//jHt+Hh2oko/qKqFx4l0BJQmQIwS3RNn/fxZXqGFbq4nQzimI9tKFs+S1S1KJ9XoQkEfUQwtKg98fSzefMMwmx5F28/IqK2RLjM2b54/gX0H0v6+IiDZSVgHJogfYWNzDMUpCtsUkKg4pKIUJAsnNTlkjNWzfBCPMOhi8JAiCSqPBmyMFVQ1OdctQwLywNZ5cPCpDl80D6IhjzBASQF0sUeREpSJCyE4ceSpJXbEO2612AHepaTSRn/YrtEAD3n8xV/ntv4+S96nyGRO9gccQZmEPiBK3bRi5kPHcG+v2T32n2+53bxNY8oQyWIB0SR9OmqxMeTh5lm/8azx8srEbCQNSqTpUTX+eagwCiPqiWeQAXO/olHV2tPaYUFjWCxsQJjt7MV564K6iOB2Xj1adNGa3PqDMFl4XwSSnAQCUIibqFPlwtTwbiOkoSR+JvLx3KYv9BXaSrlLyifSegQBNMFTAWhiIeFArRZnoX+8Y2EzKhbnuNlYO9wFpZXkwoH5Kmj/6qOFTz+0n8+Y4Y/2pVIcJqY35+YJ6wjEN33ZzL9kPY3hWjx6Sv+RcByLIQAZZYQJSn2C944FRF/QkvjQ31XZDcV04GVPOGl+WdJEhVGbaNPV3d7Va7ZP83U/1ACgzTjkg4gjUFvHhGWkrPAPnnBLNeFSEKKfAbzOu9yBAUdVj6cZURpZuU3XOUILioD93x2IEnxxFGc9c6M+M93cHSNZVzHquBQDeMn4x898wQ2us7pgGvAbyU8/z5e5EupVEqtJirCgp4KHxVI7sbrQIYKHyKF3+yvIvEEX8FsQNk9qXwgBpgQwNo7p9OKrukzfdzF08+WTmYrV35YF+tU8bEpYImInGtLVH+8PkzZ8iQcVpjrawXCLOHH5uo/9JmWjbXHJMQcNhVW8bOklbsumnJw7Q+cgtVK2mJxAUNNKKncp54KHuzAwnjCE01B1UIHA1A80ik/IkdIfTj6mE8MXh2sSKZhdHUd+IcDykwFLj4eMv7Fv+il75c8/xEmeHaojD+jZ4LgbsPVVvO5iutg4oSAFCCiAqVp/jrUKRU8mzVexsube05ff3tiD0Q1wkP/ojrYgeiaftiheHsjLKL4GrudTxYvb0H9h94bpzeAwCD4cAqJf5SmlBjFH5D8ChVC1Q8KyIkrjtgbE64y4lqtINJHel5Hq4q4ZdsYzsWBWaU+rkFWtFzQbiNNnWciNbT/qD4+Hitq/FdE/3mWzmvQU+W4hZZPenQuRHRNfylcvfVjpUqz0Tj6dNE1/fm4euufTx1z5am3/hr6z6lj9A9ElneKwPJ3IYEVEpqKys0YFeUhoDBP4TV/+bjVIkfqKuu8/ixC/+tqR73111V4DYnrrb+G8a+h1tkk9dY/m7MxV7XUzwdP3ApBgCYG6Co+L6/+kcB4X0g0ERFFzwXjojBc5q8ZhqOKtWEoROmLEwSWBIHowVySyqSS5kIABEYhisRFEov8SgRWGD6K9OMgq8IwBIkTBBYXASGsxcW3pUoHgfF5iIiLPv9x+03kuLxMqaqsUj1KJL4gsFgICGEtFrJtUG6OwDhtJHHhqLOl+dBAG0AnXRAEBAFBQBAQBAQBQUAQEAQEAUFAEBAEBAFBQBAQBAQBQUAQEAQEAUFAEBAEBAFBQBAQBAQBQUAQEAQEAUFAEBAEBAFBQBAQBAQBQUAQEAQEAUFAEBAEBAFBQBAQBAQBQUAQEAQEAUFAEBAEBAFBQBAQBAQBQUAQEAQEAUFAEBAEBAFBQBAQBAQBQUAQEAQEAUFAEBAEBAFBQBAQBAQBQUAQEAQEAUFAEBAEBAFBQBAQBAQBQUAQEAQEAUFAEBAEBAFBQBAQBAQBQUAQEAQEAUFAEBAEBAFBQBAQBAQBQUAQEAQEAUFAEBAEBAFBQBAQBAQBQUAQEAQEAUFAEBAEBAFBQBAQBAQBQUAQEAQEAUFAEBAEBAFBQBAQBAQBQUAQEAQEAUFAEBAEBAFBQBAQBAQBQUAQEAQEAUFAEBAEBAFBQBAQBAQBQUAQEAQEAUFAEBAEBAFBQBAQBAQBQUAQEAQEAUFAEBAEBAFBQBAQBAQBQUAQEAQEAUFAEBAEBAFBQBAQBAQBQUAQEAQEAUFAEBAEBAFBQBAQBAQBQUAQEAQEAUFAEBAEBAFBQBAQBAQBQUAQEAQEAUFAEBAEBAFBQBAQBAQBQUAQEAQEAUFAEBAEBAFBQBAQBAQBQUAQEAQEAUFAEBAEBAFBQBAQBAQBQUAQEAQEAUFAEBAEBAFBQBAQBAQBQUAQEAQEAUFAEBAEBIGVhMD/D0fV/fpMMM+gAAAAAElFTkSuQmCC'
+ }
+
+}
diff --git a/uni_modules/uview-ui/libs/config/props/noticeBar.js b/uni_modules/uview-ui/libs/config/props/noticeBar.js
new file mode 100644
index 0000000..02c660a
--- /dev/null
+++ b/uni_modules/uview-ui/libs/config/props/noticeBar.js
@@ -0,0 +1,27 @@
+/*
+ * @Author : LQ
+ * @Description :
+ * @version : 1.0
+ * @Date : 2021-08-20 16:44:21
+ * @LastAuthor : LQ
+ * @lastTime : 2021-08-20 17:17:13
+ * @FilePath : /u-view2.0/uview-ui/libs/config/props/noticeBar.js
+ */
+export default {
+ // noticeBar
+ noticeBar: {
+ text: () => [],
+ direction: 'row',
+ step: false,
+ icon: 'volume',
+ mode: '',
+ color: '#f9ae3d',
+ bgColor: '#fdf6ec',
+ speed: 80,
+ fontSize: 14,
+ duration: 2000,
+ disableTouch: true,
+ url: '',
+ linkType: 'navigateTo'
+ }
+}
diff --git a/uni_modules/uview-ui/libs/config/props/notify.js b/uni_modules/uview-ui/libs/config/props/notify.js
new file mode 100644
index 0000000..1042d2a
--- /dev/null
+++ b/uni_modules/uview-ui/libs/config/props/notify.js
@@ -0,0 +1,22 @@
+/*
+ * @Author : LQ
+ * @Description :
+ * @version : 1.0
+ * @Date : 2021-08-20 16:44:21
+ * @LastAuthor : LQ
+ * @lastTime : 2021-08-20 17:10:21
+ * @FilePath : /u-view2.0/uview-ui/libs/config/props/notify.js
+ */
+export default {
+ // notify������
+ notify: {
+ top: 0,
+ type: 'primary',
+ color: '#ffffff',
+ bgColor: '',
+ message: '',
+ duration: 3000,
+ fontSize: 15,
+ safeAreaInsetTop: false
+ }
+}
diff --git a/uni_modules/uview-ui/libs/config/props/numberBox.js b/uni_modules/uview-ui/libs/config/props/numberBox.js
new file mode 100644
index 0000000..424f0ca
--- /dev/null
+++ b/uni_modules/uview-ui/libs/config/props/numberBox.js
@@ -0,0 +1,35 @@
+/*
+ * @Author : LQ
+ * @Description :
+ * @version : 1.0
+ * @Date : 2021-08-20 16:44:21
+ * @LastAuthor : LQ
+ * @lastTime : 2021-08-20 17:11:46
+ * @FilePath : /u-view2.0/uview-ui/libs/config/props/numberBox.js
+ */
+export default {
+ // ���������������
+ numberBox: {
+ name: '',
+ value: 0,
+ min: 1,
+ max: Number.MAX_SAFE_INTEGER,
+ step: 1,
+ integer: false,
+ disabled: false,
+ disabledInput: false,
+ asyncChange: false,
+ inputWidth: 35,
+ showMinus: true,
+ showPlus: true,
+ decimalLength: null,
+ longPress: true,
+ color: '#323233',
+ buttonSize: 30,
+ bgColor: '#EBECEE',
+ cursorSpacing: 100,
+ disableMinus: false,
+ disablePlus: false,
+ iconStyle: ''
+ }
+}
diff --git a/uni_modules/uview-ui/libs/config/props/numberKeyboard.js b/uni_modules/uview-ui/libs/config/props/numberKeyboard.js
new file mode 100644
index 0000000..7b45065
--- /dev/null
+++ b/uni_modules/uview-ui/libs/config/props/numberKeyboard.js
@@ -0,0 +1,17 @@
+/*
+ * @Author : LQ
+ * @Description :
+ * @version : 1.0
+ * @Date : 2021-08-20 16:44:21
+ * @LastAuthor : LQ
+ * @lastTime : 2021-08-20 17:08:05
+ * @FilePath : /u-view2.0/uview-ui/libs/config/props/numberKeyboard.js
+ */
+export default {
+ // ������������
+ numberKeyboard: {
+ mode: 'number',
+ dotDisabled: false,
+ random: false
+ }
+}
diff --git a/uni_modules/uview-ui/libs/config/props/overlay.js b/uni_modules/uview-ui/libs/config/props/overlay.js
new file mode 100644
index 0000000..c26d068
--- /dev/null
+++ b/uni_modules/uview-ui/libs/config/props/overlay.js
@@ -0,0 +1,18 @@
+/*
+ * @Author : LQ
+ * @Description :
+ * @version : 1.0
+ * @Date : 2021-08-20 16:44:21
+ * @LastAuthor : LQ
+ * @lastTime : 2021-08-20 17:06:50
+ * @FilePath : /u-view2.0/uview-ui/libs/config/props/overlay.js
+ */
+export default {
+ // overlay������
+ overlay: {
+ show: false,
+ zIndex: 10070,
+ duration: 300,
+ opacity: 0.5
+ }
+}
diff --git a/uni_modules/uview-ui/libs/config/props/parse.js b/uni_modules/uview-ui/libs/config/props/parse.js
new file mode 100644
index 0000000..feb22b9
--- /dev/null
+++ b/uni_modules/uview-ui/libs/config/props/parse.js
@@ -0,0 +1,22 @@
+/*
+ * @Author : LQ
+ * @Description :
+ * @version : 1.0
+ * @Date : 2021-08-20 16:44:21
+ * @LastAuthor : LQ
+ * @lastTime : 2021-08-20 17:17:33
+ * @FilePath : /u-view2.0/uview-ui/libs/config/props/parse.js
+ */
+export default {
+ // parse
+ parse: {
+ copyLink: true,
+ errorImg: '',
+ lazyLoad: false,
+ loadingImg: '',
+ pauseVideo: true,
+ previewImg: true,
+ setTitle: true,
+ showImgMenu: true
+ }
+}
diff --git a/uni_modules/uview-ui/libs/config/props/picker.js b/uni_modules/uview-ui/libs/config/props/picker.js
new file mode 100644
index 0000000..f06b321
--- /dev/null
+++ b/uni_modules/uview-ui/libs/config/props/picker.js
@@ -0,0 +1,29 @@
+/*
+ * @Author : LQ
+ * @Description :
+ * @version : 1.0
+ * @Date : 2021-08-20 16:44:21
+ * @LastAuthor : LQ
+ * @lastTime : 2021-08-20 17:18:20
+ * @FilePath : /u-view2.0/uview-ui/libs/config/props/picker.js
+ */
+export default {
+ // picker
+ picker: {
+ show: false,
+ showToolbar: true,
+ title: '',
+ columns: () => [],
+ loading: false,
+ itemHeight: 44,
+ cancelText: '������',
+ confirmText: '������',
+ cancelColor: '#909193',
+ confirmColor: '#3c9cff',
+ visibleItemCount: 5,
+ keyName: 'text',
+ closeOnClickOverlay: false,
+ defaultIndex: () => [],
+ immediateChange: false
+ }
+}
diff --git a/uni_modules/uview-ui/libs/config/props/popup.js b/uni_modules/uview-ui/libs/config/props/popup.js
new file mode 100644
index 0000000..0cc1bc0
--- /dev/null
+++ b/uni_modules/uview-ui/libs/config/props/popup.js
@@ -0,0 +1,29 @@
+/*
+ * @Author : LQ
+ * @Description :
+ * @version : 1.0
+ * @Date : 2021-08-20 16:44:21
+ * @LastAuthor : LQ
+ * @lastTime : 2021-08-20 17:06:33
+ * @FilePath : /u-view2.0/uview-ui/libs/config/props/popup.js
+ */
+export default {
+ // popup������
+ popup: {
+ show: false,
+ overlay: true,
+ mode: 'bottom',
+ duration: 300,
+ closeable: false,
+ overlayStyle: () => {},
+ closeOnClickOverlay: true,
+ zIndex: 10075,
+ safeAreaInsetBottom: true,
+ safeAreaInsetTop: false,
+ closeIconPos: 'top-right',
+ round: 0,
+ zoom: true,
+ bgColor: '',
+ overlayOpacity: 0.5
+ }
+}
diff --git a/uni_modules/uview-ui/libs/config/props/radio.js b/uni_modules/uview-ui/libs/config/props/radio.js
new file mode 100644
index 0000000..4df200f
--- /dev/null
+++ b/uni_modules/uview-ui/libs/config/props/radio.js
@@ -0,0 +1,27 @@
+/*
+ * @Author : LQ
+ * @Description :
+ * @version : 1.0
+ * @Date : 2021-08-20 16:44:21
+ * @LastAuthor : LQ
+ * @lastTime : 2021-08-20 17:02:34
+ * @FilePath : /u-view2.0/uview-ui/libs/config/props/radio.js
+ */
+export default {
+ // radio������
+ radio: {
+ name: '',
+ shape: '',
+ disabled: '',
+ labelDisabled: '',
+ activeColor: '',
+ inactiveColor: '',
+ iconSize: '',
+ labelSize: '',
+ label: '',
+ labelColor: '',
+ size: '',
+ iconColor: '',
+ placement: ''
+ }
+}
diff --git a/uni_modules/uview-ui/libs/config/props/radioGroup.js b/uni_modules/uview-ui/libs/config/props/radioGroup.js
new file mode 100644
index 0000000..728e9db
--- /dev/null
+++ b/uni_modules/uview-ui/libs/config/props/radioGroup.js
@@ -0,0 +1,30 @@
+/*
+ * @Author : LQ
+ * @Description :
+ * @version : 1.0
+ * @Date : 2021-08-20 16:44:21
+ * @LastAuthor : LQ
+ * @lastTime : 2021-08-20 17:03:12
+ * @FilePath : /u-view2.0/uview-ui/libs/config/props/radioGroup.js
+ */
+export default {
+ // radio-group������
+ radioGroup: {
+ value: '',
+ disabled: false,
+ shape: 'circle',
+ activeColor: '#2979ff',
+ inactiveColor: '#c8c9cc',
+ name: '',
+ size: 18,
+ placement: 'row',
+ label: '',
+ labelColor: '#303133',
+ labelSize: 14,
+ labelDisabled: false,
+ iconColor: '#ffffff',
+ iconSize: 12,
+ borderBottom: false,
+ iconPlacement: 'left'
+ }
+}
diff --git a/uni_modules/uview-ui/libs/config/props/rate.js b/uni_modules/uview-ui/libs/config/props/rate.js
new file mode 100644
index 0000000..d31c61a
--- /dev/null
+++ b/uni_modules/uview-ui/libs/config/props/rate.js
@@ -0,0 +1,26 @@
+/*
+ * @Author : LQ
+ * @Description :
+ * @version : 1.0
+ * @Date : 2021-08-20 16:44:21
+ * @LastAuthor : LQ
+ * @lastTime : 2021-08-20 17:05:09
+ * @FilePath : /u-view2.0/uview-ui/libs/config/props/rate.js
+ */
+export default {
+ // rate������
+ rate: {
+ value: 1,
+ count: 5,
+ disabled: false,
+ size: 18,
+ inactiveColor: '#b2b2b2',
+ activeColor: '#FA3534',
+ gutter: 4,
+ minCount: 1,
+ allowHalf: false,
+ activeIcon: 'star-fill',
+ inactiveIcon: 'star',
+ touchable: true
+ }
+}
diff --git a/uni_modules/uview-ui/libs/config/props/readMore.js b/uni_modules/uview-ui/libs/config/props/readMore.js
new file mode 100644
index 0000000..09b11cc
--- /dev/null
+++ b/uni_modules/uview-ui/libs/config/props/readMore.js
@@ -0,0 +1,22 @@
+/*
+ * @Author : LQ
+ * @Description :
+ * @version : 1.0
+ * @Date : 2021-08-20 16:44:21
+ * @LastAuthor : LQ
+ * @lastTime : 2021-08-20 17:18:41
+ * @FilePath : /u-view2.0/uview-ui/libs/config/props/readMore.js
+ */
+export default {
+ // readMore
+ readMore: {
+ showHeight: 400,
+ toggle: false,
+ closeText: '������������������',
+ openText: '������',
+ color: '#2979ff',
+ fontSize: 14,
+ textIndent: '2em',
+ name: ''
+ }
+}
diff --git a/uni_modules/uview-ui/libs/config/props/row.js b/uni_modules/uview-ui/libs/config/props/row.js
new file mode 100644
index 0000000..573a431
--- /dev/null
+++ b/uni_modules/uview-ui/libs/config/props/row.js
@@ -0,0 +1,17 @@
+/*
+ * @Author : LQ
+ * @Description :
+ * @version : 1.0
+ * @Date : 2021-08-20 16:44:21
+ * @LastAuthor : LQ
+ * @lastTime : 2021-08-20 17:18:58
+ * @FilePath : /u-view2.0/uview-ui/libs/config/props/row.js
+ */
+export default {
+ // row
+ row: {
+ gutter: 0,
+ justify: 'start',
+ align: 'center'
+ }
+}
diff --git a/uni_modules/uview-ui/libs/config/props/rowNotice.js b/uni_modules/uview-ui/libs/config/props/rowNotice.js
new file mode 100644
index 0000000..cd9d0a0
--- /dev/null
+++ b/uni_modules/uview-ui/libs/config/props/rowNotice.js
@@ -0,0 +1,21 @@
+/*
+ * @Author : LQ
+ * @Description :
+ * @version : 1.0
+ * @Date : 2021-08-20 16:44:21
+ * @LastAuthor : LQ
+ * @lastTime : 2021-08-20 17:19:13
+ * @FilePath : /u-view2.0/uview-ui/libs/config/props/rowNotice.js
+ */
+export default {
+ // rowNotice
+ rowNotice: {
+ text: '',
+ icon: 'volume',
+ mode: '',
+ color: '#f9ae3d',
+ bgColor: '#fdf6ec',
+ fontSize: 14,
+ speed: 80
+ }
+}
diff --git a/uni_modules/uview-ui/libs/config/props/scrollList.js b/uni_modules/uview-ui/libs/config/props/scrollList.js
new file mode 100644
index 0000000..441e63a
--- /dev/null
+++ b/uni_modules/uview-ui/libs/config/props/scrollList.js
@@ -0,0 +1,20 @@
+/*
+ * @Author : LQ
+ * @Description :
+ * @version : 1.0
+ * @Date : 2021-08-20 16:44:21
+ * @LastAuthor : LQ
+ * @lastTime : 2021-08-20 17:19:28
+ * @FilePath : /u-view2.0/uview-ui/libs/config/props/scrollList.js
+ */
+export default {
+ // scrollList
+ scrollList: {
+ indicatorWidth: 50,
+ indicatorBarWidth: 20,
+ indicator: true,
+ indicatorColor: '#f2f2f2',
+ indicatorActiveColor: '#3c9cff',
+ indicatorStyle: ''
+ }
+}
diff --git a/uni_modules/uview-ui/libs/config/props/search.js b/uni_modules/uview-ui/libs/config/props/search.js
new file mode 100644
index 0000000..2699954
--- /dev/null
+++ b/uni_modules/uview-ui/libs/config/props/search.js
@@ -0,0 +1,37 @@
+/*
+ * @Author : LQ
+ * @Description :
+ * @version : 1.0
+ * @Date : 2021-08-20 16:44:21
+ * @LastAuthor : LQ
+ * @lastTime : 2021-08-20 17:19:45
+ * @FilePath : /u-view2.0/uview-ui/libs/config/props/search.js
+ */
+export default {
+ // search
+ search: {
+ shape: 'round',
+ bgColor: '#f2f2f2',
+ placeholder: '������������������',
+ clearabled: true,
+ focus: false,
+ showAction: true,
+ actionStyle: () => ({}),
+ actionText: '������',
+ inputAlign: 'left',
+ inputStyle: () => ({}),
+ disabled: false,
+ borderColor: 'transparent',
+ searchIconColor: '#909399',
+ searchIconSize: 22,
+ color: '#606266',
+ placeholderColor: '#909399',
+ searchIcon: 'search',
+ margin: '0',
+ animation: false,
+ value: '',
+ maxlength: '-1',
+ height: 32,
+ label: null
+ }
+}
diff --git a/uni_modules/uview-ui/libs/config/props/section.js b/uni_modules/uview-ui/libs/config/props/section.js
new file mode 100644
index 0000000..f432648
--- /dev/null
+++ b/uni_modules/uview-ui/libs/config/props/section.js
@@ -0,0 +1,24 @@
+/*
+ * @Author : LQ
+ * @Description :
+ * @version : 1.0
+ * @Date : 2021-08-20 16:44:21
+ * @LastAuthor : LQ
+ * @lastTime : 2021-08-20 17:07:33
+ * @FilePath : /u-view2.0/uview-ui/libs/config/props/section.js
+ */
+export default {
+ // u-section������
+ section: {
+ title: '',
+ subTitle: '������',
+ right: true,
+ fontSize: 15,
+ bold: true,
+ color: '#303133',
+ subColor: '#909399',
+ showLine: true,
+ lineColor: '',
+ arrow: true
+ }
+}
diff --git a/uni_modules/uview-ui/libs/config/props/skeleton.js b/uni_modules/uview-ui/libs/config/props/skeleton.js
new file mode 100644
index 0000000..83b777d
--- /dev/null
+++ b/uni_modules/uview-ui/libs/config/props/skeleton.js
@@ -0,0 +1,25 @@
+/*
+ * @Author : LQ
+ * @Description :
+ * @version : 1.0
+ * @Date : 2021-08-20 16:44:21
+ * @LastAuthor : LQ
+ * @lastTime : 2021-08-20 17:20:14
+ * @FilePath : /u-view2.0/uview-ui/libs/config/props/skeleton.js
+ */
+export default {
+ // skeleton
+ skeleton: {
+ loading: true,
+ animate: true,
+ rows: 0,
+ rowsWidth: '100%',
+ rowsHeight: 18,
+ title: true,
+ titleWidth: '50%',
+ titleHeight: 18,
+ avatar: false,
+ avatarSize: 32,
+ avatarShape: 'circle'
+ }
+}
diff --git a/uni_modules/uview-ui/libs/config/props/slider.js b/uni_modules/uview-ui/libs/config/props/slider.js
new file mode 100644
index 0000000..50cc37f
--- /dev/null
+++ b/uni_modules/uview-ui/libs/config/props/slider.js
@@ -0,0 +1,25 @@
+/*
+ * @Author : LQ
+ * @Description :
+ * @version : 1.0
+ * @Date : 2021-08-20 16:44:21
+ * @LastAuthor : LQ
+ * @lastTime : 2021-08-20 17:08:25
+ * @FilePath : /u-view2.0/uview-ui/libs/config/props/slider.js
+ */
+export default {
+ // slider������
+ slider: {
+ value: 0,
+ blockSize: 18,
+ min: 0,
+ max: 100,
+ step: 1,
+ activeColor: '#2979ff',
+ inactiveColor: '#c0c4cc',
+ blockColor: '#ffffff',
+ showValue: false,
+ disabled:false,
+ blockStyle: () => {}
+ }
+}
diff --git a/uni_modules/uview-ui/libs/config/props/statusBar.js b/uni_modules/uview-ui/libs/config/props/statusBar.js
new file mode 100644
index 0000000..d237a83
--- /dev/null
+++ b/uni_modules/uview-ui/libs/config/props/statusBar.js
@@ -0,0 +1,15 @@
+/*
+ * @Author : LQ
+ * @Description :
+ * @version : 1.0
+ * @Date : 2021-08-20 16:44:21
+ * @LastAuthor : LQ
+ * @lastTime : 2021-08-20 17:20:39
+ * @FilePath : /u-view2.0/uview-ui/libs/config/props/statusBar.js
+ */
+export default {
+ // statusBar
+ statusBar: {
+ bgColor: 'transparent'
+ }
+}
diff --git a/uni_modules/uview-ui/libs/config/props/steps.js b/uni_modules/uview-ui/libs/config/props/steps.js
new file mode 100644
index 0000000..881c39e
--- /dev/null
+++ b/uni_modules/uview-ui/libs/config/props/steps.js
@@ -0,0 +1,21 @@
+/*
+ * @Author : LQ
+ * @Description :
+ * @version : 1.0
+ * @Date : 2021-08-20 16:44:21
+ * @LastAuthor : LQ
+ * @lastTime : 2021-08-20 17:12:37
+ * @FilePath : /u-view2.0/uview-ui/libs/config/props/steps.js
+ */
+export default {
+ // steps������
+ steps: {
+ direction: 'row',
+ current: 0,
+ activeColor: '#3c9cff',
+ inactiveColor: '#969799',
+ activeIcon: '',
+ inactiveIcon: '',
+ dot: false
+ }
+}
diff --git a/uni_modules/uview-ui/libs/config/props/stepsItem.js b/uni_modules/uview-ui/libs/config/props/stepsItem.js
new file mode 100644
index 0000000..5dba8f4
--- /dev/null
+++ b/uni_modules/uview-ui/libs/config/props/stepsItem.js
@@ -0,0 +1,18 @@
+/*
+ * @Author : LQ
+ * @Description :
+ * @version : 1.0
+ * @Date : 2021-08-20 16:44:21
+ * @LastAuthor : LQ
+ * @lastTime : 2021-08-20 17:12:55
+ * @FilePath : /u-view2.0/uview-ui/libs/config/props/stepsItem.js
+ */
+export default {
+ // steps-item������
+ stepsItem: {
+ title: '',
+ desc: '',
+ iconSize: 17,
+ error: false
+ }
+}
diff --git a/uni_modules/uview-ui/libs/config/props/sticky.js b/uni_modules/uview-ui/libs/config/props/sticky.js
new file mode 100644
index 0000000..b034604
--- /dev/null
+++ b/uni_modules/uview-ui/libs/config/props/sticky.js
@@ -0,0 +1,20 @@
+/*
+ * @Author : LQ
+ * @Description :
+ * @version : 1.0
+ * @Date : 2021-08-20 16:44:21
+ * @LastAuthor : LQ
+ * @lastTime : 2021-08-20 17:01:30
+ * @FilePath : /u-view2.0/uview-ui/libs/config/props/sticky.js
+ */
+export default {
+ // sticky������
+ sticky: {
+ offsetTop: 0,
+ customNavHeight: 0,
+ disabled: false,
+ bgColor: 'transparent',
+ zIndex: '',
+ index: ''
+ }
+}
diff --git a/uni_modules/uview-ui/libs/config/props/subsection.js b/uni_modules/uview-ui/libs/config/props/subsection.js
new file mode 100644
index 0000000..9a165ff
--- /dev/null
+++ b/uni_modules/uview-ui/libs/config/props/subsection.js
@@ -0,0 +1,23 @@
+/*
+ * @Author : LQ
+ * @Description :
+ * @version : 1.0
+ * @Date : 2021-08-20 16:44:21
+ * @LastAuthor : LQ
+ * @lastTime : 2021-08-20 17:12:20
+ * @FilePath : /u-view2.0/uview-ui/libs/config/props/subsection.js
+ */
+export default {
+ // subsection������
+ subsection: {
+ list: [],
+ current: 0,
+ activeColor: '#3c9cff',
+ inactiveColor: '#303133',
+ mode: 'button',
+ fontSize: 12,
+ bold: true,
+ bgColor: '#eeeeef',
+ keyName: 'name'
+ }
+}
diff --git a/uni_modules/uview-ui/libs/config/props/swipeAction.js b/uni_modules/uview-ui/libs/config/props/swipeAction.js
new file mode 100644
index 0000000..25051b8
--- /dev/null
+++ b/uni_modules/uview-ui/libs/config/props/swipeAction.js
@@ -0,0 +1,15 @@
+/*
+ * @Author : LQ
+ * @Description :
+ * @version : 1.0
+ * @Date : 2021-08-20 16:44:21
+ * @LastAuthor : LQ
+ * @lastTime : 2021-08-20 17:00:42
+ * @FilePath : /u-view2.0/uview-ui/libs/config/props/swipeAction.js
+ */
+export default {
+ // swipe-action������
+ swipeAction: {
+ autoClose: true
+ }
+}
diff --git a/uni_modules/uview-ui/libs/config/props/swipeActionItem.js b/uni_modules/uview-ui/libs/config/props/swipeActionItem.js
new file mode 100644
index 0000000..40ef27c
--- /dev/null
+++ b/uni_modules/uview-ui/libs/config/props/swipeActionItem.js
@@ -0,0 +1,21 @@
+/*
+ * @Author : LQ
+ * @Description :
+ * @version : 1.0
+ * @Date : 2021-08-20 16:44:21
+ * @LastAuthor : LQ
+ * @lastTime : 2021-08-20 17:01:13
+ * @FilePath : /u-view2.0/uview-ui/libs/config/props/swipeActionItem.js
+ */
+export default {
+ // swipeActionItem ������
+ swipeActionItem: {
+ show: false,
+ name: '',
+ disabled: false,
+ threshold: 20,
+ autoClose: true,
+ options: [],
+ duration: 300
+ }
+}
diff --git a/uni_modules/uview-ui/libs/config/props/swiper.js b/uni_modules/uview-ui/libs/config/props/swiper.js
new file mode 100644
index 0000000..0e6a3b7
--- /dev/null
+++ b/uni_modules/uview-ui/libs/config/props/swiper.js
@@ -0,0 +1,39 @@
+/*
+ * @Author : LQ
+ * @Description :
+ * @version : 1.0
+ * @Date : 2021-08-20 16:44:21
+ * @LastAuthor : LQ
+ * @lastTime : 2021-08-20 17:21:38
+ * @FilePath : /u-view2.0/uview-ui/libs/config/props/swiper.js
+ */
+export default {
+ // swiper ������
+ swiper: {
+ list: () => [],
+ indicator: false,
+ indicatorActiveColor: '#FFFFFF',
+ indicatorInactiveColor: 'rgba(255, 255, 255, 0.35)',
+ indicatorStyle: '',
+ indicatorMode: 'line',
+ autoplay: true,
+ current: 0,
+ currentItemId: '',
+ interval: 3000,
+ duration: 300,
+ circular: false,
+ previousMargin: 0,
+ nextMargin: 0,
+ acceleration: false,
+ displayMultipleItems: 1,
+ easingFunction: 'default',
+ keyName: 'url',
+ imgMode: 'aspectFill',
+ height: 130,
+ bgColor: '#f3f4f6',
+ radius: 4,
+ loading: false,
+ showTitle: false
+ }
+
+}
diff --git a/uni_modules/uview-ui/libs/config/props/swipterIndicator.js b/uni_modules/uview-ui/libs/config/props/swipterIndicator.js
new file mode 100644
index 0000000..4b59e6e
--- /dev/null
+++ b/uni_modules/uview-ui/libs/config/props/swipterIndicator.js
@@ -0,0 +1,19 @@
+/*
+ * @Author : LQ
+ * @Description :
+ * @version : 1.0
+ * @Date : 2021-08-20 16:44:21
+ * @LastAuthor : LQ
+ * @lastTime : 2021-08-20 17:22:07
+ * @FilePath : /u-view2.0/uview-ui/libs/config/props/swiperIndicator.js
+ */
+export default {
+ // swiperIndicator ������
+ swiperIndicator: {
+ length: 0,
+ current: 0,
+ indicatorActiveColor: '',
+ indicatorInactiveColor: '',
+ indicatorMode: 'line'
+ }
+}
diff --git a/uni_modules/uview-ui/libs/config/props/switch.js b/uni_modules/uview-ui/libs/config/props/switch.js
new file mode 100644
index 0000000..e6400b4
--- /dev/null
+++ b/uni_modules/uview-ui/libs/config/props/switch.js
@@ -0,0 +1,24 @@
+/*
+ * @Author : LQ
+ * @Description :
+ * @version : 1.0
+ * @Date : 2021-08-20 16:44:21
+ * @LastAuthor : LQ
+ * @lastTime : 2021-08-20 17:22:24
+ * @FilePath : /u-view2.0/uview-ui/libs/config/props/switch.js
+ */
+export default {
+ // switch
+ switch: {
+ loading: false,
+ disabled: false,
+ size: 25,
+ activeColor: '#2979ff',
+ inactiveColor: '#ffffff',
+ value: false,
+ activeValue: true,
+ inactiveValue: false,
+ asyncChange: false,
+ space: 0
+ }
+}
diff --git a/uni_modules/uview-ui/libs/config/props/tabbar.js b/uni_modules/uview-ui/libs/config/props/tabbar.js
new file mode 100644
index 0000000..187112d
--- /dev/null
+++ b/uni_modules/uview-ui/libs/config/props/tabbar.js
@@ -0,0 +1,22 @@
+/*
+ * @Author : LQ
+ * @Description :
+ * @version : 1.0
+ * @Date : 2021-08-20 16:44:21
+ * @LastAuthor : LQ
+ * @lastTime : 2021-08-20 17:22:40
+ * @FilePath : /u-view2.0/uview-ui/libs/config/props/tabbar.js
+ */
+export default {
+ // tabbar
+ tabbar: {
+ value: null,
+ safeAreaInsetBottom: true,
+ border: true,
+ zIndex: 1,
+ activeColor: '#1989fa',
+ inactiveColor: '#7d7e80',
+ fixed: true,
+ placeholder: true
+ }
+}
diff --git a/uni_modules/uview-ui/libs/config/props/tabbarItem.js b/uni_modules/uview-ui/libs/config/props/tabbarItem.js
new file mode 100644
index 0000000..d036ce5
--- /dev/null
+++ b/uni_modules/uview-ui/libs/config/props/tabbarItem.js
@@ -0,0 +1,20 @@
+/*
+ * @Author : LQ
+ * @Description :
+ * @version : 1.0
+ * @Date : 2021-08-20 16:44:21
+ * @LastAuthor : LQ
+ * @lastTime : 2021-08-20 17:22:55
+ * @FilePath : /u-view2.0/uview-ui/libs/config/props/tabbarItem.js
+ */
+export default {
+ //
+ tabbarItem: {
+ name: null,
+ icon: '',
+ badge: null,
+ dot: false,
+ text: '',
+ badgeStyle: 'top: 6px;right:2px;'
+ }
+}
diff --git a/uni_modules/uview-ui/libs/config/props/tabs.js b/uni_modules/uview-ui/libs/config/props/tabs.js
new file mode 100644
index 0000000..81c794a
--- /dev/null
+++ b/uni_modules/uview-ui/libs/config/props/tabs.js
@@ -0,0 +1,32 @@
+/*
+ * @Author : LQ
+ * @Description :
+ * @version : 1.0
+ * @Date : 2021-08-20 16:44:21
+ * @LastAuthor : LQ
+ * @lastTime : 2021-08-20 17:23:14
+ * @FilePath : /u-view2.0/uview-ui/libs/config/props/tabs.js
+ */
+export default {
+ //
+ tabs: {
+ duration: 300,
+ list: () => [],
+ lineColor: '#3c9cff',
+ activeStyle: () => ({
+ color: '#303133'
+ }),
+ inactiveStyle: () => ({
+ color: '#606266'
+ }),
+ lineWidth: 20,
+ lineHeight: 3,
+ lineBgSize: 'cover',
+ itemStyle: () => ({
+ height: '44px'
+ }),
+ scrollable: true,
+ current: 0,
+ keyName: 'name'
+ }
+}
diff --git a/uni_modules/uview-ui/libs/config/props/tag.js b/uni_modules/uview-ui/libs/config/props/tag.js
new file mode 100644
index 0000000..125ce94
--- /dev/null
+++ b/uni_modules/uview-ui/libs/config/props/tag.js
@@ -0,0 +1,29 @@
+/*
+ * @Author : LQ
+ * @Description :
+ * @version : 1.0
+ * @Date : 2021-08-20 16:44:21
+ * @LastAuthor : LQ
+ * @lastTime : 2021-08-20 17:23:37
+ * @FilePath : /u-view2.0/uview-ui/libs/config/props/tag.js
+ */
+export default {
+ // tag ������
+ tag: {
+ type: 'primary',
+ disabled: false,
+ size: 'medium',
+ shape: 'square',
+ text: '',
+ bgColor: '',
+ color: '',
+ borderColor: '',
+ closeColor: '#C6C7CB',
+ name: '',
+ plainFill: false,
+ plain: false,
+ closable: false,
+ show: true,
+ icon: ''
+ }
+}
diff --git a/uni_modules/uview-ui/libs/config/props/text.js b/uni_modules/uview-ui/libs/config/props/text.js
new file mode 100644
index 0000000..7e73606
--- /dev/null
+++ b/uni_modules/uview-ui/libs/config/props/text.js
@@ -0,0 +1,38 @@
+/*
+ * @Author : LQ
+ * @Description :
+ * @version : 1.0
+ * @Date : 2021-08-20 16:44:21
+ * @LastAuthor : LQ
+ * @lastTime : 2021-08-20 17:23:58
+ * @FilePath : /u-view2.0/uview-ui/libs/config/props/text.js
+ */
+export default {
+ // text ������
+ text: {
+ type: '',
+ show: true,
+ text: '',
+ prefixIcon: '',
+ suffixIcon: '',
+ mode: '',
+ href: '',
+ format: '',
+ call: false,
+ openType: '',
+ bold: false,
+ block: false,
+ lines: '',
+ color: '#303133',
+ size: 15,
+ iconStyle: () => ({
+ fontSize: '15px'
+ }),
+ decoration: 'none',
+ margin: 0,
+ lineHeight: '',
+ align: 'left',
+ wordWrap: 'normal'
+ }
+
+}
diff --git a/uni_modules/uview-ui/libs/config/props/textarea.js b/uni_modules/uview-ui/libs/config/props/textarea.js
new file mode 100644
index 0000000..44519f9
--- /dev/null
+++ b/uni_modules/uview-ui/libs/config/props/textarea.js
@@ -0,0 +1,36 @@
+/*
+ * @Author : LQ
+ * @Description :
+ * @version : 1.0
+ * @Date : 2021-08-20 16:44:21
+ * @LastAuthor : LQ
+ * @lastTime : 2021-08-20 17:24:32
+ * @FilePath : /u-view2.0/uview-ui/libs/config/props/textarea.js
+ */
+export default {
+ // textarea ������
+ textarea: {
+ value: '',
+ placeholder: '',
+ placeholderClass: 'textarea-placeholder',
+ placeholderStyle: 'color: #c0c4cc',
+ height: 70,
+ confirmType: 'done',
+ disabled: false,
+ count: false,
+ focus: false,
+ autoHeight: false,
+ fixed: false,
+ cursorSpacing: 0,
+ cursor: '',
+ showConfirmBar: true,
+ selectionStart: -1,
+ selectionEnd: -1,
+ adjustPosition: true,
+ disableDefaultPadding: false,
+ holdKeyboard: false,
+ maxlength: 140,
+ border: 'surround',
+ formatter: null
+ }
+}
diff --git a/uni_modules/uview-ui/libs/config/props/toast.js b/uni_modules/uview-ui/libs/config/props/toast.js
new file mode 100644
index 0000000..a50134b
--- /dev/null
+++ b/uni_modules/uview-ui/libs/config/props/toast.js
@@ -0,0 +1,30 @@
+/*
+ * @Author : LQ
+ * @Description :
+ * @version : 1.0
+ * @Date : 2021-08-20 16:44:21
+ * @LastAuthor : LQ
+ * @lastTime : 2021-08-20 17:07:07
+ * @FilePath : /u-view2.0/uview-ui/libs/config/props/toast.js
+ */
+export default {
+ // toast������
+ toast: {
+ zIndex: 10090,
+ loading: false,
+ text: '',
+ icon: '',
+ type: '',
+ loadingMode: '',
+ show: '',
+ overlay: false,
+ position: 'center',
+ params: () => {},
+ duration: 2000,
+ isTab: false,
+ url: '',
+ callback: null,
+ back: false
+ }
+
+}
diff --git a/uni_modules/uview-ui/libs/config/props/toolbar.js b/uni_modules/uview-ui/libs/config/props/toolbar.js
new file mode 100644
index 0000000..3289967
--- /dev/null
+++ b/uni_modules/uview-ui/libs/config/props/toolbar.js
@@ -0,0 +1,21 @@
+/*
+ * @Author : LQ
+ * @Description :
+ * @version : 1.0
+ * @Date : 2021-08-20 16:44:21
+ * @LastAuthor : LQ
+ * @lastTime : 2021-08-20 17:24:55
+ * @FilePath : /u-view2.0/uview-ui/libs/config/props/toolbar.js
+ */
+export default {
+ // toolbar ������
+ toolbar: {
+ show: true,
+ cancelText: '������',
+ confirmText: '������',
+ cancelColor: '#909193',
+ confirmColor: '#3c9cff',
+ title: ''
+ }
+
+}
diff --git a/uni_modules/uview-ui/libs/config/props/tooltip.js b/uni_modules/uview-ui/libs/config/props/tooltip.js
new file mode 100644
index 0000000..115e030
--- /dev/null
+++ b/uni_modules/uview-ui/libs/config/props/tooltip.js
@@ -0,0 +1,25 @@
+/*
+ * @Author : LQ
+ * @Description :
+ * @version : 1.0
+ * @Date : 2021-08-20 16:44:21
+ * @LastAuthor : LQ
+ * @lastTime : 2021-08-20 17:25:14
+ * @FilePath : /u-view2.0/uview-ui/libs/config/props/tooltip.js
+ */
+export default {
+ // tooltip ������
+ tooltip: {
+ text: '',
+ copyText: '',
+ size: 14,
+ color: '#606266',
+ bgColor: 'transparent',
+ direction: 'top',
+ zIndex: 10071,
+ showCopy: true,
+ buttons: () => [],
+ overlay: true,
+ showToast: true
+ }
+}
diff --git a/uni_modules/uview-ui/libs/config/props/transition.js b/uni_modules/uview-ui/libs/config/props/transition.js
new file mode 100644
index 0000000..0fad118
--- /dev/null
+++ b/uni_modules/uview-ui/libs/config/props/transition.js
@@ -0,0 +1,18 @@
+/*
+ * @Author : LQ
+ * @Description :
+ * @version : 1.0
+ * @Date : 2021-08-20 16:44:21
+ * @LastAuthor : LQ
+ * @lastTime : 2021-08-20 16:59:00
+ * @FilePath : /u-view2.0/uview-ui/libs/config/props/transition.js
+ */
+export default {
+ // transition���������������props
+ transition: {
+ show: false,
+ mode: 'fade',
+ duration: '300',
+ timingFunction: 'ease-out'
+ }
+}
diff --git a/uni_modules/uview-ui/libs/config/props/upload.js b/uni_modules/uview-ui/libs/config/props/upload.js
new file mode 100644
index 0000000..fc7ca92
--- /dev/null
+++ b/uni_modules/uview-ui/libs/config/props/upload.js
@@ -0,0 +1,36 @@
+/*
+ * @Author : LQ
+ * @Description :
+ * @version : 1.0
+ * @Date : 2021-08-20 16:44:21
+ * @LastAuthor : LQ
+ * @lastTime : 2021-08-20 17:09:50
+ * @FilePath : /u-view2.0/uview-ui/libs/config/props/upload.js
+ */
+export default {
+ // upload������
+ upload: {
+ accept: 'image',
+ capture: () => ['album', 'camera'],
+ compressed: true,
+ camera: 'back',
+ maxDuration: 60,
+ uploadIcon: 'camera-fill',
+ uploadIconColor: '#D3D4D6',
+ useBeforeRead: false,
+ previewFullImage: true,
+ maxCount: 52,
+ disabled: false,
+ imageMode: 'aspectFill',
+ name: '',
+ sizeType: () => ['original', 'compressed'],
+ multiple: false,
+ deletable: true,
+ maxSize: Number.MAX_VALUE,
+ fileList: () => [],
+ uploadText: '',
+ width: 80,
+ height: 80,
+ previewImage: true
+ }
+}
diff --git a/uni_modules/uview-ui/libs/config/zIndex.js b/uni_modules/uview-ui/libs/config/zIndex.js
new file mode 100644
index 0000000..5fc3682
--- /dev/null
+++ b/uni_modules/uview-ui/libs/config/zIndex.js
@@ -0,0 +1,20 @@
+// uniapp���H5������API���z-index������������
+/**
+ * actionsheet: 999
+ * modal: 999
+ * navigate: 998
+ * tabbar: 998
+ * toast: 999
+ */
+
+export default {
+ toast: 10090,
+ noNetwork: 10080,
+ // popup������popup���actionsheet���keyboard���picker������
+ popup: 10075,
+ mask: 10070,
+ navbar: 980,
+ topTips: 975,
+ sticky: 970,
+ indexListSticky: 965
+}
diff --git a/uni_modules/uview-ui/libs/css/color.scss b/uni_modules/uview-ui/libs/css/color.scss
new file mode 100644
index 0000000..3237ba4
--- /dev/null
+++ b/uni_modules/uview-ui/libs/css/color.scss
@@ -0,0 +1,155 @@
+.u-primary-light {
+ color: $u-primary-light;
+}
+
+.u-warning-light {
+ color: $u-warning-light;
+}
+
+.u-success-light {
+ color: $u-success-light;
+}
+
+.u-error-light {
+ color: $u-error-light;
+}
+
+.u-info-light {
+ color: $u-info-light;
+}
+
+.u-primary-light-bg {
+ background-color: $u-primary-light;
+}
+
+.u-warning-light-bg {
+ background-color: $u-warning-light;
+}
+
+.u-success-light-bg {
+ background-color: $u-success-light;
+}
+
+.u-error-light-bg {
+ background-color: $u-error-light;
+}
+
+.u-info-light-bg {
+ background-color: $u-info-light;
+}
+
+.u-primary-dark {
+ color: $u-primary-dark;
+}
+
+.u-warning-dark {
+ color: $u-warning-dark;
+}
+
+.u-success-dark {
+ color: $u-success-dark;
+}
+
+.u-error-dark {
+ color: $u-error-dark;
+}
+
+.u-info-dark {
+ color: $u-info-dark;
+}
+
+.u-primary-dark-bg {
+ background-color: $u-primary-dark;
+}
+
+.u-warning-dark-bg {
+ background-color: $u-warning-dark;
+}
+
+.u-success-dark-bg {
+ background-color: $u-success-dark;
+}
+
+.u-error-dark-bg {
+ background-color: $u-error-dark;
+}
+
+.u-info-dark-bg {
+ background-color: $u-info-dark;
+}
+
+.u-primary-disabled {
+ color: $u-primary-disabled;
+}
+
+.u-warning-disabled {
+ color: $u-warning-disabled;
+}
+
+.u-success-disabled {
+ color: $u-success-disabled;
+}
+
+.u-error-disabled {
+ color: $u-error-disabled;
+}
+
+.u-info-disabled {
+ color: $u-info-disabled;
+}
+
+.u-primary {
+ color: $u-primary;
+}
+
+.u-warning {
+ color: $u-warning;
+}
+
+.u-success {
+ color: $u-success;
+}
+
+.u-error {
+ color: $u-error;
+}
+
+.u-info {
+ color: $u-info;
+}
+
+.u-primary-bg {
+ background-color: $u-primary;
+}
+
+.u-warning-bg {
+ background-color: $u-warning;
+}
+
+.u-success-bg {
+ background-color: $u-success;
+}
+
+.u-error-bg {
+ background-color: $u-error;
+}
+
+.u-info-bg {
+ background-color: $u-info;
+}
+
+.u-main-color {
+ color: $u-main-color;
+}
+
+.u-content-color {
+ color: $u-content-color;
+}
+
+.u-tips-color {
+ color: $u-tips-color;
+}
+
+.u-light-color {
+ color: $u-light-color;
+}
diff --git a/uni_modules/uview-ui/libs/css/common.scss b/uni_modules/uview-ui/libs/css/common.scss
new file mode 100644
index 0000000..11f1e53
--- /dev/null
+++ b/uni_modules/uview-ui/libs/css/common.scss
@@ -0,0 +1,97 @@
+// ���������������������������������������������������5���
+// ������uView���������������������������������������������������������������������App.vue���style���������������lang="scss"���
+@for $i from 1 through 5 {
+ .u-line-#{$i} {
+ /* #ifdef APP-NVUE */
+ // nvue������������������������lines���������������weex������������
+ lines: $i;
+ text-overflow: ellipsis;
+ overflow: hidden;
+ flex: 1;
+ /* #endif */
+
+ /* #ifndef APP-NVUE */
+ // vue������������������������������������������������������
+ @if $i == '1' {
+ overflow: hidden;
+ white-space: nowrap;
+ text-overflow: ellipsis;
+ } @else {
+ display: -webkit-box!important;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ word-break: break-all;
+ -webkit-line-clamp: $i;
+ -webkit-box-orient: vertical!important;
+ }
+ /* #endif */
+ }
+}
+
+
+// ������������!important���������������������������������������*.nvue���������������H5������
+// App.vue���������������uni-app���view���������������border���������������������������
+// ���������������uni-app������������������������������������������������������������!important
+// ���������������������������������������0.5px���������������������������������������������������
+.u-border {
+ border-width: 0.5px!important;
+ border-color: $u-border-color!important;
+ border-style: solid;
+}
+
+.u-border-top {
+ border-top-width: 0.5px!important;
+ border-color: $u-border-color!important;
+ border-top-style: solid;
+}
+
+.u-border-left {
+ border-left-width: 0.5px!important;
+ border-color: $u-border-color!important;
+ border-left-style: solid;
+}
+
+.u-border-right {
+ border-right-width: 0.5px!important;
+ border-color: $u-border-color!important;
+ border-right-style: solid;
+}
+
+.u-border-bottom {
+ border-bottom-width: 0.5px!important;
+ border-color: $u-border-color!important;
+ border-bottom-style: solid;
+}
+
+.u-border-top-bottom {
+ border-top-width: 0.5px!important;
+ border-bottom-width: 0.5px!important;
+ border-color: $u-border-color!important;
+ border-top-style: solid;
+ border-bottom-style: solid;
+}
+
+// ������button������������������������������������������������view���text������������
+.u-reset-button {
+ padding: 0;
+ background-color: transparent;
+ /* #ifndef APP-PLUS */
+ font-size: inherit;
+ line-height: inherit;
+ color: inherit;
+ /* #endif */
+ /* #ifdef APP-NVUE */
+ border-width: 0;
+ /* #endif */
+}
+
+/* #ifndef APP-NVUE */
+.u-reset-button::after {
+ border: none;
+}
+/* #endif */
+
+.u-hover-class {
+ opacity: 0.7;
+}
+
diff --git a/uni_modules/uview-ui/libs/css/components.scss b/uni_modules/uview-ui/libs/css/components.scss
new file mode 100644
index 0000000..766679e
--- /dev/null
+++ b/uni_modules/uview-ui/libs/css/components.scss
@@ -0,0 +1,15 @@
+@import "./mixin.scss";
+
+/* #ifndef APP-NVUE */
+// ������uView���������nvue���������������������������������������������������������flex-direction: column;
+// ������������nvue������������������������������������flex-direction: column; ���������������������������
+view, scroll-view, swiper-item {
+ display: flex;
+ flex-direction: column;
+ flex-shrink: 0;
+ flex-grow: 0;
+ flex-basis: auto;
+ align-items: stretch;
+ align-content: flex-start;
+}
+/* #endif */
diff --git a/uni_modules/uview-ui/libs/css/flex.scss b/uni_modules/uview-ui/libs/css/flex.scss
new file mode 100644
index 0000000..6d61be9
--- /dev/null
+++ b/uni_modules/uview-ui/libs/css/flex.scss
@@ -0,0 +1,257 @@
+// .u-flex {
+// @include vue-flex(row);
+// }
+
+// .u-flex-x {
+// @include vue-flex(row);
+// }
+
+// .u-flex-y {
+// @include vue-flex(column);
+// }
+
+// .u-flex-xy-center {
+// @include vue-flex(row);
+// justify-content: center;
+// align-items: center;
+// }
+
+// .u-flex-x-center {
+// @include vue-flex(row);
+// justify-content: center;
+// }
+
+// .u-flex-y-center {
+// @include vue-flex(column);
+// justify-content: center;
+// }
+
+
+// flex������
+.u-flex,
+.u-flex-row,
+.u-flex-x {
+ @include flex;
+}
+
+.u-flex-y,
+.u-flex-column {
+ @include flex(column);
+}
+
+.u-flex-x-center {
+ @include flex;
+ justify-content: center;
+}
+
+.u-flex-xy-center {
+ @include flex;
+ justify-content: center;
+ align-items: center;
+}
+
+.u-flex-y-center {
+ @include flex;
+ align-items: center;
+}
+
+.u-flex-x-left {
+ @include flex;
+}
+
+.u-flex-x-reverse,
+.u-flex-row-reverse {
+ flex-direction: row-reverse;
+}
+
+.u-flex-y-reverse,
+.u-flex-column-reverse {
+ flex-direction: column-reverse;
+}
+
+/* #ifndef APP-NVUE */
+// ���������vue������������������������nvue���������������������������������������������������
+// nvue���������������class="u-flex-x u-flex-x-reverse���������"
+.u-flex.u-flex-reverse,
+.u-flex-row.u-flex-reverse,
+.u-flex-x.u-flex-reverse {
+ flex-direction: row-reverse;
+}
+
+.u-flex-column.u-flex-reverse,
+.u-flex-y.u-flex-reverse {
+ flex-direction: column-reverse;
+}
+
+// ������������
+.u-flex-fill {
+ flex: 1 1 auto
+}
+
+// ������������������
+.u-margin-top-auto,
+.u-m-t-auto {
+ margin-top: auto !important
+}
+
+.u-margin-right-auto,
+.u-m-r-auto {
+ margin-right: auto !important
+}
+
+.u-margin-bottom-auto,
+.u-m-b-auto {
+ margin-bottom: auto !important
+}
+
+.u-margin-left-auto,
+.u-m-l-auto {
+ margin-left: auto !important
+}
+
+.u-margin-center-auto,
+.u-m-c-auto {
+ margin-left: auto !important;
+ margin-right: auto !important
+}
+
+.u-margin-middle-auto,
+.u-m-m-auto {
+ margin-top: auto !important;
+ margin-bottom: auto !important
+}
+/* #endif */
+
+// ������
+.u-flex-wrap {
+ flex-wrap: wrap;
+}
+
+// ������������
+.u-flex-wrap-reverse {
+ flex-wrap: wrap-reverse;
+}
+
+// ������������������
+.u-flex-start {
+ justify-content: flex-start
+}
+
+// ������������������
+.u-flex-center {
+ justify-content: center
+}
+
+// ������������������
+.u-flex-end {
+ justify-content: flex-end
+}
+
+// ������������������
+.u-flex-between {
+ justify-content: space-between
+}
+
+// ������������������
+.u-flex-around {
+ justify-content: space-around
+}
+
+// ���������������������
+.u-flex-items-start {
+ align-items: flex-start
+}
+
+// ���������������������
+.u-flex-items-center {
+ align-items: center
+}
+
+// ���������������������
+.u-flex-items-end {
+ align-items: flex-end
+}
+
+// ������������������������������������
+.u-flex-items-baseline {
+ align-items: baseline
+}
+
+// ���������������������������
+.u-flex-items-stretch {
+ align-items: stretch
+}
+
+
+// ������������������(���������)������
+
+// ������������������������������
+.u-flex-self-start {
+ align-self: flex-start
+}
+
+// ������������������������������
+.u-flex-self-center {
+ align-self: center
+}
+
+// ������������������������������
+.u-flex-self-end {
+ align-self: flex-end
+}
+
+// ���������������������������������������������
+.u-flex-self-baseline {
+ align-self: baseline
+}
+
+// ������������������������������������
+.u-flex-self-stretch {
+ align-self: stretch
+}
+
+// ������������������������������
+
+// ������������
+.u-flex-content-start {
+ align-content: flex-start
+}
+
+// ������������
+.u-flex-content-center {
+ align-content: center
+}
+
+// ������������
+.u-flex-content-end {
+ align-content: flex-end
+}
+
+// ������������
+.u-flex-content-between {
+ align-content: space-between
+}
+
+// ������������
+.u-flex-content-around {
+ align-content: space-around
+}
+
+// ������������������
+.u-flex-middle {
+ justify-content: center;
+ align-items: center;
+ align-self: center;
+ align-content: center
+}
+
+// ������������������
+.u-flex-grow {
+ flex-grow: 1
+}
+
+// ������������������
+.u-flex-shrink {
+ flex-shrink: 1
+}
+
diff --git a/uni_modules/uview-ui/libs/css/h5.scss b/uni_modules/uview-ui/libs/css/h5.scss
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/uni_modules/uview-ui/libs/css/h5.scss
diff --git a/uni_modules/uview-ui/libs/css/mixin.scss b/uni_modules/uview-ui/libs/css/mixin.scss
new file mode 100644
index 0000000..7e35b3b
--- /dev/null
+++ b/uni_modules/uview-ui/libs/css/mixin.scss
@@ -0,0 +1,8 @@
+// ������scss���mixin���������������������������4������css���������������
+// ������������������������������������������������nvue���������������������display:flex���������������
+@mixin flex($direction: row) {
+ /* #ifndef APP-NVUE */
+ display: flex;
+ /* #endif */
+ flex-direction: $direction;
+}
diff --git a/uni_modules/uview-ui/libs/css/mp.scss b/uni_modules/uview-ui/libs/css/mp.scss
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/uni_modules/uview-ui/libs/css/mp.scss
diff --git a/uni_modules/uview-ui/libs/css/nvue.scss b/uni_modules/uview-ui/libs/css/nvue.scss
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/uni_modules/uview-ui/libs/css/nvue.scss
diff --git a/uni_modules/uview-ui/libs/css/vue.scss b/uni_modules/uview-ui/libs/css/vue.scss
new file mode 100644
index 0000000..3ae4d29
--- /dev/null
+++ b/uni_modules/uview-ui/libs/css/vue.scss
@@ -0,0 +1,27 @@
+// ������������4���������������������������
+@each $d in top, right, bottom, left {
+ .u-safe-area-inset-#{$d} {
+ padding-#{$d}: 0;
+ padding-#{$d}: constant(safe-area-inset-#{$d});
+ padding-#{$d}: env(safe-area-inset-#{$d});
+ }
+}
+
+//������H5���uni.toast()���������������������uView���modal���������
+/* #ifdef H5 */
+uni-toast {
+ z-index: 10090;
+}
+uni-toast .uni-toast {
+ z-index: 10090;
+}
+/* #endif */
+
+// ������scroll-view������������
+::-webkit-scrollbar {
+ display: none;
+ width: 0 !important;
+ height: 0 !important;
+ -webkit-appearance: none;
+ background: transparent;
+}
\ No newline at end of file
diff --git a/uni_modules/uview-ui/libs/function/colorGradient.js b/uni_modules/uview-ui/libs/function/colorGradient.js
new file mode 100644
index 0000000..9727732
--- /dev/null
+++ b/uni_modules/uview-ui/libs/function/colorGradient.js
@@ -0,0 +1,134 @@
+/**
+ * ���������������������������������
+ * @param {string} startColor ���������������
+ * @param {string} endColor ���������������
+ * @param {number} step ���������������������
+ * */
+function colorGradient(startColor = 'rgb(0, 0, 0)', endColor = 'rgb(255, 255, 255)', step = 10) {
+ const startRGB = hexToRgb(startColor, false) // ���������rgb������������
+ const startR = startRGB[0]
+ const startG = startRGB[1]
+ const startB = startRGB[2]
+
+ const endRGB = hexToRgb(endColor, false)
+ const endR = endRGB[0]
+ const endG = endRGB[1]
+ const endB = endRGB[2]
+
+ const sR = (endR - startR) / step // ���������
+ const sG = (endG - startG) / step
+ const sB = (endB - startB) / step
+ const colorArr = []
+ for (let i = 0; i < step; i++) {
+ // ������������������hex���
+ let hex = rgbToHex(`rgb(${Math.round((sR * i + startR))},${Math.round((sG * i + startG))},${Math.round((sB
+ * i + startB))})`)
+ // ���������������������������startColor������
+ if (i === 0) hex = rgbToHex(startColor)
+ // ������������������������������endColor������
+ if (i === step - 1) hex = rgbToHex(endColor)
+ colorArr.push(hex)
+ }
+ return colorArr
+}
+
+// ���hex���������������������rgb������������(������������rgb������������)
+function hexToRgb(sColor, str = true) {
+ const reg = /^#([0-9a-fA-f]{3}|[0-9a-fA-f]{6})$/
+ sColor = String(sColor).toLowerCase()
+ if (sColor && reg.test(sColor)) {
+ if (sColor.length === 4) {
+ let sColorNew = '#'
+ for (let i = 1; i < 4; i += 1) {
+ sColorNew += sColor.slice(i, i + 1).concat(sColor.slice(i, i + 1))
+ }
+ sColor = sColorNew
+ }
+ // ������������������������
+ const sColorChange = []
+ for (let i = 1; i < 7; i += 2) {
+ sColorChange.push(parseInt(`0x${sColor.slice(i, i + 2)}`))
+ }
+ if (!str) {
+ return sColorChange
+ }
+ return `rgb(${sColorChange[0]},${sColorChange[1]},${sColorChange[2]})`
+ } if (/^(rgb|RGB)/.test(sColor)) {
+ const arr = sColor.replace(/(?:\(|\)|rgb|RGB)*/g, '').split(',')
+ return arr.map((val) => Number(val))
+ }
+ return sColor
+}
+
+// ���rgb���������������������hex������������
+function rgbToHex(rgb) {
+ const _this = rgb
+ const reg = /^#([0-9a-fA-f]{3}|[0-9a-fA-f]{6})$/
+ if (/^(rgb|RGB)/.test(_this)) {
+ const aColor = _this.replace(/(?:\(|\)|rgb|RGB)*/g, '').split(',')
+ let strHex = '#'
+ for (let i = 0; i < aColor.length; i++) {
+ let hex = Number(aColor[i]).toString(16)
+ hex = String(hex).length == 1 ? `${0}${hex}` : hex // ������������rgb���������2���
+ if (hex === '0') {
+ hex += hex
+ }
+ strHex += hex
+ }
+ if (strHex.length !== 7) {
+ strHex = _this
+ }
+ return strHex
+ } if (reg.test(_this)) {
+ const aNum = _this.replace(/#/, '').split('')
+ if (aNum.length === 6) {
+ return _this
+ } if (aNum.length === 3) {
+ let numHex = '#'
+ for (let i = 0; i < aNum.length; i += 1) {
+ numHex += (aNum[i] + aNum[i])
+ }
+ return numHex
+ }
+ } else {
+ return _this
+ }
+}
+
+/**
+* JS���������������������������rgb���rgba,������������������ rgba���255���255���255���0.5������������
+* sHex���������������������������������
+* alpha���rgba������������
+*/
+function colorToRgba(color, alpha) {
+ color = rgbToHex(color)
+ // ���������������������������������������
+ const reg = /^#([0-9a-fA-f]{3}|[0-9a-fA-f]{6})$/
+ /* 16������������������RGB������ */
+ let sColor = String(color).toLowerCase()
+ if (sColor && reg.test(sColor)) {
+ if (sColor.length === 4) {
+ let sColorNew = '#'
+ for (let i = 1; i < 4; i += 1) {
+ sColorNew += sColor.slice(i, i + 1).concat(sColor.slice(i, i + 1))
+ }
+ sColor = sColorNew
+ }
+ // ������������������������
+ const sColorChange = []
+ for (let i = 1; i < 7; i += 2) {
+ sColorChange.push(parseInt(`0x${sColor.slice(i, i + 2)}`))
+ }
+ // return sColorChange.join(',')
+ return `rgba(${sColorChange.join(',')},${alpha})`
+ }
+
+ return sColor
+}
+
+export default {
+ colorGradient,
+ hexToRgb,
+ rgbToHex,
+ colorToRgba
+}
diff --git a/uni_modules/uview-ui/libs/function/debounce.js b/uni_modules/uview-ui/libs/function/debounce.js
new file mode 100644
index 0000000..ad3996b
--- /dev/null
+++ b/uni_modules/uview-ui/libs/function/debounce.js
@@ -0,0 +1,29 @@
+let timeout = null
+
+/**
+ * ������������������������������������������������������������������wait������������������������
+ *
+ * @param {Function} func ������������������������
+ * @param {Number} wait ���������������
+ * @param {Boolean} immediate ������������������
+ * @return null
+ */
+function debounce(func, wait = 500, immediate = false) {
+ // ���������������
+ if (timeout !== null) clearTimeout(timeout)
+ // ������������������������������������������
+ if (immediate) {
+ const callNow = !timeout
+ timeout = setTimeout(() => {
+ timeout = null
+ }, wait)
+ if (callNow) typeof func === 'function' && func()
+ } else {
+ // ���������������������������������������������timeout������������������������������������wait���������������func������������
+ timeout = setTimeout(() => {
+ typeof func === 'function' && func()
+ }, wait)
+ }
+}
+
+export default debounce
diff --git a/uni_modules/uview-ui/libs/function/digit.js b/uni_modules/uview-ui/libs/function/digit.js
new file mode 100644
index 0000000..c8260a0
--- /dev/null
+++ b/uni_modules/uview-ui/libs/function/digit.js
@@ -0,0 +1,167 @@
+let _boundaryCheckingState = true; // ���������������������������������������
+
+/**
+ * ������������������������
+ * @private
+ * @example strip(0.09999999999999998)=0.1
+ */
+function strip(num, precision = 15) {
+ return +parseFloat(Number(num).toPrecision(precision));
+}
+
+/**
+ * Return digits length of a number
+ * @private
+ * @param {*number} num Input number
+ */
+function digitLength(num) {
+ // Get digit length of e
+ const eSplit = num.toString().split(/[eE]/);
+ const len = (eSplit[0].split('.')[1] || '').length - +(eSplit[1] || 0);
+ return len > 0 ? len : 0;
+}
+
+/**
+ * ���������������������,���������������������������������
+ * @private
+ * @param {*number} num ���������
+ */
+function float2Fixed(num) {
+ if (num.toString().indexOf('e') === -1) {
+ return Number(num.toString().replace('.', ''));
+ }
+ const dLen = digitLength(num);
+ return dLen > 0 ? strip(Number(num) * Math.pow(10, dLen)) : Number(num);
+}
+
+/**
+ * ���������������������������������������������������
+ * @private
+ * @param {*number} num ���������
+ */
+function checkBoundary(num) {
+ if (_boundaryCheckingState) {
+ if (num > Number.MAX_SAFE_INTEGER || num < Number.MIN_SAFE_INTEGER) {
+ console.warn(`${num} ���������������������������������������������`);
+ }
+ }
+}
+
+/**
+ * ������������������������������
+ * @param {number[]} arr ������������������������
+ * @param {function} operation ������������
+ * @private
+ */
+function iteratorOperation(arr, operation) {
+ const [num1, num2, ...others] = arr;
+ let res = operation(num1, num2);
+
+ others.forEach((num) => {
+ res = operation(res, num);
+ });
+
+ return res;
+}
+
+/**
+ * ���������������
+ * @export
+ */
+export function times(...nums) {
+ if (nums.length > 2) {
+ return iteratorOperation(nums, times);
+ }
+
+ const [num1, num2] = nums;
+ const num1Changed = float2Fixed(num1);
+ const num2Changed = float2Fixed(num2);
+ const baseNum = digitLength(num1) + digitLength(num2);
+ const leftValue = num1Changed * num2Changed;
+
+ checkBoundary(leftValue);
+
+ return leftValue / Math.pow(10, baseNum);
+}
+
+/**
+ * ���������������
+ * @export
+ */
+export function plus(...nums) {
+ if (nums.length > 2) {
+ return iteratorOperation(nums, plus);
+ }
+
+ const [num1, num2] = nums;
+ // ���������������������
+ const baseNum = Math.pow(10, Math.max(digitLength(num1), digitLength(num2)));
+ // ���������������������������������������
+ return (times(num1, baseNum) + times(num2, baseNum)) / baseNum;
+}
+
+/**
+ * ���������������
+ * @export
+ */
+export function minus(...nums) {
+ if (nums.length > 2) {
+ return iteratorOperation(nums, minus);
+ }
+
+ const [num1, num2] = nums;
+ const baseNum = Math.pow(10, Math.max(digitLength(num1), digitLength(num2)));
+ return (times(num1, baseNum) - times(num2, baseNum)) / baseNum;
+}
+
+/**
+ * ���������������
+ * @export
+ */
+export function divide(...nums) {
+ if (nums.length > 2) {
+ return iteratorOperation(nums, divide);
+ }
+
+ const [num1, num2] = nums;
+ const num1Changed = float2Fixed(num1);
+ const num2Changed = float2Fixed(num2);
+ checkBoundary(num1Changed);
+ checkBoundary(num2Changed);
+ // ������������������������strip������������
+ return times(num1Changed / num2Changed, strip(Math.pow(10, digitLength(num2) - digitLength(num1))));
+}
+
+/**
+ * ������������
+ * @export
+ */
+export function round(num, ratio) {
+ const base = Math.pow(10, ratio);
+ let result = divide(Math.round(Math.abs(times(num, base))), base);
+ if (num < 0 && result !== 0) {
+ result = times(result, -1);
+ }
+ // ������������������0
+ return result;
+}
+
+/**
+ * ���������������������������������������
+ * @param flag ���������������true ������������false ��������������������� true
+ * @export
+ */
+export function enableBoundaryChecking(flag = true) {
+ _boundaryCheckingState = flag;
+}
+
+
+export default {
+ times,
+ plus,
+ minus,
+ divide,
+ round,
+ enableBoundaryChecking,
+};
+
diff --git a/uni_modules/uview-ui/libs/function/index.js b/uni_modules/uview-ui/libs/function/index.js
new file mode 100644
index 0000000..bd80ee7
--- /dev/null
+++ b/uni_modules/uview-ui/libs/function/index.js
@@ -0,0 +1,731 @@
+import test from './test.js'
+import { round } from './digit.js'
+/**
+ * @description ������value������min������min���������value������max������max
+ * @param {number} min
+ * @param {number} max
+ * @param {number} value
+ */
+function range(min = 0, max = 0, value = 0) {
+ return Math.max(min, Math.min(max, Number(value)))
+}
+
+/**
+ * @description ������������������������������px��� ���������������������"xxpx"������"xxrpx"������������������������������������"xxxrpx"���������������uni.upx2px������������
+ * @param {number|string} value ������������������px���
+ * @param {boolean} unit
+ * @returns {number|string}
+ */
+function getPx(value, unit = false) {
+ if (test.number(value)) {
+ return unit ? `${value}px` : Number(value)
+ }
+ // ������������rpx���������������������������������������px���
+ if (/(rpx|upx)$/.test(value)) {
+ return unit ? `${uni.upx2px(parseInt(value))}px` : Number(uni.upx2px(parseInt(value)))
+ }
+ return unit ? `${parseInt(value)}px` : parseInt(value)
+}
+
+/**
+ * @description ��������������������������������������������������� ������: await uni.$u.sleep(20)������������20ms
+ * @param {number} value ������������ ������ms ������
+ * @returns {Promise} ������promise
+ */
+function sleep(value = 30) {
+ return new Promise((resolve) => {
+ setTimeout(() => {
+ resolve()
+ }, value)
+ })
+}
+/**
+ * @description ���������������������
+ * @returns {string} ������������������(������)
+ * @link ��������������������� https://uniapp.dcloud.io/frame?id=������������
+ */
+function os() {
+ return uni.getSystemInfoSync().platform.toLowerCase()
+}
+/**
+ * @description ������������������������������
+ * @link ������������������������������ https://uniapp.dcloud.io/api/system/info?id=getsysteminfosync
+ */
+function sys() {
+ return uni.getSystemInfoSync()
+}
+
+/**
+ * @description ������������������
+ * @param {Number} min ���������
+ * @param {Number} max ���������
+ */
+function random(min, max) {
+ if (min >= 0 && max > 0 && max >= min) {
+ const gab = max - min + 1
+ return Math.floor(Math.random() * gab + min)
+ }
+ return 0
+}
+
+/**
+ * @param {Number} len uuid���������
+ * @param {Boolean} firstU ���������������������������"u"
+ * @param {Nubmer} radix ������uuid���������(���������������������������������������������),2-���������,8-���������,10-���������,16-������������
+ */
+function guid(len = 32, firstU = true, radix = null) {
+ const chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split('')
+ const uuid = []
+ radix = radix || chars.length
+
+ if (len) {
+ // ������������uuid������,������������������������,0|x������������,���������x������������,���������������
+ for (let i = 0; i < len; i++) uuid[i] = chars[0 | Math.random() * radix]
+ } else {
+ let r
+ // rfc4122���������������������uuid���,���������������������������
+ uuid[8] = uuid[13] = uuid[18] = uuid[23] = '-'
+ uuid[14] = '4'
+
+ for (let i = 0; i < 36; i++) {
+ if (!uuid[i]) {
+ r = 0 | Math.random() * 16
+ uuid[i] = chars[(i == 19) ? (r & 0x3) | 0x8 : r]
+ }
+ }
+ }
+ // ���������������������,������u������,���������������������������������,���guuid������������id������class
+ if (firstU) {
+ uuid.shift()
+ return `u${uuid.join('')}`
+ }
+ return uuid.join('')
+}
+
+/**
+* @description ������������������������������������������������������������provide/inject���������
+ this.$parent������H5������������������������������������������������H5������������������this.$parent.$parent.xxx
+ ���������������������undefined���������������������������������������(������)���$parent������undefined������������������name
+ ���(���������undefined)���������������������������$parent
+* @param {string|undefined} name ���������������������
+*/
+function $parent(name = undefined) {
+ let parent = this.$parent
+ // ������while������������������������������H5���������������������������
+ while (parent) {
+ // ���������
+ if (parent.$options && parent.$options.name !== name) {
+ // ���������������name���������������������������������
+ parent = parent.$parent
+ } else {
+ return parent
+ }
+ }
+ return false
+}
+
+/**
+ * @description ������������
+ * ���������������������������������������������
+ * @param {object | string} customStyle ���������������������
+ * @param {String} target ������������������object-���������������string-���������������
+ * @returns {object|string}
+ */
+function addStyle(customStyle, target = 'object') {
+ // ������������������������������������������������������������
+ if (test.empty(customStyle) || typeof(customStyle) === 'object' && target === 'object' || target === 'string' &&
+ typeof(customStyle) === 'string') {
+ return customStyle
+ }
+ // ������������������
+ if (target === 'object') {
+ // ���������������������������������������(������������������������������������padding: 20px 0������������������������)���������������������
+ customStyle = trim(customStyle)
+ // ������";"������������������������������
+ const styleArray = customStyle.split(';')
+ const style = {}
+ // ������������������������������
+ for (let i = 0; i < styleArray.length; i++) {
+ // 'font-size:20px;color:red;'���������������������������";"������������������styleArray������������������������������������������������������
+ if (styleArray[i]) {
+ const item = styleArray[i].split(':')
+ style[trim(item[0])] = trim(item[1])
+ }
+ }
+ return style
+ }
+ // ���������������������������������
+ let string = ''
+ for (const i in customStyle) {
+ // ���������������������������������������css������������������������������������������������
+ const key = i.replace(/([A-Z])/g, '-$1').toLowerCase()
+ string += `${key}:${customStyle[i]};`
+ }
+ // ������������������
+ return trim(string)
+}
+
+/**
+ * @description ������������������������rpx���upx���%���px���������������������������auto������������������������������px������������
+ * @param {string|number} value ������������������������
+ * @param {string} unit ������������������ ������px
+ */
+function addUnit(value = 'auto', unit = uni?.$u?.config?.unit ?? 'px') {
+ value = String(value)
+ // ���uView������������������������number���������������������
+ return test.number(value) ? `${value}${unit}` : value
+}
+
+/**
+ * @description ������������
+ * @param {object} obj ���������������������������
+ * @param cache ������
+ * @returns {*} ������������������������������������������������
+ */
+function deepClone(obj, cache = new WeakMap()) {
+ if (obj === null || typeof obj !== 'object') return obj;
+ if (cache.has(obj)) return cache.get(obj);
+ let clone;
+ if (obj instanceof Date) {
+ clone = new Date(obj.getTime());
+ } else if (obj instanceof RegExp) {
+ clone = new RegExp(obj);
+ } else if (obj instanceof Map) {
+ clone = new Map(Array.from(obj, ([key, value]) => [key, deepClone(value, cache)]));
+ } else if (obj instanceof Set) {
+ clone = new Set(Array.from(obj, value => deepClone(value, cache)));
+ } else if (Array.isArray(obj)) {
+ clone = obj.map(value => deepClone(value, cache));
+ } else if (Object.prototype.toString.call(obj) === '[object Object]') {
+ clone = Object.create(Object.getPrototypeOf(obj));
+ cache.set(obj, clone);
+ for (const [key, value] of Object.entries(obj)) {
+ clone[key] = deepClone(value, cache);
+ }
+ } else {
+ clone = Object.assign({}, obj);
+ }
+ cache.set(obj, clone);
+ return clone;
+}
+
+/**
+ * @description JS������������������
+ * @param {object} target ���������������������
+ * @param {object} source ���������������������
+ * @returns {object|boolean} ������������������������������false���������������������������
+ */
+function deepMerge(target = {}, source = {}) {
+ target = deepClone(target)
+ if (typeof target !== 'object' || target === null || typeof source !== 'object' || source === null) return target;
+ const merged = Array.isArray(target) ? target.slice() : Object.assign({}, target);
+ for (const prop in source) {
+ if (!source.hasOwnProperty(prop)) continue;
+ const sourceValue = source[prop];
+ const targetValue = merged[prop];
+ if (sourceValue instanceof Date) {
+ merged[prop] = new Date(sourceValue);
+ } else if (sourceValue instanceof RegExp) {
+ merged[prop] = new RegExp(sourceValue);
+ } else if (sourceValue instanceof Map) {
+ merged[prop] = new Map(sourceValue);
+ } else if (sourceValue instanceof Set) {
+ merged[prop] = new Set(sourceValue);
+ } else if (typeof sourceValue === 'object' && sourceValue !== null) {
+ merged[prop] = deepMerge(targetValue, sourceValue);
+ } else {
+ merged[prop] = sourceValue;
+ }
+ }
+ return merged;
+}
+
+/**
+ * @description error������
+ * @param {*} err ������������
+ */
+function error(err) {
+ // ������������������������������������������������
+ if (process.env.NODE_ENV === 'development') {
+ console.error(`uView���������${err}`)
+ }
+}
+
+/**
+ * @description ������������
+ * @param {array} array ���������������������
+ * @returns {array} ������������������
+ */
+function randomArray(array = []) {
+ // ���������sort������,Math.random()������0<= x < 1������������,���������x-0.05������������������0
+ return array.sort(() => Math.random() - 0.5)
+}
+
+// padStart ��� polyfill������������������������������������������������es7���padStart������������������������������������
+// ���������������������������polyfill���������������
+if (!String.prototype.padStart) {
+ // ������������������������ fillString ������ES6 ���������������������������������
+ String.prototype.padStart = function(maxLength, fillString = ' ') {
+ if (Object.prototype.toString.call(fillString) !== '[object String]') {
+ throw new TypeError(
+ 'fillString must be String'
+ )
+ }
+ const str = this
+ // ������ String(str) ������������������������������������������������������������������������������������
+ if (str.length >= maxLength) return String(str)
+
+ const fillLength = maxLength - str.length
+ let times = Math.ceil(fillLength / fillString.length)
+ while (times >>= 1) {
+ fillString += fillString
+ if (times === 1) {
+ fillString += fillString
+ }
+ }
+ return fillString.slice(0, fillLength) + str
+ }
+}
+
+/**
+ * @description ���������������
+ * @param {String|Number} dateTime ���������������������������
+ * @param {String} fmt ��������������� yyyy:mm:dd|yyyy:mm|yyyy���mm���dd���|yyyy���mm���dd��� hh���MM������,������������������ ������yyyy-mm-dd
+ * @returns {string} ������������������������������
+ */
+ function timeFormat(dateTime = null, formatStr = 'yyyy-mm-dd') {
+ let date
+ // ���������������������������������������������
+ if (!dateTime) {
+ date = new Date()
+ }
+ // ������unix������������������������������������������������������������������������������������������������������
+ else if (/^\d{10}$/.test(dateTime?.toString().trim())) {
+ date = new Date(dateTime * 1000)
+ }
+ // ������������������������������������������new Date���������������������������
+ else if (typeof dateTime === 'string' && /^\d+$/.test(dateTime.trim())) {
+ date = new Date(Number(dateTime))
+ }
+ // ���������������������������Safari/Webkit������new Date���������/���������������������������������
+ // ������ '2022-07-10 01:02:03'��������� '2022-07-10T01:02:03'
+ else if (typeof dateTime === 'string' && dateTime.includes('-') && !dateTime.includes('T')) {
+ date = new Date(dateTime.replace(/-/g, '/'))
+ }
+ // ��������������������� RFC 2822 ������
+ else {
+ date = new Date(dateTime)
+ }
+
+ const timeSource = {
+ 'y': date.getFullYear().toString(), // ���
+ 'm': (date.getMonth() + 1).toString().padStart(2, '0'), // ���
+ 'd': date.getDate().toString().padStart(2, '0'), // ���
+ 'h': date.getHours().toString().padStart(2, '0'), // ���
+ 'M': date.getMinutes().toString().padStart(2, '0'), // ���
+ 's': date.getSeconds().toString().padStart(2, '0') // ���
+ // ���������������������������������������������������������������������������
+ }
+
+ for (const key in timeSource) {
+ const [ret] = new RegExp(`${key}+`).exec(formatStr) || []
+ if (ret) {
+ // ���������������������������
+ const beginIndex = key === 'y' && ret.length === 2 ? 2 : 0
+ formatStr = formatStr.replace(ret, timeSource[key].slice(beginIndex))
+ }
+ }
+
+ return formatStr
+}
+
+/**
+ * @description ���������������������������
+ * @param {String|Number} timestamp ���������
+ * @param {String|Boolean} format
+ * ���������������������������������������������������������������������������������������������������������
+ * ������������������false������������������������������������������������������
+ * @returns {string} ������������������
+ */
+function timeFrom(timestamp = null, format = 'yyyy-mm-dd') {
+ if (timestamp == null) timestamp = Number(new Date())
+ timestamp = parseInt(timestamp)
+ // ������������������������������������������������,������������js���������������������������(13���),������������������������(10���)
+ if (timestamp.toString().length == 10) timestamp *= 1000
+ let timer = (new Date()).getTime() - timestamp
+ timer = parseInt(timer / 1000)
+ // ������������5������,���������"������",������������������
+ let tips = ''
+ switch (true) {
+ case timer < 300:
+ tips = '������'
+ break
+ case timer >= 300 && timer < 3600:
+ tips = `${parseInt(timer / 60)}���������`
+ break
+ case timer >= 3600 && timer < 86400:
+ tips = `${parseInt(timer / 3600)}���������`
+ break
+ case timer >= 86400 && timer < 2592000:
+ tips = `${parseInt(timer / 86400)}������`
+ break
+ default:
+ // ������format���false���������������������������������������xx������
+ if (format === false) {
+ if (timer >= 2592000 && timer < 365 * 86400) {
+ tips = `${parseInt(timer / (86400 * 30))}���������`
+ } else {
+ tips = `${parseInt(timer / (86400 * 365))}������`
+ }
+ } else {
+ tips = timeFormat(timestamp, format)
+ }
+ }
+ return tips
+}
+
+/**
+ * @description ������������
+ * @param String str ������������������������������
+ * @param String pos both(������)|left|right|all ������both
+ */
+function trim(str, pos = 'both') {
+ str = String(str)
+ if (pos == 'both') {
+ return str.replace(/^\s+|\s+$/g, '')
+ }
+ if (pos == 'left') {
+ return str.replace(/^\s*/, '')
+ }
+ if (pos == 'right') {
+ return str.replace(/(\s*$)/g, '')
+ }
+ if (pos == 'all') {
+ return str.replace(/\s+/g, '')
+ }
+ return str
+}
+
+/**
+ * @description ���������url������
+ * @param {object} data,������
+ * @param {Boolean} isPrefix,������������������"?"
+ * @param {string} arrayFormat ������ indices|brackets|repeat|comma
+ */
+function queryParams(data = {}, isPrefix = true, arrayFormat = 'brackets') {
+ const prefix = isPrefix ? '?' : ''
+ const _result = []
+ if (['indices', 'brackets', 'repeat', 'comma'].indexOf(arrayFormat) == -1) arrayFormat = 'brackets'
+ for (const key in data) {
+ const value = data[key]
+ // ���������������������
+ if (['', undefined, null].indexOf(value) >= 0) {
+ continue
+ }
+ // ���������������������������������
+ if (value.constructor === Array) {
+ // e.g. {ids: [1, 2, 3]}
+ switch (arrayFormat) {
+ case 'indices':
+ // ������: ids[0]=1&ids[1]=2&ids[2]=3
+ for (let i = 0; i < value.length; i++) {
+ _result.push(`${key}[${i}]=${value[i]}`)
+ }
+ break
+ case 'brackets':
+ // ������: ids[]=1&ids[]=2&ids[]=3
+ value.forEach((_value) => {
+ _result.push(`${key}[]=${_value}`)
+ })
+ break
+ case 'repeat':
+ // ������: ids=1&ids=2&ids=3
+ value.forEach((_value) => {
+ _result.push(`${key}=${_value}`)
+ })
+ break
+ case 'comma':
+ // ������: ids=1,2,3
+ let commaStr = ''
+ value.forEach((_value) => {
+ commaStr += (commaStr ? ',' : '') + _value
+ })
+ _result.push(`${key}=${commaStr}`)
+ break
+ default:
+ value.forEach((_value) => {
+ _result.push(`${key}[]=${_value}`)
+ })
+ }
+ } else {
+ _result.push(`${key}=${value}`)
+ }
+ }
+ return _result.length ? prefix + _result.join('&') : ''
+}
+
+/**
+ * ���������������������
+ * @param {String} title ��������������������������� icon ���������������
+ * @param {Number} duration ������������������������������������������������2000
+ */
+function toast(title, duration = 2000) {
+ uni.showToast({
+ title: String(title),
+ icon: 'none',
+ duration
+ })
+}
+
+/**
+ * @description ������������type���,���������������������
+ * @param {String} type ������������,primary|info|error|warning|success
+ * @param {boolean} fill ������������fill���������������������
+ */
+function type2icon(type = 'success', fill = false) {
+ // ������������������,���������success
+ if (['primary', 'info', 'error', 'warning', 'success'].indexOf(type) == -1) type = 'success'
+ let iconName = ''
+ // ������(2019-12-12),info���primary���������������������
+ switch (type) {
+ case 'primary':
+ iconName = 'info-circle'
+ break
+ case 'info':
+ iconName = 'info-circle'
+ break
+ case 'error':
+ iconName = 'close-circle'
+ break
+ case 'warning':
+ iconName = 'error-circle'
+ break
+ case 'success':
+ iconName = 'checkmark-circle'
+ break
+ default:
+ iconName = 'checkmark-circle'
+ }
+ // ���������������������,������-fill,���icon������������,���������������������������-fill���
+ if (fill) iconName += '-fill'
+ return iconName
+}
+
+/**
+ * @description ���������������
+ * @param {number|string} number ���������������������
+ * @param {number} decimals ������������������
+ * @param {string} decimalPoint ���������������
+ * @param {string} thousandsSeparator ���������������
+ * @returns {string} ���������������������
+ */
+function priceFormat(number, decimals = 0, decimalPoint = '.', thousandsSeparator = ',') {
+ number = (`${number}`).replace(/[^0-9+-Ee.]/g, '')
+ const n = !isFinite(+number) ? 0 : +number
+ const prec = !isFinite(+decimals) ? 0 : Math.abs(decimals)
+ const sep = (typeof thousandsSeparator === 'undefined') ? ',' : thousandsSeparator
+ const dec = (typeof decimalPoint === 'undefined') ? '.' : decimalPoint
+ let s = ''
+
+ s = (prec ? round(n, prec) + '' : `${Math.round(n)}`).split('.')
+ const re = /(-?\d+)(\d{3})/
+ while (re.test(s[0])) {
+ s[0] = s[0].replace(re, `$1${sep}$2`)
+ }
+
+ if ((s[1] || '').length < prec) {
+ s[1] = s[1] || ''
+ s[1] += new Array(prec - s[1].length + 1).join('0')
+ }
+ return s.join(dec)
+}
+
+/**
+ * @description ������duration���
+ * ������������ms������s������������������������������������������������ms������������������������������������s������
+ * ���������30������������������300������30������������������������������������300ms������������������300s���������������������
+ * @param {String|number} value ������: "1s"|"100ms"|1|100
+ * @param {boolean} unit ������: ���������false ������������number
+ * @return {string|number}
+ */
+function getDuration(value, unit = true) {
+ const valueNum = parseInt(value)
+ if (unit) {
+ if (/s$/.test(value)) return value
+ return value > 30 ? `${value}ms` : `${value}s`
+ }
+ if (/ms$/.test(value)) return valueNum
+ if (/s$/.test(value)) return valueNum > 30 ? valueNum : valueNum * 1000
+ return valueNum
+}
+
+/**
+ * @description ������������������������������
+ * @param {String} value ������������������
+ */
+function padZero(value) {
+ return `00${value}`.slice(-2)
+}
+
+/**
+ * @description ���u-form���������������������������������������������������������������������u-form������������������
+ * @param {*} instance
+ * @param {*} event
+ */
+function formValidate(instance, event) {
+ const formItem = uni.$u.$parent.call(instance, 'u-form-item')
+ const form = uni.$u.$parent.call(instance, 'u-form')
+ // ���������������������input������textarea������������������������u-form-item������u-form���������������form���validate������
+ // ���������form-item���pros���������form���������������������������������
+ if (formItem && form) {
+ form.validateField(formItem.prop, () => {}, event)
+ }
+}
+
+/**
+ * @description ���������������������������������������������������'a.b.c'���������������������������������������������������
+ * @param {object} obj ������
+ * @param {string} key ���������������������������
+ * @returns {*}
+ */
+function getProperty(obj, key) {
+ if (!obj) {
+ return
+ }
+ if (typeof key !== 'string' || key === '') {
+ return ''
+ }
+ if (key.indexOf('.') !== -1) {
+ const keys = key.split('.')
+ let firstObj = obj[keys[0]] || {}
+
+ for (let i = 1; i < keys.length; i++) {
+ if (firstObj) {
+ firstObj = firstObj[keys[i]]
+ }
+ }
+ return firstObj
+ }
+ return obj[key]
+}
+
+/**
+ * @description ���������������������������������'a.b.c'���������������������
+ * @param {object} obj ������
+ * @param {string} key ���������������������
+ * @param {string} value ������������
+ */
+function setProperty(obj, key, value) {
+ if (!obj) {
+ return
+ }
+ // ������������
+ const inFn = function(_obj, keys, v) {
+ // ������������������key
+ if (keys.length === 1) {
+ _obj[keys[0]] = v
+ return
+ }
+ // 0~length-1���key
+ while (keys.length > 1) {
+ const k = keys[0]
+ if (!_obj[k] || (typeof _obj[k] !== 'object')) {
+ _obj[k] = {}
+ }
+ const key = keys.shift()
+ // ������������������������������������������������������������������
+ inFn(_obj[k], keys, v)
+ }
+ }
+
+ if (typeof key !== 'string' || key === '') {
+
+ } else if (key.indexOf('.') !== -1) { // ���������������������������
+ const keys = key.split('.')
+ inFn(obj, keys, value)
+ } else {
+ obj[key] = value
+ }
+}
+
+/**
+ * @description ������������������������
+ */
+function page() {
+ const pages = getCurrentPages()
+ // ���������������������(������������������redirectTo������������������)���pages������������������
+ return `/${pages[pages.length - 1]?.route ?? ''}`
+}
+
+/**
+ * @description ���������������������������������
+ */
+function pages() {
+ const pages = getCurrentPages()
+ return pages
+}
+
+/**
+ * ������������������������������������
+ * @param back {number} [0] - 0���������������������������������������������������0���������������������������������-1 ������������������������������������������0���
+ */
+function getHistoryPage(back = 0) {
+ const pages = getCurrentPages()
+ const len = pages.length
+ return pages[len - 1 + back]
+}
+
+/**
+ * @description ������uView���������������
+ * @param {object} props ������������props������
+ * @param {object} config ������������config������
+ * @param {object} color ������������color������
+ * @param {object} zIndex ������������zIndex������
+ */
+function setConfig({
+ props = {},
+ config = {},
+ color = {},
+ zIndex = {}
+}) {
+ const {
+ deepMerge,
+ } = uni.$u
+ uni.$u.config = deepMerge(uni.$u.config, config)
+ uni.$u.props = deepMerge(uni.$u.props, props)
+ uni.$u.color = deepMerge(uni.$u.color, color)
+ uni.$u.zIndex = deepMerge(uni.$u.zIndex, zIndex)
+}
+
+export default {
+ range,
+ getPx,
+ sleep,
+ os,
+ sys,
+ random,
+ guid,
+ $parent,
+ addStyle,
+ addUnit,
+ deepClone,
+ deepMerge,
+ error,
+ randomArray,
+ timeFormat,
+ timeFrom,
+ trim,
+ queryParams,
+ toast,
+ type2icon,
+ priceFormat,
+ getDuration,
+ padZero,
+ formValidate,
+ getProperty,
+ setProperty,
+ page,
+ pages,
+ getHistoryPage,
+ setConfig
+}
diff --git a/uni_modules/uview-ui/libs/function/platform.js b/uni_modules/uview-ui/libs/function/platform.js
new file mode 100644
index 0000000..d6b926e
--- /dev/null
+++ b/uni_modules/uview-ui/libs/function/platform.js
@@ -0,0 +1,75 @@
+/**
+ * ���������
+ * ���������������������vue-cli���������������������vue.config.js������������������������������
+ * module.exports = {
+ * transpileDependencies: ['uview-v2']
+ * }
+ */
+
+let platform = 'none'
+
+// #ifdef VUE3
+platform = 'vue3'
+// #endif
+
+// #ifdef VUE2
+platform = 'vue2'
+// #endif
+
+// #ifdef APP-PLUS
+platform = 'plus'
+// #endif
+
+// #ifdef APP-NVUE
+platform = 'nvue'
+// #endif
+
+// #ifdef H5
+platform = 'h5'
+// #endif
+
+// #ifdef MP-WEIXIN
+platform = 'weixin'
+// #endif
+
+// #ifdef MP-ALIPAY
+platform = 'alipay'
+// #endif
+
+// #ifdef MP-BAIDU
+platform = 'baidu'
+// #endif
+
+// #ifdef MP-TOUTIAO
+platform = 'toutiao'
+// #endif
+
+// #ifdef MP-QQ
+platform = 'qq'
+// #endif
+
+// #ifdef MP-KUAISHOU
+platform = 'kuaishou'
+// #endif
+
+// #ifdef MP-360
+platform = '360'
+// #endif
+
+// #ifdef MP
+platform = 'mp'
+// #endif
+
+// #ifdef QUICKAPP-WEBVIEW
+platform = 'quickapp-webview'
+// #endif
+
+// #ifdef QUICKAPP-WEBVIEW-HUAWEI
+platform = 'quickapp-webview-huawei'
+// #endif
+
+// #ifdef QUICKAPP-WEBVIEW-UNION
+platform = 'quckapp-webview-union'
+// #endif
+
+export default platform
diff --git a/uni_modules/uview-ui/libs/function/test.js b/uni_modules/uview-ui/libs/function/test.js
new file mode 100644
index 0000000..c776437
--- /dev/null
+++ b/uni_modules/uview-ui/libs/function/test.js
@@ -0,0 +1,288 @@
+/**
+ * ������������������������
+ */
+function email(value) {
+ return /^\w+((-\w+)|(\.\w+))*\@[A-Za-z0-9]+((\.|-)[A-Za-z0-9]+)*\.[A-Za-z0-9]+$/.test(value)
+}
+
+/**
+ * ������������������
+ */
+function mobile(value) {
+ return /^1([3589]\d|4[5-9]|6[1-2,4-7]|7[0-8])\d{8}$/.test(value)
+}
+
+/**
+ * ������URL������
+ */
+function url(value) {
+ return /^((https|http|ftp|rtsp|mms):\/\/)(([0-9a-zA-Z_!~*'().&=+$%-]+: )?[0-9a-zA-Z_!~*'().&=+$%-]+@)?(([0-9]{1,3}.){3}[0-9]{1,3}|([0-9a-zA-Z_!~*'()-]+.)*([0-9a-zA-Z][0-9a-zA-Z-]{0,61})?[0-9a-zA-Z].[a-zA-Z]{2,6})(:[0-9]{1,4})?((\/?)|(\/[0-9a-zA-Z_!~*'().;?:@&=+$,%#-]+)+\/?)$/
+ .test(value)
+}
+
+/**
+ * ������������������
+ */
+function date(value) {
+ if (!value) return false
+ // ���������������������������������������(���������������������)������������������������new Date������������������������������
+ if (number(value)) value = +value
+ return !/Invalid|NaN/.test(new Date(value).toString())
+}
+
+/**
+ * ������ISO���������������������
+ */
+function dateISO(value) {
+ return /^\d{4}[\/\-](0?[1-9]|1[012])[\/\-](0?[1-9]|[12][0-9]|3[01])$/.test(value)
+}
+
+/**
+ * ���������������������
+ */
+function number(value) {
+ return /^[\+-]?(\d+\.?\d*|\.\d+|\d\.\d+e\+\d+)$/.test(value)
+}
+
+/**
+ * ���������������
+ */
+function string(value) {
+ return typeof value === 'string'
+}
+
+/**
+ * ������������
+ */
+function digits(value) {
+ return /^\d+$/.test(value)
+}
+
+/**
+ * ���������������������
+ */
+function idCard(value) {
+ return /^[1-9]\d{5}[1-9]\d{3}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}([0-9]|X)$/.test(
+ value
+ )
+}
+
+/**
+ * ���������������
+ */
+function carNo(value) {
+ // ���������������
+ const xreg = /^[���������������������������������������������������������������������������������������������������A-Z]{1}[A-Z]{1}(([0-9]{5}[DF]$)|([DF][A-HJ-NP-Z0-9][0-9]{4}$))/
+ // ���������
+ const creg = /^[���������������������������������������������������������������������������������������������������A-Z]{1}[A-Z]{1}[A-HJ-NP-Z0-9]{4}[A-HJ-NP-Z0-9���������������]{1}$/
+ if (value.length === 7) {
+ return creg.test(value)
+ } if (value.length === 8) {
+ return xreg.test(value)
+ }
+ return false
+}
+
+/**
+ * ������,���������2���������
+ */
+function amount(value) {
+ // ������������������������������������
+ return /^[1-9]\d*(,\d{3})*(\.\d{1,2})?$|^0\.\d{1,2}$/.test(value)
+}
+
+/**
+ * ������
+ */
+function chinese(value) {
+ const reg = /^[\u4e00-\u9fa5]+$/gi
+ return reg.test(value)
+}
+
+/**
+ * ������������������
+ */
+function letter(value) {
+ return /^[a-zA-Z]*$/.test(value)
+}
+
+/**
+ * ���������������������������
+ */
+function enOrNum(value) {
+ // ������������������
+ const reg = /^[0-9a-zA-Z]*$/g
+ return reg.test(value)
+}
+
+/**
+ * ���������������������������
+ */
+function contains(value, param) {
+ return value.indexOf(param) >= 0
+}
+
+/**
+ * ���������������������[min, max]
+ */
+function range(value, param) {
+ return value >= param[0] && value <= param[1]
+}
+
+/**
+ * ������������������������[min, max]
+ */
+function rangeLength(value, param) {
+ return value.length >= param[0] && value.length <= param[1]
+}
+
+/**
+ * ������������������
+ */
+function landline(value) {
+ const reg = /^\d{3,4}-\d{7,8}(-\d{3,4})?$/
+ return reg.test(value)
+}
+
+/**
+ * ������������������
+ */
+function empty(value) {
+ switch (typeof value) {
+ case 'undefined':
+ return true
+ case 'string':
+ if (value.replace(/(^[ \t\n\r]*)|([ \t\n\r]*$)/g, '').length == 0) return true
+ break
+ case 'boolean':
+ if (!value) return true
+ break
+ case 'number':
+ if (value === 0 || isNaN(value)) return true
+ break
+ case 'object':
+ if (value === null || value.length === 0) return true
+ for (const i in value) {
+ return false
+ }
+ return true
+ }
+ return false
+}
+
+/**
+ * ������json���������
+ */
+function jsonString(value) {
+ if (typeof value === 'string') {
+ try {
+ const obj = JSON.parse(value)
+ if (typeof obj === 'object' && obj) {
+ return true
+ }
+ return false
+ } catch (e) {
+ return false
+ }
+ }
+ return false
+}
+
+/**
+ * ������������
+ */
+function array(value) {
+ if (typeof Array.isArray === 'function') {
+ return Array.isArray(value)
+ }
+ return Object.prototype.toString.call(value) === '[object Array]'
+}
+
+/**
+ * ������������
+ */
+function object(value) {
+ return Object.prototype.toString.call(value) === '[object Object]'
+}
+
+/**
+ * ���������������������
+ */
+function code(value, len = 6) {
+ return new RegExp(`^\\d{${len}}$`).test(value)
+}
+
+/**
+ * ������������������
+ * @param {Object} value
+ */
+function func(value) {
+ return typeof value === 'function'
+}
+
+/**
+ * ������promise������
+ * @param {Object} value
+ */
+function promise(value) {
+ return object(value) && func(value.then) && func(value.catch)
+}
+
+/** ������������������
+ * @param {Object} value
+ */
+function image(value) {
+ const newValue = value.split('?')[0]
+ const IMAGE_REGEXP = /\.(jpeg|jpg|gif|png|svg|webp|jfif|bmp|dpg)/i
+ return IMAGE_REGEXP.test(newValue)
+}
+
+/**
+ * ������������������
+ * @param {Object} value
+ */
+function video(value) {
+ const VIDEO_REGEXP = /\.(mp4|mpg|mpeg|dat|asf|avi|rm|rmvb|mov|wmv|flv|mkv|m3u8)/i
+ return VIDEO_REGEXP.test(value)
+}
+
+/**
+ * ���������������������
+ * @param {Object}
+ * @return {Boolean}
+ */
+function regExp(o) {
+ return o && Object.prototype.toString.call(o) === '[object RegExp]'
+}
+
+export default {
+ email,
+ mobile,
+ url,
+ date,
+ dateISO,
+ number,
+ digits,
+ idCard,
+ carNo,
+ amount,
+ chinese,
+ letter,
+ enOrNum,
+ contains,
+ range,
+ rangeLength,
+ empty,
+ isEmpty: empty,
+ jsonString,
+ landline,
+ object,
+ array,
+ code,
+ func,
+ promise,
+ video,
+ image,
+ regExp,
+ string
+}
diff --git a/uni_modules/uview-ui/libs/function/throttle.js b/uni_modules/uview-ui/libs/function/throttle.js
new file mode 100644
index 0000000..2f33611
--- /dev/null
+++ b/uni_modules/uview-ui/libs/function/throttle.js
@@ -0,0 +1,30 @@
+let timer; let
+ flag
+/**
+ * ������������������������������������������������������
+ *
+ * @param {Function} func ������������������������
+ * @param {Number} wait ���������������
+ * @param {Boolean} immediate ������������������
+ * @return null
+ */
+function throttle(func, wait = 500, immediate = true) {
+ if (immediate) {
+ if (!flag) {
+ flag = true
+ // ������������������������������wait������������������������
+ typeof func === 'function' && func()
+ timer = setTimeout(() => {
+ flag = false
+ }, wait)
+ }
+ } else if (!flag) {
+ flag = true
+ // ���������������������������������wait���������������������������
+ timer = setTimeout(() => {
+ flag = false
+ typeof func === 'function' && func()
+ }, wait)
+ }
+}
+export default throttle
diff --git a/uni_modules/uview-ui/libs/luch-request/adapters/index.js b/uni_modules/uview-ui/libs/luch-request/adapters/index.js
new file mode 100644
index 0000000..e03cf5f
--- /dev/null
+++ b/uni_modules/uview-ui/libs/luch-request/adapters/index.js
@@ -0,0 +1,97 @@
+import buildURL from '../helpers/buildURL'
+import buildFullPath from '../core/buildFullPath'
+import settle from '../core/settle'
+import { isUndefined } from '../utils'
+
+/**
+ * ������������������������������
+ * @param {Array} keys - ���������������
+ * @param {Object} config2 - ������
+ * @return {{}} - ������������������
+ */
+const mergeKeys = (keys, config2) => {
+ const config = {}
+ keys.forEach((prop) => {
+ if (!isUndefined(config2[prop])) {
+ config[prop] = config2[prop]
+ }
+ })
+ return config
+}
+export default (config) => new Promise((resolve, reject) => {
+ const fullPath = buildURL(buildFullPath(config.baseURL, config.url), config.params)
+ const _config = {
+ url: fullPath,
+ header: config.header,
+ complete: (response) => {
+ config.fullPath = fullPath
+ response.config = config
+ try {
+ // ������������������������json ���������������
+ if (typeof response.data === 'string') {
+ response.data = JSON.parse(response.data)
+ }
+ // eslint-disable-next-line no-empty
+ } catch (e) {
+ }
+ settle(resolve, reject, response)
+ }
+ }
+ let requestTask
+ if (config.method === 'UPLOAD') {
+ delete _config.header['content-type']
+ delete _config.header['Content-Type']
+ const otherConfig = {
+ // #ifdef MP-ALIPAY
+ fileType: config.fileType,
+ // #endif
+ filePath: config.filePath,
+ name: config.name
+ }
+ const optionalKeys = [
+ // #ifdef APP-PLUS || H5
+ 'files',
+ // #endif
+ // #ifdef H5
+ 'file',
+ // #endif
+ // #ifdef H5 || APP-PLUS
+ 'timeout',
+ // #endif
+ 'formData'
+ ]
+ requestTask = uni.uploadFile({ ..._config, ...otherConfig, ...mergeKeys(optionalKeys, config) })
+ } else if (config.method === 'DOWNLOAD') {
+ // #ifdef H5 || APP-PLUS
+ if (!isUndefined(config.timeout)) {
+ _config.timeout = config.timeout
+ }
+ // #endif
+ requestTask = uni.downloadFile(_config)
+ } else {
+ const optionalKeys = [
+ 'data',
+ 'method',
+ // #ifdef H5 || APP-PLUS || MP-ALIPAY || MP-WEIXIN
+ 'timeout',
+ // #endif
+ 'dataType',
+ // #ifndef MP-ALIPAY
+ 'responseType',
+ // #endif
+ // #ifdef APP-PLUS
+ 'sslVerify',
+ // #endif
+ // #ifdef H5
+ 'withCredentials',
+ // #endif
+ // #ifdef APP-PLUS
+ 'firstIpv4'
+ // #endif
+ ]
+ requestTask = uni.request({ ..._config, ...mergeKeys(optionalKeys, config) })
+ }
+ if (config.getTask) {
+ config.getTask(requestTask, config)
+ }
+})
diff --git a/uni_modules/uview-ui/libs/luch-request/core/InterceptorManager.js b/uni_modules/uview-ui/libs/luch-request/core/InterceptorManager.js
new file mode 100644
index 0000000..3e8728d
--- /dev/null
+++ b/uni_modules/uview-ui/libs/luch-request/core/InterceptorManager.js
@@ -0,0 +1,50 @@
+'use strict'
+
+function InterceptorManager() {
+ this.handlers = []
+}
+
+/**
+ * Add a new interceptor to the stack
+ *
+ * @param {Function} fulfilled The function to handle `then` for a `Promise`
+ * @param {Function} rejected The function to handle `reject` for a `Promise`
+ *
+ * @return {Number} An ID used to remove interceptor later
+ */
+InterceptorManager.prototype.use = function use(fulfilled, rejected) {
+ this.handlers.push({
+ fulfilled,
+ rejected
+ })
+ return this.handlers.length - 1
+}
+
+/**
+ * Remove an interceptor from the stack
+ *
+ * @param {Number} id The ID that was returned by `use`
+ */
+InterceptorManager.prototype.eject = function eject(id) {
+ if (this.handlers[id]) {
+ this.handlers[id] = null
+ }
+}
+
+/**
+ * Iterate over all the registered interceptors
+ *
+ * This method is particularly useful for skipping over any
+ * interceptors that may have become `null` calling `eject`.
+ *
+ * @param {Function} fn The function to call for each interceptor
+ */
+InterceptorManager.prototype.forEach = function forEach(fn) {
+ this.handlers.forEach((h) => {
+ if (h !== null) {
+ fn(h)
+ }
+ })
+}
+
+export default InterceptorManager
diff --git a/uni_modules/uview-ui/libs/luch-request/core/Request.js b/uni_modules/uview-ui/libs/luch-request/core/Request.js
new file mode 100644
index 0000000..cc48566
--- /dev/null
+++ b/uni_modules/uview-ui/libs/luch-request/core/Request.js
@@ -0,0 +1,198 @@
+/**
+ * @Class Request
+ * @description luch-request http������������
+ * @version 3.0.7
+ * @Author lu-ch
+ * @Date 2021-09-04
+ * @Email webwork.s@qq.com
+ * ������: https://www.quanzhan.co/luch-request/
+ * github: https://github.com/lei-mu/luch-request
+ * DCloud: http://ext.dcloud.net.cn/plugin?id=392
+ * HBuilderX: beat-3.0.4 alpha-3.0.4
+ */
+
+import dispatchRequest from './dispatchRequest'
+import InterceptorManager from './InterceptorManager'
+import mergeConfig from './mergeConfig'
+import defaults from './defaults'
+import { isPlainObject } from '../utils'
+import clone from '../utils/clone'
+
+export default class Request {
+ /**
+ * @param {Object} arg - ������������
+ * @param {String} arg.baseURL - ���������������
+ * @param {Object} arg.header - ������header
+ * @param {String} arg.method = [GET|POST|PUT|DELETE|CONNECT|HEAD|OPTIONS|TRACE] - ������������������������
+ * @param {String} arg.dataType = [json] - ���������������dataType
+ * @param {String} arg.responseType = [text|arraybuffer] - ���������������responseType������������������������������
+ * @param {Object} arg.custom - ������������������������������
+ * @param {Number} arg.timeout - ������������������������������������ ms���������60000���H5(HBuilderX 2.9.9+)���APP(HBuilderX 2.9.9+)���������������������2.10.0������������������������
+ * @param {Boolean} arg.sslVerify - ��������������������������� ssl ���������������true.���App������������������HBuilderX 2.3.3+���
+ * @param {Boolean} arg.withCredentials - ���������������������������������������������������cookies������������false������H5���������HBuilderX 2.6.15+���
+ * @param {Boolean} arg.firstIpv4 - ���DNS���������������������ipv4���������false������ App-Android ������ (HBuilderX 2.8.0+)
+ * @param {Function(statusCode):Boolean} arg.validateStatus - ������������������������������������������statusCode >= 200 && statusCode < 300
+ */
+ constructor(arg = {}) {
+ if (!isPlainObject(arg)) {
+ arg = {}
+ console.warn('������������������������������������Object')
+ }
+ this.config = clone({ ...defaults, ...arg })
+ this.interceptors = {
+ request: new InterceptorManager(),
+ response: new InterceptorManager()
+ }
+ }
+
+ /**
+ * @Function
+ * @param {Request~setConfigCallback} f - ������������������������
+ */
+ setConfig(f) {
+ this.config = f(this.config)
+ }
+
+ middleware(config) {
+ config = mergeConfig(this.config, config)
+ const chain = [dispatchRequest, undefined]
+ let promise = Promise.resolve(config)
+
+ this.interceptors.request.forEach((interceptor) => {
+ chain.unshift(interceptor.fulfilled, interceptor.rejected)
+ })
+
+ this.interceptors.response.forEach((interceptor) => {
+ chain.push(interceptor.fulfilled, interceptor.rejected)
+ })
+
+ while (chain.length) {
+ promise = promise.then(chain.shift(), chain.shift())
+ }
+
+ return promise
+ }
+
+ /**
+ * @Function
+ * @param {Object} config - ���������������
+ * @prop {String} options.url - ������������
+ * @prop {Object} options.data - ������������
+ * @prop {Object} [options.responseType = config.responseType] [text|arraybuffer] - ���������������������
+ * @prop {Object} [options.dataType = config.dataType] - ������������ json��������������������������������������� JSON.parse
+ * @prop {Object} [options.header = config.header] - ������header
+ * @prop {Object} [options.method = config.method] - ������������
+ * @returns {Promise<unknown>}
+ */
+ request(config = {}) {
+ return this.middleware(config)
+ }
+
+ get(url, options = {}) {
+ return this.middleware({
+ url,
+ method: 'GET',
+ ...options
+ })
+ }
+
+ post(url, data, options = {}) {
+ return this.middleware({
+ url,
+ data,
+ method: 'POST',
+ ...options
+ })
+ }
+
+ // #ifndef MP-ALIPAY
+ put(url, data, options = {}) {
+ return this.middleware({
+ url,
+ data,
+ method: 'PUT',
+ ...options
+ })
+ }
+
+ // #endif
+
+ // #ifdef APP-PLUS || H5 || MP-WEIXIN || MP-BAIDU
+ delete(url, data, options = {}) {
+ return this.middleware({
+ url,
+ data,
+ method: 'DELETE',
+ ...options
+ })
+ }
+
+ // #endif
+
+ // #ifdef H5 || MP-WEIXIN
+ connect(url, data, options = {}) {
+ return this.middleware({
+ url,
+ data,
+ method: 'CONNECT',
+ ...options
+ })
+ }
+
+ // #endif
+
+ // #ifdef H5 || MP-WEIXIN || MP-BAIDU
+ head(url, data, options = {}) {
+ return this.middleware({
+ url,
+ data,
+ method: 'HEAD',
+ ...options
+ })
+ }
+
+ // #endif
+
+ // #ifdef APP-PLUS || H5 || MP-WEIXIN || MP-BAIDU
+ options(url, data, options = {}) {
+ return this.middleware({
+ url,
+ data,
+ method: 'OPTIONS',
+ ...options
+ })
+ }
+
+ // #endif
+
+ // #ifdef H5 || MP-WEIXIN
+ trace(url, data, options = {}) {
+ return this.middleware({
+ url,
+ data,
+ method: 'TRACE',
+ ...options
+ })
+ }
+
+ // #endif
+
+ upload(url, config = {}) {
+ config.url = url
+ config.method = 'UPLOAD'
+ return this.middleware(config)
+ }
+
+ download(url, config = {}) {
+ config.url = url
+ config.method = 'DOWNLOAD'
+ return this.middleware(config)
+ }
+}
+
+/**
+ * setConfig������
+ * @return {Object} - ������������������config
+ * @callback Request~setConfigCallback
+ * @param {Object} config - ������������config
+ */
diff --git a/uni_modules/uview-ui/libs/luch-request/core/buildFullPath.js b/uni_modules/uview-ui/libs/luch-request/core/buildFullPath.js
new file mode 100644
index 0000000..5eb8a17
--- /dev/null
+++ b/uni_modules/uview-ui/libs/luch-request/core/buildFullPath.js
@@ -0,0 +1,20 @@
+'use strict'
+
+import isAbsoluteURL from '../helpers/isAbsoluteURL'
+import combineURLs from '../helpers/combineURLs'
+
+/**
+ * Creates a new URL by combining the baseURL with the requestedURL,
+ * only when the requestedURL is not already an absolute URL.
+ * If the requestURL is absolute, this function returns the requestedURL untouched.
+ *
+ * @param {string} baseURL The base URL
+ * @param {string} requestedURL Absolute or relative URL to combine
+ * @returns {string} The combined full path
+ */
+export default function buildFullPath(baseURL, requestedURL) {
+ if (baseURL && !isAbsoluteURL(requestedURL)) {
+ return combineURLs(baseURL, requestedURL)
+ }
+ return requestedURL
+}
diff --git a/uni_modules/uview-ui/libs/luch-request/core/defaults.js b/uni_modules/uview-ui/libs/luch-request/core/defaults.js
new file mode 100644
index 0000000..be375a9
--- /dev/null
+++ b/uni_modules/uview-ui/libs/luch-request/core/defaults.js
@@ -0,0 +1,29 @@
+/**
+ * ���������������������
+ */
+
+export default {
+ baseURL: '',
+ header: {},
+ method: 'GET',
+ dataType: 'json',
+ // #ifndef MP-ALIPAY
+ responseType: 'text',
+ // #endif
+ custom: {},
+ // #ifdef H5 || APP-PLUS || MP-ALIPAY || MP-WEIXIN
+ timeout: 60000,
+ // #endif
+ // #ifdef APP-PLUS
+ sslVerify: true,
+ // #endif
+ // #ifdef H5
+ withCredentials: false,
+ // #endif
+ // #ifdef APP-PLUS
+ firstIpv4: false,
+ // #endif
+ validateStatus: function validateStatus(status) {
+ return status >= 200 && status < 300
+ }
+}
diff --git a/uni_modules/uview-ui/libs/luch-request/core/dispatchRequest.js b/uni_modules/uview-ui/libs/luch-request/core/dispatchRequest.js
new file mode 100644
index 0000000..724545c
--- /dev/null
+++ b/uni_modules/uview-ui/libs/luch-request/core/dispatchRequest.js
@@ -0,0 +1,3 @@
+import adapter from '../adapters/index'
+
+export default (config) => adapter(config)
diff --git a/uni_modules/uview-ui/libs/luch-request/core/mergeConfig.js b/uni_modules/uview-ui/libs/luch-request/core/mergeConfig.js
new file mode 100644
index 0000000..08f8b9b
--- /dev/null
+++ b/uni_modules/uview-ui/libs/luch-request/core/mergeConfig.js
@@ -0,0 +1,103 @@
+import { deepMerge, isUndefined } from '../utils'
+
+/**
+ * ���������������������������������������������������������������������������������������������������������������������
+ * @param {Array} keys - ���������
+ * @param {Object} globalsConfig - ���������������������
+ * @param {Object} config2 - ������������
+ * @return {{}}
+ */
+const mergeKeys = (keys, globalsConfig, config2) => {
+ const config = {}
+ keys.forEach((prop) => {
+ if (!isUndefined(config2[prop])) {
+ config[prop] = config2[prop]
+ } else if (!isUndefined(globalsConfig[prop])) {
+ config[prop] = globalsConfig[prop]
+ }
+ })
+ return config
+}
+/**
+ *
+ * @param globalsConfig - ���������������������������
+ * @param config2 - ���������������������
+ * @return - ������������������
+ */
+export default (globalsConfig, config2 = {}) => {
+ const method = config2.method || globalsConfig.method || 'GET'
+ let config = {
+ baseURL: globalsConfig.baseURL || '',
+ method,
+ url: config2.url || '',
+ params: config2.params || {},
+ custom: { ...(globalsConfig.custom || {}), ...(config2.custom || {}) },
+ header: deepMerge(globalsConfig.header || {}, config2.header || {})
+ }
+ const defaultToConfig2Keys = ['getTask', 'validateStatus']
+ config = { ...config, ...mergeKeys(defaultToConfig2Keys, globalsConfig, config2) }
+
+ // eslint-disable-next-line no-empty
+ if (method === 'DOWNLOAD') {
+ // #ifdef H5 || APP-PLUS
+ if (!isUndefined(config2.timeout)) {
+ config.timeout = config2.timeout
+ } else if (!isUndefined(globalsConfig.timeout)) {
+ config.timeout = globalsConfig.timeout
+ }
+ // #endif
+ } else if (method === 'UPLOAD') {
+ delete config.header['content-type']
+ delete config.header['Content-Type']
+ const uploadKeys = [
+ // #ifdef APP-PLUS || H5
+ 'files',
+ // #endif
+ // #ifdef MP-ALIPAY
+ 'fileType',
+ // #endif
+ // #ifdef H5
+ 'file',
+ // #endif
+ 'filePath',
+ 'name',
+ // #ifdef H5 || APP-PLUS
+ 'timeout',
+ // #endif
+ 'formData'
+ ]
+ uploadKeys.forEach((prop) => {
+ if (!isUndefined(config2[prop])) {
+ config[prop] = config2[prop]
+ }
+ })
+ // #ifdef H5 || APP-PLUS
+ if (isUndefined(config.timeout) && !isUndefined(globalsConfig.timeout)) {
+ config.timeout = globalsConfig.timeout
+ }
+ // #endif
+ } else {
+ const defaultsKeys = [
+ 'data',
+ // #ifdef H5 || APP-PLUS || MP-ALIPAY || MP-WEIXIN
+ 'timeout',
+ // #endif
+ 'dataType',
+ // #ifndef MP-ALIPAY
+ 'responseType',
+ // #endif
+ // #ifdef APP-PLUS
+ 'sslVerify',
+ // #endif
+ // #ifdef H5
+ 'withCredentials',
+ // #endif
+ // #ifdef APP-PLUS
+ 'firstIpv4'
+ // #endif
+ ]
+ config = { ...config, ...mergeKeys(defaultsKeys, globalsConfig, config2) }
+ }
+
+ return config
+}
diff --git a/uni_modules/uview-ui/libs/luch-request/core/settle.js b/uni_modules/uview-ui/libs/luch-request/core/settle.js
new file mode 100644
index 0000000..8d3638f
--- /dev/null
+++ b/uni_modules/uview-ui/libs/luch-request/core/settle.js
@@ -0,0 +1,16 @@
+/**
+ * Resolve or reject a Promise based on response status.
+ *
+ * @param {Function} resolve A function that resolves the promise.
+ * @param {Function} reject A function that rejects the promise.
+ * @param {object} response The response.
+ */
+export default function settle(resolve, reject, response) {
+ const { validateStatus } = response.config
+ const status = response.statusCode
+ if (status && (!validateStatus || validateStatus(status))) {
+ resolve(response)
+ } else {
+ reject(response)
+ }
+}
diff --git a/uni_modules/uview-ui/libs/luch-request/helpers/buildURL.js b/uni_modules/uview-ui/libs/luch-request/helpers/buildURL.js
new file mode 100644
index 0000000..472ad6a
--- /dev/null
+++ b/uni_modules/uview-ui/libs/luch-request/helpers/buildURL.js
@@ -0,0 +1,69 @@
+'use strict'
+
+import * as utils from '../utils'
+
+function encode(val) {
+ return encodeURIComponent(val)
+ .replace(/%40/gi, '@')
+ .replace(/%3A/gi, ':')
+ .replace(/%24/g, '$')
+ .replace(/%2C/gi, ',')
+ .replace(/%20/g, '+')
+ .replace(/%5B/gi, '[')
+ .replace(/%5D/gi, ']')
+}
+
+/**
+ * Build a URL by appending params to the end
+ *
+ * @param {string} url The base of the url (e.g., http://www.google.com)
+ * @param {object} [params] The params to be appended
+ * @returns {string} The formatted url
+ */
+export default function buildURL(url, params) {
+ /* eslint no-param-reassign:0 */
+ if (!params) {
+ return url
+ }
+
+ let serializedParams
+ if (utils.isURLSearchParams(params)) {
+ serializedParams = params.toString()
+ } else {
+ const parts = []
+
+ utils.forEach(params, (val, key) => {
+ if (val === null || typeof val === 'undefined') {
+ return
+ }
+
+ if (utils.isArray(val)) {
+ key = `${key}[]`
+ } else {
+ val = [val]
+ }
+
+ utils.forEach(val, (v) => {
+ if (utils.isDate(v)) {
+ v = v.toISOString()
+ } else if (utils.isObject(v)) {
+ v = JSON.stringify(v)
+ }
+ parts.push(`${encode(key)}=${encode(v)}`)
+ })
+ })
+
+ serializedParams = parts.join('&')
+ }
+
+ if (serializedParams) {
+ const hashmarkIndex = url.indexOf('#')
+ if (hashmarkIndex !== -1) {
+ url = url.slice(0, hashmarkIndex)
+ }
+
+ url += (url.indexOf('?') === -1 ? '?' : '&') + serializedParams
+ }
+
+ return url
+}
diff --git a/uni_modules/uview-ui/libs/luch-request/helpers/combineURLs.js b/uni_modules/uview-ui/libs/luch-request/helpers/combineURLs.js
new file mode 100644
index 0000000..ac7c124
--- /dev/null
+++ b/uni_modules/uview-ui/libs/luch-request/helpers/combineURLs.js
@@ -0,0 +1,14 @@
+'use strict'
+
+/**
+ * Creates a new URL by combining the specified URLs
+ *
+ * @param {string} baseURL The base URL
+ * @param {string} relativeURL The relative URL
+ * @returns {string} The combined URL
+ */
+export default function combineURLs(baseURL, relativeURL) {
+ return relativeURL
+ ? `${baseURL.replace(/\/+$/, '')}/${relativeURL.replace(/^\/+/, '')}`
+ : baseURL
+}
diff --git a/uni_modules/uview-ui/libs/luch-request/helpers/isAbsoluteURL.js b/uni_modules/uview-ui/libs/luch-request/helpers/isAbsoluteURL.js
new file mode 100644
index 0000000..63c6647
--- /dev/null
+++ b/uni_modules/uview-ui/libs/luch-request/helpers/isAbsoluteURL.js
@@ -0,0 +1,14 @@
+'use strict'
+
+/**
+ * Determines whether the specified URL is absolute
+ *
+ * @param {string} url The URL to test
+ * @returns {boolean} True if the specified URL is absolute, otherwise false
+ */
+export default function isAbsoluteURL(url) {
+ // A URL is considered absolute if it begins with "<scheme>://" or "//" (protocol-relative URL).
+ // RFC 3986 defines scheme name as a sequence of characters beginning with a letter and followed
+ // by any combination of letters, digits, plus, period, or hyphen.
+ return /^([a-z][a-z\d+\-.]*:)?\/\//i.test(url)
+}
diff --git a/uni_modules/uview-ui/libs/luch-request/index.d.ts b/uni_modules/uview-ui/libs/luch-request/index.d.ts
new file mode 100644
index 0000000..e939ce1
--- /dev/null
+++ b/uni_modules/uview-ui/libs/luch-request/index.d.ts
@@ -0,0 +1,116 @@
+type AnyObject = Record<string | number | symbol, any>
+type HttpPromise<T> = Promise<HttpResponse<T>>;
+type Tasks = UniApp.RequestTask | UniApp.UploadTask | UniApp.DownloadTask
+export interface RequestTask {
+ abort: () => void;
+ offHeadersReceived: () => void;
+ onHeadersReceived: () => void;
+}
+export interface HttpRequestConfig<T = Tasks> {
+ /** ��������������� */
+ baseURL?: string;
+ /** ��������������������������� */
+ url?: string;
+
+ /** ��������������������������������������������������� */
+ params?: AnyObject;
+ /** ��������������� */
+ data?: AnyObject;
+
+ /** ��������������� key */
+ name?: string;
+ /** HTTP ������������������������ form data */
+ formData?: AnyObject;
+ /** ��������������������������������� */
+ filePath?: string;
+ /** ������������������������������������ files ������filePath ��� name ������������App���H5��� 2.6.15+��� */
+ files?: Array<{
+ name?: string;
+ file?: File;
+ uri: string;
+ }>;
+ /** ������������������������������H5���2.6.15+��������� */
+ file?: File;
+
+ /** ��������������� */
+ header?: AnyObject;
+ /** ������������ */
+ method?: "GET" | "POST" | "PUT" | "DELETE" | "CONNECT" | "HEAD" | "OPTIONS" | "TRACE" | "UPLOAD" | "DOWNLOAD";
+ /** ������������ json��������������������������������������� JSON.parse */
+ dataType?: string;
+ /** ��������������������������������������������������������� */
+ responseType?: "text" | "arraybuffer";
+ /** ��������������� */
+ custom?: AnyObject;
+ /** ������������������������������������2.10.0������������������������������ */
+ timeout?: number;
+ /** DNS���������������������ipv4������ App-Android ������ (HBuilderX 2.8.0+) */
+ firstIpv4?: boolean;
+ /** ������ ssl ������ ���5+App������������������HBuilderX 2.3.3+��� */
+ sslVerify?: boolean;
+ /** ������������������������������������cookies������H5���������HBuilderX 2.6.15+��� */
+ withCredentials?: boolean;
+
+ /** ���������������������task, options������������������������options��� */
+ getTask?: (task: T, options: HttpRequestConfig<T>) => void;
+ /** ������������������������ */
+ validateStatus?: (statusCode: number) => boolean | void;
+}
+export interface HttpResponse<T = any> {
+ config: HttpRequestConfig;
+ statusCode: number;
+ cookies: Array<string>;
+ data: T;
+ errMsg: string;
+ header: AnyObject;
+}
+export interface HttpUploadResponse<T = any> {
+ config: HttpRequestConfig;
+ statusCode: number;
+ data: T;
+ errMsg: string;
+}
+export interface HttpDownloadResponse extends HttpResponse {
+ tempFilePath: string;
+}
+export interface HttpError {
+ config: HttpRequestConfig;
+ statusCode?: number;
+ cookies?: Array<string>;
+ data?: any;
+ errMsg: string;
+ header?: AnyObject;
+}
+export interface HttpInterceptorManager<V, E = V> {
+ use(
+ onFulfilled?: (config: V) => Promise<V> | V,
+ onRejected?: (config: E) => Promise<E> | E
+ ): void;
+ eject(id: number): void;
+}
+export abstract class HttpRequestAbstract {
+ constructor(config?: HttpRequestConfig);
+ config: HttpRequestConfig;
+ interceptors: {
+ request: HttpInterceptorManager<HttpRequestConfig, HttpRequestConfig>;
+ response: HttpInterceptorManager<HttpResponse, HttpError>;
+ }
+ middleware<T = any>(config: HttpRequestConfig): HttpPromise<T>;
+ request<T = any>(config: HttpRequestConfig<UniApp.RequestTask>): HttpPromise<T>;
+ get<T = any>(url: string, config?: HttpRequestConfig<UniApp.RequestTask>): HttpPromise<T>;
+ upload<T = any>(url: string, config?: HttpRequestConfig<UniApp.UploadTask>): HttpPromise<T>;
+ delete<T = any>(url: string, data?: AnyObject, config?: HttpRequestConfig<UniApp.RequestTask>): HttpPromise<T>;
+ head<T = any>(url: string, data?: AnyObject, config?: HttpRequestConfig<UniApp.RequestTask>): HttpPromise<T>;
+ post<T = any>(url: string, data?: AnyObject, config?: HttpRequestConfig<UniApp.RequestTask>): HttpPromise<T>;
+ put<T = any>(url: string, data?: AnyObject, config?: HttpRequestConfig<UniApp.RequestTask>): HttpPromise<T>;
+ connect<T = any>(url: string, data?: AnyObject, config?: HttpRequestConfig<UniApp.RequestTask>): HttpPromise<T>;
+ options<T = any>(url: string, data?: AnyObject, config?: HttpRequestConfig<UniApp.RequestTask>): HttpPromise<T>;
+ trace<T = any>(url: string, data?: AnyObject, config?: HttpRequestConfig<UniApp.RequestTask>): HttpPromise<T>;
+
+ download(url: string, config?: HttpRequestConfig<UniApp.DownloadTask>): Promise<HttpDownloadResponse>;
+
+ setConfig(onSend: (config: HttpRequestConfig) => HttpRequestConfig): void;
+}
+
+declare class HttpRequest extends HttpRequestAbstract { }
+export default HttpRequest;
diff --git a/uni_modules/uview-ui/libs/luch-request/index.js b/uni_modules/uview-ui/libs/luch-request/index.js
new file mode 100644
index 0000000..8fb2b44
--- /dev/null
+++ b/uni_modules/uview-ui/libs/luch-request/index.js
@@ -0,0 +1,3 @@
+import Request from './core/Request'
+
+export default Request
diff --git a/uni_modules/uview-ui/libs/luch-request/utils.js b/uni_modules/uview-ui/libs/luch-request/utils.js
new file mode 100644
index 0000000..847283d
--- /dev/null
+++ b/uni_modules/uview-ui/libs/luch-request/utils.js
@@ -0,0 +1,131 @@
+'use strict'
+
+// utils is a library of generic helper functions non-specific to axios
+
+const { toString } = Object.prototype
+
+/**
+ * Determine if a value is an Array
+ *
+ * @param {Object} val The value to test
+ * @returns {boolean} True if value is an Array, otherwise false
+ */
+export function isArray(val) {
+ return toString.call(val) === '[object Array]'
+}
+
+/**
+ * Determine if a value is an Object
+ *
+ * @param {Object} val The value to test
+ * @returns {boolean} True if value is an Object, otherwise false
+ */
+export function isObject(val) {
+ return val !== null && typeof val === 'object'
+}
+
+/**
+ * Determine if a value is a Date
+ *
+ * @param {Object} val The value to test
+ * @returns {boolean} True if value is a Date, otherwise false
+ */
+export function isDate(val) {
+ return toString.call(val) === '[object Date]'
+}
+
+/**
+ * Determine if a value is a URLSearchParams object
+ *
+ * @param {Object} val The value to test
+ * @returns {boolean} True if value is a URLSearchParams object, otherwise false
+ */
+export function isURLSearchParams(val) {
+ return typeof URLSearchParams !== 'undefined' && val instanceof URLSearchParams
+}
+
+/**
+ * Iterate over an Array or an Object invoking a function for each item.
+ *
+ * If `obj` is an Array callback will be called passing
+ * the value, index, and complete array for each item.
+ *
+ * If 'obj' is an Object callback will be called passing
+ * the value, key, and complete object for each property.
+ *
+ * @param {Object|Array} obj The object to iterate
+ * @param {Function} fn The callback to invoke for each item
+ */
+export function forEach(obj, fn) {
+ // Don't bother if no value provided
+ if (obj === null || typeof obj === 'undefined') {
+ return
+ }
+
+ // Force an array if not already something iterable
+ if (typeof obj !== 'object') {
+ /* eslint no-param-reassign:0 */
+ obj = [obj]
+ }
+
+ if (isArray(obj)) {
+ // Iterate over array values
+ for (let i = 0, l = obj.length; i < l; i++) {
+ fn.call(null, obj[i], i, obj)
+ }
+ } else {
+ // Iterate over object keys
+ for (const key in obj) {
+ if (Object.prototype.hasOwnProperty.call(obj, key)) {
+ fn.call(null, obj[key], key, obj)
+ }
+ }
+ }
+}
+
+/**
+ * ���������boolean ���
+ * @param val
+ * @returns {boolean}
+ */
+export function isBoolean(val) {
+ return typeof val === 'boolean'
+}
+
+/**
+ * ������������������������{} new Object
+ * @param {any} obj - ���������������
+ * @returns {boolean}
+ */
+export function isPlainObject(obj) {
+ return Object.prototype.toString.call(obj) === '[object Object]'
+}
+
+/**
+ * Function equal to merge with the difference being that no reference
+ * to original objects is kept.
+ *
+ * @see merge
+ * @param {Object} obj1 Object to merge
+ * @returns {Object} Result of all merge properties
+ */
+export function deepMerge(/* obj1, obj2, obj3, ... */) {
+ const result = {}
+ function assignValue(val, key) {
+ if (typeof result[key] === 'object' && typeof val === 'object') {
+ result[key] = deepMerge(result[key], val)
+ } else if (typeof val === 'object') {
+ result[key] = deepMerge({}, val)
+ } else {
+ result[key] = val
+ }
+ }
+ for (let i = 0, l = arguments.length; i < l; i++) {
+ forEach(arguments[i], assignValue)
+ }
+ return result
+}
+
+export function isUndefined(val) {
+ return typeof val === 'undefined'
+}
diff --git a/uni_modules/uview-ui/libs/luch-request/utils/clone.js b/uni_modules/uview-ui/libs/luch-request/utils/clone.js
new file mode 100644
index 0000000..2fee704
--- /dev/null
+++ b/uni_modules/uview-ui/libs/luch-request/utils/clone.js
@@ -0,0 +1,264 @@
+/* eslint-disable */
+var clone = (function() {
+ 'use strict';
+
+ function _instanceof(obj, type) {
+ return type != null && obj instanceof type;
+ }
+
+ var nativeMap;
+ try {
+ nativeMap = Map;
+ } catch(_) {
+ // maybe a reference error because no `Map`. Give it a dummy value that no
+ // value will ever be an instanceof.
+ nativeMap = function() {};
+ }
+
+ var nativeSet;
+ try {
+ nativeSet = Set;
+ } catch(_) {
+ nativeSet = function() {};
+ }
+
+ var nativePromise;
+ try {
+ nativePromise = Promise;
+ } catch(_) {
+ nativePromise = function() {};
+ }
+
+ /**
+ * Clones (copies) an Object using deep copying.
+ *
+ * This function supports circular references by default, but if you are certain
+ * there are no circular references in your object, you can save some CPU time
+ * by calling clone(obj, false).
+ *
+ * Caution: if `circular` is false and `parent` contains circular references,
+ * your program may enter an infinite loop and crash.
+ *
+ * @param `parent` - the object to be cloned
+ * @param `circular` - set to true if the object to be cloned may contain
+ * circular references. (optional - true by default)
+ * @param `depth` - set to a number if the object is only to be cloned to
+ * a particular depth. (optional - defaults to Infinity)
+ * @param `prototype` - sets the prototype to be used when cloning an object.
+ * (optional - defaults to parent prototype).
+ * @param `includeNonEnumerable` - set to true if the non-enumerable properties
+ * should be cloned as well. Non-enumerable properties on the prototype
+ * chain will be ignored. (optional - false by default)
+ */
+ function clone(parent, circular, depth, prototype, includeNonEnumerable) {
+ if (typeof circular === 'object') {
+ depth = circular.depth;
+ prototype = circular.prototype;
+ includeNonEnumerable = circular.includeNonEnumerable;
+ circular = circular.circular;
+ }
+ // maintain two arrays for circular references, where corresponding parents
+ // and children have the same index
+ var allParents = [];
+ var allChildren = [];
+
+ var useBuffer = typeof Buffer != 'undefined';
+
+ if (typeof circular == 'undefined')
+ circular = true;
+
+ if (typeof depth == 'undefined')
+ depth = Infinity;
+
+ // recurse this function so we don't reset allParents and allChildren
+ function _clone(parent, depth) {
+ // cloning null always returns null
+ if (parent === null)
+ return null;
+
+ if (depth === 0)
+ return parent;
+
+ var child;
+ var proto;
+ if (typeof parent != 'object') {
+ return parent;
+ }
+
+ if (_instanceof(parent, nativeMap)) {
+ child = new nativeMap();
+ } else if (_instanceof(parent, nativeSet)) {
+ child = new nativeSet();
+ } else if (_instanceof(parent, nativePromise)) {
+ child = new nativePromise(function (resolve, reject) {
+ parent.then(function(value) {
+ resolve(_clone(value, depth - 1));
+ }, function(err) {
+ reject(_clone(err, depth - 1));
+ });
+ });
+ } else if (clone.__isArray(parent)) {
+ child = [];
+ } else if (clone.__isRegExp(parent)) {
+ child = new RegExp(parent.source, __getRegExpFlags(parent));
+ if (parent.lastIndex) child.lastIndex = parent.lastIndex;
+ } else if (clone.__isDate(parent)) {
+ child = new Date(parent.getTime());
+ } else if (useBuffer && Buffer.isBuffer(parent)) {
+ if (Buffer.from) {
+ // Node.js >= 5.10.0
+ child = Buffer.from(parent);
+ } else {
+ // Older Node.js versions
+ child = new Buffer(parent.length);
+ parent.copy(child);
+ }
+ return child;
+ } else if (_instanceof(parent, Error)) {
+ child = Object.create(parent);
+ } else {
+ if (typeof prototype == 'undefined') {
+ proto = Object.getPrototypeOf(parent);
+ child = Object.create(proto);
+ }
+ else {
+ child = Object.create(prototype);
+ proto = prototype;
+ }
+ }
+
+ if (circular) {
+ var index = allParents.indexOf(parent);
+
+ if (index != -1) {
+ return allChildren[index];
+ }
+ allParents.push(parent);
+ allChildren.push(child);
+ }
+
+ if (_instanceof(parent, nativeMap)) {
+ parent.forEach(function(value, key) {
+ var keyChild = _clone(key, depth - 1);
+ var valueChild = _clone(value, depth - 1);
+ child.set(keyChild, valueChild);
+ });
+ }
+ if (_instanceof(parent, nativeSet)) {
+ parent.forEach(function(value) {
+ var entryChild = _clone(value, depth - 1);
+ child.add(entryChild);
+ });
+ }
+
+ for (var i in parent) {
+ var attrs = Object.getOwnPropertyDescriptor(parent, i);
+ if (attrs) {
+ child[i] = _clone(parent[i], depth - 1);
+ }
+
+ try {
+ var objProperty = Object.getOwnPropertyDescriptor(parent, i);
+ if (objProperty.set === 'undefined') {
+ // no setter defined. Skip cloning this property
+ continue;
+ }
+ child[i] = _clone(parent[i], depth - 1);
+ } catch(e){
+ if (e instanceof TypeError) {
+ // when in strict mode, TypeError will be thrown if child[i] property only has a getter
+ // we can't do anything about this, other than inform the user that this property cannot be set.
+ continue
+ } else if (e instanceof ReferenceError) {
+ //this may happen in non strict mode
+ continue
+ }
+ }
+
+ }
+
+ if (Object.getOwnPropertySymbols) {
+ var symbols = Object.getOwnPropertySymbols(parent);
+ for (var i = 0; i < symbols.length; i++) {
+ // Don't need to worry about cloning a symbol because it is a primitive,
+ // like a number or string.
+ var symbol = symbols[i];
+ var descriptor = Object.getOwnPropertyDescriptor(parent, symbol);
+ if (descriptor && !descriptor.enumerable && !includeNonEnumerable) {
+ continue;
+ }
+ child[symbol] = _clone(parent[symbol], depth - 1);
+ Object.defineProperty(child, symbol, descriptor);
+ }
+ }
+
+ if (includeNonEnumerable) {
+ var allPropertyNames = Object.getOwnPropertyNames(parent);
+ for (var i = 0; i < allPropertyNames.length; i++) {
+ var propertyName = allPropertyNames[i];
+ var descriptor = Object.getOwnPropertyDescriptor(parent, propertyName);
+ if (descriptor && descriptor.enumerable) {
+ continue;
+ }
+ child[propertyName] = _clone(parent[propertyName], depth - 1);
+ Object.defineProperty(child, propertyName, descriptor);
+ }
+ }
+
+ return child;
+ }
+
+ return _clone(parent, depth);
+ }
+
+ /**
+ * Simple flat clone using prototype, accepts only objects, usefull for property
+ * override on FLAT configuration object (no nested props).
+ *
+ * USE WITH CAUTION! This may not behave as you wish if you do not know how this
+ * works.
+ */
+ clone.clonePrototype = function clonePrototype(parent) {
+ if (parent === null)
+ return null;
+
+ var c = function () {};
+ c.prototype = parent;
+ return new c();
+ };
+
+// private utility functions
+
+ function __objToStr(o) {
+ return Object.prototype.toString.call(o);
+ }
+ clone.__objToStr = __objToStr;
+
+ function __isDate(o) {
+ return typeof o === 'object' && __objToStr(o) === '[object Date]';
+ }
+ clone.__isDate = __isDate;
+
+ function __isArray(o) {
+ return typeof o === 'object' && __objToStr(o) === '[object Array]';
+ }
+ clone.__isArray = __isArray;
+
+ function __isRegExp(o) {
+ return typeof o === 'object' && __objToStr(o) === '[object RegExp]';
+ }
+ clone.__isRegExp = __isRegExp;
+
+ function __getRegExpFlags(re) {
+ var flags = '';
+ if (re.global) flags += 'g';
+ if (re.ignoreCase) flags += 'i';
+ if (re.multiline) flags += 'm';
+ return flags;
+ }
+ clone.__getRegExpFlags = __getRegExpFlags;
+
+ return clone;
+})();
+
+export default clone
diff --git a/uni_modules/uview-ui/libs/mixin/button.js b/uni_modules/uview-ui/libs/mixin/button.js
new file mode 100644
index 0000000..0c019c2
--- /dev/null
+++ b/uni_modules/uview-ui/libs/mixin/button.js
@@ -0,0 +1,13 @@
+export default {
+ props: {
+ lang: String,
+ sessionFrom: String,
+ sendMessageTitle: String,
+ sendMessagePath: String,
+ sendMessageImg: String,
+ showMessageCard: Boolean,
+ appParameter: String,
+ formType: String,
+ openType: String
+ }
+}
diff --git a/uni_modules/uview-ui/libs/mixin/mixin.js b/uni_modules/uview-ui/libs/mixin/mixin.js
new file mode 100644
index 0000000..f41a178
--- /dev/null
+++ b/uni_modules/uview-ui/libs/mixin/mixin.js
@@ -0,0 +1,160 @@
+module.exports = {
+ // ������������������������������������������������������������������
+ props: {
+ // ������������������������������������������������������������������������������������
+ customStyle: {
+ type: [Object, String],
+ default: () => ({})
+ },
+ customClass: {
+ type: String,
+ default: ''
+ },
+ // ���������������������
+ url: {
+ type: String,
+ default: ''
+ },
+ // ���������������������
+ linkType: {
+ type: String,
+ default: 'navigateTo'
+ }
+ },
+ data() {
+ return {}
+ },
+ onLoad() {
+ // getRect���������$u���������������������������������in(this)���������������������������������������������������������
+ this.$u.getRect = this.$uGetRect
+ },
+ created() {
+ // ���������������������created���������������������������������������������������created���������������������$u
+ this.$u.getRect = this.$uGetRect
+ },
+ computed: {
+ // ���2.x���������������������$u���������uni������������������������������������������uni.$u.xxx������
+ // ������������������computed���������������������������this.$u������������������������������js���������uni.$u.xxx
+ // ������nvue������������������������������������$u������������������������������������������nvue���������������������������������props���������
+ $u() {
+ // #ifndef APP-NVUE
+ // ������nvue������������props���http���mixin������������������������������setData���������������������������
+ return uni.$u.deepMerge(uni.$u, {
+ props: undefined,
+ http: undefined,
+ mixin: undefined
+ })
+ // #endif
+ // #ifdef APP-NVUE
+ return uni.$u
+ // #endif
+ },
+ /**
+ * ������bem������������
+ * ������������������������H5���nvue������������class������������������������:class="[bem()]"���������������������
+ * ���������������������������������������������������������������������������������������������������������������������������������['a', 'b', 'c']���'a b c'���������
+ * @param {String} name ������������
+ * @param {Array} fixed ������������������������
+ * @param {Array} change ���������������������true������false������������������������������
+ * @returns {Array|string}
+ */
+ bem() {
+ return function (name, fixed, change) {
+ // ������������
+ const prefix = `u-${name}--`
+ const classes = {}
+ if (fixed) {
+ fixed.map((item) => {
+ // ���������������������������������
+ classes[prefix + this[item]] = true
+ })
+ }
+ if (change) {
+ change.map((item) => {
+ // ���������������������������this[item]���������true������false������������������������������������������
+ this[item] ? (classes[prefix + item] = this[item]) : (delete classes[prefix + item])
+ })
+ }
+ return Object.keys(classes)
+ // ������������������������������������������������������������������������������������������������������","������������������
+ // #ifdef MP-ALIPAY || MP-TOUTIAO || MP-LARK
+ .join(' ')
+ // #endif
+ }
+ }
+ },
+ methods: {
+ // ���������������������
+ openPage(urlKey = 'url') {
+ const url = this[urlKey]
+ if (url) {
+ // ������������uni.navigateTo���������
+ uni[this.linkType]({
+ url
+ })
+ }
+ },
+ // ������������������
+ // ���������������������������������������������������������������������������������������������bug(2020-07-21)
+ // ���������������������������������������������������������������view������
+ $uGetRect(selector, all) {
+ return new Promise((resolve) => {
+ uni.createSelectorQuery()
+ .in(this)[all ? 'selectAll' : 'select'](selector)
+ .boundingClientRect((rect) => {
+ if (all && Array.isArray(rect) && rect.length) {
+ resolve(rect)
+ }
+ if (!all && rect) {
+ resolve(rect)
+ }
+ })
+ .exec()
+ })
+ },
+ getParentData(parentName = '') {
+ // ���������created������������parent������
+ if (!this.parent) this.parent = {}
+ // ������������������������������������������������������(������������u-radio������������u-radio-group���this)
+ // ������������this���������������������������������������(u-radio���this)���parentData������������������������
+ // ���������������������������������������������������������������������������������this.parent.xxx���������������������������������
+ // ���������������������������������������������������������������������u-radio-group���������data���������������������������������������������������������������
+ this.parent = uni.$u.$parent.call(this, parentName)
+ if (this.parent.children) {
+ // ������������������children������������������������������������������������������������������children���
+ this.parent.children.indexOf(this) === -1 && this.parent.children.push(this)
+ }
+ if (this.parent && this.parentData) {
+ // ������parentData������������������parent���������������������������parentData
+ Object.keys(this.parentData).map((key) => {
+ this.parentData[key] = this.parent[key]
+ })
+ }
+ },
+ // ������������������
+ preventEvent(e) {
+ e && typeof (e.stopPropagation) === 'function' && e.stopPropagation()
+ },
+ // ���������
+ noop(e) {
+ this.preventEvent(e)
+ }
+ },
+ onReachBottom() {
+ uni.$emit('uOnReachBottom')
+ },
+ beforeDestroy() {
+ // ������������������������������parent���chldren������������checkbox���checkbox-group������������������������������������
+ // ���������������������������������������������children������������������������������������������������������
+ if (this.parent && uni.$u.test.array(this.parent.children)) {
+ // ���������������������������������������children������������������������
+ const childrenList = this.parent.children
+ childrenList.map((child, index) => {
+ // ������������������������
+ if (child === this) {
+ childrenList.splice(index, 1)
+ }
+ })
+ }
+ }
+}
diff --git a/uni_modules/uview-ui/libs/mixin/mpMixin.js b/uni_modules/uview-ui/libs/mixin/mpMixin.js
new file mode 100644
index 0000000..29e7e65
--- /dev/null
+++ b/uni_modules/uview-ui/libs/mixin/mpMixin.js
@@ -0,0 +1,8 @@
+export default {
+ // #ifdef MP-WEIXIN
+ // ���������������������������������������������������Vue������������������������������������flex������
+ options: {
+ virtualHost: true
+ }
+ // #endif
+}
diff --git a/uni_modules/uview-ui/libs/mixin/mpShare.js b/uni_modules/uview-ui/libs/mixin/mpShare.js
new file mode 100644
index 0000000..b07bbd3
--- /dev/null
+++ b/uni_modules/uview-ui/libs/mixin/mpShare.js
@@ -0,0 +1,13 @@
+module.exports = {
+ onLoad() {
+ // ���������������������������
+ uni.$u.mpShare = {
+ title: '', // ������������������������
+ path: '', // ���������������������������
+ imageUrl: '' // ������������������������������
+ }
+ },
+ onShareAppMessage() {
+ return uni.$u.mpShare
+ }
+}
diff --git a/uni_modules/uview-ui/libs/mixin/openType.js b/uni_modules/uview-ui/libs/mixin/openType.js
new file mode 100644
index 0000000..1216181
--- /dev/null
+++ b/uni_modules/uview-ui/libs/mixin/openType.js
@@ -0,0 +1,25 @@
+export default {
+ props: {
+ openType: String
+ },
+ methods: {
+ onGetUserInfo(event) {
+ this.$emit('getuserinfo', event.detail)
+ },
+ onContact(event) {
+ this.$emit('contact', event.detail)
+ },
+ onGetPhoneNumber(event) {
+ this.$emit('getphonenumber', event.detail)
+ },
+ onError(event) {
+ this.$emit('error', event.detail)
+ },
+ onLaunchApp(event) {
+ this.$emit('launchapp', event.detail)
+ },
+ onOpenSetting(event) {
+ this.$emit('opensetting', event.detail)
+ }
+ }
+}
diff --git a/uni_modules/uview-ui/libs/mixin/style.js b/uni_modules/uview-ui/libs/mixin/style.js
new file mode 100644
index 0000000..2660180
--- /dev/null
+++ b/uni_modules/uview-ui/libs/mixin/style.js
@@ -0,0 +1,228 @@
+export default {
+ props: {
+ // flex������������
+ flexDirection: {
+ type: String,
+ default: ''
+ },
+ // flex-direction���������
+ fd: {
+ type: String,
+ default: ''
+ },
+ // ������������
+ display: {
+ type: String,
+ default: ''
+ },
+ // display������
+ d: {
+ type: String,
+ default: ''
+ },
+ // ������������������
+ justifyContent: {
+ type: String,
+ default: ''
+ },
+ // justifyContent���������
+ jc: {
+ type: String,
+ default: ''
+ },
+ // ������������������
+ alignItems: {
+ type: String,
+ default: ''
+ },
+ // align-items���������
+ ai: {
+ type: String,
+ default: ''
+ },
+ color: {
+ type: String,
+ default: ''
+ },
+ // color������
+ c: {
+ type: String,
+ default: ''
+ },
+ // ������������
+ fontSize: {
+ type: [String, Number],
+ default: 0
+ },
+ // font-size������
+ fs: {
+ type: [String, Number],
+ default: ''
+ },
+ margin: {
+ type: [String, Number],
+ default: 0
+ },
+ // margin������
+ m: {
+ type: [String, Number],
+ default: 0
+ },
+ // margin-top
+ marginTop: {
+ type: [String, Number],
+ default: 0
+ },
+ // margin-top������
+ mt: {
+ type: [String, Number],
+ default: 0
+ },
+ // margin-right
+ marginRight: {
+ type: [String, Number],
+ default: 0
+ },
+ // margin-right������
+ mr: {
+ type: [String, Number],
+ default: 0
+ },
+ // margin-bottom
+ marginBottom: {
+ type: [String, Number],
+ default: 0
+ },
+ // margin-bottom������
+ mb: {
+ type: [String, Number],
+ default: 0
+ },
+ // margin-left
+ marginLeft: {
+ type: [String, Number],
+ default: 0
+ },
+ // margin-left������
+ ml: {
+ type: [String, Number],
+ default: 0
+ },
+ // padding-left
+ paddingLeft: {
+ type: [String, Number],
+ default: 0
+ },
+ // padding-left������
+ pl: {
+ type: [String, Number],
+ default: 0
+ },
+ // padding-top
+ paddingTop: {
+ type: [String, Number],
+ default: 0
+ },
+ // padding-top������
+ pt: {
+ type: [String, Number],
+ default: 0
+ },
+ // padding-right
+ paddingRight: {
+ type: [String, Number],
+ default: 0
+ },
+ // padding-right������
+ pr: {
+ type: [String, Number],
+ default: 0
+ },
+ // padding-bottom
+ paddingBottom: {
+ type: [String, Number],
+ default: 0
+ },
+ // padding-bottom������
+ pb: {
+ type: [String, Number],
+ default: 0
+ },
+ // border-radius
+ borderRadius: {
+ type: [String, Number],
+ default: 0
+ },
+ // border-radius������
+ radius: {
+ type: [String, Number],
+ default: 0
+ },
+ // transform
+ transform: {
+ type: String,
+ default: ''
+ },
+ // ������
+ position: {
+ type: String,
+ default: ''
+ },
+ // position������
+ pos: {
+ type: String,
+ default: ''
+ },
+ // ������
+ width: {
+ type: [String, Number],
+ default: null
+ },
+ // width������
+ w: {
+ type: [String, Number],
+ default: null
+ },
+ // ������
+ height: {
+ type: [String, Number],
+ default: null
+ },
+ // height������
+ h: {
+ type: [String, Number],
+ default: null
+ },
+ top: {
+ type: [String, Number],
+ default: 0
+ },
+ right: {
+ type: [String, Number],
+ default: 0
+ },
+ bottom: {
+ type: [String, Number],
+ default: 0
+ },
+ left: {
+ type: [String, Number],
+ default: 0
+ }
+ },
+ computed: {
+ viewStyle() {
+ const style = {}
+ const addStyle = uni.$u.addStyle(this.width || this.w) && (style.width = addStyle(this.width || this.w))(this.height || this.h) && (style.height = addStyle(this.height || this.h))(this.margin || this.m) && (style.margin = addStyle(this.margin || this.m))(this.marginTop || this.mt) && (style.marginTop = addStyle(this.marginTop || this.mt))(this.marginRight || this.mr) && (style.marginRight = addStyle(this.marginRight || this.mr))(this.marginBottom || this.mb) && (style.marginBottom = addStyle(this.marginBottom || this.mb))(this.marginLeft || this.ml) && (style.marginLeft = addStyle(this.marginLeft || this.ml))(this.padding || this.p) && (style.padding = addStyle(this.padding || this.p))(this.paddingTop || this.pt) && (style.paddingTop = addStyle(this.paddingTop || this.pt))(this.paddingRight || this.pr) && (style.paddingRight = addStyle(this.paddingRight || this.pr))(this.paddingBottom || this.pb) && (style.paddingBottom = addStyle(this.paddingBottom || this.pb))(this.paddingLeft || this.pl) && (style.paddingLeft = addStyle(this.paddingLeft || this.pl))(this.color || this.c) && (style.color = this.color || this.c)(this.fontSize || this.fs) && (style.fontSize = this.fontSize || this.fs)(this.borderRadius || this.radius) && (style.borderRadius = this.borderRadius || this.radius)(this.position || this.pos) && (this.position = this.position || this.pos)(this.flexDirection || this.fd) && (this.flexDirection = this.flexDirection || this.fd)(this.justifyContent || jc) && (this.justifyContent = this.justifyContent || jc)(this.alignItems || ai) && (this.alignItems = this.alignItems || ai)
+
+ return uni.$u.deepMerge(style, uni.$u.addStyle(this.customStyle))
+ }
+ },
+ methods: {
+ // ������margin������padding������������������padding: 0 20������padding: 0 20px
+ getUnit(unit = '') {
+ // ������������������������������������������������������������������������������������������������������������
+ return uni.$u.trim(unit).split(' ').map((item) => uni.$u.addUnit(item)).join(' ')
+ }
+ }
+}
diff --git a/uni_modules/uview-ui/libs/mixin/touch.js b/uni_modules/uview-ui/libs/mixin/touch.js
new file mode 100644
index 0000000..0ecbd88
--- /dev/null
+++ b/uni_modules/uview-ui/libs/mixin/touch.js
@@ -0,0 +1,59 @@
+const MIN_DISTANCE = 10
+
+function getDirection(x, y) {
+ if (x > y && x > MIN_DISTANCE) {
+ return 'horizontal'
+ }
+ if (y > x && y > MIN_DISTANCE) {
+ return 'vertical'
+ }
+ return ''
+}
+
+export default {
+ methods: {
+ getTouchPoint(e) {
+ if (!e) {
+ return {
+ x: 0,
+ y: 0
+ }
+ } if (e.touches && e.touches[0]) {
+ return {
+ x: e.touches[0].pageX,
+ y: e.touches[0].pageY
+ }
+ } if (e.changedTouches && e.changedTouches[0]) {
+ return {
+ x: e.changedTouches[0].pageX,
+ y: e.changedTouches[0].pageY
+ }
+ }
+ return {
+ x: e.clientX || 0,
+ y: e.clientY || 0
+ }
+ },
+ resetTouchStatus() {
+ this.direction = ''
+ this.deltaX = 0
+ this.deltaY = 0
+ this.offsetX = 0
+ this.offsetY = 0
+ },
+ touchStart(event) {
+ this.resetTouchStatus()
+ const touch = this.getTouchPoint(event)
+ this.startX = touch.x
+ this.startY = touch.y
+ },
+ touchMove(event) {
+ const touch = this.getTouchPoint(event)
+ this.deltaX = touch.x - this.startX
+ this.deltaY = touch.y - this.startY
+ this.offsetX = Math.abs(this.deltaX)
+ this.offsetY = Math.abs(this.deltaY)
+ this.direction = this.direction || getDirection(this.offsetX, this.offsetY)
+ }
+ }
+}
diff --git a/uni_modules/uview-ui/libs/util/async-validator.js b/uni_modules/uview-ui/libs/util/async-validator.js
new file mode 100644
index 0000000..9e114df
--- /dev/null
+++ b/uni_modules/uview-ui/libs/util/async-validator.js
@@ -0,0 +1,1343 @@
+function _extends() {
+ _extends = Object.assign || function (target) {
+ for (let i = 1; i < arguments.length; i++) {
+ const source = arguments[i]
+
+ for (const key in source) {
+ if (Object.prototype.hasOwnProperty.call(source, key)) {
+ target[key] = source[key]
+ }
+ }
+ }
+
+ return target
+ }
+
+ return _extends.apply(this, arguments)
+}
+
+/* eslint no-console:0 */
+const formatRegExp = /%[sdj%]/g
+let warning = function warning() {} // don't print warning message when in production env or node runtime
+
+if (typeof process !== 'undefined' && process.env && process.env.NODE_ENV !== 'production' && typeof window
+ !== 'undefined' && typeof document !== 'undefined') {
+ warning = function warning(type, errors) {
+ if (typeof console !== 'undefined' && console.warn) {
+ if (errors.every((e) => typeof e === 'string')) {
+ console.warn(type, errors)
+ }
+ }
+ }
+}
+
+function convertFieldsError(errors) {
+ if (!errors || !errors.length) return null
+ const fields = {}
+ errors.forEach((error) => {
+ const { field } = error
+ fields[field] = fields[field] || []
+ fields[field].push(error)
+ })
+ return fields
+}
+
+function format() {
+ for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
+ args[_key] = arguments[_key]
+ }
+
+ let i = 1
+ const f = args[0]
+ const len = args.length
+
+ if (typeof f === 'function') {
+ return f.apply(null, args.slice(1))
+ }
+
+ if (typeof f === 'string') {
+ let str = String(f).replace(formatRegExp, (x) => {
+ if (x === '%%') {
+ return '%'
+ }
+
+ if (i >= len) {
+ return x
+ }
+
+ switch (x) {
+ case '%s':
+ return String(args[i++])
+
+ case '%d':
+ return Number(args[i++])
+
+ case '%j':
+ try {
+ return JSON.stringify(args[i++])
+ } catch (_) {
+ return '[Circular]'
+ }
+
+ break
+
+ default:
+ return x
+ }
+ })
+
+ for (let arg = args[i]; i < len; arg = args[++i]) {
+ str += ` ${arg}`
+ }
+
+ return str
+ }
+
+ return f
+}
+
+function isNativeStringType(type) {
+ return type === 'string' || type === 'url' || type === 'hex' || type === 'email' || type === 'pattern'
+}
+
+function isEmptyValue(value, type) {
+ if (value === undefined || value === null) {
+ return true
+ }
+
+ if (type === 'array' && Array.isArray(value) && !value.length) {
+ return true
+ }
+
+ if (isNativeStringType(type) && typeof value === 'string' && !value) {
+ return true
+ }
+
+ return false
+}
+
+function asyncParallelArray(arr, func, callback) {
+ const results = []
+ let total = 0
+ const arrLength = arr.length
+
+ function count(errors) {
+ results.push.apply(results, errors)
+ total++
+
+ if (total === arrLength) {
+ callback(results)
+ }
+ }
+
+ arr.forEach((a) => {
+ func(a, count)
+ })
+}
+
+function asyncSerialArray(arr, func, callback) {
+ let index = 0
+ const arrLength = arr.length
+
+ function next(errors) {
+ if (errors && errors.length) {
+ callback(errors)
+ return
+ }
+
+ const original = index
+ index += 1
+
+ if (original < arrLength) {
+ func(arr[original], next)
+ } else {
+ callback([])
+ }
+ }
+
+ next([])
+}
+
+function flattenObjArr(objArr) {
+ const ret = []
+ Object.keys(objArr).forEach((k) => {
+ ret.push.apply(ret, objArr[k])
+ })
+ return ret
+}
+
+function asyncMap(objArr, option, func, callback) {
+ if (option.first) {
+ const _pending = new Promise((resolve, reject) => {
+ const next = function next(errors) {
+ callback(errors)
+ return errors.length ? reject({
+ errors,
+ fields: convertFieldsError(errors)
+ }) : resolve()
+ }
+
+ const flattenArr = flattenObjArr(objArr)
+ asyncSerialArray(flattenArr, func, next)
+ })
+
+ _pending.catch((e) => e)
+
+ return _pending
+ }
+
+ let firstFields = option.firstFields || []
+
+ if (firstFields === true) {
+ firstFields = Object.keys(objArr)
+ }
+
+ const objArrKeys = Object.keys(objArr)
+ const objArrLength = objArrKeys.length
+ let total = 0
+ const results = []
+ const pending = new Promise((resolve, reject) => {
+ const next = function next(errors) {
+ results.push.apply(results, errors)
+ total++
+
+ if (total === objArrLength) {
+ callback(results)
+ return results.length ? reject({
+ errors: results,
+ fields: convertFieldsError(results)
+ }) : resolve()
+ }
+ }
+
+ if (!objArrKeys.length) {
+ callback(results)
+ resolve()
+ }
+
+ objArrKeys.forEach((key) => {
+ const arr = objArr[key]
+
+ if (firstFields.indexOf(key) !== -1) {
+ asyncSerialArray(arr, func, next)
+ } else {
+ asyncParallelArray(arr, func, next)
+ }
+ })
+ })
+ pending.catch((e) => e)
+ return pending
+}
+
+function complementError(rule) {
+ return function (oe) {
+ if (oe && oe.message) {
+ oe.field = oe.field || rule.fullField
+ return oe
+ }
+
+ return {
+ message: typeof oe === 'function' ? oe() : oe,
+ field: oe.field || rule.fullField
+ }
+ }
+}
+
+function deepMerge(target, source) {
+ if (source) {
+ for (const s in source) {
+ if (source.hasOwnProperty(s)) {
+ const value = source[s]
+
+ if (typeof value === 'object' && typeof target[s] === 'object') {
+ target[s] = { ...target[s], ...value }
+ } else {
+ target[s] = value
+ }
+ }
+ }
+ }
+
+ return target
+}
+
+/**
+ * Rule for validating required fields.
+ *
+ * @param rule The validation rule.
+ * @param value The value of the field on the source object.
+ * @param source The source object being validated.
+ * @param errors An array of errors that this rule may add
+ * validation errors to.
+ * @param options The validation options.
+ * @param options.messages The validation messages.
+ */
+
+function required(rule, value, source, errors, options, type) {
+ if (rule.required && (!source.hasOwnProperty(rule.field) || isEmptyValue(value, type || rule.type))) {
+ errors.push(format(options.messages.required, rule.fullField))
+ }
+}
+
+/**
+ * Rule for validating whitespace.
+ *
+ * @param rule The validation rule.
+ * @param value The value of the field on the source object.
+ * @param source The source object being validated.
+ * @param errors An array of errors that this rule may add
+ * validation errors to.
+ * @param options The validation options.
+ * @param options.messages The validation messages.
+ */
+
+function whitespace(rule, value, source, errors, options) {
+ if (/^\s+$/.test(value) || value === '') {
+ errors.push(format(options.messages.whitespace, rule.fullField))
+ }
+}
+
+/* eslint max-len:0 */
+
+const pattern = {
+ // http://emailregex.com/
+ email: /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/,
+ url: new RegExp(
+ '^(?!mailto:)(?:(?:http|https|ftp)://|//)(?:\\S+(?::\\S*)?@)?(?:(?:(?:[1-9]\\d?|1\\d\\d|2[01]\\d|22[0-3])(?:\\.(?:1?\\d{1,2}|2[0-4]\\d|25[0-5])){2}(?:\\.(?:[0-9]\\d?|1\\d\\d|2[0-4]\\d|25[0-4]))|(?:(?:[a-z\\u00a1-\\uffff0-9]+-*)*[a-z\\u00a1-\\uffff0-9]+)(?:\\.(?:[a-z\\u00a1-\\uffff0-9]+-*)*[a-z\\u00a1-\\uffff0-9]+)*(?:\\.(?:[a-z\\u00a1-\\uffff]{2,})))|localhost)(?::\\d{2,5})?(?:(/|\\?|#)[^\\s]*)?$',
+ 'i'
+ ),
+ hex: /^#?([a-f0-9]{6}|[a-f0-9]{3})$/i
+}
+var types = {
+ integer: function integer(value) {
+ return /^(-)?\d+$/.test(value);
+ },
+ float: function float(value) {
+ return /^(-)?\d+(\.\d+)?$/.test(value);
+ },
+ array: function array(value) {
+ return Array.isArray(value)
+ },
+ regexp: function regexp(value) {
+ if (value instanceof RegExp) {
+ return true
+ }
+
+ try {
+ return !!new RegExp(value)
+ } catch (e) {
+ return false
+ }
+ },
+ date: function date(value) {
+ return typeof value.getTime === 'function' && typeof value.getMonth === 'function' && typeof value.getYear
+ === 'function'
+ },
+ number: function number(value) {
+ if (isNaN(value)) {
+ return false
+ }
+
+ // ������������������������������������������������
+ return typeof +value === 'number'
+ },
+ object: function object(value) {
+ return typeof value === 'object' && !types.array(value)
+ },
+ method: function method(value) {
+ return typeof value === 'function'
+ },
+ email: function email(value) {
+ return typeof value === 'string' && !!value.match(pattern.email) && value.length < 255
+ },
+ url: function url(value) {
+ return typeof value === 'string' && !!value.match(pattern.url)
+ },
+ hex: function hex(value) {
+ return typeof value === 'string' && !!value.match(pattern.hex)
+ }
+}
+/**
+ * Rule for validating the type of a value.
+ *
+ * @param rule The validation rule.
+ * @param value The value of the field on the source object.
+ * @param source The source object being validated.
+ * @param errors An array of errors that this rule may add
+ * validation errors to.
+ * @param options The validation options.
+ * @param options.messages The validation messages.
+ */
+
+function type(rule, value, source, errors, options) {
+ if (rule.required && value === undefined) {
+ required(rule, value, source, errors, options)
+ return
+ }
+
+ const custom = ['integer', 'float', 'array', 'regexp', 'object', 'method', 'email', 'number', 'date', 'url', 'hex']
+ const ruleType = rule.type
+
+ if (custom.indexOf(ruleType) > -1) {
+ if (!types[ruleType](value)) {
+ errors.push(format(options.messages.types[ruleType], rule.fullField, rule.type))
+ } // straight typeof check
+ } else if (ruleType && typeof value !== rule.type) {
+ errors.push(format(options.messages.types[ruleType], rule.fullField, rule.type))
+ }
+}
+
+/**
+ * Rule for validating minimum and maximum allowed values.
+ *
+ * @param rule The validation rule.
+ * @param value The value of the field on the source object.
+ * @param source The source object being validated.
+ * @param errors An array of errors that this rule may add
+ * validation errors to.
+ * @param options The validation options.
+ * @param options.messages The validation messages.
+ */
+
+function range(rule, value, source, errors, options) {
+ const len = typeof rule.len === 'number'
+ const min = typeof rule.min === 'number'
+ const max = typeof rule.max === 'number' // ���������������������������U+010000���������U+10FFFF������������������������Supplementary Plane���
+
+ const spRegexp = /[\uD800-\uDBFF][\uDC00-\uDFFF]/g
+ let val = value
+ let key = null
+ const num = typeof value === 'number'
+ const str = typeof value === 'string'
+ const arr = Array.isArray(value)
+
+ if (num) {
+ key = 'number'
+ } else if (str) {
+ key = 'string'
+ } else if (arr) {
+ key = 'array'
+ } // if the value is not of a supported type for range validation
+ // the validation rule rule should use the
+ // type property to also test for a particular type
+
+ if (!key) {
+ return false
+ }
+
+ if (arr) {
+ val = value.length
+ }
+
+ if (str) {
+ // ������������������U+010000���������length������������������bug������"������������".lenght !== 3
+ val = value.replace(spRegexp, '_').length
+ }
+
+ if (len) {
+ if (val !== rule.len) {
+ errors.push(format(options.messages[key].len, rule.fullField, rule.len))
+ }
+ } else if (min && !max && val < rule.min) {
+ errors.push(format(options.messages[key].min, rule.fullField, rule.min))
+ } else if (max && !min && val > rule.max) {
+ errors.push(format(options.messages[key].max, rule.fullField, rule.max))
+ } else if (min && max && (val < rule.min || val > rule.max)) {
+ errors.push(format(options.messages[key].range, rule.fullField, rule.min, rule.max))
+ }
+}
+
+const ENUM = 'enum'
+/**
+ * Rule for validating a value exists in an enumerable list.
+ *
+ * @param rule The validation rule.
+ * @param value The value of the field on the source object.
+ * @param source The source object being validated.
+ * @param errors An array of errors that this rule may add
+ * validation errors to.
+ * @param options The validation options.
+ * @param options.messages The validation messages.
+ */
+
+function enumerable(rule, value, source, errors, options) {
+ rule[ENUM] = Array.isArray(rule[ENUM]) ? rule[ENUM] : []
+
+ if (rule[ENUM].indexOf(value) === -1) {
+ errors.push(format(options.messages[ENUM], rule.fullField, rule[ENUM].join(', ')))
+ }
+}
+
+/**
+ * Rule for validating a regular expression pattern.
+ *
+ * @param rule The validation rule.
+ * @param value The value of the field on the source object.
+ * @param source The source object being validated.
+ * @param errors An array of errors that this rule may add
+ * validation errors to.
+ * @param options The validation options.
+ * @param options.messages The validation messages.
+ */
+
+function pattern$1(rule, value, source, errors, options) {
+ if (rule.pattern) {
+ if (rule.pattern instanceof RegExp) {
+ // if a RegExp instance is passed, reset `lastIndex` in case its `global`
+ // flag is accidentally set to `true`, which in a validation scenario
+ // is not necessary and the result might be misleading
+ rule.pattern.lastIndex = 0
+
+ if (!rule.pattern.test(value)) {
+ errors.push(format(options.messages.pattern.mismatch, rule.fullField, value, rule.pattern))
+ }
+ } else if (typeof rule.pattern === 'string') {
+ const _pattern = new RegExp(rule.pattern)
+
+ if (!_pattern.test(value)) {
+ errors.push(format(options.messages.pattern.mismatch, rule.fullField, value, rule.pattern))
+ }
+ }
+ }
+}
+
+const rules = {
+ required,
+ whitespace,
+ type,
+ range,
+ enum: enumerable,
+ pattern: pattern$1
+}
+
+/**
+ * Performs validation for string types.
+ *
+ * @param rule The validation rule.
+ * @param value The value of the field on the source object.
+ * @param callback The callback function.
+ * @param source The source object being validated.
+ * @param options The validation options.
+ * @param options.messages The validation messages.
+ */
+
+function string(rule, value, callback, source, options) {
+ const errors = []
+ const validate = rule.required || !rule.required && source.hasOwnProperty(rule.field)
+
+ if (validate) {
+ if (isEmptyValue(value, 'string') && !rule.required) {
+ return callback()
+ }
+
+ rules.required(rule, value, source, errors, options, 'string')
+
+ if (!isEmptyValue(value, 'string')) {
+ rules.type(rule, value, source, errors, options)
+ rules.range(rule, value, source, errors, options)
+ rules.pattern(rule, value, source, errors, options)
+
+ if (rule.whitespace === true) {
+ rules.whitespace(rule, value, source, errors, options)
+ }
+ }
+ }
+
+ callback(errors)
+}
+
+/**
+ * Validates a function.
+ *
+ * @param rule The validation rule.
+ * @param value The value of the field on the source object.
+ * @param callback The callback function.
+ * @param source The source object being validated.
+ * @param options The validation options.
+ * @param options.messages The validation messages.
+ */
+
+function method(rule, value, callback, source, options) {
+ const errors = []
+ const validate = rule.required || !rule.required && source.hasOwnProperty(rule.field)
+
+ if (validate) {
+ if (isEmptyValue(value) && !rule.required) {
+ return callback()
+ }
+
+ rules.required(rule, value, source, errors, options)
+
+ if (value !== undefined) {
+ rules.type(rule, value, source, errors, options)
+ }
+ }
+
+ callback(errors)
+}
+
+/**
+ * Validates a number.
+ *
+ * @param rule The validation rule.
+ * @param value The value of the field on the source object.
+ * @param callback The callback function.
+ * @param source The source object being validated.
+ * @param options The validation options.
+ * @param options.messages The validation messages.
+ */
+
+function number(rule, value, callback, source, options) {
+ const errors = []
+ const validate = rule.required || !rule.required && source.hasOwnProperty(rule.field)
+
+ if (validate) {
+ if (value === '') {
+ value = undefined
+ }
+
+ if (isEmptyValue(value) && !rule.required) {
+ return callback()
+ }
+
+ rules.required(rule, value, source, errors, options)
+
+ if (value !== undefined) {
+ rules.type(rule, value, source, errors, options)
+ rules.range(rule, value, source, errors, options)
+ }
+ }
+
+ callback(errors)
+}
+
+/**
+ * Validates a boolean.
+ *
+ * @param rule The validation rule.
+ * @param value The value of the field on the source object.
+ * @param callback The callback function.
+ * @param source The source object being validated.
+ * @param options The validation options.
+ * @param options.messages The validation messages.
+ */
+
+function _boolean(rule, value, callback, source, options) {
+ const errors = []
+ const validate = rule.required || !rule.required && source.hasOwnProperty(rule.field)
+
+ if (validate) {
+ if (isEmptyValue(value) && !rule.required) {
+ return callback()
+ }
+
+ rules.required(rule, value, source, errors, options)
+
+ if (value !== undefined) {
+ rules.type(rule, value, source, errors, options)
+ }
+ }
+
+ callback(errors)
+}
+
+/**
+ * Validates the regular expression type.
+ *
+ * @param rule The validation rule.
+ * @param value The value of the field on the source object.
+ * @param callback The callback function.
+ * @param source The source object being validated.
+ * @param options The validation options.
+ * @param options.messages The validation messages.
+ */
+
+function regexp(rule, value, callback, source, options) {
+ const errors = []
+ const validate = rule.required || !rule.required && source.hasOwnProperty(rule.field)
+
+ if (validate) {
+ if (isEmptyValue(value) && !rule.required) {
+ return callback()
+ }
+
+ rules.required(rule, value, source, errors, options)
+
+ if (!isEmptyValue(value)) {
+ rules.type(rule, value, source, errors, options)
+ }
+ }
+
+ callback(errors)
+}
+
+/**
+ * Validates a number is an integer.
+ *
+ * @param rule The validation rule.
+ * @param value The value of the field on the source object.
+ * @param callback The callback function.
+ * @param source The source object being validated.
+ * @param options The validation options.
+ * @param options.messages The validation messages.
+ */
+
+function integer(rule, value, callback, source, options) {
+ const errors = []
+ const validate = rule.required || !rule.required && source.hasOwnProperty(rule.field)
+
+ if (validate) {
+ if (isEmptyValue(value) && !rule.required) {
+ return callback()
+ }
+
+ rules.required(rule, value, source, errors, options)
+
+ if (value !== undefined) {
+ rules.type(rule, value, source, errors, options)
+ rules.range(rule, value, source, errors, options)
+ }
+ }
+
+ callback(errors)
+}
+
+/**
+ * Validates a number is a floating point number.
+ *
+ * @param rule The validation rule.
+ * @param value The value of the field on the source object.
+ * @param callback The callback function.
+ * @param source The source object being validated.
+ * @param options The validation options.
+ * @param options.messages The validation messages.
+ */
+
+function floatFn(rule, value, callback, source, options) {
+ const errors = []
+ const validate = rule.required || !rule.required && source.hasOwnProperty(rule.field)
+
+ if (validate) {
+ if (isEmptyValue(value) && !rule.required) {
+ return callback()
+ }
+
+ rules.required(rule, value, source, errors, options)
+
+ if (value !== undefined) {
+ rules.type(rule, value, source, errors, options)
+ rules.range(rule, value, source, errors, options)
+ }
+ }
+
+ callback(errors)
+}
+
+/**
+ * Validates an array.
+ *
+ * @param rule The validation rule.
+ * @param value The value of the field on the source object.
+ * @param callback The callback function.
+ * @param source The source object being validated.
+ * @param options The validation options.
+ * @param options.messages The validation messages.
+ */
+
+function array(rule, value, callback, source, options) {
+ const errors = []
+ const validate = rule.required || !rule.required && source.hasOwnProperty(rule.field)
+
+ if (validate) {
+ if (isEmptyValue(value, 'array') && !rule.required) {
+ return callback()
+ }
+
+ rules.required(rule, value, source, errors, options, 'array')
+
+ if (!isEmptyValue(value, 'array')) {
+ rules.type(rule, value, source, errors, options)
+ rules.range(rule, value, source, errors, options)
+ }
+ }
+
+ callback(errors)
+}
+
+/**
+ * Validates an object.
+ *
+ * @param rule The validation rule.
+ * @param value The value of the field on the source object.
+ * @param callback The callback function.
+ * @param source The source object being validated.
+ * @param options The validation options.
+ * @param options.messages The validation messages.
+ */
+
+function object(rule, value, callback, source, options) {
+ const errors = []
+ const validate = rule.required || !rule.required && source.hasOwnProperty(rule.field)
+
+ if (validate) {
+ if (isEmptyValue(value) && !rule.required) {
+ return callback()
+ }
+
+ rules.required(rule, value, source, errors, options)
+
+ if (value !== undefined) {
+ rules.type(rule, value, source, errors, options)
+ }
+ }
+
+ callback(errors)
+}
+
+const ENUM$1 = 'enum'
+/**
+ * Validates an enumerable list.
+ *
+ * @param rule The validation rule.
+ * @param value The value of the field on the source object.
+ * @param callback The callback function.
+ * @param source The source object being validated.
+ * @param options The validation options.
+ * @param options.messages The validation messages.
+ */
+
+function enumerable$1(rule, value, callback, source, options) {
+ const errors = []
+ const validate = rule.required || !rule.required && source.hasOwnProperty(rule.field)
+
+ if (validate) {
+ if (isEmptyValue(value) && !rule.required) {
+ return callback()
+ }
+
+ rules.required(rule, value, source, errors, options)
+
+ if (value !== undefined) {
+ rules[ENUM$1](rule, value, source, errors, options)
+ }
+ }
+
+ callback(errors)
+}
+
+/**
+ * Validates a regular expression pattern.
+ *
+ * Performs validation when a rule only contains
+ * a pattern property but is not declared as a string type.
+ *
+ * @param rule The validation rule.
+ * @param value The value of the field on the source object.
+ * @param callback The callback function.
+ * @param source The source object being validated.
+ * @param options The validation options.
+ * @param options.messages The validation messages.
+ */
+
+function pattern$2(rule, value, callback, source, options) {
+ const errors = []
+ const validate = rule.required || !rule.required && source.hasOwnProperty(rule.field)
+
+ if (validate) {
+ if (isEmptyValue(value, 'string') && !rule.required) {
+ return callback()
+ }
+
+ rules.required(rule, value, source, errors, options)
+
+ if (!isEmptyValue(value, 'string')) {
+ rules.pattern(rule, value, source, errors, options)
+ }
+ }
+
+ callback(errors)
+}
+
+function date(rule, value, callback, source, options) {
+ const errors = []
+ const validate = rule.required || !rule.required && source.hasOwnProperty(rule.field)
+
+ if (validate) {
+ if (isEmptyValue(value) && !rule.required) {
+ return callback()
+ }
+
+ rules.required(rule, value, source, errors, options)
+
+ if (!isEmptyValue(value)) {
+ let dateObject
+
+ if (typeof value === 'number') {
+ dateObject = new Date(value)
+ } else {
+ dateObject = value
+ }
+
+ rules.type(rule, dateObject, source, errors, options)
+
+ if (dateObject) {
+ rules.range(rule, dateObject.getTime(), source, errors, options)
+ }
+ }
+ }
+
+ callback(errors)
+}
+
+function required$1(rule, value, callback, source, options) {
+ const errors = []
+ const type = Array.isArray(value) ? 'array' : typeof value
+ rules.required(rule, value, source, errors, options, type)
+ callback(errors)
+}
+
+function type$1(rule, value, callback, source, options) {
+ const ruleType = rule.type
+ const errors = []
+ const validate = rule.required || !rule.required && source.hasOwnProperty(rule.field)
+
+ if (validate) {
+ if (isEmptyValue(value, ruleType) && !rule.required) {
+ return callback()
+ }
+
+ rules.required(rule, value, source, errors, options, ruleType)
+
+ if (!isEmptyValue(value, ruleType)) {
+ rules.type(rule, value, source, errors, options)
+ }
+ }
+
+ callback(errors)
+}
+
+/**
+ * Performs validation for any type.
+ *
+ * @param rule The validation rule.
+ * @param value The value of the field on the source object.
+ * @param callback The callback function.
+ * @param source The source object being validated.
+ * @param options The validation options.
+ * @param options.messages The validation messages.
+ */
+
+function any(rule, value, callback, source, options) {
+ const errors = []
+ const validate = rule.required || !rule.required && source.hasOwnProperty(rule.field)
+
+ if (validate) {
+ if (isEmptyValue(value) && !rule.required) {
+ return callback()
+ }
+
+ rules.required(rule, value, source, errors, options)
+ }
+
+ callback(errors)
+}
+
+const validators = {
+ string,
+ method,
+ number,
+ boolean: _boolean,
+ regexp,
+ integer,
+ float: floatFn,
+ array,
+ object,
+ enum: enumerable$1,
+ pattern: pattern$2,
+ date,
+ url: type$1,
+ hex: type$1,
+ email: type$1,
+ required: required$1,
+ any
+}
+
+function newMessages() {
+ return {
+ default: 'Validation error on field %s',
+ required: '%s is required',
+ enum: '%s must be one of %s',
+ whitespace: '%s cannot be empty',
+ date: {
+ format: '%s date %s is invalid for format %s',
+ parse: '%s date could not be parsed, %s is invalid ',
+ invalid: '%s date %s is invalid'
+ },
+ types: {
+ string: '%s is not a %s',
+ method: '%s is not a %s (function)',
+ array: '%s is not an %s',
+ object: '%s is not an %s',
+ number: '%s is not a %s',
+ date: '%s is not a %s',
+ boolean: '%s is not a %s',
+ integer: '%s is not an %s',
+ float: '%s is not a %s',
+ regexp: '%s is not a valid %s',
+ email: '%s is not a valid %s',
+ url: '%s is not a valid %s',
+ hex: '%s is not a valid %s'
+ },
+ string: {
+ len: '%s must be exactly %s characters',
+ min: '%s must be at least %s characters',
+ max: '%s cannot be longer than %s characters',
+ range: '%s must be between %s and %s characters'
+ },
+ number: {
+ len: '%s must equal %s',
+ min: '%s cannot be less than %s',
+ max: '%s cannot be greater than %s',
+ range: '%s must be between %s and %s'
+ },
+ array: {
+ len: '%s must be exactly %s in length',
+ min: '%s cannot be less than %s in length',
+ max: '%s cannot be greater than %s in length',
+ range: '%s must be between %s and %s in length'
+ },
+ pattern: {
+ mismatch: '%s value %s does not match pattern %s'
+ },
+ clone: function clone() {
+ const cloned = JSON.parse(JSON.stringify(this))
+ cloned.clone = this.clone
+ return cloned
+ }
+ }
+}
+const messages = newMessages()
+
+/**
+ * Encapsulates a validation schema.
+ *
+ * @param descriptor An object declaring validation rules
+ * for this schema.
+ */
+
+function Schema(descriptor) {
+ this.rules = null
+ this._messages = messages
+ this.define(descriptor)
+}
+
+Schema.prototype = {
+ messages: function messages(_messages) {
+ if (_messages) {
+ this._messages = deepMerge(newMessages(), _messages)
+ }
+
+ return this._messages
+ },
+ define: function define(rules) {
+ if (!rules) {
+ throw new Error('Cannot configure a schema with no rules')
+ }
+
+ if (typeof rules !== 'object' || Array.isArray(rules)) {
+ throw new Error('Rules must be an object')
+ }
+
+ this.rules = {}
+ let z
+ let item
+
+ for (z in rules) {
+ if (rules.hasOwnProperty(z)) {
+ item = rules[z]
+ this.rules[z] = Array.isArray(item) ? item : [item]
+ }
+ }
+ },
+ validate: function validate(source_, o, oc) {
+ const _this = this
+
+ if (o === void 0) {
+ o = {}
+ }
+
+ if (oc === void 0) {
+ oc = function oc() {}
+ }
+
+ let source = source_
+ let options = o
+ let callback = oc
+
+ if (typeof options === 'function') {
+ callback = options
+ options = {}
+ }
+
+ if (!this.rules || Object.keys(this.rules).length === 0) {
+ if (callback) {
+ callback()
+ }
+
+ return Promise.resolve()
+ }
+
+ function complete(results) {
+ let i
+ let errors = []
+ let fields = {}
+
+ function add(e) {
+ if (Array.isArray(e)) {
+ let _errors
+
+ errors = (_errors = errors).concat.apply(_errors, e)
+ } else {
+ errors.push(e)
+ }
+ }
+
+ for (i = 0; i < results.length; i++) {
+ add(results[i])
+ }
+
+ if (!errors.length) {
+ errors = null
+ fields = null
+ } else {
+ fields = convertFieldsError(errors)
+ }
+
+ callback(errors, fields)
+ }
+
+ if (options.messages) {
+ let messages$1 = this.messages()
+
+ if (messages$1 === messages) {
+ messages$1 = newMessages()
+ }
+
+ deepMerge(messages$1, options.messages)
+ options.messages = messages$1
+ } else {
+ options.messages = this.messages()
+ }
+
+ let arr
+ let value
+ const series = {}
+ const keys = options.keys || Object.keys(this.rules)
+ keys.forEach((z) => {
+ arr = _this.rules[z]
+ value = source[z]
+ arr.forEach((r) => {
+ let rule = r
+
+ if (typeof rule.transform === 'function') {
+ if (source === source_) {
+ source = { ...source }
+ }
+
+ value = source[z] = rule.transform(value)
+ }
+
+ if (typeof rule === 'function') {
+ rule = {
+ validator: rule
+ }
+ } else {
+ rule = { ...rule }
+ }
+
+ rule.validator = _this.getValidationMethod(rule)
+ rule.field = z
+ rule.fullField = rule.fullField || z
+ rule.type = _this.getType(rule)
+
+ if (!rule.validator) {
+ return
+ }
+
+ series[z] = series[z] || []
+ series[z].push({
+ rule,
+ value,
+ source,
+ field: z
+ })
+ })
+ })
+ const errorFields = {}
+ return asyncMap(series, options, (data, doIt) => {
+ const { rule } = data
+ let deep = (rule.type === 'object' || rule.type === 'array') && (typeof rule.fields === 'object' || typeof rule.defaultField
+ === 'object')
+ deep = deep && (rule.required || !rule.required && data.value)
+ rule.field = data.field
+
+ function addFullfield(key, schema) {
+ return { ...schema, fullField: `${rule.fullField}.${key}` }
+ }
+
+ function cb(e) {
+ if (e === void 0) {
+ e = []
+ }
+
+ let errors = e
+
+ if (!Array.isArray(errors)) {
+ errors = [errors]
+ }
+
+ if (!options.suppressWarning && errors.length) {
+ Schema.warning('async-validator:', errors)
+ }
+
+ if (errors.length && rule.message) {
+ errors = [].concat(rule.message)
+ }
+
+ errors = errors.map(complementError(rule))
+
+ if (options.first && errors.length) {
+ errorFields[rule.field] = 1
+ return doIt(errors)
+ }
+
+ if (!deep) {
+ doIt(errors)
+ } else {
+ // if rule is required but the target object
+ // does not exist fail at the rule level and don't
+ // go deeper
+ if (rule.required && !data.value) {
+ if (rule.message) {
+ errors = [].concat(rule.message).map(complementError(rule))
+ } else if (options.error) {
+ errors = [options.error(rule, format(options.messages.required, rule.field))]
+ } else {
+ errors = []
+ }
+
+ return doIt(errors)
+ }
+
+ let fieldsSchema = {}
+
+ if (rule.defaultField) {
+ for (const k in data.value) {
+ if (data.value.hasOwnProperty(k)) {
+ fieldsSchema[k] = rule.defaultField
+ }
+ }
+ }
+
+ fieldsSchema = { ...fieldsSchema, ...data.rule.fields }
+
+ for (const f in fieldsSchema) {
+ if (fieldsSchema.hasOwnProperty(f)) {
+ const fieldSchema = Array.isArray(fieldsSchema[f]) ? fieldsSchema[f] : [fieldsSchema[f]]
+ fieldsSchema[f] = fieldSchema.map(addFullfield.bind(null, f))
+ }
+ }
+
+ const schema = new Schema(fieldsSchema)
+ schema.messages(options.messages)
+
+ if (data.rule.options) {
+ data.rule.options.messages = options.messages
+ data.rule.options.error = options.error
+ }
+
+ schema.validate(data.value, data.rule.options || options, (errs) => {
+ const finalErrors = []
+
+ if (errors && errors.length) {
+ finalErrors.push.apply(finalErrors, errors)
+ }
+
+ if (errs && errs.length) {
+ finalErrors.push.apply(finalErrors, errs)
+ }
+
+ doIt(finalErrors.length ? finalErrors : null)
+ })
+ }
+ }
+
+ let res
+
+ if (rule.asyncValidator) {
+ res = rule.asyncValidator(rule, data.value, cb, data.source, options)
+ } else if (rule.validator) {
+ res = rule.validator(rule, data.value, cb, data.source, options)
+
+ if (res === true) {
+ cb()
+ } else if (res === false) {
+ cb(rule.message || `${rule.field} fails`)
+ } else if (res instanceof Array) {
+ cb(res)
+ } else if (res instanceof Error) {
+ cb(res.message)
+ }
+ }
+
+ if (res && res.then) {
+ res.then(() => cb(), (e) => cb(e))
+ }
+ }, (results) => {
+ complete(results)
+ })
+ },
+ getType: function getType(rule) {
+ if (rule.type === undefined && rule.pattern instanceof RegExp) {
+ rule.type = 'pattern'
+ }
+
+ if (typeof rule.validator !== 'function' && rule.type && !validators.hasOwnProperty(rule.type)) {
+ throw new Error(format('Unknown rule type %s', rule.type))
+ }
+
+ return rule.type || 'string'
+ },
+ getValidationMethod: function getValidationMethod(rule) {
+ if (typeof rule.validator === 'function') {
+ return rule.validator
+ }
+
+ const keys = Object.keys(rule)
+ const messageIndex = keys.indexOf('message')
+
+ if (messageIndex !== -1) {
+ keys.splice(messageIndex, 1)
+ }
+
+ if (keys.length === 1 && keys[0] === 'required') {
+ return validators.required
+ }
+
+ return validators[this.getType(rule)] || false
+ }
+}
+
+Schema.register = function register(type, validator) {
+ if (typeof validator !== 'function') {
+ throw new Error('Cannot register a validator by type, validator is not a function')
+ }
+
+ validators[type] = validator
+}
+
+Schema.warning = warning
+Schema.messages = messages
+
+export default Schema
+// # sourceMappingURL=index.js.map
diff --git a/uni_modules/uview-ui/libs/util/calendar.js b/uni_modules/uview-ui/libs/util/calendar.js
new file mode 100644
index 0000000..e006dea
--- /dev/null
+++ b/uni_modules/uview-ui/libs/util/calendar.js
@@ -0,0 +1,546 @@
+/**
+* @1900-2100���������������������������������
+* @charset UTF-8
+* @github https://github.com/jjonline/calendar.js
+* @Author Jea���(JJonline@JJonline.Cn)
+* @Time 2014-7-21
+* @Time 2016-8-13 Fixed 2033hex���Attribution Annals
+* @Time 2016-9-25 Fixed lunar LeapMonth Param Bug
+* @Time 2017-7-24 Fixed use getTerm Func Param Error.use solar year,NOT lunar year
+* @Version 1.0.3
+* @������������������calendar.solar2lunar(1987,11,01); //[you can ignore params of prefix 0]
+* @������������������calendar.lunar2solar(1987,09,10); //[you can ignore params of prefix 0]
+*/
+/* eslint-disable */
+var calendar = {
+
+ /**
+ * ������1900-2100���������������������
+ * @Array Of Property
+ * @return Hex
+ */
+ lunarInfo: [0x04bd8, 0x04ae0, 0x0a570, 0x054d5, 0x0d260, 0x0d950, 0x16554, 0x056a0, 0x09ad0, 0x055d2, // 1900-1909
+ 0x04ae0, 0x0a5b6, 0x0a4d0, 0x0d250, 0x1d255, 0x0b540, 0x0d6a0, 0x0ada2, 0x095b0, 0x14977, // 1910-1919
+ 0x04970, 0x0a4b0, 0x0b4b5, 0x06a50, 0x06d40, 0x1ab54, 0x02b60, 0x09570, 0x052f2, 0x04970, // 1920-1929
+ 0x06566, 0x0d4a0, 0x0ea50, 0x06e95, 0x05ad0, 0x02b60, 0x186e3, 0x092e0, 0x1c8d7, 0x0c950, // 1930-1939
+ 0x0d4a0, 0x1d8a6, 0x0b550, 0x056a0, 0x1a5b4, 0x025d0, 0x092d0, 0x0d2b2, 0x0a950, 0x0b557, // 1940-1949
+ 0x06ca0, 0x0b550, 0x15355, 0x04da0, 0x0a5b0, 0x14573, 0x052b0, 0x0a9a8, 0x0e950, 0x06aa0, // 1950-1959
+ 0x0aea6, 0x0ab50, 0x04b60, 0x0aae4, 0x0a570, 0x05260, 0x0f263, 0x0d950, 0x05b57, 0x056a0, // 1960-1969
+ 0x096d0, 0x04dd5, 0x04ad0, 0x0a4d0, 0x0d4d4, 0x0d250, 0x0d558, 0x0b540, 0x0b6a0, 0x195a6, // 1970-1979
+ 0x095b0, 0x049b0, 0x0a974, 0x0a4b0, 0x0b27a, 0x06a50, 0x06d40, 0x0af46, 0x0ab60, 0x09570, // 1980-1989
+ 0x04af5, 0x04970, 0x064b0, 0x074a3, 0x0ea50, 0x06b58, 0x05ac0, 0x0ab60, 0x096d5, 0x092e0, // 1990-1999
+ 0x0c960, 0x0d954, 0x0d4a0, 0x0da50, 0x07552, 0x056a0, 0x0abb7, 0x025d0, 0x092d0, 0x0cab5, // 2000-2009
+ 0x0a950, 0x0b4a0, 0x0baa4, 0x0ad50, 0x055d9, 0x04ba0, 0x0a5b0, 0x15176, 0x052b0, 0x0a930, // 2010-2019
+ 0x07954, 0x06aa0, 0x0ad50, 0x05b52, 0x04b60, 0x0a6e6, 0x0a4e0, 0x0d260, 0x0ea65, 0x0d530, // 2020-2029
+ 0x05aa0, 0x076a3, 0x096d0, 0x04afb, 0x04ad0, 0x0a4d0, 0x1d0b6, 0x0d250, 0x0d520, 0x0dd45, // 2030-2039
+ 0x0b5a0, 0x056d0, 0x055b2, 0x049b0, 0x0a577, 0x0a4b0, 0x0aa50, 0x1b255, 0x06d20, 0x0ada0, // 2040-2049
+ /** Add By JJonline@JJonline.Cn**/
+ 0x14b63, 0x09370, 0x049f8, 0x04970, 0x064b0, 0x168a6, 0x0ea50, 0x06b20, 0x1a6c4, 0x0aae0, // 2050-2059
+ 0x0a2e0, 0x0d2e3, 0x0c960, 0x0d557, 0x0d4a0, 0x0da50, 0x05d55, 0x056a0, 0x0a6d0, 0x055d4, // 2060-2069
+ 0x052d0, 0x0a9b8, 0x0a950, 0x0b4a0, 0x0b6a6, 0x0ad50, 0x055a0, 0x0aba4, 0x0a5b0, 0x052b0, // 2070-2079
+ 0x0b273, 0x06930, 0x07337, 0x06aa0, 0x0ad50, 0x14b55, 0x04b60, 0x0a570, 0x054e4, 0x0d160, // 2080-2089
+ 0x0e968, 0x0d520, 0x0daa0, 0x16aa6, 0x056d0, 0x04ae0, 0x0a9d4, 0x0a2d0, 0x0d150, 0x0f252, // 2090-2099
+ 0x0d520], // 2100
+
+ /**
+ * ������������������������������������
+ * @Array Of Property
+ * @return Number
+ */
+ solarMonth: [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31],
+
+ /**
+ * ������������������������������
+ * @Array Of Property trans["���","���","���","���","���","���","���","���","���","���"]
+ * @return Cn string
+ */
+ Gan: ['\u7532', '\u4e59', '\u4e19', '\u4e01', '\u620a', '\u5df1', '\u5e9a', '\u8f9b', '\u58ec', '\u7678'],
+
+ /**
+ * ������������������������������
+ * @Array Of Property
+ * @trans["���","���","���","���","���","���","���","���","���","���","���","���"]
+ * @return Cn string
+ */
+ Zhi: ['\u5b50', '\u4e11', '\u5bc5', '\u536f', '\u8fb0', '\u5df3', '\u5348', '\u672a', '\u7533', '\u9149', '\u620c', '\u4ea5'],
+
+ /**
+ * ������������������������������<=>������
+ * @Array Of Property
+ * @trans["���","���","���","���","���","���","���","���","���","���","���","���"]
+ * @return Cn string
+ */
+ Animals: ['\u9f20', '\u725b', '\u864e', '\u5154', '\u9f99', '\u86c7', '\u9a6c', '\u7f8a', '\u7334', '\u9e21', '\u72d7', '\u732a'],
+
+ /**
+ * 24���������������
+ * @Array Of Property
+ * @trans["������","������","������","������","������","������","������","������","������","������","������","������","������","������","������","������","������","������","������","������","������","������","������","������"]
+ * @return Cn string
+ */
+ solarTerm: ['\u5c0f\u5bd2', '\u5927\u5bd2', '\u7acb\u6625', '\u96e8\u6c34', '\u60ca\u86f0', '\u6625\u5206', '\u6e05\u660e', '\u8c37\u96e8', '\u7acb\u590f', '\u5c0f\u6ee1', '\u8292\u79cd', '\u590f\u81f3', '\u5c0f\u6691', '\u5927\u6691', '\u7acb\u79cb', '\u5904\u6691', '\u767d\u9732', '\u79cb\u5206', '\u5bd2\u9732', '\u971c\u964d', '\u7acb\u51ac', '\u5c0f\u96ea', '\u5927\u96ea', '\u51ac\u81f3'],
+
+ /**
+ * 1900-2100���������24���������������������
+ * @Array Of Property
+ * @return 0x string For splice
+ */
+ sTermInfo: ['9778397bd097c36b0b6fc9274c91aa', '97b6b97bd19801ec9210c965cc920e', '97bcf97c3598082c95f8c965cc920f',
+ '97bd0b06bdb0722c965ce1cfcc920f', 'b027097bd097c36b0b6fc9274c91aa', '97b6b97bd19801ec9210c965cc920e',
+ '97bcf97c359801ec95f8c965cc920f', '97bd0b06bdb0722c965ce1cfcc920f', 'b027097bd097c36b0b6fc9274c91aa',
+ '97b6b97bd19801ec9210c965cc920e', '97bcf97c359801ec95f8c965cc920f', '97bd0b06bdb0722c965ce1cfcc920f',
+ 'b027097bd097c36b0b6fc9274c91aa', '9778397bd19801ec9210c965cc920e', '97b6b97bd19801ec95f8c965cc920f',
+ '97bd09801d98082c95f8e1cfcc920f', '97bd097bd097c36b0b6fc9210c8dc2', '9778397bd197c36c9210c9274c91aa',
+ '97b6b97bd19801ec95f8c965cc920e', '97bd09801d98082c95f8e1cfcc920f', '97bd097bd097c36b0b6fc9210c8dc2',
+ '9778397bd097c36c9210c9274c91aa', '97b6b97bd19801ec95f8c965cc920e', '97bcf97c3598082c95f8e1cfcc920f',
+ '97bd097bd097c36b0b6fc9210c8dc2', '9778397bd097c36c9210c9274c91aa', '97b6b97bd19801ec9210c965cc920e',
+ '97bcf97c3598082c95f8c965cc920f', '97bd097bd097c35b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa',
+ '97b6b97bd19801ec9210c965cc920e', '97bcf97c3598082c95f8c965cc920f', '97bd097bd097c35b0b6fc920fb0722',
+ '9778397bd097c36b0b6fc9274c91aa', '97b6b97bd19801ec9210c965cc920e', '97bcf97c359801ec95f8c965cc920f',
+ '97bd097bd097c35b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa', '97b6b97bd19801ec9210c965cc920e',
+ '97bcf97c359801ec95f8c965cc920f', '97bd097bd097c35b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa',
+ '97b6b97bd19801ec9210c965cc920e', '97bcf97c359801ec95f8c965cc920f', '97bd097bd07f595b0b6fc920fb0722',
+ '9778397bd097c36b0b6fc9210c8dc2', '9778397bd19801ec9210c9274c920e', '97b6b97bd19801ec95f8c965cc920f',
+ '97bd07f5307f595b0b0bc920fb0722', '7f0e397bd097c36b0b6fc9210c8dc2', '9778397bd097c36c9210c9274c920e',
+ '97b6b97bd19801ec95f8c965cc920f', '97bd07f5307f595b0b0bc920fb0722', '7f0e397bd097c36b0b6fc9210c8dc2',
+ '9778397bd097c36c9210c9274c91aa', '97b6b97bd19801ec9210c965cc920e', '97bd07f1487f595b0b0bc920fb0722',
+ '7f0e397bd097c36b0b6fc9210c8dc2', '9778397bd097c36b0b6fc9274c91aa', '97b6b97bd19801ec9210c965cc920e',
+ '97bcf7f1487f595b0b0bb0b6fb0722', '7f0e397bd097c35b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa',
+ '97b6b97bd19801ec9210c965cc920e', '97bcf7f1487f595b0b0bb0b6fb0722', '7f0e397bd097c35b0b6fc920fb0722',
+ '9778397bd097c36b0b6fc9274c91aa', '97b6b97bd19801ec9210c965cc920e', '97bcf7f1487f531b0b0bb0b6fb0722',
+ '7f0e397bd097c35b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa', '97b6b97bd19801ec9210c965cc920e',
+ '97bcf7f1487f531b0b0bb0b6fb0722', '7f0e397bd07f595b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa',
+ '97b6b97bd19801ec9210c9274c920e', '97bcf7f0e47f531b0b0bb0b6fb0722', '7f0e397bd07f595b0b0bc920fb0722',
+ '9778397bd097c36b0b6fc9210c91aa', '97b6b97bd197c36c9210c9274c920e', '97bcf7f0e47f531b0b0bb0b6fb0722',
+ '7f0e397bd07f595b0b0bc920fb0722', '9778397bd097c36b0b6fc9210c8dc2', '9778397bd097c36c9210c9274c920e',
+ '97b6b7f0e47f531b0723b0b6fb0722', '7f0e37f5307f595b0b0bc920fb0722', '7f0e397bd097c36b0b6fc9210c8dc2',
+ '9778397bd097c36b0b70c9274c91aa', '97b6b7f0e47f531b0723b0b6fb0721', '7f0e37f1487f595b0b0bb0b6fb0722',
+ '7f0e397bd097c35b0b6fc9210c8dc2', '9778397bd097c36b0b6fc9274c91aa', '97b6b7f0e47f531b0723b0b6fb0721',
+ '7f0e27f1487f595b0b0bb0b6fb0722', '7f0e397bd097c35b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa',
+ '97b6b7f0e47f531b0723b0b6fb0721', '7f0e27f1487f531b0b0bb0b6fb0722', '7f0e397bd097c35b0b6fc920fb0722',
+ '9778397bd097c36b0b6fc9274c91aa', '97b6b7f0e47f531b0723b0b6fb0721', '7f0e27f1487f531b0b0bb0b6fb0722',
+ '7f0e397bd097c35b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa', '97b6b7f0e47f531b0723b0b6fb0721',
+ '7f0e27f1487f531b0b0bb0b6fb0722', '7f0e397bd07f595b0b0bc920fb0722', '9778397bd097c36b0b6fc9274c91aa',
+ '97b6b7f0e47f531b0723b0787b0721', '7f0e27f0e47f531b0b0bb0b6fb0722', '7f0e397bd07f595b0b0bc920fb0722',
+ '9778397bd097c36b0b6fc9210c91aa', '97b6b7f0e47f149b0723b0787b0721', '7f0e27f0e47f531b0723b0b6fb0722',
+ '7f0e397bd07f595b0b0bc920fb0722', '9778397bd097c36b0b6fc9210c8dc2', '977837f0e37f149b0723b0787b0721',
+ '7f07e7f0e47f531b0723b0b6fb0722', '7f0e37f5307f595b0b0bc920fb0722', '7f0e397bd097c35b0b6fc9210c8dc2',
+ '977837f0e37f14998082b0787b0721', '7f07e7f0e47f531b0723b0b6fb0721', '7f0e37f1487f595b0b0bb0b6fb0722',
+ '7f0e397bd097c35b0b6fc9210c8dc2', '977837f0e37f14998082b0787b06bd', '7f07e7f0e47f531b0723b0b6fb0721',
+ '7f0e27f1487f531b0b0bb0b6fb0722', '7f0e397bd097c35b0b6fc920fb0722', '977837f0e37f14998082b0787b06bd',
+ '7f07e7f0e47f531b0723b0b6fb0721', '7f0e27f1487f531b0b0bb0b6fb0722', '7f0e397bd097c35b0b6fc920fb0722',
+ '977837f0e37f14998082b0787b06bd', '7f07e7f0e47f531b0723b0b6fb0721', '7f0e27f1487f531b0b0bb0b6fb0722',
+ '7f0e397bd07f595b0b0bc920fb0722', '977837f0e37f14998082b0787b06bd', '7f07e7f0e47f531b0723b0b6fb0721',
+ '7f0e27f1487f531b0b0bb0b6fb0722', '7f0e397bd07f595b0b0bc920fb0722', '977837f0e37f14998082b0787b06bd',
+ '7f07e7f0e47f149b0723b0787b0721', '7f0e27f0e47f531b0b0bb0b6fb0722', '7f0e397bd07f595b0b0bc920fb0722',
+ '977837f0e37f14998082b0723b06bd', '7f07e7f0e37f149b0723b0787b0721', '7f0e27f0e47f531b0723b0b6fb0722',
+ '7f0e397bd07f595b0b0bc920fb0722', '977837f0e37f14898082b0723b02d5', '7ec967f0e37f14998082b0787b0721',
+ '7f07e7f0e47f531b0723b0b6fb0722', '7f0e37f1487f595b0b0bb0b6fb0722', '7f0e37f0e37f14898082b0723b02d5',
+ '7ec967f0e37f14998082b0787b0721', '7f07e7f0e47f531b0723b0b6fb0722', '7f0e37f1487f531b0b0bb0b6fb0722',
+ '7f0e37f0e37f14898082b0723b02d5', '7ec967f0e37f14998082b0787b06bd', '7f07e7f0e47f531b0723b0b6fb0721',
+ '7f0e37f1487f531b0b0bb0b6fb0722', '7f0e37f0e37f14898082b072297c35', '7ec967f0e37f14998082b0787b06bd',
+ '7f07e7f0e47f531b0723b0b6fb0721', '7f0e27f1487f531b0b0bb0b6fb0722', '7f0e37f0e37f14898082b072297c35',
+ '7ec967f0e37f14998082b0787b06bd', '7f07e7f0e47f531b0723b0b6fb0721', '7f0e27f1487f531b0b0bb0b6fb0722',
+ '7f0e37f0e366aa89801eb072297c35', '7ec967f0e37f14998082b0787b06bd', '7f07e7f0e47f149b0723b0787b0721',
+ '7f0e27f1487f531b0b0bb0b6fb0722', '7f0e37f0e366aa89801eb072297c35', '7ec967f0e37f14998082b0723b06bd',
+ '7f07e7f0e47f149b0723b0787b0721', '7f0e27f0e47f531b0723b0b6fb0722', '7f0e37f0e366aa89801eb072297c35',
+ '7ec967f0e37f14998082b0723b06bd', '7f07e7f0e37f14998083b0787b0721', '7f0e27f0e47f531b0723b0b6fb0722',
+ '7f0e37f0e366aa89801eb072297c35', '7ec967f0e37f14898082b0723b02d5', '7f07e7f0e37f14998082b0787b0721',
+ '7f07e7f0e47f531b0723b0b6fb0722', '7f0e36665b66aa89801e9808297c35', '665f67f0e37f14898082b0723b02d5',
+ '7ec967f0e37f14998082b0787b0721', '7f07e7f0e47f531b0723b0b6fb0722', '7f0e36665b66a449801e9808297c35',
+ '665f67f0e37f14898082b0723b02d5', '7ec967f0e37f14998082b0787b06bd', '7f07e7f0e47f531b0723b0b6fb0721',
+ '7f0e36665b66a449801e9808297c35', '665f67f0e37f14898082b072297c35', '7ec967f0e37f14998082b0787b06bd',
+ '7f07e7f0e47f531b0723b0b6fb0721', '7f0e26665b66a449801e9808297c35', '665f67f0e37f1489801eb072297c35',
+ '7ec967f0e37f14998082b0787b06bd', '7f07e7f0e47f531b0723b0b6fb0721', '7f0e27f1487f531b0b0bb0b6fb0722'],
+
+ /**
+ * ������������������������
+ * @Array Of Property
+ * @trans ['���','���','���','���','���','���','���','���','���','���','���']
+ * @return Cn string
+ */
+ nStr1: ['\u65e5', '\u4e00', '\u4e8c', '\u4e09', '\u56db', '\u4e94', '\u516d', '\u4e03', '\u516b', '\u4e5d', '\u5341'],
+
+ /**
+ * ������������������������������
+ * @Array Of Property
+ * @trans ['���','���','���','���']
+ * @return Cn string
+ */
+ nStr2: ['\u521d', '\u5341', '\u5eff', '\u5345'],
+
+ /**
+ * ������������������������������
+ * @Array Of Property
+ * @trans ['���','���','���','���','���','���','���','���','���','���','���','���','���']
+ * @return Cn string
+ */
+ nStr3: ['\u6b63', '\u4e8c', '\u4e09', '\u56db', '\u4e94', '\u516d', '\u4e03', '\u516b', '\u4e5d', '\u5341', '\u51ac', '\u814a'],
+
+ /**
+ * ������������y������������������������
+ * @param lunar Year
+ * @return Number
+ * @eg:var count = calendar.lYearDays(1987) ;//count=387
+ */
+ lYearDays: function (y) {
+ var i; var sum = 348
+ for (i = 0x8000; i > 0x8; i >>= 1) { sum += (this.lunarInfo[y - 1900] & i) ? 1 : 0 }
+ return (sum + this.leapDays(y))
+ },
+
+ /**
+ * ������������y���������������������������y��������������� ���������0
+ * @param lunar Year
+ * @return Number (0-12)
+ * @eg:var leapMonth = calendar.leapMonth(1987) ;//leapMonth=6
+ */
+ leapMonth: function (y) { // ������������ \u95f0
+ return (this.lunarInfo[y - 1900] & 0xf)
+ },
+
+ /**
+ * ������������y������������������ ������������������������������0
+ * @param lunar Year
+ * @return Number (0���29���30)
+ * @eg:var leapMonthDay = calendar.leapDays(1987) ;//leapMonthDay=29
+ */
+ leapDays: function (y) {
+ if (this.leapMonth(y)) {
+ return ((this.lunarInfo[y - 1900] & 0x10000) ? 30 : 29)
+ }
+ return (0)
+ },
+
+ /**
+ * ������������y���m���������������������������������������m������������������������������leapDays������
+ * @param lunar Year
+ * @return Number (-1���29���30)
+ * @eg:var MonthDay = calendar.monthDays(1987,9) ;//MonthDay=29
+ */
+ monthDays: function (y, m) {
+ if (m > 12 || m < 1) { return -1 }// ���������������1���12���������������������-1
+ return ((this.lunarInfo[y - 1900] & (0x10000 >> m)) ? 30 : 29)
+ },
+
+ /**
+ * ������������(!)y���m������������
+ * @param solar Year
+ * @return Number (-1���28���29���30���31)
+ * @eg:var solarMonthDay = calendar.leapDays(1987) ;//solarMonthDay=30
+ */
+ solarDays: function (y, m) {
+ if (m > 12 || m < 1) { return -1 } // ��������������� ������-1
+ var ms = m - 1
+ if (ms == 1) { // 2������������������������������������������28���29
+ return (((y % 4 == 0) && (y % 100 != 0) || (y % 400 == 0)) ? 29 : 28)
+ } else {
+ return (this.solarMonth[ms])
+ }
+ },
+
+ /**
+ * ���������������������������������
+ * @param lYear ���������������������
+ * @return Cn string
+ */
+ toGanZhiYear: function (lYear) {
+ var ganKey = (lYear - 3) % 10
+ var zhiKey = (lYear - 3) % 12
+ if (ganKey == 0) ganKey = 10// ���������������0������������������������
+ if (zhiKey == 0) zhiKey = 12// ���������������0������������������������
+ return this.Gan[ganKey - 1] + this.Zhi[zhiKey - 1]
+ },
+
+ /**
+ * ���������������������������������
+ * @param cMonth [description]
+ * @param cDay [description]
+ * @return Cn string
+ */
+ toAstro: function (cMonth, cDay) {
+ var s = '\u9b54\u7faf\u6c34\u74f6\u53cc\u9c7c\u767d\u7f8a\u91d1\u725b\u53cc\u5b50\u5de8\u87f9\u72ee\u5b50\u5904\u5973\u5929\u79e4\u5929\u874e\u5c04\u624b\u9b54\u7faf'
+ var arr = [20, 19, 21, 21, 21, 22, 23, 23, 23, 23, 22, 22]
+ return s.substr(cMonth * 2 - (cDay < arr[cMonth - 1] ? 2 : 0), 2) + '\u5ea7'// ���
+ },
+
+ /**
+ * ������offset���������������������
+ * @param offset ������������������������
+ * @return Cn string
+ */
+ toGanZhi: function (offset) {
+ return this.Gan[offset % 10] + this.Zhi[offset % 12]
+ },
+
+ /**
+ * ������������(!)y������������������n������������������������
+ * @param y���������(1900-2100)���n������������������������������������(1~24)������n=1(������)������
+ * @return day Number
+ * @eg:var _24 = calendar.getTerm(1987,3) ;//_24=4;������1987���2���4���������
+ */
+ getTerm: function (y, n) {
+ if (y < 1900 || y > 2100) { return -1 }
+ if (n < 1 || n > 24) { return -1 }
+ var _table = this.sTermInfo[y - 1900]
+ var _info = [
+ parseInt('0x' + _table.substr(0, 5)).toString(),
+ parseInt('0x' + _table.substr(5, 5)).toString(),
+ parseInt('0x' + _table.substr(10, 5)).toString(),
+ parseInt('0x' + _table.substr(15, 5)).toString(),
+ parseInt('0x' + _table.substr(20, 5)).toString(),
+ parseInt('0x' + _table.substr(25, 5)).toString()
+ ]
+ var _calday = [
+ _info[0].substr(0, 1),
+ _info[0].substr(1, 2),
+ _info[0].substr(3, 1),
+ _info[0].substr(4, 2),
+
+ _info[1].substr(0, 1),
+ _info[1].substr(1, 2),
+ _info[1].substr(3, 1),
+ _info[1].substr(4, 2),
+
+ _info[2].substr(0, 1),
+ _info[2].substr(1, 2),
+ _info[2].substr(3, 1),
+ _info[2].substr(4, 2),
+
+ _info[3].substr(0, 1),
+ _info[3].substr(1, 2),
+ _info[3].substr(3, 1),
+ _info[3].substr(4, 2),
+
+ _info[4].substr(0, 1),
+ _info[4].substr(1, 2),
+ _info[4].substr(3, 1),
+ _info[4].substr(4, 2),
+
+ _info[5].substr(0, 1),
+ _info[5].substr(1, 2),
+ _info[5].substr(3, 1),
+ _info[5].substr(4, 2)
+ ]
+ return parseInt(_calday[n - 1])
+ },
+
+ /**
+ * ���������������������������������������������������
+ * @param lunar month
+ * @return Cn string
+ * @eg:var cnMonth = calendar.toChinaMonth(12) ;//cnMonth='������'
+ */
+ toChinaMonth: function (m) { // ��� => \u6708
+ if (m > 12 || m < 1) { return -1 } // ��������������� ������-1
+ var s = this.nStr3[m - 1]
+ s += '\u6708'// ������������
+ return s
+ },
+
+ /**
+ * ���������������������������������������������
+ * @param lunar day
+ * @return Cn string
+ * @eg:var cnDay = calendar.toChinaDay(21) ;//cnMonth='������'
+ */
+ toChinaDay: function (d) { // ��� => \u65e5
+ var s
+ switch (d) {
+ case 10:
+ s = '\u521d\u5341'; break
+ case 20:
+ s = '\u4e8c\u5341'; break
+ break
+ case 30:
+ s = '\u4e09\u5341'; break
+ break
+ default:
+ s = this.nStr2[Math.floor(d / 10)]
+ s += this.nStr1[d % 10]
+ }
+ return (s)
+ },
+
+ /**
+ * ���������������[!������������������] => ������������������������������������������
+ * @param y year
+ * @return Cn string
+ * @eg:var animal = calendar.getAnimal(1987) ;//animal='���'
+ */
+ getAnimal: function (y) {
+ return this.Animals[(y - 4) % 12]
+ },
+
+ /**
+ * ���������������������������������������������������object������ <=>JSON
+ * @param y solar year
+ * @param m solar month
+ * @param d solar day
+ * @return JSON object
+ * @eg:console.log(calendar.solar2lunar(1987,11,01));
+ */
+ solar2lunar: function (y, m, d) { // ������������1900.1.31~2100.12.31
+ // ���������������������
+ if (y < 1900 || y > 2100) {
+ return -1// undefined���������������������NaN
+ }
+ // ���������������������
+ if (y == 1900 && m == 1 && d < 31) {
+ return -1
+ }
+ // ��������� ������������
+ if (!y) {
+ var objDate = new Date()
+ } else {
+ var objDate = new Date(y, parseInt(m) - 1, d)
+ }
+ var i; var leap = 0; var temp = 0
+ // ������ymd������
+ var y = objDate.getFullYear()
+ var m = objDate.getMonth() + 1
+ var d = objDate.getDate()
+ var offset = (Date.UTC(objDate.getFullYear(), objDate.getMonth(), objDate.getDate()) - Date.UTC(1900, 0, 31)) / 86400000
+ for (i = 1900; i < 2101 && offset > 0; i++) {
+ temp = this.lYearDays(i)
+ offset -= temp
+ }
+ if (offset < 0) {
+ offset += temp; i--
+ }
+
+ // ������������
+ var isTodayObj = new Date()
+ var isToday = false
+ if (isTodayObj.getFullYear() == y && isTodayObj.getMonth() + 1 == m && isTodayObj.getDate() == d) {
+ isToday = true
+ }
+ // ���������
+ var nWeek = objDate.getDay()
+ var cWeek = this.nStr1[nWeek]
+ // ���������������������������������������������������
+ if (nWeek == 0) {
+ nWeek = 7
+ }
+ // ���������
+ var year = i
+ var leap = this.leapMonth(i) // ������������
+ var isLeap = false
+
+ // ������������
+ for (i = 1; i < 13 && offset > 0; i++) {
+ // ������
+ if (leap > 0 && i == (leap + 1) && isLeap == false) {
+ --i
+ isLeap = true; temp = this.leapDays(year) // ������������������������
+ } else {
+ temp = this.monthDays(year, i)// ���������������������������
+ }
+ // ������������
+ if (isLeap == true && i == (leap + 1)) { isLeap = false }
+ offset -= temp
+ }
+ // ������������������������������������
+ if (offset == 0 && leap > 0 && i == leap + 1) {
+ if (isLeap) {
+ isLeap = false
+ } else {
+ isLeap = true; --i
+ }
+ }
+ if (offset < 0) {
+ offset += temp; --i
+ }
+ // ���������
+ var month = i
+ // ���������
+ var day = offset + 1
+ // ������������������
+ var sm = m - 1
+ var gzY = this.toGanZhiYear(year)
+
+ // ���������������������
+ // bugfix-2017-7-24 11:03:38 use lunar Year Param `y` Not `year`
+ var firstNode = this.getTerm(y, (m * 2 - 1))// ������������������������������������
+ var secondNode = this.getTerm(y, (m * 2))// ������������������������������������
+
+ // ������12���������������������
+ var gzM = this.toGanZhi((y - 1900) * 12 + m + 11)
+ if (d >= firstNode) {
+ gzM = this.toGanZhi((y - 1900) * 12 + m + 12)
+ }
+
+ // ������������������������������
+ var isTerm = false
+ var Term = null
+ if (firstNode == d) {
+ isTerm = true
+ Term = this.solarTerm[m * 2 - 2]
+ }
+ if (secondNode == d) {
+ isTerm = true
+ Term = this.solarTerm[m * 2 - 1]
+ }
+ // ������ ��������������� 1900/1/1 ������������
+ var dayCyclical = Date.UTC(y, sm, 1, 0, 0, 0, 0) / 86400000 + 25567 + 10
+ var gzD = this.toGanZhi(dayCyclical + d - 1)
+ // ������������������������
+ var astro = this.toAstro(m, d)
+
+ return { 'lYear': year, 'lMonth': month, 'lDay': day, 'Animal': this.getAnimal(year), 'IMonthCn': (isLeap ? '\u95f0' : '') + this.toChinaMonth(month), 'IDayCn': this.toChinaDay(day), 'cYear': y, 'cMonth': m, 'cDay': d, 'gzYear': gzY, 'gzMonth': gzM, 'gzDay': gzD, 'isToday': isToday, 'isLeap': isLeap, 'nWeek': nWeek, 'ncWeek': '\u661f\u671f' + cWeek, 'isTerm': isTerm, 'Term': Term, 'astro': astro }
+ },
+
+ /**
+ * ������������������������������������������������������������������������������������object������ <=>JSON
+ * @param y lunar year
+ * @param m lunar month
+ * @param d lunar day
+ * @param isLeapMonth lunar month is leap or not.[������������������������������������������true������]
+ * @return JSON object
+ * @eg:console.log(calendar.lunar2solar(1987,9,10));
+ */
+ lunar2solar: function (y, m, d, isLeapMonth) { // ������������1900.1.31~2100.12.1
+ var isLeapMonth = !!isLeapMonth
+ var leapOffset = 0
+ var leapMonth = this.leapMonth(y)
+ var leapDay = this.leapDays(y)
+ if (isLeapMonth && (leapMonth != m)) { return -1 }// ��������������������������������� ���������������������������������������������������
+ if (y == 2100 && m == 12 && d > 1 || y == 1900 && m == 1 && d < 31) { return -1 }// ������������������������
+ var day = this.monthDays(y, m)
+ var _day = day
+ // bugFix 2016-9-25
+ // if month is leap, _day use leapDays method
+ if (isLeapMonth) {
+ _day = this.leapDays(y, m)
+ }
+ if (y < 1900 || y > 2100 || d > _day) { return -1 }// ���������������������
+
+ // ������������������������
+ var offset = 0
+ for (var i = 1900; i < y; i++) {
+ offset += this.lYearDays(i)
+ }
+ var leap = 0; var isAdd = false
+ for (var i = 1; i < m; i++) {
+ leap = this.leapMonth(y)
+ if (!isAdd) { // ������������
+ if (leap <= i && leap > 0) {
+ offset += this.leapDays(y); isAdd = true
+ }
+ }
+ offset += this.monthDays(y, i)
+ }
+ // ������������������ ���������������������������������������������
+ if (isLeapMonth) { offset += day }
+ // 1900���������������������������������������1900���1���30���0���0���0���(���������������������������������������������)
+ var stmap = Date.UTC(1900, 1, 30, 0, 0, 0)
+ var calObj = new Date((offset + d - 31) * 86400000 + stmap)
+ var cY = calObj.getUTCFullYear()
+ var cM = calObj.getUTCMonth() + 1
+ var cD = calObj.getUTCDate()
+
+ return this.solar2lunar(cY, cM, cD)
+ }
+}
+
+export default calendar
diff --git a/uni_modules/uview-ui/libs/util/dayjs.js b/uni_modules/uview-ui/libs/util/dayjs.js
new file mode 100644
index 0000000..c4efea0
--- /dev/null
+++ b/uni_modules/uview-ui/libs/util/dayjs.js
@@ -0,0 +1,308 @@
+!(function (t, e) {
+ typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = e() : typeof define === 'function'
+ && define.amd ? define(e) : t.dayjs = e()
+}(this, () => {
+ 'use strict'
+
+ const t = 'millisecond'
+ const e = 'second'
+ const n = 'minute'
+ const r = 'hour'
+ const i = 'day'
+ const s = 'week'
+ const u = 'month'
+ const a = 'quarter'
+ const o = 'year'
+ const f = 'date'
+ const h = /^(\d{4})[-/]?(\d{1,2})?[-/]?(\d{0,2})[^0-9]*(\d{1,2})?:?(\d{1,2})?:?(\d{1,2})?.?(\d+)?$/
+ const c = /\[([^\]]+)]|Y{1,4}|M{1,4}|D{1,2}|d{1,4}|H{1,2}|h{1,2}|a|A|m{1,2}|s{1,2}|Z{1,2}|SSS/g
+ const d = {
+ name: 'en',
+ weekdays: 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'),
+ months: 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_')
+ }
+ const $ = function (t, e, n) {
+ const r = String(t)
+ return !r || r.length >= e ? t : `${Array(e + 1 - r.length).join(n)}${t}`
+ }
+ const l = {
+ s: $,
+ z(t) {
+ const e = -t.utcOffset()
+ const n = Math.abs(e)
+ const r = Math.floor(n / 60)
+ const i = n % 60
+ return `${(e <= 0 ? '+' : '-') + $(r, 2, '0')}:${$(i, 2, '0')}`
+ },
+ m: function t(e, n) {
+ if (e.date() < n.date()) return -t(n, e)
+ const r = 12 * (n.year() - e.year()) + (n.month() - e.month())
+ const i = e.clone().add(r, u)
+ const s = n - i < 0
+ const a = e.clone().add(r + (s ? -1 : 1), u)
+ return +(-(r + (n - i) / (s ? i - a : a - i)) || 0)
+ },
+ a(t) {
+ return t < 0 ? Math.ceil(t) || 0 : Math.floor(t)
+ },
+ p(h) {
+ return {
+ M: u,
+ y: o,
+ w: s,
+ d: i,
+ D: f,
+ h: r,
+ m: n,
+ s: e,
+ ms: t,
+ Q: a
+ }[h] || String(h || '').toLowerCase().replace(/s$/, '')
+ },
+ u(t) {
+ return void 0 === t
+ }
+ }
+ let y = 'en'
+ const M = {}
+ M[y] = d
+ const m = function (t) {
+ return t instanceof S
+ }
+ const D = function (t, e, n) {
+ let r
+ if (!t) return y
+ if (typeof t === 'string') M[t] && (r = t), e && (M[t] = e, r = t)
+ else {
+ const i = t.name
+ M[i] = t, r = i
+ }
+ return !n && r && (y = r), r || !n && y
+ }
+ const v = function (t, e) {
+ if (m(t)) return t.clone()
+ const n = typeof e === 'object' ? e : {}
+ return n.date = t, n.args = arguments, new S(n)
+ }
+ const g = l
+ g.l = D, g.i = m, g.w = function (t, e) {
+ return v(t, {
+ locale: e.$L,
+ utc: e.$u,
+ x: e.$x,
+ $offset: e.$offset
+ })
+ }
+ var S = (function () {
+ function d(t) {
+ this.$L = D(t.locale, null, !0), this.parse(t)
+ }
+ const $ = d.prototype
+ return $.parse = function (t) {
+ this.$d = (function (t) {
+ const e = t.date
+ const n = t.utc
+ if (e === null) return new Date(NaN)
+ if (g.u(e)) return new Date()
+ if (e instanceof Date) return new Date(e)
+ if (typeof e === 'string' && !/Z$/i.test(e)) {
+ const r = e.match(h)
+ if (r) {
+ const i = r[2] - 1 || 0
+ const s = (r[7] || '0').substring(0, 3)
+ return n ? new Date(Date.UTC(r[1], i, r[3] || 1, r[4] || 0, r[5] || 0, r[6] || 0, s)) : new Date(r[1], i, r[3]
+ || 1, r[4] || 0, r[5] || 0, r[6] || 0, s)
+ }
+ }
+ return new Date(e)
+ }(t)), this.$x = t.x || {}, this.init()
+ }, $.init = function () {
+ const t = this.$d
+ this.$y = t.getFullYear(), this.$M = t.getMonth(), this.$D = t.getDate(), this.$W = t.getDay(), this.$H = t.getHours(),
+ this.$m = t.getMinutes(), this.$s = t.getSeconds(), this.$ms = t.getMilliseconds()
+ }, $.$utils = function () {
+ return g
+ }, $.isValid = function () {
+ return !(this.$d.toString() === 'Invalid Date')
+ }, $.isSame = function (t, e) {
+ const n = v(t)
+ return this.startOf(e) <= n && n <= this.endOf(e)
+ }, $.isAfter = function (t, e) {
+ return v(t) < this.startOf(e)
+ }, $.isBefore = function (t, e) {
+ return this.endOf(e) < v(t)
+ }, $.$g = function (t, e, n) {
+ return g.u(t) ? this[e] : this.set(n, t)
+ }, $.unix = function () {
+ return Math.floor(this.valueOf() / 1e3)
+ }, $.valueOf = function () {
+ return this.$d.getTime()
+ }, $.startOf = function (t, a) {
+ const h = this
+ const c = !!g.u(a) || a
+ const d = g.p(t)
+ const $ = function (t, e) {
+ const n = g.w(h.$u ? Date.UTC(h.$y, e, t) : new Date(h.$y, e, t), h)
+ return c ? n : n.endOf(i)
+ }
+ const l = function (t, e) {
+ return g.w(h.toDate()[t].apply(h.toDate('s'), (c ? [0, 0, 0, 0] : [23, 59, 59, 999]).slice(e)), h)
+ }
+ const y = this.$W
+ const M = this.$M
+ const m = this.$D
+ const D = `set${this.$u ? 'UTC' : ''}`
+ switch (d) {
+ case o:
+ return c ? $(1, 0) : $(31, 11)
+ case u:
+ return c ? $(1, M) : $(0, M + 1)
+ case s:
+ var v = this.$locale().weekStart || 0
+ var S = (y < v ? y + 7 : y) - v
+ return $(c ? m - S : m + (6 - S), M)
+ case i:
+ case f:
+ return l(`${D}Hours`, 0)
+ case r:
+ return l(`${D}Minutes`, 1)
+ case n:
+ return l(`${D}Seconds`, 2)
+ case e:
+ return l(`${D}Milliseconds`, 3)
+ default:
+ return this.clone()
+ }
+ }, $.endOf = function (t) {
+ return this.startOf(t, !1)
+ }, $.$set = function (s, a) {
+ let h; const c = g.p(s)
+ const d = `set${this.$u ? 'UTC' : ''}`
+ const $ = (h = {}, h[i] = `${d}Date`, h[f] = `${d}Date`, h[u] = `${d}Month`, h[o] = `${d}FullYear`, h[r] = `${d}Hours`,
+ h[n] = `${d}Minutes`, h[e] = `${d}Seconds`, h[t] = `${d}Milliseconds`, h)[c]
+ const l = c === i ? this.$D + (a - this.$W) : a
+ if (c === u || c === o) {
+ const y = this.clone().set(f, 1)
+ y.$d[$](l), y.init(), this.$d = y.set(f, Math.min(this.$D, y.daysInMonth())).$d
+ } else $ && this.$d[$](l)
+ return this.init(), this
+ }, $.set = function (t, e) {
+ return this.clone().$set(t, e)
+ }, $.get = function (t) {
+ return this[g.p(t)]()
+ }, $.add = function (t, a) {
+ let f; const
+ h = this
+ t = Number(t)
+ const c = g.p(a)
+ const d = function (e) {
+ const n = v(h)
+ return g.w(n.date(n.date() + Math.round(e * t)), h)
+ }
+ if (c === u) return this.set(u, this.$M + t)
+ if (c === o) return this.set(o, this.$y + t)
+ if (c === i) return d(1)
+ if (c === s) return d(7)
+ const $ = (f = {}, f[n] = 6e4, f[r] = 36e5, f[e] = 1e3, f)[c] || 1
+ const l = this.$d.getTime() + t * $
+ return g.w(l, this)
+ }, $.subtract = function (t, e) {
+ return this.add(-1 * t, e)
+ }, $.format = function (t) {
+ const e = this
+ if (!this.isValid()) return 'Invalid Date'
+ const n = t || 'YYYY-MM-DDTHH:mm:ssZ'
+ const r = g.z(this)
+ const i = this.$locale()
+ const s = this.$H
+ const u = this.$m
+ const a = this.$M
+ const o = i.weekdays
+ const f = i.months
+ const h = function (t, r, i, s) {
+ return t && (t[r] || t(e, n)) || i[r].substr(0, s)
+ }
+ const d = function (t) {
+ return g.s(s % 12 || 12, t, '0')
+ }
+ const $ = i.meridiem || function (t, e, n) {
+ const r = t < 12 ? 'AM' : 'PM'
+ return n ? r.toLowerCase() : r
+ }
+ const l = {
+ YY: String(this.$y).slice(-2),
+ YYYY: this.$y,
+ M: a + 1,
+ MM: g.s(a + 1, 2, '0'),
+ MMM: h(i.monthsShort, a, f, 3),
+ MMMM: h(f, a),
+ D: this.$D,
+ DD: g.s(this.$D, 2, '0'),
+ d: String(this.$W),
+ dd: h(i.weekdaysMin, this.$W, o, 2),
+ ddd: h(i.weekdaysShort, this.$W, o, 3),
+ dddd: o[this.$W],
+ H: String(s),
+ HH: g.s(s, 2, '0'),
+ h: d(1),
+ hh: d(2),
+ a: $(s, u, !0),
+ A: $(s, u, !1),
+ m: String(u),
+ mm: g.s(u, 2, '0'),
+ s: String(this.$s),
+ ss: g.s(this.$s, 2, '0'),
+ SSS: g.s(this.$ms, 3, '0'),
+ Z: r
+ }
+ return n.replace(c, (t, e) => e || l[t] || r.replace(':', ''))
+ }, $.utcOffset = function () {
+ return 15 * -Math.round(this.$d.getTimezoneOffset() / 15)
+ }, $.diff = function (t, f, h) {
+ let c; const d = g.p(f)
+ const $ = v(t)
+ const l = 6e4 * ($.utcOffset() - this.utcOffset())
+ const y = this - $
+ let M = g.m(this, $)
+ return M = (c = {}, c[o] = M / 12, c[u] = M, c[a] = M / 3, c[s] = (y - l) / 6048e5, c[i] = (y - l) / 864e5, c[r] = y / 36e5, c[n] = y / 6e4, c[e] = y / 1e3, c)[d] || y, h ? M : g.a(M)
+ }, $.daysInMonth = function () {
+ return this.endOf(u).$D
+ }, $.$locale = function () {
+ return M[this.$L]
+ }, $.locale = function (t, e) {
+ if (!t) return this.$L
+ const n = this.clone()
+ const r = D(t, e, !0)
+ return r && (n.$L = r), n
+ }, $.clone = function () {
+ return g.w(this.$d, this)
+ }, $.toDate = function () {
+ return new Date(this.valueOf())
+ }, $.toJSON = function () {
+ return this.isValid() ? this.toISOString() : null
+ }, $.toISOString = function () {
+ return this.$d.toISOString()
+ }, $.toString = function () {
+ return this.$d.toUTCString()
+ }, d
+ }())
+ const p = S.prototype
+ return v.prototype = p, [
+ ['$ms', t],
+ ['$s', e],
+ ['$m', n],
+ ['$H', r],
+ ['$W', i],
+ ['$M', u],
+ ['$y', o],
+ ['$D', f]
+ ].forEach((t) => {
+ p[t[1]] = function (e) {
+ return this.$g(e, t[0], t[1])
+ }
+ }), v.extend = function (t, e) {
+ return t.$i || (t(e, S, v), t.$i = !0), v
+ }, v.locale = D, v.isDayjs = m, v.unix = function (t) {
+ return v(1e3 * t)
+ }, v.en = M[y], v.Ls = M, v.p = {}, v
+}))
diff --git a/uni_modules/uview-ui/libs/util/emitter.js b/uni_modules/uview-ui/libs/util/emitter.js
new file mode 100644
index 0000000..1e64044
--- /dev/null
+++ b/uni_modules/uview-ui/libs/util/emitter.js
@@ -0,0 +1,51 @@
+/**
+ * ������������ call ������this������
+ * @param componentName // ���������������������������
+ * @param eventName // ������������
+ * @param params // ���������������������
+ */
+function broadcast(componentName, eventName, params) {
+ // ��������������������������������������������� ������ ������ ���������������
+ this.$children.map((child) => {
+ if (componentName === child.$options.name) {
+ child.$emit.apply(child, [eventName].concat(params))
+ } else {
+ broadcast.apply(child, [componentName, eventName].concat(params))
+ }
+ })
+}
+export default {
+ methods: {
+ /**
+ * ������ (������������) (������)
+ * @param componentName // ���������������������������
+ * @param eventName // ������������
+ * @param params // ���������������������
+ */
+ dispatch(componentName, eventName, params) {
+ let parent = this.$parent || this.$root// $parent ������������������������ $root ���������
+ let { name } = parent.$options // ���������������������������name
+ // ��������������������� && ��������������� ��� ������������������������������������������������������������������������������
+ // ���������������������������������������������
+ while (parent && (!name || name !== componentName)) {
+ parent = parent.$parent
+ if (parent) {
+ name = parent.$options.name
+ }
+ }
+ // ������������������������������name���������������
+ if (parent) {
+ parent.$emit.apply(parent, [eventName].concat(params))
+ }
+ },
+ /**
+ * ������ (������������) (������������)
+ * @param componentName // ���������������������������
+ * @param eventName // ������������
+ * @param params // ���������������������
+ */
+ broadcast(componentName, eventName, params) {
+ broadcast.call(this, componentName, eventName, params)
+ }
+ }
+}
diff --git a/uni_modules/uview-ui/libs/util/route.js b/uni_modules/uview-ui/libs/util/route.js
new file mode 100644
index 0000000..2afeea5
--- /dev/null
+++ b/uni_modules/uview-ui/libs/util/route.js
@@ -0,0 +1,124 @@
+/**
+ * ���������������������������������������������������uni.xxx������������������������������������
+ * ������������������������������
+ */
+
+class Router {
+ constructor() {
+ // ������������������
+ this.config = {
+ type: 'navigateTo',
+ url: '',
+ delta: 1, // navigateBack���������������,���������������
+ params: {}, // ���������������
+ animationType: 'pop-in', // ������������,������APP������
+ animationDuration: 300, // ������������������������,������������,������APP������
+ intercept: false // ������������������
+ }
+ // ������route������������������������������������������������������������route���������������this������������route���������������
+ // ������������������������������this������
+ this.route = this.route.bind(this)
+ }
+
+ // ������url���������������"/"���������������������������������������������
+ addRootPath(url) {
+ return url[0] === '/' ? url : `/${url}`
+ }
+
+ // ������������������
+ mixinParam(url, params) {
+ url = url && this.addRootPath(url)
+
+ // ���������������������������������������������������"/","?","="������������/page/index/index?name=mary"
+ // ���������url������get������������������������������"?"
+ let query = ''
+ if (/.*\/.*\?.*=.*/.test(url)) {
+ // object������������get���������������
+ query = uni.$u.queryParams(params, false)
+ // ������������get������,���������������������������������������"&"������
+ return url += `&${query}`
+ }
+ // ���������������������������������url������������������query���������������������"?/&"���������������
+ query = uni.$u.queryParams(params)
+ return url += query
+ }
+
+ // ���������������������
+ async route(options = {}, params = {}) {
+ // ���������������������������������������������
+ let mergeConfig = {}
+
+ if (typeof options === 'string') {
+ // ������options���������������������route(url, params)���������
+ mergeConfig.url = this.mixinParam(options, params)
+ mergeConfig.type = 'navigateTo'
+ } else {
+ mergeConfig = uni.$u.deepMerge(this.config, options)
+ // ������������������mergeConfig������url���params������������
+ mergeConfig.url = this.mixinParam(options.url, options.params)
+ }
+
+ // ���������������������������������������������������������������������������������������������������������������������������������������������������������
+ if (mergeConfig.url === uni.$u.page()) return
+
+ if (params.intercept) {
+ this.config.intercept = params.intercept
+ }
+ // params������������������������
+ mergeConfig.params = params
+ // ���������������������
+ mergeConfig = uni.$u.deepMerge(this.config, mergeConfig)
+ // ������������������������������������
+ if (typeof uni.$u.routeIntercept === 'function') {
+ // ���������promise���������������������resolve(true)������resolve(false)���������������������������������
+ const isNext = await new Promise((resolve, reject) => {
+ uni.$u.routeIntercept(mergeConfig, resolve)
+ })
+ // ������isNext���true������������������������
+ isNext && this.openPage(mergeConfig)
+ } else {
+ this.openPage(mergeConfig)
+ }
+ }
+
+ // ������������������
+ openPage(config) {
+ // ������������
+ const {
+ url,
+ type,
+ delta,
+ animationType,
+ animationDuration
+ } = config
+ if (config.type == 'navigateTo' || config.type == 'to') {
+ uni.navigateTo({
+ url,
+ animationType,
+ animationDuration
+ })
+ }
+ if (config.type == 'redirectTo' || config.type == 'redirect') {
+ uni.redirectTo({
+ url
+ })
+ }
+ if (config.type == 'switchTab' || config.type == 'tab') {
+ uni.switchTab({
+ url
+ })
+ }
+ if (config.type == 'reLaunch' || config.type == 'launch') {
+ uni.reLaunch({
+ url
+ })
+ }
+ if (config.type == 'navigateBack' || config.type == 'back') {
+ uni.navigateBack({
+ delta
+ })
+ }
+ }
+}
+
+export default (new Router()).route
diff --git a/uni_modules/uview-ui/package.json b/uni_modules/uview-ui/package.json
new file mode 100644
index 0000000..e1169e5
--- /dev/null
+++ b/uni_modules/uview-ui/package.json
@@ -0,0 +1,84 @@
+{
+ "id": "uview-ui",
+ "name": "uview-ui",
+ "displayName": "uView2.0������������������������������������������",
+ "version": "2.0.36",
+ "description": "uView UI���������������nvue������������������������������������������������������������������������",
+ "keywords": [
+ "uview",
+ "uview",
+ "ui",
+ "ui",
+ "uni-app",
+ "uni-app",
+ "ui"
+ ],
+ "repository": "https://github.com/umicro/uView2.0",
+ "engines": {
+ "HBuilderX": "^3.1.0"
+ },
+ "dcloudext": {
+ "sale": {
+ "regular": {
+ "price": "0.00"
+ },
+ "sourcecode": {
+ "price": "0.00"
+ }
+ },
+ "contact": {
+ "qq": "1416956117"
+ },
+ "declaration": {
+ "ads": "���",
+ "data": "���",
+ "permissions": "���"
+ },
+ "npmurl": "https://www.npmjs.com/package/uview-ui",
+ "type": "component-vue"
+ },
+ "uni_modules": {
+ "dependencies": [],
+ "encrypt": [],
+ "platforms": {
+ "cloud": {
+ "tcb": "y",
+ "aliyun": "y"
+ },
+ "client": {
+ "Vue": {
+ "vue2": "y",
+ "vue3": "n"
+ },
+ "App": {
+ "app-vue": "y",
+ "app-nvue": "y"
+ },
+ "H5-mobile": {
+ "Safari": "y",
+ "Android Browser": "y",
+ "���������������(Android)": "y",
+ "QQ���������(Android)": "y"
+ },
+ "H5-pc": {
+ "Chrome": "y",
+ "IE": "y",
+ "Edge": "y",
+ "Firefox": "y",
+ "Safari": "y"
+ },
+ "���������": {
+ "������": "y",
+ "������": "y",
+ "������": "y",
+ "������������": "y",
+ "QQ": "y"
+ },
+ "���������": {
+ "������": "y",
+ "������": "y"
+ }
+ }
+ }
+ }
+}
diff --git a/uni_modules/uview-ui/theme.scss b/uni_modules/uview-ui/theme.scss
new file mode 100644
index 0000000..331b30f
--- /dev/null
+++ b/uni_modules/uview-ui/theme.scss
@@ -0,0 +1,44 @@
+// ������������uView������������������������������������������������uni.scss������������������������������
+// uni.scss���������������������������������������������������������������������������������������������������������������������������
+// ���uni.scss������������scss���������������������������������������������������main.js������App.vue������
+
+$u-main-color: #303133;
+$u-content-color: #606266;
+$u-tips-color: #909193;
+$u-light-color: #c0c4cc;
+$u-border-color: #dadbde;
+$u-bg-color: #f3f4f6;
+$u-disabled-color: #c8c9cc;
+
+$u-primary: #3c9cff;
+$u-primary-dark: #398ade;
+$u-primary-disabled: #9acafc;
+$u-primary-light: #ecf5ff;
+
+$u-warning: #f9ae3d;
+$u-warning-dark: #f1a532;
+$u-warning-disabled: #f9d39b;
+$u-warning-light: #fdf6ec;
+
+$u-success: #5ac725;
+$u-success-dark: #53c21d;
+$u-success-disabled: #a9e08f;
+$u-success-light: #f5fff0;
+
+$u-error: #f56c6c;
+$u-error-dark: #e45656;
+$u-error-disabled: #f7b2b2;
+$u-error-light: #fef0f0;
+
+$u-info: #909399;
+$u-info-dark: #767a82;
+$u-info-disabled: #c4c6c9;
+$u-info-light: #f4f4f5;
+
+// scss���������������������������#ifndef
+@mixin flex($direction: row) {
+ /* #ifndef APP-NVUE */
+ display: flex;
+ /* #endif */
+ flex-direction: $direction;
+}
diff --git a/unpackage/.gitkeep b/unpackage/.gitkeep
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/unpackage/.gitkeep
diff --git a/utils/http.js b/utils/http.js
new file mode 100644
index 0000000..dd26b93
--- /dev/null
+++ b/utils/http.js
@@ -0,0 +1,28 @@
+import request from "./request";
+
+// ������������������������������������������������������������������������������������������������������������������������������������
+export function httpGet(url, params) {
+ return new Promise((resolve, reject) => {
+ request
+ .get(url, params)
+ .then((result) => {
+ resolve(result);
+ })
+ .catch((err) => {
+ reject(err);
+ });
+ });
+}
+
+export function httpPost(url, params) {
+ return new Promise((resolve, reject) => {
+ request
+ .post(url, params)
+ .then((result) => {
+ resolve(result);
+ })
+ .catch((err) => {
+ reject(err);
+ });
+ });
+}
diff --git a/utils/login.js b/utils/login.js
new file mode 100644
index 0000000..aec9bba
--- /dev/null
+++ b/utils/login.js
@@ -0,0 +1,42 @@
+import request from '@/utils/request'
+export function login(params) {
+ return new Promise((resolve, reject) => {
+ request.post('/AppUser/logins', params, false).then(result => {
+ resolve(result)
+ }).catch(err => {
+ reject(err)
+ })
+ })
+}
+export function logout() {
+ return request({
+ url: '/logout',
+ method: 'post',
+ })
+}
+export function getUserInfor(token) {
+ request.post('/getUserInfo', token).then(result => {
+ uni.setStorageSync('userInfo', JSON.stringify(result.data))
+ })
+}
+export function getDic() {
+ request.get('/dict/list').then(result => {
+ uni.setStorageSync('dict', JSON.stringify(result.data))
+ uni.setStorageSync('dictObj', JSON.stringify(objToArr(result.data)))
+ })
+}
+
+function arrToObj(arr) {
+ return arr.reduce((obj, item) => {
+ obj[item.value] = item.name
+ return obj
+ }, {})
+}
+
+function objToArr(obj) {
+ const objde = {}
+ for (const key in obj) {
+ objde[key] = arrToObj(obj[key])
+ }
+ return objde
+}
\ No newline at end of file
diff --git a/utils/request.js b/utils/request.js
new file mode 100644
index 0000000..8496956
--- /dev/null
+++ b/utils/request.js
@@ -0,0 +1,74 @@
+import storage from './storage' // ������������
+export default {
+ console(options) {
+ if (config.debug) {
+ console.log('<<===============================================>>')
+ // console.log("request start");
+ // console.log("header" + JSON.stringify(options.header));
+ // console.log("method: " + options.method + " URL: " + options.url);
+ // console.log(options.data);
+ // console.log("request end");
+ // console.log("<<===============================================>>");
+ }
+ },
+ domain() {
+ return config.uni_app_web_api_url.replace('api', '')
+ },
+ send(options = {}, isLogin = true) {
+ const baseUrl = process.uniEnv.baseUrl
+ storage.set('baseUrl', baseUrl)
+ // loading������
+ uni.showLoading({ title: '���������', })
+ // ���������������������������������������������
+ options.url = baseUrl + '' + options.url
+ // ������������
+ options.method = options.method || 'GET'
+ // ������������������
+ if (isLogin) {
+ let token = storage.get('token')
+ console.log('tokentoken', token)
+ if (token !== null) {
+ // options.header["token"] = token;
+ options.header = {
+ token: token,
+ Authorization: token,
+ }
+ }
+ }
+ // this.console(options); // ���������������������������������������������������
+ // ������Promise������
+ return new Promise((resolve, reject) => {
+ uni.request(options).then(data => {
+ var [error, res] = data
+ if (error != null) {
+ reject(error)
+ } else {
+ // ���������������������������������������������������������������������������
+ if (res.data.code === 0) {
+ uni.hideLoading()
+ // uni.navigateTo({
+ // url: "/pages/Login/login/login",
+ // });
+ resolve(res.data)
+ } else {
+ uni.hideLoading()
+ reject(res.data.message)
+ }
+ }
+ })
+ })
+ },
+ get(url = '', data = {}, isLogin = true) {
+ return this.send({
+ url: url,
+ data: data,
+ }, isLogin)
+ },
+ post(url = '', data = {}, isLogin = true) {
+ return this.send({
+ url: url,
+ data: data,
+ method: 'POST',
+ }, isLogin)
+ },
+}
\ No newline at end of file
diff --git a/utils/storage.js b/utils/storage.js
new file mode 100644
index 0000000..64b7e43
--- /dev/null
+++ b/utils/storage.js
@@ -0,0 +1,30 @@
+export default {
+ set(name, value) {
+ uni.setStorageSync(name, value);
+ },
+
+ setJson(name, value) {
+ uni.setStorageSync(name, JSON.stringify(value));
+ },
+
+ get(name) {
+ return uni.getStorageSync(name);
+ },
+
+ getJson(name) {
+ const content = uni.getStorageSync(name);
+ if (!content) {
+ return null;
+ }
+
+ return JSON.parse(content);
+ },
+
+ remove(name) {
+ uni.removeStorageSync(name);
+ },
+
+ clear() {
+ uni.clearStorageSync();
+ },
+};
diff --git a/utils/utils.js b/utils/utils.js
new file mode 100644
index 0000000..299edff
--- /dev/null
+++ b/utils/utils.js
@@ -0,0 +1,179 @@
+import dayjs from "dayjs";
+export function msg(content, time = 3000) {
+ uni.showToast({
+ icon: "none",
+ title: content,
+ duration: time,
+ });
+}
+
+export function showLoading(content = "���������������...", mask = true) {
+ uni.showLoading({
+ title: content,
+ mask: mask,
+ });
+}
+
+export function hideLoading(timer = 0) {
+ if (timer > 0) {
+ var t = setTimeout(function () {
+ uni.hideLoading();
+ clearTimeout(t);
+ }, timer);
+ } else {
+ uni.hideLoading();
+ }
+}
+
+export function in_array(search, array) {
+ let flag = false;
+ for (let i in array) {
+ if (array[i] == search) {
+ flag = true;
+ break;
+ }
+ }
+
+ return flag;
+}
+
+export function isDataType(data, type) {
+ return Object.prototype.toString.call(data) === "[object " + type + "]";
+}
+// ���������������
+export function dateFormatter(dateObj) {
+ return dateObj ? dayjs(dateObj).format("YYYY-MM-DD") : "";
+}
+
+export function ltrim(str, char) {
+ let pos = str.indexOf(char);
+ let sonstr = str.substr(pos + 1);
+ return sonstr;
+}
+
+export function rtrim(str, char) {
+ let pos = str.lastIndexOf(char);
+ let sonstr = str.substr(0, pos);
+ return sonstr;
+}
+
+/**
+ * ���������������������������������������������������������������uni.navigateBack���������������������������
+ */
+export function navigateTo(url, params) {
+ uni.navigateTo({
+ url: parseUrl(url, params),
+ });
+}
+
+/**
+ * ���������������������������������������������������������
+ */
+export function redirectTo(url, params) {
+ uni.redirectTo({
+ url: parseUrl(url, params),
+ });
+}
+
+/**
+ * ���������������������������������������������������������
+ */
+export function reLaunch(url, params) {
+ uni.reLaunch({
+ url: parseUrl(url, params),
+ });
+}
+
+/**
+ * ��������� tabBar ��������������������������������� tabBar ���������
+ */
+export function switchTab(url, params) {
+ uni.switchTab({
+ url: parseUrl(url, params),
+ });
+}
+
+/**
+ * ������������������������������������������������������
+ */
+export function navigateBack(delta) {
+ uni.navigateBack({
+ delta: delta,
+ });
+}
+
+/**
+ * ������������������������������������������������������������������������������������������������
+ */
+export function preloadPage(url, params) {
+ uni.preloadPage({
+ url: parseUrl(url, params),
+ });
+}
+
+export function prePage() {
+ let pages = getCurrentPages();
+ let prePage = pages[pages.length - 2];
+ // #ifdef H5
+ return prePage;
+ // #endif
+ return prePage.$vm;
+}
+
+/**
+ * rpx���px
+ * @param int|float num
+ */
+export function rpx2px(num) {
+ // const info = uni.getSystemInfoSync()
+ // let scale = 750 / info.windowWidth;
+ // return (Number.isNaN(parseFloat(num)) ? 0 : parseFloat(num)) / scale;
+ return uni.upx2px(num);
+}
+
+/**
+ * @param int|float num
+ */
+export function px2rpx(num) {
+ return num / (uni.upx2px(num) / num);
+}
+
+/**
+ * ���������������������
+ */
+export function getSystemInfo() {
+ const info = uni.getSystemInfoSync();
+ return {
+ w: info.windowWidth,
+ h: info.windowHeight,
+ };
+}
+
+function parseUrl(url, params) {
+ let arr = [];
+ let string = "";
+ for (let i in params) {
+ arr.push(i + "=" + params[i]);
+ }
+
+ string = "/pages/" + url;
+ if (arr.length > 0) {
+ string += "?" + arr.join("&");
+ }
+
+ return string;
+}
+export function arrToObj(arr) {
+ return arr.reduce((obj, item) => {
+ obj[item.value] = item.name;
+ return obj;
+ }, {});
+}
+export function objToArr(obj) {
+ const objde = {};
+
+ for (const key in obj) {
+ objde[key] = arrToObj(obj[key]);
+ }
+ return objde;
+}
--
Gitblit v1.8.0