From e7cb9cf85f5f1c0db0833dbbd9ad3f4ed09b3598 Mon Sep 17 00:00:00 2001 From: whycq <10027870+whycq@user.noreply.gitee.com> Date: 星期二, 07 十一月 2023 16:34:02 +0800 Subject: [PATCH] # --- uni_modules/uview-ui/components/u-swipe-action-item/u-swipe-action-item.vue | 190 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/components/u-dropdown-item/props.js | 36 uni_modules/uview-ui/libs/luch-request/core/settle.js | 16 uni_modules/uview-ui/components/u-slider/mpwxs.wxs | 121 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-safe-bottom/props.js | 5 uni_modules/uview-ui/libs/mixin/touch.js | 59 uni_modules/uview-ui/libs/config/props/checkboxGroup.js | 29 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-rate/u-rate.vue | 306 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/upload.js | 36 uni_modules/uview-ui/libs/config/props/codeInput.js | 29 uni_modules/uview-ui/libs/config/props/countTo.js | 25 uni_modules/uview-ui/libs/config/props/formItem.js | 23 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-empty/props.js | 59 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/components/u-td/props.js | 5 uni_modules/uview-ui/libs/config/props/tabbarItem.js | 20 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/components/u-button/u-button.vue | 490 uni_modules/uview-ui/components/u-steps-item/props.js | 24 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/components/u-picker-column/u-picker-column.vue | 27 uni_modules/uview-ui/libs/config/props/scrollList.js | 20 uni_modules/uview-ui/libs/config/props/numberKeyboard.js | 17 uni_modules/uview-ui/libs/luch-request/helpers/isAbsoluteURL.js | 14 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 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/config/props/subsection.js | 23 uni_modules/uview-ui/libs/css/components.scss | 15 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/components/u-slider/nvue - 副本.js | 180 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-upload/mixin.js | 21 uni_modules/uview-ui/libs/config/props/columnNotice.js | 24 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-radio-group/u-radio-group.vue | 108 uni_modules/uview-ui/components/u-count-down/utils.js | 62 uni_modules/uview-ui/libs/config/props/overlay.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/libs/css/flex.scss | 257 uni_modules/uview-ui/components/u-swiper/props.js | 125 uni_modules/uview-ui/libs/util/dayjs.js | 308 uni_modules/uview-ui/components/u-link/props.js | 39 uni_modules/uview-ui/components/u-search/props.js | 118 uni_modules/uview-ui/libs/config/props/list.js | 28 uni_modules/uview-ui/components/u-row/props.js | 19 uni_modules/uview-ui/components/u-loading-page/u-loading-page.vue | 115 uni_modules/uview-ui/libs/config/props/tabbar.js | 22 uni_modules/uview-ui/libs/config/color.js | 17 uni_modules/uview-ui/components/u-image/u-image.vue | 232 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-loading-icon/u-loading-icon.vue | 343 uni_modules/uview-ui/components/u-code-input/props.js | 79 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/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-textarea/props.js | 119 uni_modules/uview-ui/components/u-checkbox/u-checkbox.vue | 344 uni_modules/uview-ui/components/u-upload/utils.js | 151 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-grid/u-grid.vue | 97 uni_modules/uview-ui/components/u-picker/u-picker.vue | 283 uni_modules/uview-ui/libs/mixin/mpMixin.js | 8 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-count-to/u-count-to.vue | 184 uni_modules/uview-ui/components/u-avatar-group/u-avatar-group.vue | 103 uni_modules/uview-ui/components/u-tag/u-tag.vue | 358 uni_modules/uview-ui/components/u-datetime-picker/props.js | 116 uni_modules/uview-ui/components/u-swipe-action-item/index.wxs | 225 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 uni_modules/uview-ui/libs/config/props/swiper.js | 39 uni_modules/uview-ui/libs/config/props/indexAnchor.js | 19 uni_modules/uview-ui/components/u-column-notice/props.js | 55 uni_modules/uview-ui/libs/config/props/countDown.js | 18 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/components/u-swipe-action/u-swipe-action.vue | 67 uni_modules/uview-ui/libs/config/props/divider.js | 23 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-read-more/props.js | 61 uni_modules/uview-ui/components/u-scroll-list/u-scroll-list.vue | 224 uni_modules/uview-ui/components/u-tabbar/u-tabbar.vue | 141 uni_modules/uview-ui/components/u--image/u--image.vue | 47 uni_modules/uview-ui/components/u-tabs-item/u-tabs-item.vue | 29 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/components/u-slider/nvue.js | 193 uni_modules/uview-ui/libs/config/props/col.js | 19 uni_modules/uview-ui/components/u-swipe-action/props.js | 9 uni_modules/uview-ui/libs/luch-request/index.d.ts | 116 uni_modules/uview-ui/components/u-text/u-text.vue | 223 uni_modules/uview-ui/libs/config/props/calendar.js | 42 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-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/components/u-image/props.js | 84 uni_modules/uview-ui/libs/config/props/alert.js | 22 uni_modules/uview-ui/libs/luch-request/helpers/buildURL.js | 69 uni_modules/uview-ui/components/u-radio/props.js | 64 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 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/components/u-cell-group/u-cell-group.vue | 61 uni_modules/uview-ui/components/u-upload/props.js | 124 uni_modules/uview-ui/libs/config/props/navbar.js | 32 uni_modules/uview-ui/components/u-status-bar/props.js | 8 uni_modules/uview-ui/components/u-car-keyboard/props.js | 14 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/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-slider/mpwxs.js | 42 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-grid-item/props.js | 14 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-loadmore/props.js | 94 uni_modules/uview-ui/components/u-slider/props.js | 54 uni_modules/uview-ui/libs/function/colorGradient.js | 134 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/changelog.md | 362 uni_modules/uview-ui/components/u-modal/u-modal.vue | 227 uni_modules/uview-ui/libs/css/mp.scss | 0 uni_modules/uview-ui/libs/config/props/circleProgress.js | 15 uni_modules/uview-ui/components/u-row-notice/props.js | 39 uni_modules/uview-ui/components/u-icon/icons.js | 214 uni_modules/uview-ui/components/u-subsection/u-subsection.vue | 299 uni_modules/uview-ui/libs/config/props/skeleton.js | 25 uni_modules/uview-ui/libs/function/index.js | 731 + uni_modules/uview-ui/components/u-avatar-group/props.js | 52 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-form/props.js | 45 uni_modules/uview-ui/components/u-index-anchor/props.js | 29 uni_modules/uview-ui/components/u-toolbar/props.js | 34 uni_modules/uview-ui/libs/config/props/swipterIndicator.js | 19 uni_modules/uview-ui/libs/config/props/line.js | 20 uni_modules/uview-ui/index.js | 79 uni_modules/uview-ui/components/u-list-item/u-list-item.vue | 116 uni_modules/uview-ui/libs/config/props/icon.js | 36 uni_modules/uview-ui/components/u-swiper-indicator/props.js | 29 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/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/config/props/collapse.js | 17 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-swiper-indicator/u-swiper-indicator.vue | 110 uni_modules/uview-ui/components/u-table/props.js | 5 uni_modules/uview-ui/components/u-text/props.js | 110 uni_modules/uview-ui/libs/luch-request/core/mergeConfig.js | 103 uni_modules/uview-ui/components/u-number-keyboard/props.js | 19 uni_modules/uview-ui/components/u-status-bar/u-status-bar.vue | 46 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/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 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/libs/function/digit.js | 167 uni_modules/uview-ui/components/u-transition/props.js | 24 uni_modules/uview-ui/components/u-avatar/props.js | 78 uni_modules/uview-ui/components/u-skeleton/props.js | 59 uni_modules/uview-ui/libs/config/props/popup.js | 29 uni_modules/uview-ui/components/u-tabbar/props.js | 44 uni_modules/uview-ui/components/u-toast/u-toast.vue | 291 uni_modules/uview-ui/index.scss | 23 uni_modules/uview-ui/components/u-collapse/u-collapse.vue | 90 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/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/libs/config/props/checkbox.js | 27 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 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-list/props.js | 76 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-popup/props.js | 79 uni_modules/uview-ui/components/u-subsection/props.js | 49 uni_modules/uview-ui/libs/config/props/indexList.js | 19 uni_modules/uview-ui/libs/config/props/row.js | 17 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-calendar/header.vue | 99 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/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/libs/mixin/style.js | 228 uni_modules/uview-ui/components/u-steps/props.js | 39 uni_modules/uview-ui/components/u-slider/u-slider.vue | 55 uni_modules/uview-ui/components/u-switch/u-switch.vue | 177 uni_modules/uview-ui/components/u-td/u-td.vue | 31 uni_modules/uview-ui/components/u-list/u-list.vue | 157 uni_modules/uview-ui/libs/config/props.js | 190 uni_modules/uview-ui/components/u-cell/props.js | 110 uni_modules/uview-ui/components/u-transition/transition.js | 157 uni_modules/uview-ui/components/u-swipe-action-item/nvue.js | 174 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/libs/luch-request/core/buildFullPath.js | 20 uni_modules/uview-ui/components/u-swipe-action-item/props.js | 41 uni_modules/uview-ui/components/u-transition/nvue.ani-map.js | 68 uni_modules/uview-ui/libs/config/props/rate.js | 26 uni_modules/uview-ui/libs/luch-request/utils/clone.js | 264 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-input/props.js | 187 uni_modules/uview-ui/libs/luch-request/core/Request.js | 198 uni_modules/uview-ui/components/u-modal/props.js | 84 uni_modules/uview-ui/components/u-slider/mpother.js | 113 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-swipe-action-item/index - backup.wxs | 256 uni_modules/uview-ui/components/u-code-input/u-code-input.vue | 252 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/function/platform.js | 75 uni_modules/uview-ui/libs/config/props/radio.js | 27 uni_modules/uview-ui/components/u-cell-group/props.js | 14 uni_modules/uview-ui/components/u-tabs-item/props.js | 5 uni_modules/uview-ui/components/u-no-network/u-no-network.vue | 220 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/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/util/calendar.js | 546 uni_modules/uview-ui/libs/config/props/loadmore.js | 32 uni_modules/uview-ui/components/u-read-more/u-read-more.vue | 157 uni_modules/uview-ui/libs/config/props/datetimePicker.js | 36 uni_modules/uview-ui/components/u-scroll-list/props.js | 34 uni_modules/uview-ui/components/u-tabbar-item/props.js | 35 uni_modules/uview-ui/libs/config/props/cellGroup.js | 17 uni_modules/uview-ui/components/u-circle-progress/u-circle-progress.vue | 198 uni_modules/uview-ui/libs/mixin/openType.js | 25 uni_modules/uview-ui/libs/luch-request/core/dispatchRequest.js | 3 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-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-tabbar-item/u-tabbar-item.vue | 142 uni_modules/uview-ui/components/u-parse/u-parse.vue | 366 uni_modules/uview-ui/components/u-no-network/props.js | 19 uni_modules/uview-ui/components/u-transition/u-transition.vue | 92 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/libs/config/props/numberBox.js | 35 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/components/u-swipe-action-item/wxs.js | 15 uni_modules/uview-ui/libs/config/props/album.js | 25 uni_modules/uview-ui/components/u-line/u-line.vue | 62 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/libs/luch-request/core/InterceptorManager.js | 50 uni_modules/uview-ui/components/u-grid/props.js | 19 uni_modules/uview-ui/libs/util/emitter.js | 51 uni_modules/uview-ui/components/u-safe-bottom/u-safe-bottom.vue | 56 368 files changed, 38,496 insertions(+), 0 deletions(-) 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鐨剈ni-app鐢熸�佹鏋讹紝鍏ㄩ潰鐨勭粍浠跺拰渚挎嵎鐨勫伐鍏蜂細璁╂偍淇℃墜鎷堟潵锛屽楸煎緱姘� + +## [瀹樻柟鏂囨。锛歨ttps://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) + +## 浜ゆ祦鍙嶉 + +娆㈣繋鍔犲叆鎴戜滑鐨凲Q缇や氦娴佸弽棣堬細[鐐规璺宠浆](https://www.uviewui.com/components/addQQGroup.html) + +## 鍏充簬PR + +> 鎴戜滑闈炲父涔愭剰鎺ュ彈鍚勪綅鐨勪紭璐≒R锛屼絾鍦ㄦ涔嬪墠鎴戝笇鏈涙偍浜嗚ВuView2.0鏄竴涓渶瑕佸吋瀹瑰涓钩鍙扮殑锛堝皬绋嬪簭銆乭5銆乮os app銆乤ndroid app锛夊寘鎷琻vue椤甸潰銆乿ue椤甸潰銆� +> 鎵�浠ュ笇鏈涘湪鎮ㄤ慨澶峛ug骞舵彁浜や箣鍓嶅敖鍙兘鐨勫幓杩欎簺骞冲彴娴嬭瘯涓�涓嬪吋瀹规�с�傛渶濂借兘鎼哄甫娴嬭瘯鎴浘浠ユ柟渚垮鏍搞�傞潪甯告劅璋紒 + +## 瀹夎 + +#### **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`缁勪欢鍦╤5涓奵onfirmType=""鎶ラ敊鐨勯棶棰� +5. `u-rate`閫傞厤`nvue` +6. 浼樺寲楠岃瘉鎵嬫満鍙风爜鐨勬鍒欒〃杈惧紡(鏍规嵁宸ヤ俊閮ㄥ彂甯冪殑銆婄數淇$綉缂栧彿璁″垝锛�2017骞寸増锛夈�嬭繘琛屼慨鏀广��) +7. `form-item`娣诲姞`labelPosition`灞炴�� +8. `u-calendar`淇`maxDate`璁剧疆涓哄綋鍓嶆棩鏈燂紝骞朵笖褰撳墠鏃堕棿澶т簬08锛�00鏃舵棤娉曟樉绀烘棩鏈熷垪琛ㄧ殑闂 (#724) +9. `u-radio`澧炲姞涓�涓粯璁ゆ彃妲界敤浜庤嚜瀹氫箟淇敼label鍐呭 (#680) +10. 淇`timeFormat`鍑芥暟鍦╯afari閲嶇殑鍏煎鎬ч棶棰� (#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`鐨刡ug +8. `u-code-input`缁勪欢鏂板閿洏寮硅捣鏃讹紝鏄惁鑷姩涓婃帹椤甸潰鍙傛暟`adjustPosition` +9. 淇`image`缁勪欢`load`浜嬩欢鏃犲洖璋冨璞¢棶棰� +10. 淇`button`缁勪欢`loadingSize`璁剧疆鏃犳晥闂 +10. 鍏朵粬淇 +## 2.0.31锛�2022-04-19锛� +# uView2.0閲嶇鍙戝竷锛屽埄鍓戝嚭闉橈紝涓�缁熸睙婀� + +1. 淇`upload`鍦╜vue`椤甸潰涓婁紶鎴愬姛鍚庢病鏈夋垚鍔熸爣蹇楃殑闂 +2. 瑙e喅婕旂ず椤圭洰涓井淇″皬绋嬪簭妯℃嫙涓婁紶鍥剧墖涓�鐩村嚭浜庝笂浼犱腑闂 +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鍜寁ideo閫昏緫 +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`鍚庤繑鍥炲�间笉姝g‘ +3. 淇`u-datetime-picker` `intercept` 鍙兘涓簎ndefined +4. 淇宸茶缃崟浣� uni..config.unit = 'rpx'鏃讹紝绾垮瀷鎸囩ず鍣� `transform` 鐨勪綅缃炕鍊嶏紝瀵艰嚧鎸囩ず鍣ㄨ秴鍑哄搴� +5. 淇mixin涓璪em鏂规硶鐢熸垚鐨勭被鍚嶅湪鏀粯瀹濆拰瀛楄妭灏忕▼搴忎腑澶辨晥 +6. 淇榛樿鍊间紶鍊间负绌虹殑鏃跺�欙紝鎵撳紑`u-datetime-picker`鎶ラ敊锛屼笉鑳介�変腑绗竴鍒楁椂闂寸殑bug +7. 淇`u-datetime-picker`浣跨敤`formatter`鍚庤繑鍥炲�间笉姝g‘ +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 鍒ゆ柇鏃ユ湡鍑篺ormat閿欒闂 +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鍐呯疆鐨刢onfig, 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缁勪欢鍦╡rrorType=toast鏃讹紝濡傛灉杈撳叆閿欒椤甸潰浼氭湁鎶栧姩鐨勯棶棰� +4. 淇$u.addUnit()瀵归厤缃粯璁ゅ崟浣嶅彲鑳芥棤鏁堢殑闂 +## 2.0.24锛�2022-01-25锛� +# uView2.0閲嶇鍙戝竷锛屽埄鍓戝嚭闉橈紝涓�缁熸睙婀� + +1. 淇swiper鍦╟urrent鎸囧畾闈�0鏃剁缉鏀炬湁璇� +2. 淇u-icon娣诲姞stop灞炴�х殑鏃跺�欐姤閿� +3. 浼樺寲閬楃暀鐨勯�氳繃姝e垯鍒ゆ柇rpx鍗曚綅鐨勯棶棰� +4. 浼樺寲Layout甯冨眬 vue浣跨敤gutter鏃讹紝浼氳秴鍑哄浐瀹氬尯鍩� +5. 浼樺寲search缁勪欢楂樺害鍗曚綅闂锛坮px -> px锛� +6. 淇u-image slot 鍔犺浇鍜岄敊璇殑鍥剧墖澶卞幓浜嗛珮搴� +7. 淇u-index-list涓璮ooter鎻掓Ы涓巋eader鎻掓Ы瀛樺湪鎬у垽鏂敊璇� +8. 淇閮ㄥ垎鏈哄瀷涓媢-popup鍏抽棴鏃朵細闂儊 +9. 淇u-image鍦╪vue-app涓嬪け鍘诲楂� +10. 淇u-popup杩愯鎶ラ敊 +11. 淇u-tooltip鎶ラ敊 +12. 淇box-sizing鍦╝pp涓嬬殑璀﹀憡 +13. 淇u-navbar鍦ㄥ皬绋嬪簭涓姤杩愯鏃堕敊璇� +14. 鍏朵粬淇 +## 2.0.23锛�2022-01-24锛� +# uView2.0閲嶇鍙戝竷锛屽埄鍓戝嚭闉橈紝涓�缁熸睙婀� + +1. 淇image缁勪欢鍦╤x3.3.9鐨刵vue涓嬪彲鑳戒細鏄剧ず寮傚父鐨勯棶棰� +2. 淇col缁勪欢gutter鍙傛暟甯px鍗曚綅澶勭悊涓嶆纭殑闂 +3. 淇text缁勪欢鍗曡鏃舵棤娉曟樉绀虹渷鐣ュ彿鐨勯棶棰� +4. navbar娣诲姞titleStyle鍙傛暟 +5. 鍗囩骇鍒癶x3.3.9鍙秷闄vue涓嬫帶鍒跺彴鏍峰紡璀﹀憡鐨勯棶棰� +## 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. 浼樺寲锛歠orm缁勪欢鍦ㄧ敤鎴疯缃畆ules鐨勬椂鍊欐彁绀虹敤鎴穖odel蹇呬紶 +2. 浼樺寲閬楃暀鐨勯�氳繃姝e垯鍒ゆ柇rpx鍗曚綅鐨勯棶棰� +3. 淇寰俊灏忕▼搴忕幆澧冧腑tabbar缁勪欢寮�鍚痵afeAreaInsetBottom灞炴�у悗锛宲laceholder楂樺害濉厖涓嶆纭� +4. 淇swiper鍦╟urrent鎸囧畾闈�0鏃剁缉鏀炬湁璇� +5. 淇u-icon娣诲姞stop灞炴�х殑鏃跺�欐姤閿� +6. 淇upload缁勪欢鍦╝ccept=all鐨勬椂鍊欐病鏈変綔鐢� +7. 淇鍦╰ext缁勪欢mode涓簆hone鏃禼all灞炴�ф棤鏁堢殑闂 +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鍦╲ue鏂囦欢涓嬶紝app绔嚜瀹氫箟鎻掓Ы涓嶇敓鏁堢殑闂 +5. 浼樺寲澶村儚涓虹┖鏃舵樉绀洪粯璁ゅご鍍� +6. 淇鍥剧墖鍦板潃璧嬪�煎悗鍒ゆ柇鍔犺浇鐘舵�佷负瀹屾垚闂 +7. 淇鏃ュ巻婊氬姩鍒伴粯璁ゆ棩鏈熸湀浠藉尯鍩� +8. search缁勪欢鏆撮湶鐐瑰嚮宸﹁竟icon浜嬩欢 +9. 淇u-form clearValidate鏂规硶涓嶇敓鏁� +10. upload h5绔鍔犺繑鍥炴枃浠跺弬鏁帮紙鏂囦欢鐨刵ame鍙傛暟锛� +11. 澶勭悊upload閫夋嫨鏂囦欢鍚巙rl涓篵lob绫诲瀷鏃犳硶棰勮鐨勯棶棰� +12. u-code-input 淇杈撳叆妗嗘病鏈夊線宸︾Щ鍑轰竴鍗婂睆骞� +13. 淇Upload涓婁紶 disabled涓簍rue鏃讹紝鎺у埗鍙版姤hoverClass绫诲瀷閿欒 +14. 涓存椂澶勭悊ios app涓媑rid鐐瑰嚮鍧嶅闂 +15. 鍏朵粬淇 +## 2.0.19锛�2021-12-29锛� +# uView2.0閲嶇鍙戝竷锛屽埄鍓戝嚭闉橈紝涓�缁熸睙婀� + +1. 浼樺寲寰俊灏忕▼搴忓寘浣撶Н鍙湪寰俊涓瑙堬紝璇峰崌绾builderX3.3.4锛屽悓鏃跺湪鈥滆繍琛�->杩愯鍒板皬绋嬪簭妯℃嫙鍣ㄢ�濅腑鍕鹃�夆�滆繍琛屾椂鏄惁鍘嬬缉浠g爜鈥� +2. 浼樺寲寰俊灏忕▼搴弒etData鎬ц兘锛屽鐞嗘煇浜涙柟娉曞$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鐨刾laceholder鍦ㄥ皬绋嬪簭绔粯璁ゆ樉绀轰负true闂 +7. 淇divider缁勪欢click浜嬩欢鏃犳晥闂 +8. 淇u-code-input maxlength 灞炴�у�间负 String 绫诲瀷鏃舵樉绀哄紓甯� +9. 淇褰� grid鍙湁 1鍒�2鏃� 鍦ㄥ皬绋嬪簭绔痑lgin璁剧疆鏃犳晥鐨勯棶棰� +10. 澶勭悊form-item鐨刲abel涓簍op鏃讹紝鍙栨秷閿欒鎻愮ず鐨勫乏杈硅窛 +11. 鍏朵粬淇 +## 2.0.17锛�2021-12-26锛� +## uView姝e湪鍙備笌寮�婧愪腑鍥界殑鈥滃勾搴︽渶浣抽」鐩�濊瘎閫夛紝涔嬪墠鎶曡繃绁ㄧ殑鐜板湪涔熷彲浠ユ姇绁紝鎭宠鍚屽浠姇涓�绁紝[鐐规甯姪uView](https://www.oschina.net/project/top_cn_2021/?id=583) + +# uView2.0閲嶇鍙戝竷锛屽埄鍓戝嚭闉橈紝涓�缁熸睙婀� + +1. 瑙e喅HBuilderX3.3.3.20211225鐗堟湰瀵艰嚧鐨勬牱寮忛棶棰� +2. calendar鏃ュ巻娣诲姞monthNum鍙傛暟 +3. navbar娣诲姞center slot +## 2.0.16锛�2021-12-25锛� +## uView姝e湪鍙備笌寮�婧愪腑鍥界殑鈥滃勾搴︽渶浣抽」鐩�濊瘎閫夛紝涔嬪墠鎶曡繃绁ㄧ殑鐜板湪涔熷彲浠ユ姇绁紝鎭宠鍚屽浠姇涓�绁紝[鐐规甯姪uView](https://www.oschina.net/project/top_cn_2021/?id=583) + +# uView2.0閲嶇鍙戝竷锛屽埄鍓戝嚭闉橈紝涓�缁熸睙婀� + +1. 瑙e喅寰俊灏忕▼搴弒etData鎬ц兘闂 +2. 淇count-down缁勪欢change浜嬩欢涓嶈Е鍙戦棶棰� +## 2.0.15锛�2021-12-21锛� +## uView姝e湪鍙備笌寮�婧愪腑鍥界殑鈥滃勾搴︽渶浣抽」鐩�濊瘎閫夛紝涔嬪墠鎶曡繃绁ㄧ殑鐜板湪涔熷彲浠ユ姇绁紝鎭宠鍚屽浠姇涓�绁紝[鐐规甯姪uView](https://www.oschina.net/project/top_cn_2021/?id=583) + +# uView2.0閲嶇鍙戝竷锛屽埄鍓戝嚭闉橈紝涓�缁熸睙婀� + +1. 淇Cell鍗曞厓鏍紅itleWidth鏃犳晥 +2. 淇cheakbox缁勪欢ischecked涓嶆洿鏂� +3. 淇keyboard鏄惁鏄剧ず"."鎸夐敭榛樿鍊奸棶棰� +4. 淇number-keyboard鏄惁鏄剧ず閿洏鐨�"."绗﹀彿闂 +5. 淇Input杈撳叆妗� readonly鏃犳晥 +6. 淇u-avatar 瀵艰嚧鎵撳寘app銆丠5鏃跺�欐姤閿欓棶棰� +7. 淇Upload涓婁紶deletable鏃犳晥 +8. 淇upload褰撹缃甿axSize鏃舵棤鏁堢殑闂 +9. 淇tabs lineWidth浼犲叆甯﹀崟浣嶇殑瀛楃涓茬殑鏃跺�欏亸绉婚噺璁$畻閿欒闂 +10. 淇rate缁勪欢鍦ㄦ湁padding鐨剉iew鍐咃紝鏄剧ず鐨勬槦鏄熶綅缃拰鍙Е鎽稿尯鍩熶笉鍖归厤锛屾棤娉曟甯搁�変腑鏄熸槦 +## 2.0.13锛�2021-12-14锛� +## [鐐瑰嚮鍔犵兢浜ゆ祦鍙嶉锛�364463526](https://jq.qq.com/?_chanwv=1027&k=mCxS3TGY) + +# uView2.0閲嶇鍙戝竷锛屽埄鍓戝嚭闉橈紝涓�缁熸睙婀� + +1. 淇閰嶇疆榛樿鍗曚綅涓簉px鍙兘浼氬鑷磋嚜瀹氫箟瀵艰埅鏍忛珮搴﹀紓甯哥殑闂 +## 2.0.12锛�2021-12-14锛� +## [鐐瑰嚮鍔犵兢浜ゆ祦鍙嶉锛�364463526](https://jq.qq.com/?_chanwv=1027&k=mCxS3TGY) + +# uView2.0閲嶇鍙戝竷锛屽埄鍓戝嚭闉橈紝涓�缁熸睙婀� + +1. 淇tabs缁勪欢鍦╲ue鐜涓嬪垝绾挎秷澶辩殑闂 +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缁勪欢鍦╲ue鐜涓嬮粯璁よ鎵撳紑鐨勯棶棰� +9. button缁勪欢鐨則hrottleTime鑺傛祦鍙傛暟鏃犳晥鐨勯棶棰� +10. 瑙e喅u-notify鎵嬪姩鍏抽棴鏂规硶close()鏃犳晥鐨勯棶棰� +11. input缁勪欢readonly涓嶇敓鏁堥棶棰� +12. tag缁勪欢type鍙傛暟涓篿nfo涓嶇敓鏁堥棶棰� +## 2.0.10锛�2021-12-08锛� +## [鐐瑰嚮鍔犵兢浜ゆ祦鍙嶉锛�364463526](https://jq.qq.com/?_chanwv=1027&k=mCxS3TGY) + +# uView2.0閲嶇鍙戝竷锛屽埄鍓戝嚭闉橈紝涓�缁熸睙婀� + +1. 淇button sendMessagePath灞炴�т笉鐢熸晥 +2. 淇DatetimePicker閫夋嫨鍣╰itle鏃犳晥 +3. 淇u-toast璁剧疆loading=true涓嶇敓鏁� +4. 淇u-text閲戦妯″紡浼�0鎶ラ敊 +5. 淇u-toast缁勪欢鐨刬con灞炴�ч厤缃笉鐢熸晥 +6. button鐨刬con鍦ㄧ壒娈婂満鏅笅鐨勯鑹蹭紭鍖� +7. IndexList浼樺寲锛屽鍔�# +## 2.0.9锛�2021-12-01锛� +## [鐐瑰嚮鍔犵兢浜ゆ祦鍙嶉锛�232041042](https://jq.qq.com/?_wv=1027&k=KnbeceDU) + +# uView2.0閲嶇鍙戝竷锛屽埄鍓戝嚭闉橈紝涓�缁熸睙婀� + +1. 浼樺寲swiper鐨刪eight鏀寔100%鍊�(浠卾ue鏈夋晥)锛屼慨澶嶅祵鍏ヨ棰戞椂click浜嬩欢鏃犳硶瑙﹀彂鐨勯棶棰� +2. 浼樺寲tabs缁勪欢瀵筶ist鍊间负绌虹殑鍒ゆ柇锛屾垨鑰呭姩鎬佸彉鍖杔ist鏃堕噸鏂拌绠楃浉鍏冲昂瀵哥殑闂 +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鐨刾osition鍙傛暟鏃犳晥闂 +2. 澶勭悊input鍦╥os 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鍜宑heckbox鍔ㄦ�佹敼鍙榲-model鏃犳晥鐨勯棶棰樸�� +2. 浼樺寲form瑙勫垯validator鍦ㄥ井淇″皬绋嬪簭鐢ㄦ硶 +3. 淇backtop缁勪欢mode鍙傛暟鍦ㄥ井淇″皬绋嬪簭鏃犳晥鐨勯棶棰� +4. 澶勭悊Album鐨刾reviewFullImage灞炴�ф棤鏁堢殑闂 +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缁勪欢鍦╲ue涓嬭竟妗嗘棤鏁堢殑闂銆� +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鍦╲ue涓嬫樉绀哄紓甯搁棶棰樸�� +2. form缁勪欢labelPosition鍜宔rrorType鍙傛暟鏃犳晥鐨勯棶棰� +3. input缁勪欢inputAlign鏃犳晥鐨勯棶棰� +4. 鍏朵粬涓�浜涗慨澶� +## 2.0.4锛�2021-11-23锛� +## [鐐瑰嚮鍔犵兢浜ゆ祦鍙嶉锛�232041042](https://jq.qq.com/?_wv=1027&k=KnbeceDU) + +# uView2.0閲嶇鍙戝竷锛屽埄鍓戝嚭闉橈紝涓�缁熸睙婀� + +0. input缁勪欢缂哄け@confirm浜嬩欢锛屼互鍙妔ubfix鍜宲refix鏃犳晥闂 +1. component.scss鏂囦欢鏍峰紡鍦╲ue涓嬪共鎵板叏灞�甯冨眬闂 +2. 淇subsection鍦╲ue鐜涓嬭〃鐜板紓甯哥殑闂 +3. tag缁勪欢鐨刡gColor绛夊弬鏁版棤鏁堢殑闂 +4. upload缁勪欢涓嶆崲琛岀殑闂 +5. 鍏朵粬鐨勪竴浜涗慨澶嶅鐞� +## 2.0.3锛�2021-11-16锛� +## [鐐瑰嚮鍔犵兢浜ゆ祦鍙嶉锛�1129077272](https://jq.qq.com/?_wv=1027&k=KnbeceDU) + +# uView2.0閲嶇鍙戝竷锛屽埄鍓戝嚭闉橈紝涓�缁熸睙婀� + +1. uView2.0宸插疄鐜板叏闈㈠吋瀹筺vue +2. uView2.0瀵�1.x杩涜浜嗘灦鏋勯噸鏋勶紝缁嗚妭鍜屾�ц兘閮芥湁鏋佸ぇ鎻愬崌 +3. 鐩墠uView2.0涓哄叕娴嬮樁娈碉紝鐩稿叧缁嗚妭鍙兘浼氭湁鍙樺姩 +4. 鎴戜滑鍐欎簡涓�浠戒笌1.x鐨勫姣旀寚鍗楋紝璇﹁[瀵规瘮1.x](https://www.uviewui.com/components/diff1.x.html) +5. 澶勭悊modal鐨刢onfirm鍥炶皟浜嬩欢鎷煎啓閿欒闂 +6. 澶勭悊input缁勪欢@input浜嬩欢鍙傛暟閿欒闂 +7. 鍏朵粬涓�浜涗慨澶� +## 2.0.2锛�2021-11-16锛� +## [鐐瑰嚮鍔犵兢浜ゆ祦鍙嶉锛�1129077272](https://jq.qq.com/?_wv=1027&k=KnbeceDU) + +# uView2.0閲嶇鍙戝竷锛屽埄鍓戝嚭闉橈紝涓�缁熸睙婀� + +1. uView2.0宸插疄鐜板叏闈㈠吋瀹筺vue +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缁勪欢鐨剆css鍐欐硶闂锛岄槻姝笉鍏煎鏂扮増鏈瑂css +## 2.0.0(2020-11-15) +## [鐐瑰嚮鍔犵兢浜ゆ祦鍙嶉锛�1129077272](https://jq.qq.com/?_wv=1027&k=KnbeceDU) + +# uView2.0閲嶇鍙戝竷锛屽埄鍓戝嚭闉橈紝涓�缁熸睙婀� + +1. uView2.0宸插疄鐜板叏闈㈠吋瀹筺vue +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> + /** + * 姝ょ粍浠跺瓨鍦ㄧ殑鐞嗙敱鏄紝鍦╪vue涓嬶紝u-form琚玼ni-app瀹樻柟鍗犵敤浜嗭紝u-form鍦╪vue涓浉褰撲簬form缁勪欢 + * 鎵�浠ュ湪nvue涓嬶紝鍙栧悕涓簎--form锛屽唴閮ㄥ叾瀹炶繕鏄痷-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鎷垮埌鐨勭埗缁勪欢鏄痷--form锛岃�屼笉鏄叾鍐呭祵鐨剈-form + * 瀵艰嚧鍦╱-form缁勪欢涓紝鎷夸笉鍒板搴旂殑children鏁扮粍锛屼粠鑰屾牎楠屾棤鏁堬紝鎵�浠ヨ繖閲屾瘡娆¤皟鐢╱-form缁勪欢涓殑 + * 瀵瑰簲鏂规硶鐨勬椂鍊欙紝鍦ㄥ皬绋嬪簭涓兘鍏堝皢u--form鐨刢hildren璧嬪�肩粰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> + /** + * 姝ょ粍浠跺瓨鍦ㄧ殑鐞嗙敱鏄紝鍦╪vue涓嬶紝u-image琚玼ni-app瀹樻柟鍗犵敤浜嗭紝u-image鍦╪vue涓浉褰撲簬image缁勪欢 + * 鎵�浠ュ湪nvue涓嬶紝鍙栧悕涓簎--image锛屽唴閮ㄥ叾瀹炶繕鏄痷-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> + /** + * 姝ょ粍浠跺瓨鍦ㄧ殑鐞嗙敱鏄紝鍦╪vue涓嬶紝u-input琚玼ni-app瀹樻柟鍗犵敤浜嗭紝u-input鍦╪vue涓浉褰撲簬input缁勪欢 + * 鎵�浠ュ湪nvue涓嬶紝鍙栧悕涓簎--input锛屽唴閮ㄥ叾瀹炶繕鏄痷-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> +/** + * 姝ょ粍浠跺瓨鍦ㄧ殑鐞嗙敱鏄紝鍦╪vue涓嬶紝u-text琚玼ni-app瀹樻柟鍗犵敤浜嗭紝u-text鍦╪vue涓浉褰撲簬input缁勪欢 + * 鎵�浠ュ湪nvue涓嬶紝鍙栧悕涓簎--input锛屽唴閮ㄥ叾瀹炶繕鏄痷-text.vue锛屽彧涓嶈繃鍋氫竴灞備腑杞� + * 涓嶄娇鐢╲-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> + /** + * 姝ょ粍浠跺瓨鍦ㄧ殑鐞嗙敱鏄紝鍦╪vue涓嬶紝u--textarea琚玼ni-app瀹樻柟鍗犵敤浜嗭紝u-textarea鍦╪vue涓浉褰撲簬textarea缁勪欢 + * 鎵�浠ュ湪nvue涓嬶紝鍙栧悕涓簎--textarea锛屽唴閮ㄥ叾瀹炶繕鏄痷-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: { + // 鎿嶄綔鑿滃崟鏄惁灞曠ず 锛堥粯璁alse锛� + 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 鏈粍浠剁敤浜庝粠搴曢儴寮瑰嚭涓�涓搷浣滆彍鍗曪紝渚涚敤鎴烽�夋嫨骞惰繑鍥炵粨鏋溿�傛湰缁勪欢鍔熻兘绫讳技浜巙ni鐨剈ni.showActionSheetAPI锛岄厤缃洿鍔犵伒娲伙紝鎵�鏈夊钩鍙伴兘琛ㄧ幇涓�鑷淬�� + * @tutorial https://www.uviewui.com/components/actionSheet.html + * + * @property {Boolean} show 鎿嶄綔鑿滃崟鏄惁灞曠ず 锛堥粯璁� false 锛� + * @property {String} title 鎿嶄綔鑿滃崟鏍囬 + * @property {String} description 閫夐」涓婃柟鐨勬弿杩颁俊鎭� + * @property {Array<Object>} actions 鎸夐挳鐨勬枃瀛楁暟缁勶紝瑙佸畼鏂规枃妗gず渚� + * @property {String} cancelText 鍙栨秷鎸夐挳鐨勬彁绀烘枃瀛�,涓嶄负绌烘椂鏄剧ず鎸夐挳 + * @property {Boolean} closeOnClickAction 鐐瑰嚮鏌愪釜鑿滃崟椤规椂鏄惁鍏抽棴寮圭獥 锛堥粯璁� true 锛� + * @property {Boolean} safeAreaInsetBottom 澶勭悊搴曢儴瀹夊叏鍖� 锛堥粯璁� true 锛� + * @property {String} openType 灏忕▼搴忕殑鎵撳紑鏂瑰紡 (contact | launchApp | getUserInfo | openSetting 锝済etPhoneNumber 锝渆rror ) + * @property {Boolean} closeOnClickOverlay 鐐瑰嚮閬僵鏄惁鍏佽鍏抽棴 (榛樿 true ) + * @property {Number|String} round 鍦嗚鍊硷紝榛樿鏃犲渾瑙� (榛樿 0 ) + * @property {String} lang 鎸囧畾杩斿洖鐢ㄦ埛淇℃伅鐨勮瑷�锛寊h_CN 绠�浣撲腑鏂囷紝zh_TW 绻佷綋涓枃锛宔n 鑻辨枃 + * @property {String} sessionFrom 浼氳瘽鏉ユ簮锛宱penType="contact"鏃舵湁鏁� + * @property {String} sendMessageTitle 浼氳瘽鍐呮秷鎭崱鐗囨爣棰橈紝openType="contact"鏃舵湁鏁� + * @property {String} sendMessagePath 浼氳瘽鍐呮秷鎭崱鐗囩偣鍑昏烦杞皬绋嬪簭璺緞锛宱penType="contact"鏃舵湁鏁� + * @property {String} sendMessageImg 浼氳瘽鍐呮秷鎭崱鐗囧浘鐗囷紝openType="contact"鏃舵湁鏁� + * @property {Boolean} showMessageCard 鏄惁鏄剧ず浼氳瘽鍐呮秷鎭崱鐗囷紝璁剧疆姝ゅ弬鏁颁负 true锛岀敤鎴疯繘鍏ュ鏈嶄細璇濅細鍦ㄥ彸涓嬭鏄剧ず"鍙兘瑕佸彂閫佺殑灏忕▼搴�"鎻愮ず锛岀敤鎴风偣鍑诲悗鍙互蹇�熷彂閫佸皬绋嬪簭娑堟伅锛宱penType="contact"鏃舵湁鏁� 锛堥粯璁� false 锛� + * @property {String} appParameter 鎵撳紑 APP 鏃讹紝鍚� APP 浼犻�掔殑鍙傛暟锛宱penType=launchApp 鏃舵湁鏁� + * + * @event {Function} select 鐐瑰嚮ActionSheet鍒楄〃椤规椂瑙﹀彂 + * @event {Function} close 鐐瑰嚮鍙栨秷鎸夐挳鏃惰Е鍙� + * @event {Function} getuserinfo 鐢ㄦ埛鐐瑰嚮璇ユ寜閽椂锛屼細杩斿洖鑾峰彇鍒扮殑鐢ㄦ埛淇℃伅锛屽洖璋冪殑 detail 鏁版嵁涓� wx.getUserInfo 杩斿洖鐨勪竴鑷达紝openType="getUserInfo"鏃舵湁鏁� + * @event {Function} contact 瀹㈡湇娑堟伅鍥炶皟锛宱penType="contact"鏃舵湁鏁� + * @event {Function} getphonenumber 鑾峰彇鐢ㄦ埛鎵嬫満鍙峰洖璋冿紝openType="getPhoneNumber"鏃舵湁鏁� + * @event {Function} error 褰撲娇鐢ㄥ紑鏀捐兘鍔涙椂锛屽彂鐢熼敊璇殑鍥炶皟锛宱penType="error"鏃舵湁鏁� + * @event {Function} launchapp 鎵撳紑 APP 鎴愬姛鐨勫洖璋冿紝openType="launchApp"鏃舵湁鏁� + * @event {Function} opensetting 鍦ㄦ墦寮�鎺堟潈璁剧疆椤靛悗鍥炶皟锛宱penType="openSetting"鏃舵湁鏁� + * @example <u-action-sheet :actions="list" :title="title" :show="show"></u-action-sheet> + */ + export default { + name: "u-action-sheet", + // 涓�浜沺rops鍙傛暟鍜宮ethods鏂规硶锛岄�氳繃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() { + // 鍏佽鐐瑰嚮閬僵鍏抽棴鏃讹紝鎵嶅彂鍑篶lose浜嬩欢 + 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: { + // 鍥剧墖鍦板潃锛孉rray<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 + }, + // 姣忚灞曠ず鍥剧墖鏁伴噺锛屽璁剧疆锛宻ingleSize鍜宮ultipleSize灏嗕細鏃犳晥 + 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 鏈粍浠舵彁渚涗竴涓被浼肩浉鍐岀殑鍔熻兘锛岃寮�鍙戣�呭紑鍙戣捣鏉ユ洿鍔犲緱蹇冨簲鎵嬨�傚噺灏戦噸澶嶇殑妯℃澘浠g爜 + * @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 姣忚灞曠ず鍥剧墖鏁伴噺锛屽璁剧疆锛宻ingleSize鍜宮ultipleSize灏嗕細鏃犳晥 锛堥粯璁� 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 + ) + }, + // 姝ゅ彉閲忔棤瀹為檯鐢ㄩ�旓紝浠呬粎鏄负浜嗗埄鐢╟omputed鐗规�э紝璁╁叾鍦╱rls闀垮害绛夊彉鍖栨椂锛岄噸鏂拌绠楀浘鐗囩殑瀹藉害 + // 鍥犱负鐢ㄦ埛鍦ㄦ煇浜涚壒娈婄殑鎯呭喌涓嬶紝闇�瑕佽鏂囧瓧涓庣浉鍐岀殑瀹藉害鐩哥瓑锛屾墍浠ヨ繖閲屼簨浠剁殑褰㈠紡瀵瑰鍙戦�� + 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 + }, + // 鍗曞浘鏃讹紝鑾峰彇鍥剧墖鐨勫昂瀵� + // 鍦ㄥ皬绋嬪簭涓紝闇�瑕佸皢缃戠粶鍥剧墖鐨勭殑鍩熷悕娣诲姞鍒板皬绋嬪簭鐨刣ownload鍩熷悕鎵嶅彲鑳借幏鍙栧昂瀵� + // 鍦ㄦ病鏈夋坊鍔犵殑鎯呭喌涓嬶紝璁╁崟鍥惧搴﹂粯璁や负鐩掑瓙鐨勪竴瀹氬搴�(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() { + // 寤舵椂涓�瀹氭椂闂达紝浠ヨ幏鍙杁om灏哄 + 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寰幆鍑烘潵锛屽鑷磘his.$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 + }, + // 涓婚锛宻uccess/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-娴呰壊锛宒ark-娣辫壊 + 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 杈呭姪鎬ф枃瀛楋紝棰滆壊姣攖itle娴呬竴鐐癸紝瀛楀彿涔熷皬涓�鐐癸紝鍙�� + * @property {Boolean} closable 鍏抽棴鎸夐挳(榛樿涓哄弶鍙穒con鍥炬爣) 锛堥粯璁� 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浠h〃閬尅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 + }, + // 澶村儚褰㈢姸锛宑ircle-鍦嗗舰锛宻quare-鏂瑰舰 + 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 + }, + // 濡傛灉閰嶇疆浜唕andomBgColor涓簍rue锛屼笖閰嶇疆浜嗘鍊硷紝鍒欎粠榛樿鐨勮儗鏅壊鏁扮粍涓彇鍑哄搴旂储寮曠殑棰滆壊鍊硷紝鍙栧��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 澶村儚鍥剧墖鐨勮鍓被鍨嬶紝涓巙ni鐨刬mage缁勪欢鐨刴ode鍙傛暟涓�鑷达紝濡傛晥鏋滆揪涓嶅埌闇�姹傦紝鍙皾璇曚紶widthFix鍊� 锛堥粯璁� 'scaleToFill' 锛� + * @property {String} text 鐢ㄦ枃瀛楁浛浠e浘鐗囷紝绾у埆浼樺厛浜巗rc + * @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 濡傛灉閰嶇疆浜唕andomBgColor涓簍rue锛屼笖閰嶇疆浜嗘鍊硷紝鍒欎粠榛樿鐨勮儗鏅壊鏁扮粍涓彇鍑哄搴旂储寮曠殑棰滆壊鍊硷紝鍙栧��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鍙傛暟涓簍rue锛屽湪鍥炬爣鎴栬�呮枃瀛楃殑妯″紡涓嬶紝浼氶殢鏈轰粠涓彇鍑轰竴涓鑹插�煎綋鍋氳儗鏅壊 + 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鐨勫彉鍖栵紝璧嬪�肩粰鍐呴儴鐨刟vatarUrl鍙橀噺锛屽洜涓哄浘鐗囧姞杞藉け璐ユ椂锛岄渶瑕佷慨鏀瑰浘鐗囩殑src涓洪粯璁ゅ�� + // 鑰岀粍浠跺唴閮ㄤ笉鑳界洿鎺ヤ慨鏀筽rops鐨勫�硷紝鎵�浠ラ渶瑕佷竴涓腑闂村彉閲� + src: { + immediate: true, + handler(newVal) { + this.avatarUrl = newVal + // 濡傛灉娌℃湁浼爏rc锛屽垯涓诲姩瑙﹀彂error浜嬩欢锛岀敤浜庢樉绀洪粯璁ょ殑澶村儚锛屽惁鍒檚rc涓�''绌哄瓧绗︾瓑鐨勬椂鍊欙紝浼氭棤鍐呭灞曠ず + 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 + }, + // 鍒ゆ柇浼犲叆鐨刵ame灞炴�э紝鏄惁鍥剧墖璺緞锛屽彧瑕佸甫鏈�"/"鍧囪涓烘槸鍥剧墖褰㈠紡 + 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-鍦嗗舰锛宻quare-鏂瑰舰 + 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 + }, + // 璺濈椤堕儴澶氬皯璺濈鏄剧ず锛屽崟浣峱x + top: { + type: [String, Number], + default: uni.$u.props.backtop.top + }, + // 杩斿洖椤堕儴鎸夐挳鍒板簳閮ㄧ殑璺濈锛屽崟浣峱x + bottom: { + type: [String, Number], + default: uni.$u.props.backtop.bottom + }, + // 杩斿洖椤堕儴鎸夐挳鍒板彸杈圭殑璺濈锛屽崟浣峱x + 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-鍦嗗舰锛宻quare-鏂瑰舰 锛堥粯璁� 'circle' 锛� + * @property {String} icon 鑷畾涔夊浘鏍� 锛堥粯璁� 'arrow-upward' 锛� 瑙佸畼鏂规枃妗gず渚� + * @property {String} text 鎻愮ず鏂囧瓧 + * @property {String | Number} duration 杩斿洖椤堕儴婊氬姩鏃堕棿 锛堥粯璁� 100锛� + * @property {String | Number} scrollTop 婊氬姩璺濈 锛堥粯璁� 0 锛� + * @property {String | Number} top 璺濈椤堕儴澶氬皯璺濈鏄剧ず锛屽崟浣峱x 锛堥粯璁� 400 锛� + * @property {String | Number} bottom 杩斿洖椤堕儴鎸夐挳鍒板簳閮ㄧ殑璺濈锛屽崟浣峱x 锛堥粯璁� 100 锛� + * @property {String | Number} right 杩斿洖椤堕儴鎸夐挳鍒板彸杈圭殑璺濈锛屽崟浣峱x 锛堥粯璁� 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 + }, + // 涓婚绫诲瀷锛宔rror|warning|success|primary + type: { + type: String, + default: uni.$u.props.badge.type + }, + // 褰撴暟鍊间负 0 鏃讹紝鏄惁灞曠ず Badge + showZero: { + type: Boolean, + default: uni.$u.props.badge.showZero + }, + // 鑳屾櫙棰滆壊锛屼紭鍏堢骇姣攖ype楂橈紝濡傝缃紝type鍙傛暟浼氬け鏁� + bgColor: { + type: [String, null], + default: uni.$u.props.badge.bgColor + }, + // 瀛椾綋棰滆壊 + color: { + type: [String, null], + default: uni.$u.props.badge.color + }, + // 寰芥爣褰㈢姸锛宑ircle-鍥涜鍧囦负鍦嗚锛宧orn-宸︿笅瑙掍负鐩磋 + shape: { + type: String, + default: uni.$u.props.badge.shape + }, + // 璁剧疆鏁板瓧鐨勬樉绀烘柟寮忥紝overflow|ellipsis|limit + // overflow浼氭牴鎹甿ax瀛楁鍒ゆ柇锛岃秴鍑烘樉绀篳${max}+` + // ellipsis浼氭牴鎹甿ax鍒ゆ柇锛岃秴鍑烘樉绀篳${max}...` + // limit浼氫緷鎹�1000浣滀负鍒ゆ柇鏉′欢锛岃秴鍑�1000锛屾樉绀篳${value/1000}K`锛屾瘮濡�2.2k銆�3.34w锛屾渶澶氫繚鐣�2浣嶅皬鏁� + numberType: { + type: String, + default: uni.$u.props.badge.numberType + }, + // 璁剧疆badge鐨勪綅缃亸绉伙紝鏍煎紡涓� [x, y]锛屼篃鍗宠缃殑涓簍op鍜宺ight鐨勫�硷紝absolute涓簍rue鏃舵湁鏁� + 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 涓婚绫诲瀷锛宔rror|warning|success|primary 锛堥粯璁� 'error' 锛� + * @property {Boolean} showZero 褰撴暟鍊间负 0 鏃讹紝鏄惁灞曠ず Badge 锛堥粯璁� false 锛� + * @property {String} bgColor 鑳屾櫙棰滆壊锛屼紭鍏堢骇姣攖ype楂橈紝濡傝缃紝type鍙傛暟浼氬け鏁� + * @property {String} color 瀛椾綋棰滆壊 锛堥粯璁� '#ffffff' 锛� + * @property {String} shape 寰芥爣褰㈢姸锛宑ircle-鍥涜鍧囦负鍦嗚锛宧orn-宸︿笅瑙掍负鐩磋 锛堥粯璁� 'circle' 锛� + * @property {String} numberType 璁剧疆鏁板瓧鐨勬樉绀烘柟寮忥紝overflow|ellipsis|limit 锛堥粯璁� 'overflow' 锛� + * @property {Array}} offset 璁剧疆badge鐨勪綅缃亸绉伙紝鏍煎紡涓� [x, y]锛屼篃鍗宠缃殑涓簍op鍜宺ight鐨勫�硷紝absolute涓簍rue鏃舵湁鏁� + * @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: { + // 鏄惁灏哹adge涓績涓庣埗缁勪欢鍙充笂瑙掗噸鍚� + 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' + // 濡傛灉鏈夎缃畂ffset鍙傛暟 + if(this.offset.length) { + // top鍜宺ight鍒嗕负涓簅ffset鐨勭涓�涓拰绗簩涓�硷紝濡傛灉娌℃湁绗簩涓�硷紝鍒檙ight绛変簬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锛宲rimary锛宔rror锛寃arning锛宻uccess + type: { + type: String, + default: uni.$u.props.button.type + }, + // 鎸夐挳灏哄锛宭arge锛宯ormal锛宻mall锛宮ini + size: { + type: String, + default: uni.$u.props.button.size + }, + // 鎸夐挳褰㈢姸锛宑ircle锛堜袱杈逛负鍗婂渾锛夛紝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锛堟彁浜よ〃鍗曪級锛宺eset锛堥噸缃〃鍗曪級 + formType: { + type: String, + default: uni.$u.props.button.formType + }, + // 鎵撳紑 APP 鏃讹紝鍚� APP 浼犻�掔殑鍙傛暟锛宱pen-type=launchApp鏃舵湁鏁� + // 鍙井淇″皬绋嬪簭銆丵Q灏忕▼搴忔湁鏁� + appParameter: { + type: String, + default: uni.$u.props.button.appParameter + }, + // 鎸囧畾鏄惁闃绘鏈妭鐐圭殑绁栧厛鑺傜偣鍑虹幇鐐瑰嚮鎬侊紝寰俊灏忕▼搴忔湁鏁� + hoverStopPropagation: { + type: Boolean, + default: uni.$u.props.button.hoverStopPropagation + }, + // 鎸囧畾杩斿洖鐢ㄦ埛淇℃伅鐨勮瑷�锛寊h_CN 绠�浣撲腑鏂囷紝zh_TW 绻佷綋涓枃锛宔n 鑻辨枃銆傚彧寰俊灏忕▼搴忔湁鏁� + lang: { + type: String, + default: uni.$u.props.button.lang + }, + // 浼氳瘽鏉ユ簮锛宱pen-type="contact"鏃舵湁鏁堛�傚彧寰俊灏忕▼搴忔湁鏁� + sessionFrom: { + type: String, + default: uni.$u.props.button.sessionFrom + }, + // 浼氳瘽鍐呮秷鎭崱鐗囨爣棰橈紝open-type="contact"鏃舵湁鏁� + // 榛樿褰撳墠鏍囬锛屽彧寰俊灏忕▼搴忔湁鏁� + sendMessageTitle: { + type: String, + default: uni.$u.props.button.sendMessageTitle + }, + // 浼氳瘽鍐呮秷鎭崱鐗囩偣鍑昏烦杞皬绋嬪簭璺緞锛宱pen-type="contact"鏃舵湁鏁� + // 榛樿褰撳墠鍒嗕韩璺緞锛屽彧寰俊灏忕▼搴忔湁鏁� + sendMessagePath: { + type: String, + default: uni.$u.props.button.sendMessagePath + }, + // 浼氳瘽鍐呮秷鎭崱鐗囧浘鐗囷紝open-type="contact"鏃舵湁鏁� + // 榛樿褰撳墠椤甸潰鎴浘锛屽彧寰俊灏忕▼搴忔湁鏁� + sendMessageImg: { + type: String, + default: uni.$u.props.button.sendMessageImg + }, + // 鏄惁鏄剧ず浼氳瘽鍐呮秷鎭崱鐗囷紝璁剧疆姝ゅ弬鏁颁负 true锛岀敤鎴疯繘鍏ュ鏈嶄細璇濅細鍦ㄥ彸涓嬭鏄剧ず"鍙兘瑕佸彂閫佺殑灏忕▼搴�"鎻愮ず锛� + // 鐢ㄦ埛鐐瑰嚮鍚庡彲浠ュ揩閫熷彂閫佸皬绋嬪簭娑堟伅锛宱pen-type="contact"鏃舵湁鏁� + showMessageCard: { + type: Boolean, + default: uni.$u.props.button.showMessageCard + }, + // 棰濆浼犲弬鍙傛暟锛岀敤浜庡皬绋嬪簭鐨刣ata-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 + }, + // 鎸夐挳棰滆壊锛屾敮鎸佷紶鍏inear-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锛宲rimary锛宔rror锛寃arning锛宻uccess (榛樿 'info' ) + * @property {String} size 鎸夐挳灏哄锛宭arge锛宯ormal锛宮ini 锛堥粯璁� normal锛� + * @property {String} shape 鎸夐挳褰㈢姸锛宑ircle锛堜袱杈逛负鍗婂渾锛夛紝square锛堝甫鍦嗚锛� 锛堥粯璁� 'square' 锛� + * @property {Boolean} plain 鎸夐挳鏄惁闀傜┖锛岃儗鏅壊閫忔槑 锛堥粯璁� false锛� + * @property {Boolean} disabled 鏄惁绂佺敤 锛堥粯璁� false锛� + * @property {Boolean} loading 鎸夐挳鍚嶇О鍓嶆槸鍚﹀甫 loading 鍥炬爣(App-nvue 骞冲彴锛屽湪 ios 涓婁负闆姳锛孉ndroid涓婁负鍦嗗湀) 锛堥粯璁� 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 浼犻�掔殑鍙傛暟锛宱pen-type=launchApp鏃舵湁鏁� 锛堟敞锛氬彧寰俊灏忕▼搴忋�丵Q灏忕▼搴忔湁鏁堬級 + * @property {Boolean} hoverStopPropagation 鎸囧畾鏄惁闃绘鏈妭鐐圭殑绁栧厛鑺傜偣鍑虹幇鐐瑰嚮鎬侊紝寰俊灏忕▼搴忔湁鏁堬紙榛樿 true 锛� + * @property {String} lang 鎸囧畾杩斿洖鐢ㄦ埛淇℃伅鐨勮瑷�锛寊h_CN 绠�浣撲腑鏂囷紝zh_TW 绻佷綋涓枃锛宔n 鑻辨枃锛堥粯璁� en 锛� + * @property {String} sessionFrom 浼氳瘽鏉ユ簮锛宱penType="contact"鏃舵湁鏁� + * @property {String} sendMessageTitle 浼氳瘽鍐呮秷鎭崱鐗囨爣棰橈紝openType="contact"鏃舵湁鏁� + * @property {String} sendMessagePath 浼氳瘽鍐呮秷鎭崱鐗囩偣鍑昏烦杞皬绋嬪簭璺緞锛宱penType="contact"鏃舵湁鏁� + * @property {String} sendMessageImg 浼氳瘽鍐呮秷鎭崱鐗囧浘鐗囷紝openType="contact"鏃舵湁鏁� + * @property {Boolean} showMessageCard 鏄惁鏄剧ず浼氳瘽鍐呮秷鎭崱鐗囷紝璁剧疆姝ゅ弬鏁颁负 true锛岀敤鎴疯繘鍏ュ鏈嶄細璇濅細鍦ㄥ彸涓嬭鏄剧ず"鍙兘瑕佸彂閫佺殑灏忕▼搴�"鎻愮ず锛岀敤鎴风偣鍑诲悗鍙互蹇�熷彂閫佸皬绋嬪簭娑堟伅锛宱penType="contact"鏃舵湁鏁堬紙榛樿false锛� + * @property {String} dataName 棰濆浼犲弬鍙傛暟锛岀敤浜庡皬绋嬪簭鐨刣ata-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浼犲叆鐨勮瘽锛堟敞锛歯vue涓棤娉曟帶鍒舵枃瀛楃殑鏍峰紡锛� + * @property {String} icon 鎸夐挳鍥炬爣 + * @property {String} iconColor 鎸夐挳鍥炬爣棰滆壊 + * @property {String} color 鎸夐挳棰滆壊锛屾敮鎸佷紶鍏inear-gradient娓愬彉鑹� + * @property {Object} customStyle 瀹氫箟闇�瑕佺敤鍒扮殑澶栭儴鏍峰紡 + * + * @event {Function} click 闈炵姝㈠苟涓旈潪鍔犺浇涓紝鎵嶈兘鐐瑰嚮 + * @event {Function} getphonenumber open-type="getPhoneNumber"鏃舵湁鏁� + * @event {Function} getuserinfo 鐢ㄦ埛鐐瑰嚮璇ユ寜閽椂锛屼細杩斿洖鑾峰彇鍒扮殑鐢ㄦ埛淇℃伅锛屼粠杩斿洖鍙傛暟鐨刣etail涓幏鍙栧埌鐨勫�煎悓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涓轰竴涓猚omputed鍙橀噺锛屽湪mixin涓� + if (!this.color) { + return this.bem( + "button", + ["type", "shape", "size"], + ["disabled", "plain", "hairline"] + ); + } else { + // 鐢变簬nvue鐨勫師鍥狅紝鍦ㄦ湁color鍙傛暟鏃讹紝涓嶉渶瑕佷紶鍏ype锛屽惁鍒欎細鐢熸垚type鐩稿叧鐨勭被鍨嬶紝褰卞搷鏈�缁堢殑鏍峰紡 + return this.bem( + "button", + ["shape", "size"], + ["disabled", "plain", "hairline"] + ); + } + }, + loadingColor() { + if (this.plain) { + // 濡傛灉鏈夎缃甤olor鍊硷紝鍒欑敤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() { + // 濡傛灉鏄晜绌虹姸鎬侊紝璁剧疆浜哻olor灏辩敤color鍊硷紝鍚﹀垯浣跨敤涓婚棰滆壊锛� + // u-icon鐨刢olor鑳芥帴鍙椾竴涓富棰橀鑹茬殑鍊� + 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鏂囨。璇存槑鍙互鍐檅orderWidth鐨勫舰寮忥紝涓轰粈涔堣繖閲岄渶瑕佸垎寮�鍐欙紵 + // 鍥犱负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鐗堟湰鎸夐挳鐨勫瓧浣撲笉浼氱户鎵跨埗缁勪欢鐨勯鑹诧紝闇�瑕佸姣忎竴涓猼ext缁勪欢杩涜鍗曠嫭鐨勮缃� + 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); + } + }, + // 涓嬮潰涓哄鎺niapp瀹樻柟鎸夐挳寮�鏀捐兘鍔涗簨浠跺洖璋冪殑瀵规帴 + 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涓媓over-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涓簃ultiple鎴杛ange鏄繀椤讳负鏁扮粍鏍煎紡 + 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, + // 褰撳墠閫変腑鐨勬棩鏈焛tem + 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鍏徃鐨刬OS瀹㈡埛绔殑寮�鍙戣�呰兘鍔涙湁闄愬鑷寸殑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鏄惁鍦╯elected鏁扮粍涓紝鍥犱负鏈堜唤鍙兘浼氶渶瑕佽ˉ0锛屾墍浠ヤ娇鐢╠ateSame鍒ゆ柇锛岃�屼笉鐢ㄦ暟缁勭殑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鍏徃鐨刬OS瀹㈡埛绔殑寮�鍙戣�呰兘鍔涙湁闄愬鑷寸殑bug + // 杩涜杩樺師鎿嶄綔锛屽惁鍒欏湪nvue鐨刬OS锛寀ni-app鏈塨ug锛屼細瀵艰嚧璇″紓鐨勮〃鐜� + 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锛屼笖绗竴涓瓑浜庣浜屼釜鏃ユ湡锛屽垯鎻愮ず璇斁鍦ㄥ悓涓�涓猧tem涓� + 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(() => { + // 杩欓噷闇�瑕佸彟涓�涓欢鏃讹紝鍥犱负鑾峰彇瀹藉害鍚庯紝浼氳繘琛屾湀浠芥暟鎹覆鏌擄紝鍙湁娓叉煋瀹屾垚涔嬪悗锛屾墠鏈夌湡姝g殑楂樺害 + // 鍥犱负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++) { + // 娣诲姞鍒癿onths鏁扮粍涓紝渚泂croll-view婊氬姩浜嬩欢涓紝鍒ゆ柇褰撳墠婊氬姩鍒板摢涓湀浠� + topArr[i] = height + height += sizes[i].height + } + // 鐢变簬寰俊涓嬶紝鏃犳硶閫氳繃this.months[i].top鐨勫舰寮�(寮曠敤绫诲瀷)鍘讳慨鏀圭埗缁勪欢鐨刴onth鐨則op鍊硷紝鎵�浠ヤ娇鐢ㄤ簨浠跺舰寮忓澶栧彂鍑� + this.$emit('updateMonthTop', topArr) + }) + }, + // 鑾峰彇姣忎釜鏈堜唤鍖哄煙鐨勫昂瀵� + getMonthRectByPromise(el) { + // #ifndef APP-NVUE + // $uGetRect涓簎View鑷甫鐨勮妭鐐规煡璇㈢畝鍖栨柟娉曪紝璇﹁鏂囨。浠嬬粛锛歨ttps://www.uviewui.com/js/getRect.html + // 缁勪欢鍐呴儴涓�鑸敤this.$uGetRect锛屽澶栫殑涓簎ni.$u.getRect锛屼簩鑰呭姛鑳戒竴鑷达紝鍚嶇О涓嶅悓 + return new Promise(resolve => { + this.$uGetRect(`.${el}`).then(size => { + resolve(size) + }) + }) + // #endif + + // #ifdef APP-NVUE + // nvue涓嬶紝浣跨敤dom妯″潡鏌ヨ鍏冪礌楂樺害 + // 杩斿洖涓�涓猵romise锛岃璋冪敤姝ゆ柟娉曠殑涓讳綋鑳戒娇鐢╰hen鍥炶皟 + 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涓嬩娇鐢╟ss杩涜瀹藉害璁$畻锛屽洜涓烘煇浜涘畨鍗撴満浼氭棤娉曡繘琛宩s鑾峰彇鐖跺厓绱犲搴﹁繘琛岃绠楀緱鍑猴紝浼氭湁鍋忕Щ + 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 + }, + // 鏃ユ湡绫诲瀷閫夋嫨锛宻ingle-閫夋嫨鍗曚釜鏃ユ湡锛宮ultiple-鍙互閫夋嫨澶氫釜鏃ユ湡锛宺ange-閫夋嫨鏃ユ湡鑼冨洿 + 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涓簃ultiple鎴杛ange鏄繀椤讳负鏁扮粍鏍煎紡 + 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-閫夋嫨鍗曚釜鏃ユ湡锛宮ultiple-鍙互閫夋嫨澶氫釜鏃ユ湡锛宺ange-閫夋嫨鏃ユ湡鑼冨洿 锛� 榛樿 '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涓簃ultiple鎴杛ange鏄繀椤讳负鏁扮粍鏍煎紡 + * @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: [], + // 鍦ㄦ湀浠芥粴鍔ㄥ尯鍩熶腑锛屽綋鍓嶈鍥句腑鏈堜唤鐨刬ndex绱㈠紩 + 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鍜宮inDate鍙互涓哄瓧绗︿覆(2021-10-10)锛屾垨鑰呮暟鍊�(鏃堕棿鎴�)锛屼絾鏄痙ayjs濡傛灉鎺ュ彈瀛楃涓插舰寮忕殑鏃堕棿鎴充細鏈夐棶棰橈紝杩欓噷杩涜澶勭悊 + 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() { + // 鍒濆鍖栨椂锛宼his.months涓虹┖鏁扮粍锛屾墍浠ラ渶瑕佺壒鍒垽鏂鐞� + if (this.months.length) { + return `${this.months[this.monthIndex].year}骞�${ + this.months[this.monthIndex].month + }鏈坄 + } else { + return '' + } + }, + buttonDisabled() { + // 濡傛灉涓簉ange绫诲瀷锛屼笖閫夋嫨鐨勬棩鏈熶釜鏁颁笉瓒�1涓椂锛岃搴曢儴鐨勬寜閽嚭浜巇isabled鐘舵�� + 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锛屼笉鑳藉皬浜巑inDate + 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, + // 灏忎簬鏈�灏忓厑璁哥殑鏃ユ湡锛屾垨鑰呭ぇ浜庢渶澶х殑鏃ユ湡锛屽垯璁剧疆涓篸isabled鐘舵�� + 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 + } + } + }, + // 鏇存柊鏈堜唤鐨則op鍊� + updateMonthTop(topArr = []) { + // 璁剧疆瀵瑰簲鏈堜唤鐨則op鍊硷紝鐢ㄤ簬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灏佽鐨剅oute鏂规硶锛屽彲鑳戒細杩涜鎷︽埅鎿嶄綔 + 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 + }, + // 鏄惁鏄剧ず琛ㄥ崟鐘舵�佷笅鐨勫繀濉槦鍙�(姝ょ粍浠跺彲鑳戒細鍐呭祵鍏nput缁勪欢) + required: { + type: Boolean, + default: uni.$u.props.cell.required + }, + // 鍙充晶鐨勫浘鏍囩澶� + rightIcon: { + type: String, + default: uni.$u.props.cell.rightIcon + }, + // 鍙充晶绠ご鐨勬柟鍚戯紝鍙�夊�间负锛歭eft锛寀p锛宒own + 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灏佽鐨剅oute鏂规硶锛屽彲鑳戒細杩涜鎷︽埅鎿嶄綔 (榛樿 'navigateTo' ) + * @property {Boolean} clickable 鏄惁寮�鍚偣鍑诲弽棣�(琛ㄧ幇涓虹偣鍑绘椂鍔犱笂鐏拌壊鑳屾櫙) 锛堥粯璁� false 锛� + * @property {Boolean} isLink 鏄惁灞曠ず鍙充晶绠ご骞跺紑鍚偣鍑诲弽棣� 锛堥粯璁� false 锛� + * @property {Boolean} required 鏄惁鏄剧ず琛ㄥ崟鐘舵�佷笅鐨勫繀濉槦鍙�(姝ょ粍浠跺彲鑳戒細鍐呭祵鍏nput缁勪欢) 锛堥粯璁� false 锛� + * @property {String} rightIcon 鍙充晶鐨勫浘鏍囩澶� 锛堥粯璁� 'arrow-right'锛� + * @property {String} arrowDirection 鍙充晶绠ご鐨勬柟鍚戯紝鍙�夊�间负锛歭eft锛寀p锛宒own + * @property {Object | String} rightIconStyle 鍙充晶绠ご鍥炬爣鐨勬牱寮� + * @property {Object | String} titleStyle 鏍囬鐨勬牱寮� + * @property {Object | String} iconStyle 宸︿晶鍥炬爣鏍峰紡 + * @property {String} size 鍗曚綅鍏冪殑澶у皬锛屽彲閫夊�间负 large锛宯ormal锛宮ini + * @property {Boolean} stop 鐐瑰嚮cell鏄惁闃绘浜嬩欢浼犳挱 (榛樿 true ) + * @property {Object} customStyle 瀹氫箟闇�瑕佺敤鍒扮殑澶栭儴鏍峰紡 + * + * @event {Function} click 鐐瑰嚮cell鍒楄〃鏃惰Е鍙� + * @example 璇ョ粍浠堕渶瑕佹惌閰峜ell-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 + }) + // 濡傛灉閰嶇疆浜唘rl(姝rops鍙傛暟閫氳繃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 + }, + // 褰㈢姸锛宑ircle-鍦嗗舰锛宻quare-鏂瑰舰 + shape: { + type: String, + default: uni.$u.props.checkboxGroup.shape + }, + // 鏄惁绂佺敤鍏ㄩ儴checkbox + disabled: { + type: Boolean, + default: uni.$u.props.checkboxGroup.disabled + }, + + // 閫変腑鐘舵�佷笅鐨勯鑹诧紝濡傝缃鍊硷紝灏嗕細瑕嗙洊parent鐨刟ctiveColor鍊� + 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 + }, + // 甯冨眬鏂瑰紡锛宺ow-妯悜锛宑olumn-绾靛悜 + 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 + }, + // 鍕鹃�夊浘鏍囩殑瀵归綈鏂瑰紡锛宭eft-宸﹁竟锛宺ight-鍙宠竟 + 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 褰㈢姸锛宑ircle-鍦嗗舰锛宻quare-鏂瑰舰 锛堥粯璁� 'square' 锛� + * @property {Boolean} disabled 鏄惁绂佺敤鍏ㄩ儴checkbox 锛堥粯璁� false 锛� + * @property {String} activeColor 閫変腑鐘舵�佷笅鐨勯鑹诧紝濡傝缃鍊硷紝灏嗕細瑕嗙洊parent鐨刟ctiveColor鍊� 锛堥粯璁� '#2979ff' 锛� + * @property {String} inactiveColor 鏈�変腑鐨勯鑹� 锛堥粯璁� '#c8c9cc' 锛� + * @property {String | Number} size 鏁翠釜缁勪欢鐨勫昂瀵� 鍗曚綅px 锛堥粯璁� 18 锛� + * @property {String} placement 甯冨眬鏂瑰紡锛宺ow-妯悜锛宑olumn-绾靛悜 锛堥粯璁� '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 鍕鹃�夊浘鏍囩殑瀵归綈鏂瑰紡锛宭eft-宸﹁竟锛宺ight-鍙宠竟 锛堥粯璁� 'left' 锛� + * @property {Boolean} borderBottom placement涓簉ow鏃讹紝鏄惁鏄剧ず涓嬭竟妗� 锛堥粯璁� false 锛� + * @event {Function} change 浠讳竴涓猚heckbox鐘舵�佸彂鐢熷彉鍖栨椂瑙﹀彂锛屽洖璋冧负涓�涓璞� + * @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鐨勫彉閲忥紝閮芥槸瀛愮粍浠秛-checkbox闇�瑕佺敤鍒扮殑锛岀敱浜庡ご鏉″皬绋嬪簭鐨勫吋瀹规�у樊寮傦紝瀛愮粍浠舵棤娉曞疄鏃剁洃鍚埗缁勪欢鍙傛暟鐨勫彉鍖� + // 鎵�浠ラ渶瑕佹墜鍔ㄩ�氱煡瀛愮粍浠讹紝杩欓噷杩斿洖涓�涓猵arentData鍙橀噺锛屼緵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涓轰竴涓猚omputed鍙橀噺锛屽湪mixin涓� + return this.bem('checkbox-group', ['placement']) + }, + }, + watch: { + // 褰撶埗缁勪欢闇�瑕佸瓙缁勪欢闇�瑕佸叡浜殑鍙傛暟鍙戠敓浜嗗彉鍖栵紝鎵嬪姩閫氱煡瀛愮粍浠� + parentData() { + if (this.children.length) { + this.children.map(child => { + // 鍒ゆ柇瀛愮粍浠�(u-checkbox)濡傛灉鏈塱nit鏂规硶鐨勮瘽锛屽氨灏辨墽琛�(鎵ц鐨勭粨鏋滄槸瀛愮粍浠堕噸鏂颁粠鐖剁粍浠舵媺鍙栦簡鏈�鏂扮殑鍊�) + typeof(child.init) === 'function' && child.init() + }) + } + }, + }, + data() { + return { + + } + }, + created() { + this.children = [] + }, + methods: { + // 灏嗗叾浠栫殑checkbox璁剧疆涓烘湭閫変腑鐨勭姸鎬� + unCheckedOther(childInstance) { + const values = [] + this.children.map(child => { + // 灏嗚閫変腑鐨刢heckbox锛屾斁鍒版暟缁勪腑杩斿洖 + 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 + }, + // 褰㈢姸锛宻quare涓烘柟褰紝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鐨刟ctiveColor鍊� + 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鎻愮ず鏂囧瓧锛屽洜涓簄vue涓嬶紝鐩存帴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 褰㈢姸锛宻quare涓烘柟褰紝circle涓哄渾鍨� + * @property {String | Number} size 鏁翠綋鐨勫ぇ灏� + * @property {Boolean} checked 鏄惁榛樿閫変腑 + * @property {String | Boolean} disabled 鏄惁绂佺敤 + * @property {String} activeColor 閫変腑鐘舵�佷笅鐨勯鑹诧紝濡傝缃鍊硷紝灏嗕細瑕嗙洊parent鐨刟ctiveColor鍊� + * @property {String} inactiveColor 鏈�変腑鐨勯鑹� + * @property {String | Number} iconSize 鍥炬爣鐨勫ぇ灏忥紝鍗曚綅px + * @property {String} iconColor 鍥炬爣棰滆壊 + * @property {String | Number} label label鎻愮ず鏂囧瓧锛屽洜涓簄vue涓嬶紝鐩存帴slot杩涙潵鐨勬枃瀛楋紝鐢变簬鐗规畩鐨勭粨鏋勶紝鏃犳硶淇敼鏍峰紡 + * @property {String} labelColor label鐨勯鑹� + * @property {String | Number} labelSize label鐨勫瓧浣撳ぇ灏忥紝px鍗曚綅 + * @property {String | Boolean} labelDisabled 鏄惁绂佹鐐瑰嚮鎻愮ず璇�変腑澶嶉�夋 + * @property {Object} customStyle 瀹氫箟闇�瑕佺敤鍒扮殑澶栭儴鏍峰紡 + * + * @event {Function} change 浠讳竴涓猚heckbox鐘舵�佸彂鐢熷彉鍖栨椂瑙﹀彂锛屽洖璋冧负涓�涓璞� + * @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, + // 鐖剁粍浠剁殑榛樿鍊硷紝鍥犱负澶存潯灏忕▼搴忎笉鏀寔鍦╟omputed涓娇鐢╰his.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; + }, + // 缁勪欢灏哄锛屽搴攕ize鐨勫�硷紝榛樿鍊间负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') + } + // 鏀粯瀹濓紝澶存潯灏忕▼搴忔棤娉曞姩鎬佺粦瀹氫竴涓暟缁勭被鍚嶏紝鍚﹀垯瑙f瀽鍑烘潵鐨勭粨鏋滀細甯︽湁","锛岃�屽鑷村け鏁� + // #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璁剧疆涓簍rue锛岄渶瑕佸悓鏃跺皢u-checkbox-group鐨刾lacement璁剧疆涓篶olumn鎵嶆湁鏁�') + } + // 褰撶埗缁勪欢璁剧疆浜嗘樉绀轰笅杈规骞朵笖鎺掑垪褰㈠紡涓虹旱鍚戞椂锛岀粰鍐呭鍜岃竟妗嗕箣闂村姞涓婁竴瀹氶棿闅� + 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() { + // 鏀粯瀹濆皬绋嬪簭涓嶆敮鎸乸rovide/inject锛屾墍浠ヤ娇鐢ㄨ繖涓柟娉曡幏鍙栨暣涓埗缁勪欢锛屽湪created瀹氫箟锛岄伩鍏嶅惊鐜紩鐢� + this.updateParentData() + if (!this.parent) { + uni.$u.error('u-checkbox蹇呴』鎼厤u-checkbox-group缁勪欢浣跨敤') + } + // 璁剧疆鍒濆鍖栨椂锛屾槸鍚﹂粯璁ら�変腑鐨勭姸鎬侊紝鐖剁粍浠秛-checkbox-group鐨剉alue鍙兘鏄痑rray锛屾墍浠ラ澶栧垽鏂� + if (this.checked) { + this.isChecked = true + } else if (uni.$u.test.array(this.parentData.value)) { + // 鏌ユ壘鏁扮粍鏄槸鍚﹀瓨鍦╰his.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) + // 濡傛灉鎸夐挳鏁翠綋琚鐢ㄦ垨鑰卨abel琚鐢紝鍒欎笉鍏佽鐐瑰嚮鏂囧瓧淇敼鐘舵�� + if (!this.elLabelDisabled && !this.elDisabled) { + this.setRadioCheckedStatus() + } + }, + emitEvent() { + this.$emit('change', this.isChecked) + // 灏濊瘯璋冪敤u-form鐨勯獙璇佹柟娉曪紝杩涜涓�瀹氬欢杩燂紝鍚﹀垯寰俊灏忕▼搴忔洿鏂板彲鑳戒細涓嶅強鏃� + this.$nextTick(() => { + uni.$u.formValidate(this, 'change') + }) + }, + // 鏀瑰彉缁勪欢閫変腑鐘舵�� + // 杩欓噷鐨勬敼鍙樼殑渚濇嵁鏄紝鏇存敼鏈粍浠剁殑checked鍊间负true锛屽悓鏃堕�氳繃鐖剁粍浠堕亶鍘嗘墍鏈塽-checkbox瀹炰緥 + // 灏嗘湰缁勪欢澶栫殑鍏朵粬u-checkbox鐨刢hecked閮借缃负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 + }, + // 鏄剧ず妯″紡锛宐ox-鐩掑瓙妯″紡锛宭ine-搴曢儴妯嚎妯″紡 + 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 璇ョ粍浠朵竴鑸敤浜庨獙璇佺敤鎴风煭淇¢獙璇佺爜鐨勫満鏅紝涔熷彲浠ョ粨鍚坲View鐨勯敭鐩樼粍浠朵娇鐢� + * @tutorial https://www.uviewui.com/components/codeInput.html + * @property {String | Number} maxlength 鏈�澶ц緭鍏ラ暱搴� 锛堥粯璁� 6 锛� + * @property {Boolean} dot 鏄惁鐢ㄥ渾鐐瑰~鍏� 锛堥粯璁� false 锛� + * @property {String} mode 鏄剧ず妯″紡锛宐ox-鐩掑瓙妯″紡锛宭ine-搴曢儴妯嚎妯″紡 锛堥粯璁� '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 瀛椾綋澶у皬锛屽崟浣峱x 锛堥粯璁� 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 杈撳叆瀛楃涓暟杈緈axlength鍊兼椂瑙﹀彂锛岃涓婃柟璇存槑 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: { + // 鏍规嵁闀垮害锛屽惊鐜緭鍏ユ鐨勪釜鏁帮紝鍥犱负澶存潯灏忕▼搴忔暟鍊间笉鑳界敤浜巚-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('.', '') + }) + } + // 鏈揪鍒癿axlength涔嬪墠锛屽彂閫乧hange浜嬩欢锛岃揪鍒板悗鍙戦�乫inish浜嬩欢 + 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 { + // 涔嬫墍浠ラ渶瑕乮nput杈撳叆妗嗭紝鏄洜涓烘湁瀹冩墠鑳藉敜璧烽敭鐩� + // 杩欓噷灏嗗畠璁剧疆涓轰袱鍊嶇殑灞忓箷瀹藉害锛屽啀灏嗗乏杈圭殑涓�鍗婄Щ鍑哄睆骞曪紝涓轰簡涓嶈鐢ㄦ埛鐪嬪埌杈撳叆鐨勫唴瀹� + 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 + }, + // 姝e湪鍊掕鏃朵腑鐨勬彁绀� + changeText: { + type: String, + default: uni.$u.props.code.changeText + }, + // 鍊掕鏃剁粨鏉熸椂鐨勬彁绀� + endText: { + type: String, + default: uni.$u.props.code.endText + }, + // 鏄惁鍦℉5鍒锋柊鎴栧悇绔繑鍥炲啀杩涘叆鏃剁户缁�掕鏃� + 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瀹屾垚锛屾棤闇�鍐檋tml閫昏緫 --> + </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 鏄惁鍦℉5鍒锋柊鎴栧悇绔繑鍥炲啀杩涘叆鏃剁户缁�掕鏃讹紙 榛樿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 { + // 濡傛灉涓嶅瓨鍦ㄩ渶瑕佺户缁笂涓�娆$殑鍊掕鏃讹紝鎵ц姝e父鐨勯�昏緫 + 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銆乧enter銆乥ottom銆乻tretch + 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 璇ョ粍浠朵竴鑸敤浜嶭ayout 甯冨眬 閫氳繃鍩虹鐨� 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銆乧enter銆乥ottom銆乻tretch (榛樿 '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 + // 鍦╪vue涓婏紝鐢变簬鏃犳硶浣跨敤鐧惧垎姣斿崟浣嶏紝杩欓噷闇�瑕佽幏鍙栫埗缁勪欢鐨勫搴︼紝鍐嶈绠楀緱鍑鸿鏈夊搴旂殑鐧惧垎姣斿昂瀵� + 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() { + // 鏀粯瀹濆皬绋嬪簭涓嶆敮鎸乸rovide/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 閫氳繃鎶樺彔闈㈡澘鏀剁撼鍐呭鍖哄煙锛堟惌閰島-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, + // 鐖剁粍浠秛-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蹇呴』瑕佹惌閰島-collapse缁勪欢浣跨敤') + } + const { + value, + accordion, + children = [] + } = this.parent + + if (accordion) { + if (uni.$u.test.array(value)) { + return uni.$u.error('鎵嬮鐞存ā寮忎笅锛寀-collapse缁勪欢鐨剉alue鍙傛暟涓嶈兘涓烘暟缁�') + } + this.expanded = this.name == value + } else { + if (!uni.$u.test.array(value) && value !== null) { + return uni.$u.error('闈炴墜椋庣惔妯″紡涓嬶紝u-collapse缁勪欢鐨剉alue鍙傛暟蹇呴』涓烘暟缁�') + } + 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, + // 蹇呴』璁剧疆涓簍rue锛屽惁鍒欎細鍒伴潰鏉挎敹璧锋垨灞曞紑鏃讹紝椤甸潰鍏朵粬鍏冪礌涓嶄細闅忎箣璋冩暣瀹冧滑鐨勫竷灞� + 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涓簎View鑷甫鐨勮妭鐐规煡璇㈢畝鍖栨柟娉曪紝璇﹁鏂囨。浠嬬粛锛歨ttps://www.uviewui.com/js/getRect.html + // 缁勪欢鍐呴儴涓�鑸敤this.$uGetRect锛屽澶栫殑涓簎ni.$u.getRect锛屼簩鑰呭姛鑳戒竴鑷达紝鍚嶇О涓嶅悓 + return new Promise(resolve => { + this.$uGetRect(`#${this.elId}`).then(size => { + resolve(size) + }) + }) + // #endif + + // #ifdef APP-NVUE + // nvue涓嬶紝浣跨敤dom妯″潡鏌ヨ鍏冪礌楂樺害 + // 杩斿洖涓�涓猵romise锛岃璋冪敤姝ゆ柟娉曠殑涓讳綋鑳戒娇鐢╰hen鍥炶皟 + 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: { + // 褰撳墠灞曞紑闈㈡澘鐨刵ame锛岄潪鎵嬮鐞存ā寮忥細[<string | number>]锛屾墜椋庣惔妯″紡锛歴tring | 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 褰撳墠灞曞紑闈㈡澘鐨刵ame锛岄潪鎵嬮鐞存ā寮忥細[<string | number>]锛屾墜椋庣惔妯″紡锛歴tring | number + * @property {Boolean} accordion 鏄惁鎵嬮鐞存ā寮忥紙 榛樿 false 锛� + * @property {Boolean} border 鏄惁鏄剧ず澶栬竟妗� ( 榛樿 true 锛� + * @event {Function} change 褰撳墠婵�娲婚潰鏉垮睍寮�鏃惰Е鍙�(濡傛灉鏄墜椋庣惔妯″紡锛屽弬鏁癮ctiveNames绫诲瀷涓篠tring锛屽惁鍒欎负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锛屽悓鏃剁洃鍚琣ccordion鍜寁alue鍊肩殑鍙樺寲 + // 鍐嶉�氳繃watch鍘绘墽琛宨nit()鏂规硶锛岃繘琛屽啀涓�娆$殑鍒濆鍖� + return [this.accordion, this.value] + } + }, + watch: { + // 褰撶埗缁勪欢闇�瑕佸瓙缁勪欢闇�瑕佸叡浜殑鍙傛暟鍙戠敓浜嗗彉鍖栵紝鎵嬪姩閫氱煡瀛愮粍浠� + parentData() { + if (this.children.length) { + this.children.map(child => { + // 鍒ゆ柇瀛愮粍浠�(u-checkbox)濡傛灉鏈塽pdateParentData鏂规硶鐨勮瘽锛屽氨灏辨墽琛�(鎵ц鐨勭粨鏋滄槸瀛愮粍浠堕噸鏂颁粠鐖剁粍浠舵媺鍙栦簡鏈�鏂扮殑鍊�) + 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 + }, + // 閫氬憡妯″紡锛宭ink-鏄剧ず鍙崇澶达紝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 + }, + // 瀛椾綋澶у皬锛屽崟浣峱x + 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+銆丠5 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 閫氬憡妯″紡锛宭ink-鏄剧ず鍙崇澶达紝closable-鏄剧ず鍙充晶鍏抽棴鍥炬爣 + * @property {String} color 鏂囧瓧棰滆壊锛屽悇鍥炬爣涔熶細浣跨敤鏂囧瓧棰滆壊 锛� 榛樿 '#f9ae3d' 锛� + * @property {String} bgColor 鑳屾櫙棰滆壊 锛� 榛樿 '#fdf6ec' 锛� + * @property {String | Number} fontSize 瀛椾綋澶у皬锛屽崟浣峱x 锛� 榛樿 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+銆丠5 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涓篶olumn鏃讹紝瑕佹眰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 + }, + // 鏃堕棿鏍煎紡锛孌D-鏃ワ紝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 鏃堕棿鏍煎紡锛孌D-鏃ワ紝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)) + } + // 鍏朵粬鍚岀悊浜嶥D鐨勬牸寮忓寲澶勭悊鏂瑰紡 + 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 + }, + // 婊氬姩鍒扮洰鏍囨暟鍊肩殑鍔ㄧ敾鎸佺画鏃堕棿锛屽崟浣嶄负姣锛坢s锛� + 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 婊氬姩鍒扮洰鏍囨暟鍊肩殑鍔ㄧ敾鎸佺画鏃堕棿锛屽崟浣嶄负姣锛坢s锛� 锛堥粯璁� 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 瀛椾綋澶у皬锛屽崟浣峱x锛� 榛樿 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(); + // 涓轰簡浣縮etTimteout鐨勫敖鍙兘鐨勬帴杩戞瘡绉�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) { + // 灏唍um杞负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 + }, + // 灞曠ず鏍煎紡锛宮ode=date涓烘棩鏈熼�夋嫨锛宮ode=time涓烘椂闂撮�夋嫨锛宮ode=year-month涓哄勾鏈堥�夋嫨锛宮ode=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 + }, + // 鍙�夌殑鏈�灏忓皬鏃讹紝浠卪ode=time鏈夋晥 + minHour: { + type: Number, + default: uni.$u.props.datetimePicker.minHour + }, + // 鍙�夌殑鏈�澶у皬鏃讹紝浠卪ode=time鏈夋晥 + maxHour: { + type: Number, + default: uni.$u.props.datetimePicker.maxHour + }, + // 鍙�夌殑鏈�灏忓垎閽燂紝浠卪ode=time鏈夋晥 + minMinute: { + type: Number, + default: uni.$u.props.datetimePicker.minMinute + }, + // 鍙�夌殑鏈�澶у垎閽燂紝浠卪ode=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涓烘棩鏈熼�夋嫨锛宮ode=time涓烘椂闂撮�夋嫨锛宮ode=year-month涓哄勾鏈堥�夋嫨锛宮ode=datetime涓烘棩鏈熸椂闂撮�夋嫨 ( 榛樿 鈥榙atetime ) + * @property {Number} maxDate 鍙�夌殑鏈�澶ф椂闂� 榛樿鍊间负鍚�10骞� + * @property {Number} minDate 鍙�夌殑鏈�灏忔椂闂� 榛樿鍊间负鍓�10骞� + * @property {Number} minHour 鍙�夌殑鏈�灏忓皬鏃讹紝浠卪ode=time鏈夋晥 ( 榛樿 0 ) + * @property {Number} maxHour 鍙�夌殑鏈�澶у皬鏃讹紝浠卪ode=time鏈夋晥 ( 榛樿 23 ) + * @property {Number} minMinute 鍙�夌殑鏈�灏忓垎閽燂紝浠卪ode=time鏈夋晥 ( 榛樿 0 ) + * @property {Number} maxMinute 鍙�夌殑鏈�澶у垎閽燂紝浠卪ode=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 + } + // 涓嶅厑璁歌秴杩噈axDate鍊� + 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鏃堕棿锛寁alue涓哄綋鍓嶉�変腑鐨勬椂闂存埑 + this.$emit('change', { + value: selectValue, + // #ifndef MP-WEIXIN + // 寰俊灏忕▼搴忎笉鑳戒紶閫抰his瀹炰緥锛屼細鍥犱负寰幆寮曠敤鑰屾姤閿� + 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') { + // 灏唗ime妯″紡鐨勬椂闂寸敤:鍒嗛殧鎴愭暟缁� + 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') { + // 鏁扮粍鐨刾ush鏂规硶锛屽彲浠ュ啓鍏ュ涓弬鏁� + 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銆乵axDate銆乵inHour銆乵axHour绛夎竟鐣屽�硷紝鍒ゆ柇鍚勫垪鐨勫紑濮嬪拰缁撴潫杈圭晫鍊� + 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-宸﹁竟锛宑enter-涓棿锛宺ight-鍙宠竟 + 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-宸﹁竟锛宑enter-涓棿锛宺ight-鍙宠竟 锛堥粯璁� '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锟皆达拷锟侥节碉拷锟窖拷蚧锟斤拷锟斤拷锟斤拷锟斤拷锟侥碉拷锟斤拷锟杰o拷https://www.uviewui.com/js/getRect.html + // 锟斤拷锟斤拷诓锟揭伙拷锟斤拷锟絫his.$uGetRect锟斤拷锟斤拷锟斤拷锟轿猼his.$u.getRect锟斤拷锟斤拷锟竭癸拷锟斤拷一锟铰o拷锟斤拷锟狡诧拷同 + return new Promise(resolve => { + this.$uGetRect(`.${el}`).then(size => { + resolve(size) + }) + }) + // #endif + + // #ifdef APP-NVUE + // nvue锟铰o拷使锟斤拷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 + }, + // 鑿滃崟鍙充晶鐨刬con鍥炬爣 + 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锟皆达拷锟侥节碉拷锟窖拷蚧锟斤拷锟斤拷锟斤拷锟斤拷锟侥碉拷锟斤拷锟杰o拷https://www.uviewui.com/js/getRect.html + // 锟斤拷锟斤拷诓锟揭伙拷锟斤拷锟絫his.$uGetRect锟斤拷锟斤拷锟斤拷锟轿猼his.$u.getRect锟斤拷锟斤拷锟竭癸拷锟斤拷一锟铰o拷锟斤拷锟狡诧拷同 + return new Promise(resolve => { + this.$uGetRect(`.${el}`).then(size => { + resolve(size) + }) + }) + // #endif + + // #ifdef APP-NVUE + // nvue锟铰o拷使锟斤拷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 + }, + // 鍥炬爣瀹藉害锛屽崟浣峱x + width: { + type: [String, Number], + default: uni.$u.props.empty.width + }, + // 鍥炬爣楂樺害锛屽崟浣峱x + height: { + type: [String, Number], + default: uni.$u.props.empty.height + }, + // 鏄惁鏄剧ず缁勪欢 + show: { + type: Boolean, + default: uni.$u.props.empty.show + }, + // 缁勪欢璺濈涓婁竴涓厓绱犱箣闂寸殑璺濈锛岄粯璁x鍗曚綅 + 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 鍥炬爣瀹藉害锛屽崟浣峱x 锛堥粯璁� 160 锛� + * @property {String | Number} height 鍥炬爣楂樺害锛屽崟浣峱x 锛堥粯璁� 160 锛� + * @property {Boolean} show 鏄惁鏄剧ず缁勪欢 锛堥粯璁� true 锛� + * @property {String | Number} marginTop 缁勪欢璺濈涓婁竴涓厓绱犱箣闂寸殑璺濈锛岄粯璁x鍗曚綅 锛堥粯璁� 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鐨刲abel鎻愮ず璇� + 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-宸﹁竟锛宼op-涓婅竟 + 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 + }, + // 鏄惁鏄剧ず宸﹁竟鐨勫繀濉槦鍙凤紝鍙綔鏄剧ず鐢紝鍏蜂綋鏍¢獙蹇呭~鐨勯�昏緫锛岃鍦╮ules涓厤缃� + 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鐨刲abel鎻愮ず璇� + * @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 鏄惁鏄剧ず宸﹁竟鐨勫繀濉槦鍙凤紝鍙綔鏄剧ず鐢紝鍏蜂綋鏍¢獙蹇呭~鐨勯�昏緫锛岃鍦╮ules涓厤缃� (榛樿 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闇�瑕佺粨鍚坲-form缁勪欢浣跨敤') + } + }, + // 鑾峰彇鐖剁粍浠剁殑鍙傛暟 + updateParentData() { + // 姝ゆ柟娉曞啓鍦╩ixin涓� + this.getParentData('u-form'); + }, + // 绉婚櫎u-form-item鐨勬牎楠岀粨鏋� + clearValidate() { + this.message = null + }, + // 娓呯┖褰撳墠鐨勭粍浠剁殑鏍¢獙缁撴灉锛屽苟閲嶇疆涓哄垵濮嬪�� + resetField() { + // 鎵惧埌鍘熷鍊� + const value = uni.$u.getProperty(this.parent.originalModel, this.prop) + // 灏唘-form鐨刴odel鐨刾rop灞炴�ч摼杩樺師鍘熷鍊� + 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-鎻愮ず淇℃伅锛宼oast-杩涜toast鎻愮ず + // border-bottom-涓嬭竟妗嗗憟鐜扮孩鑹诧紝none-鏃犳彁绀� + errorType: { + type: String, + default: uni.$u.props.form.errorType + }, + // 鏄惁鏄剧ず琛ㄥ崟鍩熺殑涓嬪垝绾胯竟妗� + borderBottom: { + type: Boolean, + default: uni.$u.props.form.borderBottom + }, + // label鐨勪綅缃紝left-宸﹁竟锛宼op-涓婅竟 + 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 琛ㄥ崟鍩熸彁绀烘枃瀛楃殑浣嶇疆锛宭eft-宸︿晶锛宼op-涓婃柟 ( 榛樿 'left' 锛� + * @property {String | Number} labelWidth 鎻愮ず鏂囧瓧鐨勫搴︼紝鍗曚綅px ( 榛樿 45 锛� + * @property {String} labelAlign lable瀛椾綋鐨勫榻愭柟寮� ( 榛樿 鈥榣eft' 锛� + * @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: {}, + // 鍘熷鐨刴odel蹇収锛岀敤浜巖esetFields鏂规硶閲嶇疆琛ㄥ崟鏃朵娇鐢� + originalModel: null, + }; + }, + watch: { + // 鐩戝惉瑙勫垯鐨勫彉鍖� + rules: { + immediate: true, + handler(n) { + this.setRules(n); + }, + }, + // 鐩戝惉灞炴�х殑鍙樺寲锛岄�氱煡瀛愮粍浠秛-form-item閲嶆柊鑾峰彇淇℃伅 + propsChange(n) { + if (this.children?.length) { + this.children.map((child) => { + // 鍒ゆ柇瀛愮粍浠�(u-form-item)濡傛灉鏈塽pdateParentData鏂规硶鐨勮瘽锛屽氨灏辨墽琛�(鎵ц鐨勭粨鏋滄槸瀛愮粍浠堕噸鏂颁粠鐖剁粍浠舵媺鍙栦簡鏈�鏂扮殑鍊�) + 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涓嬬殑鎵�鏈塽-form-item鐨勫疄渚� + // 涓嶈兘瀹氫箟鍦╠ata涓紝鍚﹀垯寰俊灏忕▼搴忎細閫犳垚寰幆寮曠敤鑰屾姤閿� + 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锛宮odel蹇呴』璁剧疆锛佸鏋滃凡缁忚缃紝璇峰埛鏂伴〉闈€��'); + return; + }; + this.formRules = rules; + // 閲嶆柊灏嗚鍒欒祴浜圴alidator + this.validator = new Schema(rules); + }, + // 娓呯┖鎵�鏈塽-form-item缁勪欢鐨勫唴瀹癸紝鏈川涓婃槸璋冪敤浜唘-form-item缁勪欢涓殑resetField()鏂规硶 + resetFields() { + this.resetModel(); + }, + // 閲嶇疆model涓哄垵濮嬪�肩殑蹇収 + resetModel(obj) { + // 鍘嗛亶鎵�鏈塽-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鐨刾rop鍦╬rops鏁扮粍涓紝鍒欐竻闄ゅ搴旂殑鏍¢獙缁撴灉淇℃伅 + if (props[0] === undefined || props.includes(child.prop)) { + child.message = null; + } + }); + }, + // 瀵归儴鍒嗚〃鍗曞瓧娈佃繘琛屾牎楠� + async validateField(value, callback, event = null) { + // $nextTick鏄繀椤荤殑锛屽惁鍒檓odel鐨勫彉鏇达紝鍙兘浼氬欢鍚庝簬姝ゆ柟娉曠殑鎵ц + this.$nextTick(() => { + // 鏍¢獙閿欒淇℃伅锛岃繑鍥炵粰鍥炶皟鏂规硶锛岀敤浜庡瓨鏀炬墍鏈塮orm-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); + + // 瀵箁ules鏁扮粍杩涜鏍¢獙 + for (let i = 0; i < rules.length; i++) { + const ruleItem = rules[i]; + // 灏唘-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('鏈缃畆ules锛岃鐪嬫枃妗h鏄庯紒濡傛灉宸茬粡璁剧疆锛岃鍒锋柊椤甸潰銆�'); + return; + } + return new Promise((resolve, reject) => { + // $nextTick鏄繀椤荤殑锛屽惁鍒檓odel鐨勫彉鏇达紝鍙兘浼氬欢鍚庝簬validate鏂规硶 + this.$nextTick(() => { + // 鑾峰彇鎵�鏈塮orm-item鐨刾rop锛屼氦缁檝alidateField鏂规硶杩涜鏍¢獙 + const formItemProps = this.children.map( + (item) => item.prop + ); + this.validateField(formItemProps, (errors) => { + if(errors.length) { + // 濡傛灉閿欒鎻愮ず鏂瑰紡涓簍oast锛屽垯杩涜鎻愮ず + 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: { + // 鑳屾櫙棰滆壊锛堥粯璁ransparent锛� + 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 涓庡墠涓�涓粍浠剁殑璺濈锛屽崟浣峱x锛� 榛樿 0 锛� + * @property {String | Number} marginBottom 涓庡悗涓�涓粍浠剁殑璺濈锛屽崟浣峱x 锛堥粯璁� 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: { + // 瀹牸鐨刵ame + 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)锛屾垨鑰呭浘鏍囩瓑锛屼篃鍙互鎵╁睍涓哄乏鍙虫粦鍔ㄧ殑杞挱褰㈠紡銆傛惌閰島-grid浣跨敤 + * @tutorial https://www.uviewui.com/components/grid.html + * @property {String | Number} name 瀹牸鐨刵ame ( 榛樿 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涓嬫墠杩欎箞璁$畻锛寁ue涓嬫斁鍒癱omputed涓紝鍚﹀垯浼氬洜涓哄欢鏃堕�犳垚闂儊 + // #endif + classes: [], // 绫诲悕闆嗗悎锛岀敤浜庡垽鏂槸鍚︽樉绀哄彸杈瑰拰涓嬭竟妗� + }; + }, + mounted() { + this.init() + }, + computed: { + // #ifndef APP-NVUE + // vue涓嬫斁鍒癱omputed涓紝鍚﹀垯浼氬洜涓哄欢鏃堕�犳垚闂儊 + 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鐨刢hildren涓娣诲姞鍏ュ瓙缁勪欢鏃讹紝 + // 閲嶆柊璁$畻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() { + // 姝ゆ柟娉曞啓鍦╩ixin涓� + 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() { + // 濡傛灉鏄痭vue锛屼笉鑳戒娇鐢ㄧ櫨鍒嗘瘮锛屽彧鑳戒娇鐢ㄥ浐瀹氬搴� + let width = 0 + if(this.parent) { + // 鑾峰彇鐖剁粍浠跺搴﹀悗锛岄櫎浠ユ爡鏍兼暟锛屽緱鍑烘瘡涓猧tem鐨勫搴� + const parentWidth = await this.getParentWidth() + width = parentWidth / Number(this.parentData.col) + 'px' + } + this.width = width + }, + // 鑾峰彇鐖跺厓绱犵殑灏哄 + getParentWidth() { + // #ifdef APP-NVUE + // 杩斿洖涓�涓猵romise锛岃璋冪敤鑰呭彲浠ョ敤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 + // 璐磋繎鍙宠竟灞忓箷杈规部鐨刢hild锛屽苟涓旀渶鍚庝竴涓紙姣斿鍙湁妯悜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 + // 鏈�涓嬮潰鐨勪竴鎺抍hild锛屾棤闇�涓嬭竟妗� + if(index < len - lessNum) { + classes.push('u-border-bottom') + } + } + }) + // 鏀粯瀹濓紝澶存潯灏忕▼搴忔棤娉曞姩鎬佺粦瀹氫竴涓暟缁勭被鍚嶏紝鍚﹀垯瑙f瀽鍑烘潵鐨勭粨鏋滀細甯︽湁","锛岃�屽鑷村け鏁� + // #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)濡傛灉鏈塽pdateParentData鏂规硶鐨勮瘽锛屽氨灏辨墽琛�(鎵ц鐨勭粨鏋滄槸瀛愮粍浠堕噸鏂颁粠鐖剁粍浠舵媺鍙栦簡鏈�鏂扮殑鍊�) + typeof(child.updateParentData) == 'function' && child.updateParentData(); + }) + } + }, + }, + created() { + // 濡傛灉灏哻hildren瀹氫箟鍦╠ata涓紝鍦ㄥ井淇″皬绋嬪簭浼氶�犳垚寰幆寮曠敤鑰屾姤閿� + 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 + }, + // 瀛椾綋澶у皬锛屽崟浣峱x + 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 + }, + // 鍥剧墖鐨刴ode + 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 + }, + // 鐢ㄤ簬瑙e喅鏌愪簺鎯呭喌涓嬶紝璁╁浘鏍囧瀭鐩村眳涓殑鐢ㄩ�� + 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鐨刣om妯″潡寮曞叆瀛椾綋锛岀浉鍏虫枃妗e湴鍧�濡備笅锛� + // 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 鍥炬爣瀛椾綋澶у皬锛屽崟浣峱x 锛堥粯璁� '16px' 锛� + * @property {Boolean} bold 鏄惁鏄剧ず绮椾綋 锛堥粯璁� false 锛� + * @property {String | Number} index 鐐瑰嚮鍥炬爣鐨勬椂鍊欎紶閫掍簨浠跺嚭鍘荤殑index锛堢敤浜庡尯鍒嗙偣鍑讳簡鍝竴涓級 + * @property {String} hoverClass 鍥炬爣鎸変笅鍘荤殑鏍峰紡绫伙紝鐢ㄦ硶鍚寀ni鐨剉iew缁勪欢鐨刪overClass鍙傛暟锛岃鎯呰瀹樼綉 + * @property {String} customPrefix 鑷畾涔夋墿灞曞墠缂�锛屾柟渚跨敤鎴锋墿灞曡嚜宸辩殑鍥炬爣搴� 锛堥粯璁� 'uicon' 锛� + * @property {String | Number} label 鍥炬爣鍙充晶鐨刲abel鏂囧瓧 + * @property {String} labelPos label鐩稿浜庡浘鏍囩殑浣嶇疆锛屽彧鑳絩ight鎴朾ottom 锛堥粯璁� 'right' 锛� + * @property {String | Number} labelSize label瀛椾綋澶у皬锛屽崟浣峱x 锛堥粯璁� '15px' 锛� + * @property {String} labelColor 鍥炬爣鍙充晶鐨刲abel鏂囧瓧棰滆壊 锛� 榛樿 color['u-content-color'] 锛� + * @property {String | Number} space label涓庡浘鏍囩殑璺濈锛屽崟浣峱x 锛堥粯璁� '3px' 锛� + * @property {String} imgMode 鍥剧墖鐨刴ode + * @property {String | Number} width 鏄剧ず鍥剧墖灏忓浘鏍囨椂鐨勫搴� + * @property {String | Number} height 鏄剧ず鍥剧墖灏忓浘鏍囨椂鐨勯珮搴� + * @property {String | Number} top 鍥炬爣鍦ㄥ瀭鐩存柟鍚戜笂鐨勫畾浣� 鐢ㄤ簬瑙e喅鏌愪簺鎯呭喌涓嬶紝璁╁浘鏍囧瀭鐩村眳涓殑鐢ㄩ�� 锛堥粯璁� 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鐨勮嚜瀹氫箟鍥炬爣绫诲悕涓簎-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 + }, + // 鍒ゆ柇浼犲叆鐨刵ame灞炴�э紝鏄惁鍥剧墖璺緞锛屽彧瑕佸甫鏈�"/"鍧囪涓烘槸鍥剧墖褰㈠紡 + isImg() { + return this.name.indexOf('/') !== -1 + }, + imgStyle() { + let style = {} + // 濡傛灉璁剧疆width鍜宧eight灞炴�э紝鍒欎紭鍏堜娇鐢紝鍚﹀垯浣跨敤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浠g爜 + 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 */ + // 闈瀗vue涓嬪姞杞藉瓧浣� + @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 + }, + // 鍥剧墖褰㈢姸锛宑ircle-鍦嗗舰锛宻quare-鏂瑰舰 + shape: { + type: String, + default: uni.$u.props.image.shape + }, + // 鍦嗚锛屽崟浣嶄换鎰� + radius: { + type: [String, Number], + default: uni.$u.props.image.radius + }, + // 鏄惁鎳掑姞杞斤紝寰俊灏忕▼搴忋�丄pp銆佺櫨搴﹀皬绋嬪簭銆佸瓧鑺傝烦鍔ㄥ皬绋嬪簭 + 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 + }, + // 鏄惁鏄剧ず鍔犺浇涓殑鍥炬爣鎴栬�呰嚜瀹氫箟鐨剆lot + showLoading: { + type: Boolean, + default: uni.$u.props.image.showLoading + }, + // 鏄惁鏄剧ず鍔犺浇閿欒鐨勫浘鏍囨垨鑰呰嚜瀹氫箟鐨剆lot + 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 + }, + // 杩囨浮鏃堕棿锛屽崟浣峬s + 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鐨刬mage缁勪欢鐨勫姞寮虹増锛屽湪缁ф壙浜嗗師鏈夊姛鑳藉锛岃繕鏀寔娣″叆鍔ㄧ敾銆佸姞杞戒腑銆佸姞杞藉け璐ユ彁绀恒�佸渾瑙掑�煎拰褰㈢姸绛夈�� + * @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 鍥剧墖褰㈢姸锛宑ircle-鍦嗗舰锛宻quare-鏂瑰舰 锛堥粯璁� 'square' 锛� + * @property {String | Number} radius 鍦嗚鍊硷紝鍗曚綅浠绘剰锛屽鏋滀负鏁板�硷紝鍒欎负px鍗曚綅 锛堥粯璁� 0 锛� + * @property {Boolean} lazyLoad 鏄惁鎳掑姞杞斤紝浠呭井淇″皬绋嬪簭銆丄pp銆佺櫨搴﹀皬绋嬪簭銆佸瓧鑺傝烦鍔ㄥ皬绋嬪簭鏈夋晥 锛堥粯璁� true 锛� + * @property {Boolean} showMenuByLongpress 鏄惁寮�鍚暱鎸夊浘鐗囨樉绀鸿瘑鍒皬绋嬪簭鐮佽彍鍗曪紝浠呭井淇″皬绋嬪簭鏈夋晥 锛堥粯璁� true 锛� + * @property {String} loadingIcon 鍔犺浇涓殑鍥炬爣锛屾垨鑰呭皬鍥剧墖 锛堥粯璁� 'photo' 锛� + * @property {String} errorIcon 鍔犺浇澶辫触鐨勫浘鏍囷紝鎴栬�呭皬鍥剧墖 锛堥粯璁� 'error-circle' 锛� + * @property {Boolean} showLoading 鏄惁鏄剧ず鍔犺浇涓殑鍥炬爣鎴栬�呰嚜瀹氫箟鐨剆lot 锛堥粯璁� true 锛� + * @property {Boolean} showError 鏄惁鏄剧ず鍔犺浇閿欒鐨勫浘鏍囨垨鑰呰嚜瀹氫箟鐨剆lot 锛堥粯璁� 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, + // 杩囨浮鏃堕棿锛屽洜涓簆rops鐨勫�兼棤娉曚慨鏀癸紝鏁呴渶瑕佷竴涓腑闂村�� + durationTime: this.duration, + // 鍥剧墖鍔犺浇瀹屾垚鏃讹紝鍘绘帀鑳屾櫙棰滆壊锛屽洜涓哄鏋滄槸png鍥剧墖锛屽氨浼氭樉绀虹伆鑹茬殑鑳屾櫙 + backgroundStyle: {}, + // 鐢ㄤ簬fade妯″紡鐨勬帶鍒剁粍浠舵樉绀轰笌鍚� + show: false + }; + }, + watch: { + src: { + immediate: true, + handler(n) { + if (!n) { + // 濡傛灉浼犲叆null鎴栬��''锛屾垨鑰協alse锛屾垨鑰卽ndefined锛屾爣璁颁负閿欒鐘舵�� + this.isError = true + + } else { + this.isError = false; + this.loading = true; + } + } + } + }, + computed: { + wrapStyle() { + let style = {}; + // 閫氳繃璋冪敤addUnit()鏂规硶锛屽鏋滄湁鍗曚綅锛屽鐧惧垎姣旓紝px鍗曚綅绛夛紝鐩存帴杩斿洖锛屽鏋滄槸绾补鐨勬暟鍊硷紝鍒欏姞涓妑px鍗曚綅 + 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) + // 濡傛灉璁剧疆鍦嗚锛屽繀椤昏鏈塰idden锛屽惁鍒欏彲鑳藉渾瑙掓棤鏁� + 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) + }, + // 鍥剧墖鍔犺浇瀹屾垚锛屾爣璁發oading缁撴潫 + onLoadHandler(event) { + this.loading = false + this.isError = false + this.$emit('load', event) + this.removeBgColor() + // 濡傛灉涓嶉渶瑕佸姩鐢绘晥鏋滐紝灏变笉鎵ц涓嬫柟浠g爜锛屽悓鏃剁Щ闄ゅ姞杞芥椂鐨勮儗鏅鑹� + // 鍚﹀垯鏃犻渶fade鏁堟灉鏃讹紝png鍥剧墖渚濈劧鑳界湅鍒颁笅鏂圭殑鑳屾櫙鑹� + // if (!this.fade) return this.removeBgColor(); + // // 鍘熸潵opacity涓�1(涓嶉�忔槑锛屾槸涓轰簡鏄剧ず鍗犱綅鍥�)锛屾敼鎴�0(閫忔槑锛屾剰鍛崇潃璇ュ厓绱犳樉绀虹殑鏄儗鏅鑹诧紝榛樿鐨勭伆鑹�)锛屽啀鏀规垚1锛屾槸涓轰簡鑾峰緱杩囨浮鏁堟灉 + // this.opacity = 0; + // // 杩欓噷璁剧疆涓�0锛屾槸涓轰簡鍥剧墖灞曠ず鍒拌儗鏅叏閫忔槑杩欎釜杩囩▼鏃堕棿涓�0锛屽欢鏃朵箣鍚庡欢鏃朵箣鍚庨噸鏂拌缃负duration锛屾槸涓轰簡鑾峰緱鑳屾櫙閫忔槑(鐏拌壊) + // // 鍒板浘鐗囧睍绀虹殑杩囩▼涓殑娣″叆鏁堟灉 + // this.durationTime = 0; + // // 寤舵椂50ms锛屽惁鍒欏湪娴忚鍣℉5锛岃繃娓℃晥鏋滄棤鏁� + // 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 + }, + // 鍒楄〃閿氱偣鏂囧瓧澶у皬锛屽崟浣嶉粯璁x + size: { + type: [String, Number], + default: uni.$u.props.indexAnchor.size + }, + // 鍒楄〃閿氱偣鑳屾櫙棰滆壊 + bgColor: { + type: String, + default: uni.$u.props.indexAnchor.bgColor + }, + // 鍒楄〃閿氱偣楂樺害锛屽崟浣嶉粯璁x + 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 鍒楄〃閿氱偣鏂囧瓧澶у皬锛屽崟浣嶉粯璁x ( 榛樿 14 ) + * @property {String} bgColor 鍒楄〃閿氱偣鑳屾櫙棰滆壊 ( 榛樿 '#dedede' ) + * @property {String | Number} height 鍒楄〃閿氱偣楂樺害锛屽崟浣嶉粯璁x ( 榛樿 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() { + // 姝ゅ浼氭椿鍔ㄧ埗缁勪欢瀹炰緥锛屽苟璧嬪�肩粰瀹炰緥鐨刾arent灞炴�� + const indexList = uni.$u.$parent.call(this, 'u-index-list') + if (!indexList) { + return uni.$u.error('u-index-anchor蹇呴』瑕佹惌閰島-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鎵嶆槸宓屽鍦╱-index-item涓殑 + if (!indexListItem) { + return uni.$u.error('u-index-anchor蹇呴』瑕佹惌閰島-index-item缁勪欢浣跨敤') + } + // 璁剧疆u-index-item鐨刬d涓篴nchor鐨則ext鏍囪瘑绗︼紝鍥犱负闈瀗vue涓嬫粴鍔ㄥ垪琛ㄩ渶瑕佷緷璧杝croll-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() { + // 瀛愮粍浠秛-index-anchor鐨勫疄渚� + this.anchor = {} + }, + mounted() { + this.init() + }, + methods: { + init() { + // 姝ゅ浼氭椿鍔ㄧ埗缁勪欢瀹炰緥锛屽苟璧嬪�肩粰瀹炰緥鐨刾arent灞炴�� + this.getParentData('u-index-list') + if (!this.parent) { + return uni.$u.error('u-index-item蹇呴』瑕佹惌閰島-index-list缁勪欢浣跨敤') + } + uni.$u.sleep().then(() =>{ + this.getIndexItemRect().then(size => { + // 鐢变簬瀵硅薄鐨勫紩鐢ㄧ壒鎬э紝姝ゅ浼氬悓鏃剁敓鏁堝埌鐖剁粍浠剁殑children鏁扮粍鐨勬湰瀹炰緥鐨則op灞炴�т腑锛屼緵鐖剁粍浠跺垽鏂鍙� + 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 + // 灏嗚嚜瀹氫箟鑺傜偣璁剧疆鎴愯櫄鎷熺殑锛屾洿鍔犳帴杩慥ue缁勪欢鐨勮〃鐜帮紝鑳芥洿濂界殑浣跨敤flex灞炴�� + options: { + virtualHost: true + }, + // #endif + data() { + return { + // 褰撳墠姝e湪琚�変腑鐨勫瓧姣嶇储寮� + activeIndex: -1, + touchmoveIndex: 1, + // 绱㈠紩瀛楁瘝鐨勪俊鎭� + letterInfo: { + height: 0, + itemHeight: 0, + top: 0 + }, + // 璁剧疆瀛楁瘝鎸囩ず鍣ㄧ殑楂樺害锛屽悗闈负浜嗚鎸囩ず鍣ㄨ窡闅忓瓧姣嶏紝骞跺皢灏栬閮ㄥ垎鎸囧悜瀛楁瘝鐨勪腑閮紝闇�瑕佷緷璧栨鍊� + indicatorHeight: 50, + // 瀛楁瘝鏀惧ぇ鎸囩ず鍣ㄧ殑top鍊硷紝涓轰簡璁╁叾鎸囧悜褰撳墠婵�娲荤殑瀛楁瘝 + // indicatorTop: 0 + // 褰撳墠鏄惁姝e湪琚Е鎽哥姸鎬� + touching: false, + // 婊氬姩鏉¢《閮╰op鍊� + 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锛屽苟灏唗his.scrollViewHeight璁剧疆涓簃axHeight + //瑙e喅褰搖-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) { + // 寤舵椂涓�瀹氭椂闂村悗鍐嶉殣钘忔寚绀哄櫒锛屼负浜嗚鐢ㄦ埛鐪嬬殑鏇寸洿瑙傦紝鍚屾椂涔熸槸涓轰簡娑堥櫎蹇�熷垏鎹-transition鐨剆how甯︽潵鐨勫奖鍝� + uni.$u.sleep(300).then(() => { + this.touching = false + }) + }, + // 鑾峰彇绱㈠紩鍒楄〃鐨勫昂瀵镐互鍙婂崟涓瓧绗︾殑灏哄淇℃伅 + getIndexListLetterRect() { + return new Promise(resolve => { + // 寤舵椂涓�瀹氭椂闂达紝浠ヨ幏鍙杁om灏哄 + // #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涓紝涓哄師鐢熷鑸爮锛屽叾楂樺害涓嶇畻鍦╳indowHeight鍐咃紝杩欓噷璁剧疆涓鸿礋鍊硷紝鍚庨潰鐩稿姞鏃跺彉鎴愬噺鍘诲叾楂樺害鐨勪竴鍗� + customNavHeight = -(sys.statusBarHeight + 44) + // #endif + } else { + customNavHeight = uni.$u.getPx(this.customNavHeight) + } + this.letterInfo = { + height, + // 涓轰簡璁╁瓧姣嶅垪琛ㄥ灞忓箷缁濆灞呬腑锛岃鍏跺瀵艰埅鏍忚繘琛屼慨姝o紝涔熷嵆寰�涓婂亸绉诲鑸爮鐨勪竴鍗婇珮搴� + top: (windowHeight - height) / 2 + customNavHeight / 2, + itemHeight: Math.floor(height / this.uIndexList.length) + } + }) + }, + // 鑾峰彇褰撳墠琚Е鎽哥殑绱㈠紩瀛楁瘝 + getIndexListLetter(pageY) { + const { + top, + height, + itemHeight + } = this.letterInfo + // 瀵笻5鐨刾ageY杩涜淇锛岃繖鏄敱浜巙ni-app鑷綔澶氭儏鍦℉5涓皢瑙︽懜鐐圭殑鍧愭爣璺烪5鐨勫鑸爮缁撳悎瀵艰嚧鐨勯棶棰� + // #ifdef H5 + pageY += uni.$u.sys().windowTop + // #endif + // 瀵圭涓�鍜屾渶鍚庝竴涓瓧姣嶅仛杈圭晫澶勭悊锛屽洜涓虹敤鎴峰彲鑳藉湪瀛楁瘝鍒楄〃涓婅Е鎽稿埌涓ょ鐨勫敖澶村悗渚濈劧缁х画婊戝姩 + if (pageY < top) { + return 0 + } else if (pageY >= top + height) { + // 濡傛灉瓒呭嚭浜嗭紝鍙栨渶鍚庝竴涓瓧姣� + return this.uIndexList.length - 1 + } else { + // 灏嗚Е鎽哥偣鐨刌杞村亸绉诲�硷紝鍑忓幓绱㈠紩瀛楁瘝鐨則op鍊硷紝闄や互姣忎釜瀛楁瘝鐨勯珮搴︼紝鍗冲彲寰楀埌褰撳墠瑙︽懜鐐硅惤鍦ㄥ摢涓瓧姣嶄笂 + return Math.floor((pageY - top) / itemHeight); + } + }, + // 璁剧疆鍚勯」鐢辫Е鎽歌�屽鑷村彉鍖栫殑鍊� + setValueForTouch(currentIndex) { + // 濡傛灉鍋忕Щ閲忓お灏忥紝鍓嶅悗寰楀嚭鐨勪細鏄悓涓�涓储寮曞瓧姣嶏紝涓轰簡闃叉姈锛岃繘琛岃繑鍥� + if (currentIndex === this.activeIndex) return + this.activeIndex = currentIndex + // #ifndef APP-NVUE || MP-WEIXIN + // 鍦ㄩ潪nvue涓紝鐢变簬anchor鍜宨tem閮藉湪u-index-item涓紝鎵�浠ラ渶瑕佸index-item杩涜鍋忕Щ + this.scrollIntoView = `u-index-item-${this.uIndexList[currentIndex].charCodeAt(0)}` + // #endif + // #ifdef MP-WEIXIN + // 寰俊灏忕▼搴忎笅锛宻croll-view鐨剆croll-into-view灞炴�ф棤娉曞slot涓殑鍐呭鐨刬d鐢熸晥锛屽彧鑳介�氳繃璁剧疆scrollTop鐨勫舰寮忓幓绉诲姩婊氬姩鏉� + this.scrollTop = this.children[currentIndex].top + // #endif + // #ifdef APP-NVUE + // 鍦╪vue涓紝鐢变簬cell鍜宧eader涓哄悓绾у厓绱狅紝鎵�浠ュ疄闄呮槸闇�瑕佸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缁勪欢涓幏鍙栧厓绱犵殑灏哄鏄病鏈塼op鍊肩殑 + 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鐨則op鍊硷紝鍦╪vue涓嬶紝妯℃嫙鍑虹殑anchor鐨則op锛岀被浼奸潪nvue涓嬬殑index-item鐨則op + let top = header.height + // 鐢变簬list缁勪欢鏃犳硶鑾峰彇cell鐨則op鍊硷紝杩欓噷閫氳繃header slot鍜屽悇涓猧tem涔嬮棿鐨刪eight锛屾ā鎷熷嚭绫讳技闈瀗vue涓嬬殑浣嶇疆淇℃伅 + children = this.children.map((item, index) => { + const child = { + height: item.height, + top + } + // 杩涜绱姞锛岀粰涓嬩竴涓猧tem鎻愪緵璁$畻渚濇嵁 + top += item.height + anchors[index].height + return child + }) + // #endif + // #ifndef APP-NVUE + // 闈瀗vue閫氳繃detail鑾峰彇婊氬姩鏉′綅绉� + scrollTop = e.detail.scrollTop + // #endif + for (let i = 0; i < len; i++) { + const item = children[i], + nextItem = children[i + 1] + // 濡傛灉婊氬姩鏉¢珮搴﹀皬浜庣涓�涓猧tem鐨則op鍊硷紝姝ゆ椂鏃犻渶璁剧疆浠绘剰瀛楁瘝涓洪珮浜� + if (scrollTop <= children[0].top || scrollTop >= children[len - 1].top + children[len - + 1].height) { + this.activeIndex = -1 + break + } else if (!nextItem) { + // 褰撲笉瀛樺湪涓嬩竴涓猧tem鏃讹紝鎰忓懗鐫�鍘嗛亶鍒颁簡鏈�鍚庝竴涓� + 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-鏁板瓧杈撳叆閿洏锛宎pp-vue涓嬪彲浠ヨ緭鍏ユ诞鐐规暟锛宎pp-nvue鍜屽皬绋嬪簭骞冲彴涓嬪彧鑳借緭鍏ユ暣鏁� + // idcard-韬唤璇佽緭鍏ラ敭鐩橈紝寰俊銆佹敮浠樺疂銆佺櫨搴︺�丵Q灏忕▼搴� + // digit-甯﹀皬鏁扮偣鐨勬暟瀛楅敭鐩橈紝App鐨刵vue椤甸潰銆佸井淇°�佹敮浠樺疂銆佺櫨搴︺�佸ご鏉°�丵Q灏忕▼搴� + // text-鏂囨湰杈撳叆閿洏 + type: { + type: String, + default: uni.$u.props.input.type + }, + // 濡傛灉 textarea 鏄湪涓�涓� position:fixed 鐨勫尯鍩燂紝闇�瑕佹樉绀烘寚瀹氬睘鎬� fixed 涓� true锛� + // 鍏煎鎬э細寰俊灏忕▼搴忋�佺櫨搴﹀皬绋嬪簭銆佸瓧鑺傝烦鍔ㄥ皬绋嬪簭銆丵Q灏忕▼搴� + 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鐨勬牱寮忕被锛屾敞鎰忛〉闈㈡垨缁勪欢鐨剆tyle涓啓浜唖coped鏃讹紝闇�瑕佸湪绫诲悕鍓嶅啓/deep/ + placeholderClass: { + type: String, + default: uni.$u.props.input.placeholderClass + }, + // 鎸囧畾placeholder鐨勬牱寮� + placeholderStyle: { + type: [String, Object], + default: uni.$u.props.input.placeholderStyle + }, + // 鏄惁鏄剧ず杈撳叆瀛楁暟缁熻锛屽彧鍦� type ="text"鎴杢ype ="textarea"鏃舵湁鏁� + showWordLimit: { + type: Boolean, + default: uni.$u.props.input.showWordLimit + }, + // 璁剧疆鍙充笅瑙掓寜閽殑鏂囧瓧锛屾湁鏁堝�硷細send|search|next|go|done锛屽吋瀹规�ц瑙乽ni-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 骞冲彴鑳藉惁鑱氱劍浠ュ強杞敭鐩樻槸鍚﹁窡闅忓脊鍑猴紝鍙栧喅浜庡綋鍓嶆祻瑙堝櫒鏈韩鐨勫疄鐜般�俷vue 椤甸潰涓嶆敮鎸侊紝闇�浣跨敤缁勪欢鐨� focus()銆乥lur() 鏂规硶鎺у埗鐒︾偣 + 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 + }, + // 鍏夋爣璧峰浣嶇疆锛岃嚜鍔ㄨ仛闆嗘椂鏈夋晥锛岄渶涓巗election-end鎼厤浣跨敤 + selectionStart: { + type: [String, Number], + default: uni.$u.props.input.selectionStart + }, + // 鍏夋爣缁撴潫浣嶇疆锛岃嚜鍔ㄨ仛闆嗘椂鏈夋晥锛岄渶涓巗election-start鎼厤浣跨敤 + selectionEnd: { + type: [String, Number], + default: uni.$u.props.input.selectionEnd + }, + // 閿洏寮硅捣鏃讹紝鏄惁鑷姩涓婃帹椤甸潰 + adjustPosition: { + type: Boolean, + default: uni.$u.props.input.adjustPosition + }, + // 杈撳叆妗嗗唴瀹瑰榻愭柟寮忥紝鍙�夊�间负锛歭eft|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 + }, + // 杈规绫诲瀷锛宻urround-鍥涘懆杈规锛宐ottom-搴曢儴杈规锛宯one-鏃犺竟妗� + border: { + type: String, + default: uni.$u.props.input.border + }, + // 鏄惁鍙锛屼笌disabled涓嶅悓涔嬪鍦ㄤ簬disabled浼氱疆鐏扮粍浠讹紝鑰宺eadonly鍒欎笉浼� + readonly: { + type: Boolean, + default: uni.$u.props.input.readonly + }, + // 杈撳叆妗嗗舰鐘讹紝circle-鍦嗗舰锛宻quare-鏂瑰舰 + 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鐨刬nput缁勪欢鏂囨。锛孒5鍜孉PP涓彧瑕佸0鏄庝簡password鍙傛暟(鏃犺true杩樻槸false)锛宼ype鍧囧け鏁堬紝姝ゆ椂 + 涓轰簡闃叉type=number鏃讹紝鍙堝瓨鍦╬assword灞炴�э紝type鏃犳晥锛屾鏃堕渶瑕佽缃畃assword涓簎ndefined + --> + <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 姝ょ粍浠朵负涓�涓緭鍏ユ锛岄粯璁ゆ病鏈夎竟妗嗗拰鏍峰紡锛屾槸涓撻棬涓洪厤鍚堣〃鍗曠粍浠秛-form鑰岃璁$殑锛屽埄鐢ㄥ畠鍙互蹇�熷疄鐜拌〃鍗曢獙璇侊紝杈撳叆鍐呭锛屼笅鎷夐�夋嫨绛夊姛鑳姐�� + * @tutorial https://uviewui.com/components/input.html + * @property {String | Number} value 杈撳叆鐨勫�� + * @property {String} type 杈撳叆妗嗙被鍨嬶紝瑙佷笂鏂硅鏄� 锛� 榛樿 'text' 锛� + * @property {Boolean} fixed 濡傛灉 textarea 鏄湪涓�涓� position:fixed 鐨勫尯鍩燂紝闇�瑕佹樉绀烘寚瀹氬睘鎬� fixed 涓� true锛屽吋瀹规�э細寰俊灏忕▼搴忋�佺櫨搴﹀皬绋嬪簭銆佸瓧鑺傝烦鍔ㄥ皬绋嬪簭銆丵Q灏忕▼搴� 锛� 榛樿 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鐨勬牱寮忕被锛屾敞鎰忛〉闈㈡垨缁勪欢鐨剆tyle涓啓浜唖coped鏃讹紝闇�瑕佸湪绫诲悕鍓嶅啓/deep/ 锛� 榛樿 'input-placeholder' 锛� + * @property {String | Object} placeholderStyle 鎸囧畾placeholder鐨勬牱寮忥紝瀛楃涓�/瀵硅薄褰㈠紡锛屽"color: red;" + * @property {Boolean} showWordLimit 鏄惁鏄剧ず杈撳叆瀛楁暟缁熻锛屽彧鍦� type ="text"鎴杢ype ="textarea"鏃舵湁鏁� 锛� 榛樿 false 锛� + * @property {String} confirmType 璁剧疆鍙充笅瑙掓寜閽殑鏂囧瓧锛屽吋瀹规�ц瑙乽ni-app鏂囨。 锛� 榛樿 'done' 锛� + * @property {Boolean} confirmHold 鐐瑰嚮閿洏鍙充笅瑙掓寜閽椂鏄惁淇濇寔閿洏涓嶆敹璧凤紝H5鏃犳晥 锛� 榛樿 false 锛� + * @property {Boolean} holdKeyboard focus鏃讹紝鐐瑰嚮椤甸潰鐨勬椂鍊欎笉鏀惰捣閿洏锛屽井淇″皬绋嬪簭鏈夋晥 锛� 榛樿 false 锛� + * @property {Boolean} focus 鑷姩鑾峰彇鐒︾偣锛屽湪 H5 骞冲彴鑳藉惁鑱氱劍浠ュ強杞敭鐩樻槸鍚﹁窡闅忓脊鍑猴紝鍙栧喅浜庡綋鍓嶆祻瑙堝櫒鏈韩鐨勫疄鐜般�俷vue 椤甸潰涓嶆敮鎸侊紝闇�浣跨敤缁勪欢鐨� focus()銆乥lur() 鏂规硶鎺у埗鐒︾偣 锛� 榛樿 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 鍏夋爣璧峰浣嶇疆锛岃嚜鍔ㄨ仛闆嗘椂鏈夋晥锛岄渶涓巗election-end鎼厤浣跨敤 锛� 榛樿 -1 锛� + * @property {String 锝� Number} selectionEnd 鍏夋爣缁撴潫浣嶇疆锛岃嚜鍔ㄨ仛闆嗘椂鏈夋晥锛岄渶涓巗election-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 杈规绫诲瀷锛宻urround-鍥涘懆杈规锛宐ottom-搴曢儴杈规锛宯one-鏃犺竟妗� 锛� 榛樿 'surround' 锛� + * @property {Boolean} readonly 鏄惁鍙锛屼笌disabled涓嶅悓涔嬪鍦ㄤ簬disabled浼氱疆鐏扮粍浠讹紝鑰宺eadonly鍒欎笉浼� 锛� 榛樿 false 锛� + * @property {String} shape 杈撳叆妗嗗舰鐘讹紝circle-鍦嗗舰锛宻quare-鏂瑰舰 锛� 榛樿 '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鏄惁绗竴娆″彉鍖栵紝鍦╳atch涓紝鐢变簬鍔犲叆immediate灞炴�э紝浼氬湪绗竴娆¤Е鍙戯紝姝ゆ椂涓嶅簲璇ヨ涓簐alue鍙戠敓浜嗗彉鍖� + firstChange: true, + // value缁戝畾鍊肩殑鍙樺寲鏄敱鍐呴儴杩樻槸澶栭儴寮曡捣鐨� + changeFromInner: false, + // 杩囨护澶勭悊鏂规硶 + innerFormatter: value => value + }; + }, + watch: { + value: { + immediate: true, + handler(newVal, oldVal) { + this.innerValue = newVal; + /* #ifdef H5 */ + // 鍦℉5涓紝澶栭儴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鐨刬OS寮�鍙戣�呰兘鍔涙湁闄愶紝瀵艰嚧闇�瑕佸垎寮�鍐欐墠鏈夋晥 + 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 + }, + // 褰撻敭鐩樿緭鍏ユ椂锛岃Е鍙慽nput浜嬩欢 + onInput(e) { + let { value = "" } = e.detail || {}; + // 鏍煎紡鍖栬繃婊ゆ柟娉� + const formatter = this.formatter || this.innerFormatter + const formatValue = formatter(value) + // 涓轰簡閬垮厤props鐨勫崟鍚戞暟鎹祦鐗规�э紝闇�瑕佸厛灏唅nnerValue鍊艰缃负褰撳墠鍊硷紝鍐嶅湪$nextTick涓噸鏂拌祴浜堣缃悗鐨勫�兼墠鏈夋晥 + this.innerValue = value + this.$nextTick(() => { + this.innerValue = formatValue; + this.valueChange(); + }) + }, + // 杈撳叆妗嗗け鍘荤劍鐐规椂瑙﹀彂 + onBlur(event) { + this.$emit("blur", event.detail.value); + // H5绔殑blur浼氬厛浜庣偣鍑绘竻闄ゆ帶浠剁殑鐐瑰嚮click浜嬩欢瑙﹀彂锛屽鑷磃ocused + // 鐬棿涓篺alse锛屼粠鑰岄殣钘忎簡娓呴櫎鎺т欢鑰屾棤娉曡鐐瑰嚮鍒� + 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+銆丄pp 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"); + }); + }, + /** + * 鍦ㄥ畨鍗搉vue涓婏紝浜嬩欢鏃犳硶鍐掓场 + * 鍦ㄦ煇浜涙椂闂达紝鎴戜滑甯屾湜鐩戝惉u-from-item鐨勭偣鍑讳簨浠讹紝姝ゆ椂浼氬鑷寸偣鍑籾-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-鏁板瓧閿洏锛宑ard-韬唤璇侀敭鐩橈紝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 鏄惁鏄剧ず"."鎸夐敭锛屽彧鍦╩ode=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 寮瑰嚭閿洏鐨剒-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 + }, + // 杩涘害鏉$殑楂樺害锛屽崟浣峱x + 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 杩涘害鏉$殑楂樺害锛屽崟浣峱x ( 榛樿 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 + // 杩斿洖涓�涓猵romise + 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 + // 閫氳繃璁剧疆鐨刾ercentage鍊硷紝璁$畻鍏舵墍鍗犳�婚暱搴︾殑鐧惧垎姣� + 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 + }, + // 闀垮害锛岀珫鍚戞椂琛ㄧ幇涓洪珮搴︼紝妯悜鏃惰〃鐜颁负闀垮害锛屽彲浠ヤ负鐧惧垎姣旓紝甯x鍗曚綅鐨勫�肩瓑 + length: { + type: [String, Number], + default: uni.$u.props.line.length + }, + // 绾挎潯鏂瑰悜锛宑ol-绔栧悜锛宺ow-妯悜 + 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 + }, + // 鏄惁铏氱嚎锛宼rue-铏氱嚎锛宖alse-瀹炵嚎 + 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 闀垮害锛岀珫鍚戞椂琛ㄧ幇涓洪珮搴︼紝妯悜鏃惰〃鐜颁负闀垮害锛屽彲浠ヤ负鐧惧垎姣旓紝甯x鍗曚綅鐨勫�肩瓑 ( 榛樿 '100%' ) + * @property {String} direction 绾挎潯鐨勬柟鍚戯紝row-妯悜锛宑ol-绔栧悜 (榛樿 'row' ) + * @property {Boolean} hairline 鏄惁鏄剧ず缁嗙嚎鏉� (榛樿 true ) + * @property {String | Number} margin 绾挎潯涓庝笂涓嬪乏鍙冲厓绱犵殑闂磋窛锛屽瓧绗︿覆褰㈠紡锛屽"30px" (榛樿 0 ) + * @property {Boolean} dashed 鏄惁铏氱嚎锛宼rue-铏氱嚎锛宖alse-瀹炵嚎 (榛樿 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 + }, + // 瀛椾綋澶у皬锛屽崟浣峱x + 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鐜鎵撳紑鍐呯疆娴忚鍣紝鍦ㄥ皬绋嬪簭涓妸閾炬帴澶嶅埗鍒扮矘璐存澘锛屽悓鏃舵彁绀轰俊鎭紝鍦℉5涓�氳繃window.open鎵撳紑閾炬帴銆� + * @tutorial https://www.uviewui.com/components/link.html + * @property {String} color 鏂囧瓧棰滆壊 锛堥粯璁� color['u-primary'] 锛� + * @property {String 锝� Number} fontSize 瀛椾綋澶у皬锛屽崟浣峱x 锛堥粯璁� 15 锛� + * @property {Boolean} underLine 鏄惁鏄剧ず涓嬪垝绾� 锛堥粯璁� false 锛� + * @property {String} href 璺宠浆鐨勯摼鎺ワ紝瑕佸甫涓奾ttp(s) + * @property {String} mpTips 鍚勪釜灏忕▼搴忓钩鍙版妸閾炬帴澶嶅埗鍒扮矘璐存澘鍚庣殑鎻愮ず璇紙榛樿鈥滈摼鎺ュ凡澶嶅埗锛岃鍦ㄦ祻瑙堝櫒鎵撳紑鈥濓級 + * @property {String} lineColor 涓嬪垝绾块鑹诧紝榛樿鍚宑olor鍙傛暟棰滆壊 + * @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: { + // 鐢ㄤ簬婊氬姩鍒版寚瀹歩tem + 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 鐢ㄤ簬婊氬姩鍒版寚瀹歩tem + * @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: { + // 鎺у埗鏄惁鍑虹幇婊氬姩鏉★紝浠卬vue鏈夋晥 + 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 浜嬩欢瑙﹀彂鐨勯鐜囷紝浠卬vue鏈夋晥 + offsetAccuracy: { + type: [String, Number], + default: uni.$u.props.list.offsetAccuracy + }, + // 鍚敤 flexbox 甯冨眬銆傚紑鍚悗锛屽綋鍓嶈妭鐐瑰0鏄庝簡display: flex灏变細鎴愪负flex container锛屽苟浣滅敤浜庡叾瀛╁瓙鑺傜偣锛屼粎寰俊灏忕▼搴忔湁鏁� + enableFlex: { + type: Boolean, + default: uni.$u.props.list.enableFlex + }, + // 鏄惁鎸夊垎椤垫ā寮忔樉绀篖ist锛岄粯璁ゅ�糵alse + pagingEnabled: { + type: Boolean, + default: uni.$u.props.list.pagingEnabled + }, + // 鏄惁鍏佽List婊氬姩 + scrollable: { + type: Boolean, + default: uni.$u.props.list.scrollable + }, + // 鍊煎簲涓烘煇瀛愬厓绱爄d锛坕d涓嶈兘浠ユ暟瀛楀紑澶达級 + 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浠h〃涓�涓睆骞曠殑楂樺害锛�1.5浠h〃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 鎺у埗鏄惁鍑虹幇婊氬姩鏉★紝浠卬vue鏈夋晥 锛堥粯璁� false 锛� + * @property {String 锝� Number} lowerThreshold 璺濆簳閮ㄥ灏戞椂瑙﹀彂scrolltolower浜嬩欢 锛堥粯璁� 50 锛� + * @property {String 锝� Number} upperThreshold 璺濋《閮ㄥ灏戞椂瑙﹀彂scrolltoupper浜嬩欢锛岄潪nvue鏈夋晥 锛堥粯璁� 0 锛� + * @property {String 锝� Number} scrollTop 璁剧疆绔栧悜婊氬姩鏉′綅缃紙榛樿 0 锛� + * @property {String 锝� Number} offsetAccuracy 鎺у埗 onscroll 浜嬩欢瑙﹀彂鐨勯鐜囷紝浠卬vue鏈夋晥锛堥粯璁� 10 锛� + * @property {Boolean} enableFlex 鍚敤 flexbox 甯冨眬銆傚紑鍚悗锛屽綋鍓嶈妭鐐瑰0鏄庝簡display: flex灏变細鎴愪负flex container锛屽苟浣滅敤浜庡叾瀛╁瓙鑺傜偣锛屼粎寰俊灏忕▼搴忔湁鏁堬紙榛樿 false 锛� + * @property {Boolean} pagingEnabled 鏄惁鎸夊垎椤垫ā寮忔樉绀篖ist锛岋紙榛樿 false 锛� + * @property {Boolean} scrollable 鏄惁鍏佽List婊氬姩锛堥粯璁� true 锛� + * @property {String} scrollIntoView 鍊煎簲涓烘煇瀛愬厓绱爄d锛坕d涓嶈兘浠ユ暟瀛楀紑澶达級 + * @property {Boolean} scrollWithAnimation 鍦ㄨ缃粴鍔ㄦ潯浣嶇疆鏃朵娇鐢ㄥ姩鐢昏繃娓� 锛堥粯璁� false 锛� + * @property {Boolean} enableBackToTop iOS鐐瑰嚮椤堕儴鐘舵�佹爮銆佸畨鍗撳弻鍑绘爣棰樻爮鏃讹紝婊氬姩鏉¤繑鍥為《閮紝鍙寰俊灏忕▼搴忔湁鏁� 锛堥粯璁� false 锛� + * @property {String 锝� Number} height 鍒楄〃鐨勯珮搴� 锛堥粯璁� 0 锛� + * @property {String 锝� Number} width 鍒楄〃瀹藉害 锛堥粯璁� 0 锛� + * @property {String 锝� Number} preLoadScreen 鍒楄〃鍓嶅悗棰勬覆鏌撶殑灞忔暟锛�1浠h〃涓�涓睆骞曠殑楂樺害锛�1.5浠h〃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鍙傛暟锛屾壘鍒版墍鏈塽-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 + }, + // 妯″紡閫夋嫨锛宑ircle-鍦嗗舰锛宻pinner-鑺辨湹褰紝semicircle-鍗婂渾褰� + mode: { + type: String, + default: uni.$u.props.loadingIcon.mode + }, + // 鍥炬爣澶у皬锛屽崟浣嶉粯璁x + 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鍜宧eight閰嶇疆浜嗕篃鏃犳晥 --> + <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 璀︽缁勪欢涓轰竴涓皬鍔ㄧ敾锛岀洰鍓嶇敤鍦╱View鐨刲oadmore鍔犺浇鏇村鍜宻witch寮�鍏崇瓑缁勪欢鐨勬鍦ㄥ姞杞界姸鎬佸満鏅�� + * @tutorial https://www.uviewui.com/components/loading.html + * @property {Boolean} show 鏄惁鏄剧ず缁勪欢 (榛樿 true) + * @property {String} color 鍔ㄧ敾娲诲姩鍖哄煙鐨勯鑹诧紝鍙 mode = flower 妯″紡鏈夋晥锛堥粯璁olor['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涓婏紝浼氬欢杩熶竴涓猟uration鍛ㄦ湡鍚庢墠鎵ц + // 鍦╥OS nvue涓婏紝鍒欎細涓�寮�濮嬮粯璁ゆ墽琛屼袱涓懆鏈熺殑鍔ㄧ敾 + aniAngel: 360, // 鍔ㄧ敾鏃嬭浆瑙掑害 + webviewHide: false, // 鐩戝惉webview鐨勭姸鎬侊紝濡傛灉闅愯棌浜嗛〉闈紝鍒欏仠姝㈠姩鐢伙紝浠ュ厤鎬ц兘娑堣�� + loading: false, // 鏄惁杩愯涓紝閽堝nvue浣跨敤 + } + }, + computed: { + // 褰撲负circle绫诲瀷鏃讹紝缁欏叾鍙﹀涓夎竟璁剧疆涓�涓洿杞讳竴浜涚殑棰滆壊 + // 涔嬫墍浠ラ渶瑕佽繖涔堝仛鐨勫師鍥犳槸锛屾瘮濡傜埗缁勪欢浼犱簡color涓虹孩鑹诧紝閭d箞闇�瑕佸彟澶栫殑涓変釜杈逛负娴呯孩鑹� + // 鑰屼笉鑳芥槸鍥哄畾鐨勬煇涓�涓叾浠栭鑹�(鍥犱负杩欎釜鍥哄畾鐨勯鑹插彲鑳芥祬钃濓紝瀵艰嚧鏁堟灉娌℃湁閭d箞缁嗚吇鑹ソ) + 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涓簍rue锛屼笖涓洪潪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] + // 褰撳墠椤甸潰鐨剋ebview瀹炰緥 + const currentWebview = page.$getAppWebview() + // 鐩戝惉webview鐨勬樉绀轰笌闅愯棌锛屼粠鑰屽仠姝㈡垨鑰呭紑濮嬪姩鐢�(涓轰簡鎬ц兘) + currentWebview.addEventListener('hide', () => { + this.webviewHide = true + }) + currentWebview.addEventListener('show', () => { + this.webviewHide = false + }) + }, + // #ifdef APP-NVUE + nvueAnimate() { + // nvue涓嬶紝闈瀞pinner绫诲瀷鏃舵墠闇�瑕佹棆杞紝鍥犱负nvue鐨剆pinner绫诲瀷锛屼娇鐢ㄤ簡weex鐨� + // loading-indicator缁勪欢锛岃嚜甯︽棆杞姛鑳� + this.mode !== 'spinner' && this.startAnimate() + }, + // 鎵цnvue鐨刟nimate妯″潡鍔ㄧ敾 + 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 + // 鍔ㄧ敾缁撴潫鍚庯紝缁х画寰幆鎵ц鍔ㄧ敾锛岄渶瑕佸悓鏃跺垽鏂瓀ebviewHide鍙橀噺 + // nvue瀹夊崜锛岄〉闈㈤殣钘忓悗渚濈劧浼氱户缁墽琛宻tartAnimate鏂规硶 + 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-鍦嗗舰锛宻pinner-鑺辨湹褰紝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 + }, + // 鍔犺浇涓浘鏍囩殑棰滆壊锛屽彧鑳絩gb鎴栬�呭崄鍏繘鍒堕鑹插�� + 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 璀︽缁勪欢涓轰竴涓皬鍔ㄧ敾锛岀洰鍓嶇敤鍦╱View鐨刲oadmore鍔犺浇鏇村鍜宻witch寮�鍏崇瓑缁勪欢鐨勬鍦ㄥ姞杞界姸鎬佸満鏅�� + * @tutorial https://www.uviewui.com/components/loading.html + * @property {String | Number} loadingText 鎻愮ず鍐呭 (榛樿 '姝e湪鍔犺浇' ) + * @property {String} image 鏂囧瓧涓婃柟鐢ㄤ簬鏇挎崲loading鍔ㄧ敾鐨勫浘鐗� + * @property {String} loadingMode 鍔犺浇鍔ㄧ敾鐨勬ā寮忥紝circle-鍦嗗舰锛宻pinner-鑺辨湹褰紝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 鍔犺浇涓浘鏍囩殑棰滆壊锛屽彧鑳絩gb鎴栬�呭崄鍏繘鍒堕鑹插�� 锛堥粯璁� '#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 + }, + // 鍔犺浇涓姸鎬佺殑鍥炬爣锛宻pinner-鑺辨湹鐘跺浘鏍囷紝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 + }, + // 楂樺害锛屽崟浣峱x + 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 + }, + // 鏄惁铏氱嚎锛宼rue-铏氱嚎锛宖alse-瀹炵嚎 + 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 鍔犺浇涓彁绀鸿锛堥粯璁� '姝e湪鍔犺浇...' 锛� + * @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 楂樺害锛屽崟浣峱x 锛堥粯璁� 'auto' 锛� + * @property {Boolean} line 鏄惁鏄剧ず宸﹁竟鍒嗗壊绾� 锛堥粯璁� false 锛� + * @property {Boolean} dashed // 鏄惁铏氱嚎锛宼rue-铏氱嚎锛宖alse-瀹炵嚎 锛堥粯璁� false 锛� + * @event {Function} loadmore status涓簂oadmore鏃讹紝鐐瑰嚮缁勪欢浼氬彂鍑烘浜嬩欢 + * @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 + }, + // 缁欎竴涓礋鐨刴argin-top锛屽線涓婂亸绉伙紝閬垮厤鍜岄敭鐩橀噸鍚堢殑鎯呭喌 + negativeTop: { + type: [String, Number], + default: uni.$u.props.modal.negativeTop + }, + // modal瀹藉害锛屼笉鏀寔鐧惧垎姣旓紝鍙互鏁板�硷紝px锛宺px鍗曚綅 + width: { + type: [String, Number], + default: uni.$u.props.modal.width + }, + // 纭鎸夐挳鐨勬牱寮忥紝circle-鍦嗗舰锛宻quare-鏂瑰舰锛屽璁剧疆锛屽皢涓嶄細鏄剧ず鍙栨秷鎸夐挳 + 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 寰�涓婂亸绉荤殑鍊硷紝缁欎竴涓礋鐨刴argin-top锛屽線涓婂亸绉伙紝閬垮厤鍜岄敭鐩橀噸鍚堢殑鎯呭喌锛屽崟浣嶄换鎰忥紝鏁板�煎垯榛樿涓簆x鍗曚綅 锛堥粯璁� 0 锛� + * @property {String | Number} width modal瀹藉害锛屼笉鏀寔鐧惧垎姣旓紝鍙互鏁板�硷紝px锛宺px鍗曚綅 锛堥粯璁� '650rpx' 锛� + * @property {String} confirmButtonShape 纭鎸夐挳鐨勬牱寮�,濡傝缃紝灏嗕笉浼氭樉绀哄彇娑堟寜閽� + * @event {Function} confirm 鐐瑰嚮纭鎸夐挳鏃惰Е鍙� + * @event {Function} cancel 鐐瑰嚮鍙栨秷鎸夐挳鏃惰Е鍙� + * @event {Function} close 鐐瑰嚮閬僵鍏抽棴鍑哄彂锛宑loseOnClickOverlay涓簍rue鏈夋晥 + * @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') + }, + // 鐐瑰嚮閬僵 + // 浠庡師鐞嗕笂鏉ヨ锛宮odal鐨勯伄缃╃偣鍑伙紝骞朵笉鏄湡鐨勭偣鍑诲埌浜嗛伄缃� + // 鍥犱负modal渚濊禆浜巔opup鐨勪腑閮ㄥ脊绐楃被鍨嬶紝涓儴寮圭獥姣旇緝鐗规畩锛岃櫧鐒舵湁閬僵锛屼絾鏄负浜嗚寮圭獥鍐呭鑳絝lex灞呬腑 + // 澶氫簡涓�涓�忔槑鐨勯伄缃╋紝姝ら�忔槑鐨勯伄缃╀細瑕嗙洊鍦ㄧ伆鑹茬殑閬僵涓婏紝鎵�浠ュ疄闄呬笂鏄偣鍑讳笉鍒扮伆鑹查伄缃╃殑锛宲opup鍐呴儴鍦� + // 閫忔槑閬僵鐨勫瓙鍏冪礌鍋氫簡.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 姝ょ粍浠朵竴鑸敤浜庡湪鐗规畩鎯呭喌涓嬶紝闇�瑕佽嚜瀹氫箟瀵艰埅鏍忕殑鏃跺�欑敤鍒帮紝涓�鑸缓璁娇鐢╱ni-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 宸﹁竟杩斿洖鍥炬爣鐨勫悕绉帮紝鍙兘涓簎View鑷甫鐨勫浘鏍� 锛堥粯璁� 'arrow-left' 锛� + * @property {String} leftText 宸﹁竟鐨勬彁绀烘枃瀛� + * @property {String} rightText 鍙宠竟鐨勬彁绀烘枃瀛� + * @property {String} rightIcon 鍙宠竟杩斿洖鍥炬爣鐨勫悕绉帮紝鍙兘涓簎View鑷甫鐨勫浘鏍� + * @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() { + // 濡傛灉閰嶇疆浜哸utoBack锛岃嚜鍔ㄨ繑鍥炰笂涓�椤� + 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 + }, + // 涓�涓獄-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骞冲彴锛屾墠鑳借烦杞缃〉锛屽洜涓洪渶瑕佽皟鐢╬lus鐜 --> + <!-- #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 缁勪欢鐨剒-index鍊� + * @property {String} image 鏃犵綉缁滅殑鍥剧墖鎻愮ず锛屽彲鐢ㄧ殑src鍦板潃鎴朾ase64鍥剧墖 + * @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 + }, + // 閫氬憡婊氬姩妯″紡锛宺ow-妯悜婊氬姩锛宑olumn-绔栧悜婊氬姩 + 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 + }, + // 閫氬憡妯″紡锛宭ink-鏄剧ず鍙崇澶达紝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+銆丠5 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 閫氬憡婊氬姩妯″紡锛宺ow-妯悜婊氬姩锛宑olumn-绔栧悜婊氬姩 ( 榛樿 'row' ) + * @property {Boolean} step direction = row鏃讹紝鏄惁浣跨敤姝ヨ繘褰㈠紡婊氬姩 ( 榛樿 false ) + * @property {String} icon 鏄惁鏄剧ず宸︿晶鐨勯煶閲忓浘鏍� ( 榛樿 'volume' ) + * @property {String} mode 閫氬憡妯″紡锛宭ink-鏄剧ず鍙崇澶达紝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+銆丠5 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) { + // 姝ゆ柟娉曞啓鍦╩ixin涓紝鍙﹀璺宠浆鐨剈rl鍜宭inkType鍙傛暟涔熷湪mixin鐨刾rops涓� + 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涓婚锛宲rimary锛宻uccess锛寃arning锛宔rror + 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鏃朵笉娑堝け锛屽崟浣峬s + 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 涓婚锛宲rimary锛宻uccess锛寃arning锛宔rror ( 榛樿 'primary' ) + * @property {String} color 瀛椾綋棰滆壊 ( 榛樿 '#ffffff' ) + * @property {String} bgColor 鑳屾櫙棰滆壊 + * @property {String} message 灞曠ず鐨勬枃瀛楀唴瀹� + * @property {String | Number} duration 灞曠ず鏃堕暱锛屼负0鏃朵笉娑堝け锛屽崟浣峬s ( 榛樿 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涓婚锛宲rimary锛宻uccess锛寃arning锛宔rror + 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鏃朵笉娑堝け锛屽崟浣峬s + 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), + // 鍥犱负缁勪欢搴曞眰涓簎-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() { + // 閫氳繃涓婚鐨勫舰寮忚皟鐢╰oast锛屾壒閲忕敓鎴愭柟娉曞嚱鏁� + ['primary', 'success', 'error', 'warning'].map(item => { + this[item] = message => this.show({ + type: item, + message + }) + }) + }, + methods: { + show(options) { + // 涓嶅皢缁撴灉鍚堝苟鍒皌his.config鍙橀噺锛岄伩鍏嶅娆¤皟鐢╱-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 + }, + // 杈撳叆妗嗗搴︼紝鍗曚綅涓簆x + 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 + }, + // 鎸囧畾鍏夋爣浜庨敭鐩樼殑璺濈锛岄伩鍏嶉敭鐩橀伄鎸¤緭鍏ユ锛屽崟浣峱x + 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 杈撳叆妗嗗搴︼紝鍗曚綅涓簆x 锛堥粯璁� 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 鎸囧畾鍏夋爣浜庨敭鐩樼殑璺濈锛岄伩鍏嶉敭鐩橀伄鎸¤緭鍏ユ锛屽崟浣峱x 锛堥粯璁� 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: { + // 澶氫釜鍊间箣闂达紝鍙涓�涓�煎彂鐢熷彉鍖栵紝閮借閲嶆柊妫�鏌heck()鍑芥暟 + watchChange(n) { + this.check() + }, + // 鐩戝惉v-mode鐨勫彉鍖栵紝閲嶆柊鍒濆鍖栧唴閮ㄧ殑鍊� + value(n) { + if (n !== this.currentValue) { + this.currentValue = this.format(this.value) + } + } + }, + computed: { + getCursorSpacing() { + // 鍒ゆ柇浼犲叆鐨勫崟浣嶏紝濡傛灉涓簆x鍗曚綅锛岄渶瑕佽浆鎴恜x + 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) + // 濡傛灉涓虹┖瀛楃涓诧紝閭d箞璁剧疆涓�0锛屽悓鏃跺皢鍊艰浆涓篘umber绫诲瀷 + value = value === '' ? 0 : +value + // 瀵规瘮鏈�澶ф渶灏忓�硷紝鍙栧湪min鍜宮ax涔嬮棿鐨勫�� + value = Math.max(Math.min(this.max, value), this.min) + // 濡傛灉璁惧畾浜嗘渶澶х殑灏忔暟浣嶆暟锛屼娇鐢╰oFixed鍘昏繘琛屾牸寮忓寲 + 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-鏁板瓧閿洏锛宑ard-韬唤璇侀敭鐩� + 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-鏁板瓧閿洏锛宑ard-韬唤璇侀敭鐩� + * @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 + }, + // 閬僵鐨勮繃娓℃椂闂达紝鍗曚綅涓簃s + 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 瑙f瀽鍣� + */ +// 閰嶇疆 +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 瑙g爜 html 瀹炰綋 + * @param {String} str 瑕佽В鐮佺殑瀛楃涓� + * @param {Boolean} amp 瑕佷笉瑕佽В鐮� & + * @returns {String} 瑙g爜鍚庣殑瀛楃涓� + */ + +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 瑙f瀽鍣� + * @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 鎵ц瑙f瀽 + * @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 瑙f瀽鏍峰紡琛� + * @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锛坮ich-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 瑙f瀽鍒版爣绛惧悕 + * @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 瑙f瀽鍒板睘鎬у悕 + * @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 瑙f瀽鍒板睘鎬у�� + * @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 瑙f瀽鍒版爣绛惧紑濮� + * @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 + } // 瑙f瀽 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 瑙f瀽鍒版爣绛剧粨鏉� + * @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銆乧ellspacing銆乥order 杩欏嚑涓父鐢ㄨ〃鏍煎睘鎬ч渶瑕侀�氳繃杞崲瀹炵幇 + 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 瑙f瀽鍒版枃鏈� + * @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 鎵ц瑙f瀽 + * @param {String} content 瑕佽В鏋愮殑鏂囨湰 + */ + +lexer.prototype.parse = function (content) { + this.content = content || '' + this.i = 0 // 鏍囪瑙f瀽浣嶇疆 + + 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]]) { + // 瑙f瀽鍒版爣绛惧悕 + 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 == '=') { + // 瑙f瀽鍒板睘鎬у悕 + 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 鑳屾櫙棰滆壊锛屽彧閫傜敤涓嶢PP-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 鏄惁鍦ㄦ墜鎸囨澗寮�鏃剁珛鍗宠Е鍙慶hange浜嬩欢锛堥粯璁� 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: [], + // 绱㈠紩鍊� 锛屽搴攑icker-view鐨剉alue + 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)) { // 鎶妘ndefined杞负鍚堟硶鍋囧��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 + // 寰俊灏忕▼搴忎笉鑳戒紶閫抰his锛屼細鍥犱负寰幆寮曠敤鑰屾姤閿� + 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) { + // 褰撹兘杩涘叆姝ゆ柟娉曪紝鎰忓懗鐫�褰撳墠璁剧疆鐨勫悇鍒楅粯璁ょ储寮曪紝鍗充负鈥滀笂涓�娆♀�濈殑閫変腑鍊硷紝闇�瑕佽褰曪紝鏄洜涓篶hangeHandler涓� + // 闇�瑕佹嬁鍓嶅悗鐨勫彉鍖栧�艰繘琛屽姣旓紝寰楀嚭褰撳墠鍙戠敓鏀瑰彉鐨勬槸鍝竴鍒� + this.lastIndex = uni.$u.deepClone(index) + }, + // 璁剧疆瀵瑰簲鍒楅�夐」鐨勬墍鏈夊�� + setColumnValues(columnIndex, values) { + // 鏇挎崲innerColumns鏁扮粍涓璫olumnIndex绱㈠紩鐨勫�间负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) { + // 杩涜鍚屾闃诲锛屽洜涓哄閮ㄥ緱鍒癱hange浜嬩欢涔嬪悗锛屽彲鑳介渶瑕佹墽琛宻etColumnValues鏇存柊鍒楃殑鍊� + // 绱㈠紩濡傛灉鍦ㄥ閮╟hange鐨勫洖璋冧腑璋冪敤getColumnValues鐨勮瘽锛屽彲鑳芥棤娉曞緱鍒板彉鏇村悗鐨勫垪鍊硷紝杩欓噷杩涜涓�瀹氬欢鏃讹紝淇濊瘉鍊肩殑鍑嗙‘鎬� + (async () => { + await uni.$u.sleep() + })() + return this.innerColumns[columnIndex] + }, + // 璁剧疆鏁翠綋鍚勫垪鐨刢olumns鐨勫�� + setColumns(columns) { + this.innerColumns = uni.$u.deepClone(columns) + // 濡傛灉鍦ㄨ缃悇鍒楁暟鎹椂锛屾病鏈夎璁剧疆榛樿鐨勫悇鍒楃储寮昫efaultIndex锛岄偅涔堢敤0鍘诲~鍏呭畠锛屾暟缁勯暱搴︿负鍒楃殑鏁伴噺 + if (this.innerIndex.length === 0) { + this.innerIndex = new Array(columns.length).fill(0) + } + }, + // 鑾峰彇鍚勫垪閫変腑鍊煎搴旂殑绱㈠紩 + getIndexs() { + return this.innerIndex + }, + // 鑾峰彇鍚勫垪閫変腑鐨勫�� + getValues() { + // 杩涜鍚屾闃诲锛屽洜涓哄閮ㄥ緱鍒癱hange浜嬩欢涔嬪悗锛屽彲鑳介渶瑕佹墽琛宻etColumnValues鏇存柊鍒楃殑鍊� + // 绱㈠紩濡傛灉鍦ㄥ閮╟hange鐨勫洖璋冧腑璋冪敤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 + }, + // 鍔ㄧ敾鏃堕暱锛屽崟浣峬s + 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 + }, + // 鏄惁涓篿PhoneX鐣欏嚭搴曢儴瀹夊叏璺濈 + safeAreaInsetBottom: { + type: Boolean, + default: uni.$u.props.popup.safeAreaInsetBottom + }, + // 鏄惁鐣欏嚭椤堕儴瀹夊叏璺濈锛堢姸鎬佹爮楂樺害锛� + safeAreaInsetTop: { + type: Boolean, + default: uni.$u.props.popup.safeAreaInsetTop + }, + // 鑷畾涔夊叧闂浘鏍囦綅缃紝top-left涓哄乏涓婅锛宼op-right涓哄彸涓婅锛宐ottom-left涓哄乏涓嬭锛宐ottom-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 + }, + // 寮圭獥鑳屾櫙鑹诧紝璁剧疆涓簍ransparent鍙幓闄ょ櫧鑹茶儗鏅� + 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 鍔ㄧ敾鏃堕暱锛屽崟浣峬s 锛堥粯璁� 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 鏄惁涓篿PhoneX鐣欏嚭搴曢儴瀹夊叏璺濈 锛堥粯璁� true 锛� + * @property {Boolean} safeAreaInsetTop 鏄惁鐣欏嚭椤堕儴瀹夊叏璺濈锛堢姸鎬佹爮楂樺害锛� 锛堥粯璁� false 锛� + * @property {String} closeIconPos 鑷畾涔夊叧闂浘鏍囦綅缃紙榛樿 'top-right' 锛� + * @property {String | Number} round 鍦嗚鍊硷紙榛樿 0锛� + * @property {Boolean} zoom 褰搈ode=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 = {} + // 閫氳繃璁惧淇℃伅鐨剆afeAreaInsets鍊兼潵鍒ゆ柇鏄惁闇�瑕侀鐣欓《閮ㄧ姸鎬佹爮鍜屽簳閮ㄥ畨鍏ㄥ眬鐨勪綅缃� + // 涓嶄娇鐢╟ss鏂规锛屾槸鍥犱负nvue涓嶆敮鎸乧ss鐨刬PhoneX瀹夊叏鍖烘煡璇㈠睘鎬� + 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() { + // 鐢变簬涓儴寮瑰嚭鏃讹紝鍏秛-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 + // 鍒ゆ柇濡傛灉鍦ㄩ渶瑕侀噸鏂板垵濮嬪寲鐨勭粍浠舵暟缁勪腑鍚嶄腑锛屽苟涓斿瓨鍦╥nit鏂规硶鐨勮瘽锛屽垯鎵ц + 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 + }, + // 褰㈢姸锛宑ircle-鍦嗗舰锛宻quare-鏂瑰舰 + shape: { + type: String, + default: uni.$u.props.radioGroup.shape + }, + // 閫変腑鐘舵�佷笅鐨勯鑹诧紝濡傝缃鍊硷紝灏嗕細瑕嗙洊parent鐨刟ctiveColor鍊� + 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 + }, + // 甯冨眬鏂瑰紡锛宺ow-妯悜锛宑olumn-绾靛悜 + 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 鍗曢�夋鐢ㄤ簬鏈変竴涓�夋嫨锛岀敤鎴峰彧鑳介�夋嫨鍏朵腑涓�涓殑鍦烘櫙銆傛惌閰島-radio浣跨敤 + * @tutorial https://www.uviewui.com/components/radio.html + * @property {String | Number | Boolean} value 缁戝畾鐨勫�� + * @property {Boolean} disabled 鏄惁绂佺敤鎵�鏈塺adio锛堥粯璁� false 锛� + * @property {String} shape 澶栬褰㈢姸锛宻hape-鏂瑰舰锛宑ircle-鍦嗗舰(榛樿 circle ) + * @property {String} activeColor 閫変腑鏃剁殑棰滆壊锛屽簲鐢ㄥ埌鎵�鏈夊瓙Radio缁勪欢锛堥粯璁� '#2979ff' 锛� + * @property {String} inactiveColor 鏈�変腑鐨勯鑹� (榛樿 '#c8c9cc' ) + * @property {String} name 鏍囪瘑绗� + * @property {String | Number} size 缁勪欢鏁翠綋鐨勫ぇ灏忥紝鍗曚綅px锛堥粯璁� 18 锛� + * @property {String} placement 甯冨眬鏂瑰紡锛宺ow-妯悜锛宑olumn-绾靛悜 锛堥粯璁� '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涓簉ow鏃讹紝鏄惁鏄剧ず涓嬭竟妗� 锛堥粯璁� false 锛� + * @property {String} iconPlacement 鍥炬爣涓庢枃瀛楃殑瀵归綈鏂瑰紡 锛堥粯璁� 'left' 锛� + * @property {Object} customStyle 缁勪欢鐨勬牱寮忥紝瀵硅薄褰㈠紡 + * @event {Function} change 浠讳竴涓猺adio鐘舵�佸彂鐢熷彉鍖栨椂瑙﹀彂 + * @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鐨勫彉閲忥紝閮芥槸瀛愮粍浠秛-radio闇�瑕佺敤鍒扮殑锛岀敱浜庡ご鏉″皬绋嬪簭鐨勫吋瀹规�у樊寮傦紝瀛愮粍浠舵棤娉曞疄鏃剁洃鍚埗缁勪欢鍙傛暟鐨勫彉鍖� + // 鎵�浠ラ渶瑕佹墜鍔ㄩ�氱煡瀛愮粍浠讹紝杩欓噷杩斿洖涓�涓猵arentData鍙橀噺锛屼緵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涓轰竴涓猚omputed鍙橀噺锛屽湪mixin涓� + return this.bem('radio-group', ['placement']) + }, + }, + watch: { + // 褰撶埗缁勪欢闇�瑕佸瓙缁勪欢闇�瑕佸叡浜殑鍙傛暟鍙戠敓浜嗗彉鍖栵紝鎵嬪姩閫氱煡瀛愮粍浠� + parentData() { + if (this.children.length) { + this.children.map(child => { + // 鍒ゆ柇瀛愮粍浠�(u-radio)濡傛灉鏈塱nit鏂规硶鐨勮瘽锛屽氨灏辨墽琛�(鎵ц鐨勭粨鏋滄槸瀛愮粍浠堕噸鏂颁粠鐖剁粍浠舵媺鍙栦簡鏈�鏂扮殑鍊�) + 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 + }, + // 褰㈢姸锛宻quare涓烘柟褰紝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鐨刟ctiveColor鍊� + 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鎻愮ず鏂囧瓧锛屽洜涓簄vue涓嬶紝鐩存帴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 鍗曢�夋鐢ㄤ簬鏈変竴涓�夋嫨锛岀敤鎴峰彧鑳介�夋嫨鍏朵腑涓�涓殑鍦烘櫙銆傛惌閰島-radio-group浣跨敤 + * @tutorial https://www.uviewui.com/components/radio.html + * @property {String | Number} name radio鐨勫悕绉� + * @property {String} shape 褰㈢姸锛宻quare涓烘柟褰紝circle涓哄渾鍨� + * @property {Boolean} disabled 鏄惁绂佺敤 + * @property {String | Boolean} labelDisabled 鏄惁绂佹鐐瑰嚮鎻愮ず璇�変腑鍗曢�夋 + * @property {String} activeColor 閫変腑鏃剁殑棰滆壊锛屽璁剧疆parent鐨刟ctive-color灏嗗け鏁� + * @property {String} inactiveColor 鏈�変腑鐨勯鑹� + * @property {String | Number} iconSize 鍥炬爣澶у皬锛屽崟浣峱x + * @property {String | Number} labelSize label瀛椾綋澶у皬锛屽崟浣峱x + * @property {String | Number} label label鎻愮ず鏂囧瓧锛屽洜涓簄vue涓嬶紝鐩存帴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, + // 褰撲綘鐪嬪埌杩欐浠g爜鐨勬椂鍊欙紝 + // 鐖剁粍浠剁殑榛樿鍊硷紝鍥犱负澶存潯灏忕▼搴忎笉鏀寔鍦╟omputed涓娇鐢╰his.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; + }, + // 缁勪欢灏哄锛屽搴攕ize鐨勫�硷紝榛樿鍊间负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') + } + // 鏀粯瀹濓紝澶存潯灏忕▼搴忔棤娉曞姩鎬佺粦瀹氫竴涓暟缁勭被鍚嶏紝鍚﹀垯瑙f瀽鍑烘潵鐨勭粨鏋滀細甯︽湁","锛岃�屽鑷村け鏁� + // #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璁剧疆涓簍rue锛岄渶瑕佸悓鏃跺皢u-radio-group鐨刾lacement璁剧疆涓篶olumn鎵嶆湁鏁�') + } + // 褰撶埗缁勪欢璁剧疆浜嗘樉绀轰笅杈规骞朵笖鎺掑垪褰㈠紡涓虹旱鍚戞椂锛岀粰鍐呭鍜岃竟妗嗕箣闂村姞涓婁竴瀹氶棿闅� + 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() { + // 鏀粯瀹濆皬绋嬪簭涓嶆敮鎸乸rovide/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) + // 濡傛灉鎸夐挳鏁翠綋琚鐢ㄦ垨鑰卨abel琚鐢紝鍒欎笉鍏佽鐐瑰嚮鏂囧瓧淇敼鐘舵�� + if (!this.elLabelDisabled && !this.elDisabled) { + this.setRadioCheckedStatus() + } + }, + emitEvent() { + // u-radio鐨刢hecked涓嶄负true鏃�(鎰忓懗鐫�鏈�変腑)锛屾墠鍙戝嚭浜嬩欢锛岄伩鍏嶅娆$偣鍑昏Е鍙戜簨浠� + if (!this.checked) { + this.$emit('change', this.name) + // 灏濊瘯璋冪敤u-form鐨勯獙璇佹柟娉曪紝杩涜涓�瀹氬欢杩燂紝鍚﹀垯寰俊灏忕▼搴忔洿鏂板彲鑳戒細涓嶅強鏃� + this.$nextTick(() => { + uni.$u.formValidate(this, 'change') + }) + } + }, + // 鏀瑰彉缁勪欢閫変腑鐘舵�� + // 杩欓噷鐨勬敼鍙樼殑渚濇嵁鏄紝鏇存敼鏈粍浠剁殑checked鍊间负true锛屽悓鏃堕�氳繃鐖剁粍浠堕亶鍘嗘墍鏈塽-radio瀹炰緥 + // 灏嗘湰缁勪欢澶栫殑鍏朵粬u-radio鐨刢hecked閮借缃负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 閫変腑鏃剁殑鍥炬爣鍚嶏紝鍙兘涓簎View鐨勫唴缃浘鏍� 锛堥粯璁� 'star-fill' 锛� + * @property {String} inactiveIcon 鏈�変腑鏃剁殑鍥炬爣鍚嶏紝鍙兘涓簎View鐨勫唴缃浘鏍� 锛堥粯璁� '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, // 姣忎釜鏄熸槦鐨勫搴� + // 鏍囪瘑鏄惁姝e湪婊戝姩锛岀敱浜巌OS浜嬩欢涓妕ouch姣攃lick鍏堣Е鍙戯紝瀵艰嚧蹇�熸粦鍔ㄧ粨鏉熷悗锛屾帴鐫�瑙﹀彂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; + // 鐐瑰嚮鏃讹紝鍦╪vue涓婏紝鏃犳硶鑾峰緱鐐瑰嚮鐨勫潗鏍囷紝鎵�浠ユ棤娉曞疄鐜扮偣鍑诲崐鏄熼�夋嫨 + // #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); + // 鍚屾椂淇敼鍙屽悜缁戝畾鐨剉alue鐨勫�� + this.$emit("input", this.activeIndex); + }, + // 鑾峰彇褰撳墠婵�娲荤殑璇勫垎鍥炬爣 + getActiveIndex(x,isClick = false) { + if (this.disabled || this.readonly) { + return; + } + // 鍒ゆ柇褰撳墠鎿嶄綔鐨勭偣鐨剎鍧愭爣鍊硷紝鏄惁鍦ㄥ厑璁哥殑杈圭晫鑼冨洿鍐� + 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; + } + + // 璁剧疆寤舵椂涓轰簡璁ヽlick浜嬩欢鍦╰ouchmove涔嬪墠瑙﹀彂 + 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 + }, + // 鏄惁鏄剧ず闃村奖 + // 姝ゅ弬鏁颁笉鑳藉啓鍦╬rops/readMore.js涓繘琛岄粯璁ら厤缃紝鍥犱负浣跨敤浜嗘潯浠剁紪璇戯紝鍦ㄥ閮╦s涓� + // uni鏃犳硶鍑嗙‘璇嗗埆褰撳墠鏄惁澶勪簬nvue杩樻槸闈瀗vue涓� + shadowStyle: { + type: Object, + default: () => ({ + // #ifndef APP-NVUE + backgroundImage: 'linear-gradient(-180deg, rgba(255, 255, 255, 0) 0%, #fff 80%)', + // #endif + // #ifdef APP-NVUE + // nvue涓婁笉鏀寔璁剧疆澶嶆潅鐨刡ackgroundImage灞炴�� + 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鍜宑lose浜嬩欢鏃讹紝灏嗘鍙傛暟杩斿洖鍦ㄥ洖璋冨弬鏁颁腑 + 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 鍐呭瓒呭嚭姝ら珮搴︽墠浼氭樉绀哄睍寮�鍏ㄦ枃鎸夐挳锛屽崟浣峱x锛堥粯璁� 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涓篺alse锛岄殣钘�"鏀惰捣"閮ㄥ垎鐨勫唴瀹� + 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 + }, + // 閫氬憡妯″紡锛宭ink-鏄剧ず鍙崇澶达紝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 + }, + // 瀛椾綋澶у皬锛屽崟浣峱x + 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 閫氬憡妯″紡锛宭ink-鏄剧ず鍙崇澶达紝closable-鏄剧ず鍙充晶鍏抽棴鍥炬爣 + * @property {String} color 鏂囧瓧棰滆壊锛屽悇鍥炬爣涔熶細浣跨敤鏂囧瓧棰滆壊 (榛樿 '#f9ae3d' ) + * @property {String} bgColor 鑳屾櫙棰滆壊 (榛樿 ''#fdf6ec' ) + * @property {String | Number} fontSize 瀛椾綋澶у皬锛屽崟浣峱x (榛樿 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涓嬶紝鍐呭鍙戠敓鍙樺寲锛屽鑷存粴鍔ㄥ搴︿篃鍙樺寲锛岄渶瑕佹爣蹇椾负鏄惁闇�瑕侀噸鏂拌绠楀搴� + // 涓嶈兘鍦ㄥ唴瀹瑰彉鍖栨椂鐩存帴閲嶆柊璁$畻锛屽洜涓簄vue鐨刟nimation妯″潡涓婁竴娆$殑婊氬姩涓嶆槸鍒氬ソ缁撴潫锛屼細鏈夊奖鍝� + 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涓簉ow鏃讹紝瑕佹眰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涓瓧绗︿互涓婏級 + // 鏀惧湪涓�涓猼ext鏍囩涓繘琛屾粴鍔紝鍦ㄤ綆绔畨鍗撴満涓婏紝鍔ㄧ敾鍙兘浼氬嚭鐜版姈鍔ㄧ幇璞★紝闇�瑕佸垎鍓插埌澶氫釜text涓彲瑙e喅姝ら棶棰� + 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 + // 鍦ˋPP涓�(鍚玭vue)锛岀洃鍚綋鍓峸ebview鏄惁澶勪簬闅愯棌鐘舵��(杩涘叆涓嬩竴椤垫椂鍗充负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涓簉ow鏃讹紝瑕佹眰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` + // 杩欓噷蹇呴』杩欐牱寮�濮嬪姩鐢伙紝鍚﹀垯鍦ˋPP涓婂姩鐢婚�熷害涓嶄細鏀瑰彉 + 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 + // 杩斿洖涓�涓猵romise + 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: { + // 缁檆ol娣诲姞闂磋窛锛屽乏鍙宠竟璺濆悇鍗犱竴鍗� + 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銆乧enter銆乥ottom + 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 + } + // 閫氳繃缁檜-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鐨刣om妯″潡鐢ㄤ簬鑾峰彇鑺傜偣 + 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 + // 鏍囪瘑涓烘槸鍚vue + 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锛屾搴撶被浼间簬寰俊灏忕▼搴弚xs锛岀洰鐨勬槸璁﹋s杩愯鍦ㄨ鍥惧眰锛屽噺灏戣鍥惧眰鍜岄�昏緫灞傜殑閫氫俊鎶樻崯 +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锛宭eft锛宺ight杩涜瀹氫綅 + 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涓惈鏈塻croll-view鐨勪俊鎭紝姣斿scroll-view鐨勫疄闄呭搴︼紝褰撳墠鏃堕棿鐐箂croll-view鐨勭Щ鍔ㄨ窛绂荤瓑 + var detail = event.detail + var scrollWidth = detail.scrollWidth + var scrollLeft = detail.scrollLeft + // 鑾峰彇褰撳墠缁勪欢鐨刣ataset锛岃鐧戒簡灏辨槸绁稿浗娈冩皯鐨勮吘xun鎼炲嚭鏉ョ殑鍨僯i + var dataset = event.currentTarget.dataset + // 姝や负scroll-view澶栭儴鍖呰9鍏冪礌鐨勫搴� + // 鏌愪簺HX鐗堟湰(3.1.18)锛屽彂鐜皏iew鍏冪礌涓ぇ鍐欑殑data-scrollWidth锛屽湪wxs涓紝鍙樻垚浜嗗叏閮ㄥ皬鍐欙紝鎵�浠ヨ繖閲岄渶瑕佺壒鍒鐞� + var scrollComponentWidth = dataset.scrollWidth || dataset.scrollwidth || 0 + // 鎸囩ず鍣ㄥ拰婊戝潡鐨勫搴� + var indicatorWidth = dataset.indicatorWidth || dataset.indicatorwidth || 0 + var barWidth = dataset.barWidth || dataset.barwidth || 0 + // 姝ゅ鐨勮绠楃悊鐢变负锛歴croll-view鐨勬粴鍔ㄨ窛绂讳笌鐩爣婊氬姩璺濈(scroll-view鐨勫疄闄呭搴﹀噺鍘诲寘瑁瑰厓绱犵殑瀹藉害)涔嬫瘮锛岀瓑浜庢粦鍧楀綋鍓嶇Щ鍔ㄨ窛绂讳笌鎬婚渶 + // 婊戝姩璺濈(鎸囩ず鍣ㄧ殑鎬诲搴﹀噺鍘绘粦鍧楀搴�)鐨勬瘮鍊� + var x = scrollLeft / (scrollWidth - scrollComponentWidth) * (indicatorWidth - barWidth) + setBarStyle(ownerInstance, x) +} + +// 鐢变簬webview鐨勬棤鑳斤紝鏃犳硶淇濊瘉scroll-view鍦ㄦ粦鍔ㄨ繃绋嬩腑锛屼竴鐩磋Е鍙憇croll浜嬩欢锛屼細瀵艰嚧 +// 鏃犳硶鐩戝惉鍒版煇浜涙粴鍔ㄥ�硷紝褰撳湪棣栧熬涓寸晫鍊兼棤娉曠洃鍚埌鏃讹紝杩欐槸鑷村懡鐨勶紝鍥犱负閿欏け杩欎簺鍊间細瀵艰嚧婊戝潡鏃犳硶鍥炲埌璧风偣鍜岀粓鐐� +// 鎵�浠ヨ繖閲岄渶瑕佸涓寸晫鍊煎仛鐩戝惉骞跺鐞� +function scrolltolower(event, ownerInstance) { + ownerInstance.callMethod('scrollEvent', 'right') + // 鑾峰彇褰撳墠缁勪欢鐨刣ataset + 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 --> + <!-- 浠ヤ笂骞冲彴锛屾敮鎸亀xs --> + <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 --> + <!-- 闈炰互涓婂钩鍙帮紝鍙兘浣跨敤鏅�歫s瀹炵幇 --> + <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锛宭eft锛宺ight杩涜瀹氫綅 + * @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 + // 姝や负鏅�歫s鏂规锛屽彧鏈夊湪闈瀗vue鍜屼笉鏀寔wxs鏂规鐨勭鎵嶄娇鐢ㄣ�� + // 姝ゅ鐨勮绠楃悊鐢变负锛歴croll-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') + // 鍦ㄦ櫘閫歫s鏂规涓紝婊氬姩鍒板彸杈规椂锛岄�氳繃璁剧疆this.scrollInfo锛屾ā鎷熷嚭婊氬姩鍒板彸杈圭殑鎯呭喌 + // 鍥犱负涓婃柟鏄敤杩嘽omputed璁$畻鐨勶紝璁剧疆鍚庯紝浼氳嚜鍔ㄨ皟鏁存粦鍧楃殑浣嶇疆 + this.scrollInfo.scrollLeft = uni.$u.getPx(this.indicatorWidth) - uni.$u.getPx(this.indicatorBarWidth) + }, + // #endif + // + scrollEvent(status) { + this.$emit(status) + }, + // 鑾峰彇缁勪欢鐨勫搴� + async getComponentWidth() { + // 寤舵椂涓�瀹氭椂闂达紝浠ヨ幏鍙杁om灏哄 + 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-鍦嗗舰锛宻quare-鏂瑰舰 + 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 + }, + // 寮�鍚痵howAction鏃讹紝鏄惁鍦╥nput鑾峰彇鐒︾偣鏃舵墠鏄剧ず + 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-鍦嗗舰锛宻quare-鏂瑰舰锛堥粯璁� '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) { + // 鍙屽悜缁戝畾鍊硷紝璁﹙-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 = ''; + // 寤跺悗鍙戝嚭浜嬩欢锛岄伩鍏嶅湪鐖剁粍浠剁洃鍚琧lear浜嬩欢鏃讹紝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浜嬩欢锛岃嚜浠巋x2.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鍦℉5涓嬶紝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 + }, + // 澶村儚鍗犱綅鍥剧殑褰㈢姸锛宑ircle-鍦嗗舰锛宻quare-鏂瑰舰 + 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 鏄惁鏄剧ず楠ㄦ灦鍗犱綅鍥撅紝璁剧疆涓篺alse灏嗕細灞曠ず瀛愮粍浠跺唴瀹� (榛樿 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 澶村儚鍗犱綅鍥剧殑褰㈢姸锛宑ircle-鍦嗗舰锛宻quare-鏂瑰舰 (榛樿 '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 + // 濡傛灉鏈塼itle鍗犱綅鍥撅紝绗竴涓钀藉崰浣嶅浘鐨勫杈硅窛闇�瑕佸ぇ涓�浜涳紝濡傛灉娌℃湁title鍗犱綅鍥撅紝绗竴涓钀藉崰浣嶅浘鍒欐棤闇�澶栬竟璺� + // 涔嬫墍浠ラ渶瑕佽繖涔堝仛锛屾槸鍥犱负weex鐨勬棤鑳斤紝浠ユ彁鍗囨�ц兘涓哄�熷彛涓嶆敮鎸乧ss鐨勪竴浜涗吉绫� + 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 + // 涓轰簡璁﹐pacity: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鍜屽紑鍚姩鐢荤姸鎬侊紝鍥犱负鏈�缁堢殑鐘舵�佸繀椤昏揪鍒皁pacity: 1锛屽惁鍒欏彲鑳� + // 浼氬仠鐣欏湪opacity: 0.5鐨勭姸鎬佷腑 + animation.transition(skeleton, { + styles: { + opacity: 1 + }, + duration: 600, + }, () => { + // 鍙湁鍦╨oading涓椂锛屾墠鎵ц鍔ㄧ敾 + this.loading && this.animate && this.setNvueAnimation() + }) + }) + // #endif + }, + // 鑾峰彇缁勪欢鐨勫搴� + async getComponentWidth() { + // 寤舵椂涓�瀹氭椂闂达紝浠ヨ幏鍙杁om灏哄 + 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 + // 鑾峰緱绉诲姩璺濈瀵规暣涓粦鍧楃殑鐧惧垎姣斿�硷紝姝や负甯︽湁澶氫綅灏忔暟鐨勫�硷紝涓嶈兘鐢ㄦ鏇存柊瑙嗗浘 + // 鍚﹀垯閫犳垚閫氫俊闃诲锛岄渶瑕佹瘡鏀瑰彉涓�涓猻tep鍊兼椂淇敼涓�娆¤鍥� + 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 + } + // 鐩存帴鐐瑰嚮婊戝潡鐨勬儏鍐碉紝璁$畻鏂瑰紡涓巓nTouchMove鏂规硶鐩稿悓 + 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璋冪敤锛岀敤浜庝慨鏀箆-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 + * 鍏煎寰俊锛孮Q锛孒5锛孷ue鐗堢殑瀹夊崜鍜宨OS + */ +/** + * 寮�濮嬫粦鍔ㄦ搷浣� + * @param {Object} e + * @param {Object} ownerInstance + */ +function onTouchMove(e, ownerInstance) { + // wxs浜嬩欢瀵硅薄涓嬫湁涓�涓猧nstance灞炴�э紝琛ㄧず褰撳墠瑙﹀彂姝や簨浠剁殑缁勪欢鐨勫疄渚嬶紝閫氳繃璇ュ疄渚嬶紝鍙互鑾峰彇鐩稿叧鐨刣ataset锛岃缃牱寮忕瓑淇℃伅 + // https://developers.weixin.qq.com/miniprogram/dev/framework/view/interactive-animation.html + var instance = e.instance; + // getState()涓轰竴涓璞★紝鎸傝浇鍦╥nstance涓婏紝绫讳技缁勪欢鐨刣ata涓�鏍凤紝鍙互瀛樻斁涓�浜涘彉閲忥紝渚涗互鍚庣殑瑙﹀彂浜嬩欢涓娇鐢� + 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 + } + + // 鐩存帴鐐瑰嚮婊戝潡鐨勬儏鍐碉紝璁$畻鏂瑰紡涓巓nTouchMove鏂规硶鐩稿悓 + 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锛岄渶瑕佽烦姝ワ紝鎵�浠ラ渶瑕佷娇鐢∕ath.round杩涜鍙栨暣 + percent = Math.round(Math.max(mp.min, Math.min(value, mp.max)) / mp.step) * mp.step + } else { + // 褰搒tep=1鏃讹紝鏃犻渶璺虫锛屽厖鍒嗗埄鐢╳xs鎬ц兘锛屾粦鍧楀疄鏃惰窡闅忔墜鍔匡紝杈惧埌涓濇粦鐨勬晥鏋� + percent = Math.max(mp.min, Math.min(value, mp.max)) + } + // 杩斿洖缁勪欢鐨勫疄渚� + var gapInstance = ownerInstance.selectComponent('.u-slider__gap') + // 鍦ㄧЩ鍔ㄦ湡闂达紝涓嶅厑璁竧ransition鍔ㄧ敾锛屽惁鍒欎細閫犳垚鍗¢】 + gapInstance[event === 'click' ? 'addClass' : 'removeClass']('u-slider__gap--ani') + // 璋冪敤閫昏緫灞傜殑鏂规硶锛屼慨鏀箆-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 + * 鍙兘浣跨敤浜巒vue涓� + */ +// 寮曞叆bindingx锛屾搴撶被浼间簬寰俊灏忕▼搴弚xs锛岀洰鐨勬槸璁﹋s杩愯鍦ㄨ鍥惧眰锛屽噺灏戣鍥惧眰鍜岄�昏緫灞傜殑閫氫俊鎶樻崯 +const BindingX = uni.requireNativePlugin('bindingx') +// nvue鎿嶄綔dom鐨勫簱锛岀敤浜庤幏鍙杁om鐨勫昂瀵镐俊鎭� +const dom = uni.requireNativePlugin('dom') +// nvue涓敤浜庢搷浣滃厓绱犲姩鐢荤殑搴擄紝绫讳技浜巙ni.animation锛屽彧涓嶈繃uni.animation涓嶈兘鐢ㄤ簬nvue +const animation = uni.requireNativePlugin('animation') + +export default { + data() { + return { + // bindingx鐨勫洖璋冨�硷紝鐢ㄤ簬鍙栨秷缁戝畾 + panEvent: null, + // 鏍囪鏄惁绉诲姩鐘舵�� + moving: false, + // 浣嶇Щ鐨勫亸绉婚噺 + x: 0, + // 鏄惁姝e湪瑙︽懜杩囩▼涓紝鐢ㄤ簬鏍囪鍔ㄧ敾绫绘槸鍚︽坊鍔犳垨绉婚櫎 + touching: false, + changeFromInside: false + } + }, + watch: { + // 鐩戝惉vlaue鐨勫彉鍖栵紝姝ゅ彉鍖栧彲鑳芥槸鐢变簬鍐呴儴淇敼v-model鐨勫�硷紝鎴栬�呭閮� + // 浠庢湇鍔$鑾峰彇涓�涓�煎悗锛岃祴鍊肩粰slider鐨剉-model鑰屽鑷寸殑 + value(n) { + if (!this.changeFromInside) { + this.initX() + } else { + this.changeFromInside = false + } + } + }, + mounted() { + this.init() + }, + methods: { + init() { + this.getSliderRect() + }, + // 鑾峰彇鑺傜偣淇℃伅 + // 鑾峰彇slider灏哄 + getSliderRect() { + // 鑾峰彇婊戝潡鏉$殑灏哄淇℃伅 + // 閫氳繃nvue鐨刣om妯″潡锛屾煡璇㈣妭鐐逛俊鎭� + 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 + + // 鍒濆鍊间负鏈鍋忕Щ閲弜锛屽姞涓婃鍋滄婊戝姩鏃剁殑缁撴潫鍊� + let exporession = `(${this.x} + x)` + // 灏嗗亸绉荤殑x鍊硷紝杞负鎬讳綅绉荤殑鐧惧垎姣斿�硷紝涓轰簡鍜宮in鍜宮ax杩涜鍒ゆ柇 + exporession = `(${exporession} / ${width}) * 100` + if (step > 1) { + // 濡傛灉step姝ヨ繘澶т簬1锛岄渶瑕佽烦姝ワ紝鎵�浠ラ渶瑕佷娇鐢∕ath.round杩涜鍙栨暣 + exporession = `round(max(${min}, min(${exporession}, ${max})) / ${step}) * ${step}` + } else { + // 褰搒tep=1鏃讹紝鏃犻渶璺虫锛屽厖鍒嗗埄鐢╞indingx鎬ц兘锛屾粦鍧楀疄鏃惰窡闅忔墜鍔匡紝杈惧埌涓濇粦鐨勬晥鏋� + exporession = `max(${min}, min(${exporession}, ${max}))` + } + // 灏嗙櫨鍒嗘瘮鏈�鍚庤浆鍖栦负瀵瑰簲鐨刾x鍊� + 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) + // 鏍囪涓嬩竴娆¤Е鍙憊alue鐨剋atch鏃讹紝杩欎釜鍊肩殑鍙樺寲锛屾槸鐢卞唴閮ㄦ敼鍙樼殑 + this.changeFromInside = true + this.moving = false + this.touching = false + } + }) + }, + // 浠巚alue鐨勫彉鍖栵紝鍊掓帹寰楀嚭x鐨勫�艰涓哄灏� + initX() { + const { + left, + width + } = this.sliderRect + // 寰楀嚭x鐨勫垵濮嬪亸绉诲�硷紝涔嬫墍浠ラ渶瑕佽繖涔堝仛锛屾槸鍥犱负鍦╞indingX涓紝瑙︽懜婊戝姩鏃讹紝鍙兘鐨勫�兼湰娆$Щ鍔ㄧ殑鍋忕Щ鍊� + // 鑰屾棤娉曠殑鍊煎噯纭殑鍓嶅悗绉诲姩鐨勪袱涓偣鐨勫潗鏍囧�硷紝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 + * 鍙兘浣跨敤浜巒vue涓� + */ +// 寮曞叆bindingx锛屾搴撶被浼间簬寰俊灏忕▼搴弚xs锛岀洰鐨勬槸璁﹋s杩愯鍦ㄨ鍥惧眰锛屽噺灏戣鍥惧眰鍜岄�昏緫灞傜殑閫氫俊鎶樻崯 +const BindingX = uni.requireNativePlugin('bindingx') +// nvue鎿嶄綔dom鐨勫簱锛岀敤浜庤幏鍙杁om鐨勫昂瀵镐俊鎭� +const dom = uni.requireNativePlugin('dom') +// nvue涓敤浜庢搷浣滃厓绱犲姩鐢荤殑搴擄紝绫讳技浜巙ni.animation锛屽彧涓嶈繃uni.animation涓嶈兘鐢ㄤ簬nvue +const animation = uni.requireNativePlugin('animation') + +export default { + data() { + return { + // 浣嶇Щ鐨勫亸绉婚噺 + x: 0, + // 鏄惁姝e湪瑙︽懜杩囩▼涓紝鐢ㄤ簬鏍囪鍔ㄧ敾绫绘槸鍚︽坊鍔犳垨绉婚櫎 + touching: false, + changeFromInside: false + } + }, + watch: { + // 鐩戝惉vlaue鐨勫彉鍖栵紝姝ゅ彉鍖栧彲鑳芥槸鐢变簬鍐呴儴淇敼v-model鐨勫�硷紝鎴栬�呭閮� + // 浠庢湇鍔$鑾峰彇涓�涓�煎悗锛岃祴鍊肩粰slider鐨剉-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鐨刣om妯″潡锛屾煡璇㈣妭鐐逛俊鎭� + 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') + // } + // // 鏍囪褰撳墠婊戝姩杩囩▼涓殑瑙︾偣淇℃伅锛屾鏂规硶鍦╰ouch 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) + } + }, + // 浠巚alue鐨勫彉鍖栵紝鍊掓帹寰楀嚭x鐨勫�艰涓哄灏� + initX() { + const { + left, + width + } = this.sliderRect + // 寰楀嚭x鐨勫垵濮嬪亸绉诲�硷紝涔嬫墍浠ラ渶瑕佽繖涔堝仛锛屾槸鍥犱负鍦╞indingX涓紝瑙︽懜婊戝姩鏃讹紝鍙兘鐨勫�兼湰娆$Щ鍔ㄧ殑鍋忕Щ鍊� + // 鑰屾棤娉曠殑鍊煎噯纭殑鍓嶅悗绉诲姩鐨勪袱涓偣鐨勫潗鏍囧�硷紝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 = {} + // 鐘舵�佹爮楂樺害锛岀敱浜庢煇浜涘畨鍗撳拰寰俊寮�鍙戝伐鍏锋棤娉曡瘑鍒玞ss鐨勯《閮ㄧ姸鎬佹爮鍙橀噺锛屾墍浠ヤ娇鐢╦s鑾峰彇鐨勬柟寮� + 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%锛屽鏋渘vue涓嬶紝鏄惧紡鍐�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蹇呴』瑕佹惌閰島-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-妯悜锛宑olumn-绔栧悜 (榛樿 '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骞冲彴锛孨avigationBar涓�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涓璸osition: sticky灞炴�у疄鐜扮殑鏁堟灉涓�鑷达紝褰撶粍浠惰揪鍒伴璁剧殑鍒伴《閮ㄨ窛绂绘椂锛� 灏变細鍥哄畾鍦ㄦ寚瀹氫綅缃紝缁勪欢浣嶇疆澶т簬棰勮鐨勯《閮ㄨ窛绂绘椂锛屼細閲嶆柊鎸夌収姝e父鐨勫竷灞�鎺掑垪銆� + * @tutorial https://www.uviewui.com/components/sticky.html + * @property {String 锝� Number} offsetTop 鍚搁《鏃朵笌椤堕儴鐨勮窛绂伙紝鍗曚綅px锛堥粯璁� 0 锛� + * @property {String 锝� Number} customNavHeight 鑷畾涔夊鑸爮鐨勯珮搴� 锛坔5 榛樿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鐨剆ticky瀹炵幇 + stickyTop: 0, // 鍚搁《鐨則op鍊硷紝鍥犱负鍙兘鍙楄嚜瀹氫箟瀵艰埅鏍忓奖鍝嶏紝鏈�缁堢殑鍚搁《鍊奸潪offsetTop鍊� + elId: uni.$u.guid(), + left: 0, // js妯″紡鏃讹紝鍚搁《鐨勫唴瀹瑰洜涓哄浜巔ostition: fixed妯″紡锛屼负浜嗗拰鍘熸潵淇濇寔涓�鑷寸殑鏍峰紡锛岄渶瑕佽褰曞苟閲嶆柊璁剧疆瀹冪殑left锛宧eight锛寃idth灞炴�� + 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鐨剆tatic闈欐�佹ā寮忓嵆鍙� + // #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() + // 濡傛灉涓嶆敮鎸乧ss sticky锛屽垯浣跨敤js鏂规锛屾鏂规鎬ц兘姣斾笉涓奵ss鏂规 + if (!this.cssSticky) { + !this.disabled && this.initObserveContent() + } + }, + initObserveContent() { + // 鑾峰彇鍚搁《鍐呭鐨勯珮搴︼紝鐢ㄤ簬鍦╦s鍚搁《妯″紡鏃讹紝缁欑埗鍏冪礌涓�涓~鍏呴珮搴︼紝闃叉"濉岄櫡" + 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锛屼竴鑸兘鏄幇浠f祻瑙堝櫒锛屾槸鏀寔css sticky鐨勶紝杩欓噷浣跨敤鍒涘缓鍏冪礌鍡呮帰鐨勫舰寮忓垽鏂� + if (this.checkCssStickyForH5()) { + this.cssSticky = true + } + // #endif + + // 濡傛灉瀹夊崜鐗堟湰楂樹簬8.0锛屼緷鐒惰涓烘槸鏀寔css sticky鐨�(鍥犱负瀹夊崜7鍦ㄦ煇浜涙満鍨嬶紝鍙兘涓嶆敮鎸乻ticky) + 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涓婏紝浠巌os6寮�濮嬶紝閮芥槸鏀寔css sticky鐨� + if (uni.$u.os() === 'ios') { + this.cssSticky = true + } + + // nvue锛屾槸鏀寔css sticky鐨� + // #ifdef APP-NVUE + this.cssSticky = true + // #endif + }, + // 鍦ˋPP鍜屽井淇″皬绋嬪簭涓婏紝閫氳繃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閫氳繃鍒涘缓鍏冪礌鐨勫舰寮忓梾鎺㈡槸鍚︽敮鎸乧ss sticky + // 鍒ゆ柇娴忚鍣ㄦ槸鍚︽敮鎸乻ticky灞炴�� + 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 */ + // 姝ゅ榛樿鍐檚ticky灞炴�э紝鏄负浜嗙粰寰俊鍜孉PP閫氳繃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 + }, + // 褰撳墠娲诲姩鐨則ab鐨刬ndex + 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 + }, + // 妯″紡閫夋嫨锛宮ode=button涓烘寜閽舰寮忥紝mode=subsection鏃朵负鍒嗘妯″紡 + mode: { + type: String, + default: uni.$u.props.subsection.mode + }, + // 瀛椾綋澶у皬 + fontSize: { + type: [String, Number], + default: uni.$u.props.subsection.fontSize + }, + // 婵�娲籺ab鐨勫瓧浣撴槸鍚﹀姞绮� + bold: { + type: Boolean, + default: uni.$u.props.subsection.bold + }, + // mode = button鏃讹紝缁勪欢鑳屾櫙棰滆壊 + bgColor: { + type: String, + default: uni.$u.props.subsection.bgColor + }, + // 浠巐ist鍏冪礌瀵硅薄涓鍙栫殑閿悕 + 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 褰撳墠娲诲姩鐨則ab鐨刬ndex锛堥粯璁� 0 锛� + * @property {String} activeColor 婵�娲绘椂鐨勯鑹诧紙榛樿 '#3c9cff' 锛� + * @property {String} inactiveColor 鏈縺娲绘椂鐨勯鑹诧紙榛樿 '#303133' 锛� + * @property {String} mode 妯″紡閫夋嫨锛宮ode=button涓烘寜閽舰寮忥紝mode=subsection鏃朵负鍒嗘妯″紡锛堥粯璁� 'button' 锛� + * @property {String 锝� Number} fontSize 瀛椾綋澶у皬锛屽崟浣峱x锛堥粯璁� 12 锛� + * @property {Boolean} bold 婵�娲婚�夐」鐨勫瓧浣撴槸鍚﹀姞绮楋紙榛樿 true 锛� + * @property {String} bgColor 缁勪欢鑳屾櫙棰滆壊锛宮ode涓篵utton鏃舵湁鏁堬紙榛樿 '#eeeeef' 锛� + * @property {Object} customStyle 瀹氫箟闇�瑕佺敤鍒扮殑澶栭儴鏍峰紡 + * @property {String} keyName 浠巂list`鍏冪礌瀵硅薄涓鍙栫殑閿悕锛堥粯璁� 'name' 锛� + * + * @event {Function} change 鍒嗘鍣ㄩ�夐」鍙戠敓鏀瑰彉鏃惰Е鍙� 鍥炶皟 index锛氶�夐」鐨刬ndex绱㈠紩鍊硷紝浠�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 + // 鍦ㄥ畨鍗搉vue涓婏紝濡傛灉閫氳繃translateX杩涜浣嶇Щ锛屽埌鏈�鍚庝竴涓椂锛屼細瀵艰嚧鍙充晶鏃犳硶缁樺埗鍦嗚 + // 鏁呯敤animation妯″潡杩涜浣嶇Щ + const ref = this.$refs?.["u-subsection__bar"]?.ref; + // 涓嶅瓨鍦╮ef鐨勬椂鍊�(鐞嗚В涓虹涓�娆″垵濮嬪寲鏃讹紝闇�瑕佹覆鏌揹om锛岃繘琛屼竴瀹氬欢鏃跺啀鑾峰彇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") { + // 鍦╯ubsection妯″紡涓嬶紝闇�瑕佸姩鎬佽缃粦鍧楃殑鍦嗚锛屽洜涓虹Щ鍔ㄦ粦鍧椾娇鐢ㄧ殑鏄痶ranslateX锛屾棤娉曢�氳繃鐖跺厓绱犺缃畂verflow: hidden闅愯棌婊戝潡鐨勭洿瑙� + style.backgroundColor = this.activeColor; + } + return style; + }, + // 鍒嗘鍣╥tem鐨勬牱寮� + 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妯″紡涓嬶紝婵�娲绘椂鏂囧瓧棰滆壊榛樿涓篴ctiveColor + 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灏忕▼搴忎互鍙奌5骞冲彴 + * wxs鍐呴儴涓嶆敮鎸乪s6璇硶锛屽彉閲忓彧鑳戒娇鐢╲ar瀹氫箟锛屾棤娉曚娇鐢ㄨВ鏋勶紝绠ご鍑芥暟绛夌壒鎬� + */ + +// 寮�濮嬭Е鎽� +function touchstart(event, ownerInstance) { + // 瑙﹀彂浜嬩欢鐨勭粍浠剁殑ComponentDescriptor瀹炰緥 + var instance = event.instance + // wxs鍐呯殑灞�閮ㄥ彉閲忓揩鐓э紝姝ゅ揩鐓ф槸灞炰簬鏁翠釜缁勪欢鐨勶紝鍦╰ouchstart鍜宼ouchmove浜嬩欢涓兘鑳借幏鍙栧埌鐩稿悓鐨勭粨鏋� + 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 + + // 绉诲姩鐨刋杞磋窛绂诲ぇ浜嶻杞磋窛绂伙紝涔熷嵆缁堢偣涓庤捣鐐逛綅缃繛绾匡紝涓嶺杞村す瑙掑皬浜�45搴︽椂锛岀姝㈤〉闈㈡粴鍔� + if (Math.abs(moveX) > Math.abs(moveY) || Math.abs(moveX) > state.threshold) { + event.preventDefault() + event.stopPropagation() + } + // 濡傛灉绉诲姩鐨刋杞磋窛绂诲皬浜嶻杞磋窛绂伙紝涔熷嵆缁堢偣浣嶇疆涓庤捣鐐逛綅缃繛绾匡紝涓嶻杞村す瑙掑皬浜�45搴︽椂锛岃涓烘槸椤甸潰涓婁笅婊戝姩锛岃�屼笉鏄乏鍙虫粦鍔ㄥ崟鍏冩牸 + if (Math.abs(moveX) < Math.abs(moveY)) return + + // 闄愬埗鍙虫粦鐨勮窛绂伙紝涓嶅厑璁稿唴瀹归儴鍒嗗線鍙冲亸绉伙紝鍙虫粦浼氬鑷碭杞村亸绉诲�煎ぇ浜�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) + // 灞曞紑杩囩▼涓紝鏄悜宸︾Щ鍔紝鎵�浠鐨勫亸绉诲簲璇ヤ负璐熷�� + 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-宸茬粡鎵撳紑锛宑lose-宸茬粡鍏抽棴 +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灏忕▼搴忎互鍙奌5骞冲彴 + * wxs鍐呴儴涓嶆敮鎸乪s6璇硶锛屽彉閲忓彧鑳戒娇鐢╲ar瀹氫箟锛屾棤娉曚娇鐢ㄨВ鏋勶紝绠ご鍑芥暟绛夌壒鎬� + */ + +// 寮�濮嬭Е鎽� +function touchstart(event, ownerInstance) { + // 瑙﹀彂浜嬩欢鐨勭粍浠剁殑ComponentDescriptor瀹炰緥 + var instance = event.instance + // wxs鍐呯殑灞�閮ㄥ彉閲忓揩鐓э紝姝ゅ揩鐓ф槸灞炰簬鏁翠釜缁勪欢鐨勶紝鍦╰ouchstart鍜宼ouchmove浜嬩欢涓兘鑳借幏鍙栧埌鐩稿悓鐨勭粨鏋� + 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 + + // 绉诲姩鐨刋杞磋窛绂诲ぇ浜嶻杞磋窛绂伙紝涔熷嵆缁堢偣涓庤捣鐐逛綅缃繛绾匡紝涓嶺杞村す瑙掑皬浜�45搴︽椂锛岀姝㈤〉闈㈡粴鍔� + if (Math.abs(moveX) > Math.abs(moveY) || Math.abs(moveX) > state.threshold) { + event.preventDefault && event.preventDefault() + event.stopPropagation && event.stopPropagation() + } + // 濡傛灉绉诲姩鐨刋杞磋窛绂诲皬浜嶻杞磋窛绂伙紝涔熷嵆缁堢偣浣嶇疆涓庤捣鐐逛綅缃繛绾匡紝涓嶻杞村す瑙掑皬浜�45搴︽椂锛岃涓烘槸椤甸潰涓婁笅婊戝姩锛岃�屼笉鏄乏鍙虫粦鍔ㄥ崟鍏冩牸 + if (Math.abs(moveX) < Math.abs(moveY)) return + + // 闄愬埗鍙虫粦鐨勮窛绂伙紝涓嶅厑璁稿唴瀹归儴鍒嗗線鍙冲亸绉伙紝鍙虫粦浼氬鑷碭杞村亸绉诲�煎ぇ浜�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) + // 灞曞紑杩囩▼涓紝鏄悜宸︾Щ鍔紝鎵�浠鐨勫亸绉诲簲璇ヤ负璐熷�� + 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-宸茬粡鎵撳紑锛宑lose-宸茬粡鍏抽棴 +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鐨勫簱锛岀敤浜庤幏鍙杁om鐨勫昂瀵镐俊鎭� +const dom = uni.requireNativePlugin('dom') +// nvue涓敤浜庢搷浣滃厓绱犲姩鐢荤殑搴擄紝绫讳技浜巙ni.animation锛屽彧涓嶈繃uni.animation涓嶈兘鐢ㄤ簬nvue +const animation = uni.requireNativePlugin('animation') + +export default { + data() { + return { + // 鏄惁婊戝姩涓� + moving: false, + // 鐘舵�侊紝open-鎵撳紑鐘舵�侊紝close-鍏抽棴鐘舵�� + status: 'close', + // 寮�濮嬭Е鎽哥偣鐨刋鍜孻杞村潗鏍� + startX: 0, + startY: 0, + // 鎵�鏈夐殣钘忔寜閽殑灏哄淇℃伅鏁扮粍 + buttons: [], + // 鎵�鏈夋寜閽殑鎬诲搴� + buttonsWidth: 0, + // 璁板綍涓婁竴娆$Щ鍔ㄧ殑浣嶇疆鍊� + moveX: 0, + // 璁板綍涓婁竴娆℃粦鍔ㄧ殑浣嶇疆锛岀敤浜庡墠鍚庝袱娆″仛瀵规瘮锛屽鏋滅Щ鍔ㄧ殑璺濈灏忎簬鏌愪竴闃堝�硷紝鍒欒涓哄墠鍚庝箣闂存病鏈夌Щ鍔紝涓轰簡瑙e喅鍙兘瀛樺湪鐨勯�氫俊闃诲闂 + 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 + + // 绉诲姩鐨刋杞磋窛绂诲ぇ浜嶻杞磋窛绂伙紝涔熷嵆缁堢偣涓庤捣鐐逛綅缃繛绾匡紝涓嶺杞村す瑙掑皬浜�45搴︽椂锛岀姝㈤〉闈㈡粴鍔� + if (Math.abs(moveX) > Math.abs(moveY) || Math.abs(moveX) > this.threshold) { + event.stopPropagation() + } + // 濡傛灉绉诲姩鐨刋杞磋窛绂诲皬浜嶻杞磋窛绂伙紝涔熷嵆缁堢偣浣嶇疆涓庤捣鐐逛綅缃繛绾匡紝涓嶻杞村す瑙掑皬浜�45搴︽椂锛岃涓烘槸椤甸潰涓婁笅婊戝姩锛岃�屼笉鏄乏鍙虫粦鍔ㄥ崟鍏冩牸 + if (Math.abs(moveX) < Math.abs(moveY)) return + + // 闄愬埗鍙虫粦鐨勮窛绂伙紝涓嶅厑璁稿唴瀹归儴鍒嗗線鍙冲亸绉伙紝鍙虫粦浼氬鑷碭杞村亸绉诲�煎ぇ浜�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杩斿洖涓�涓猵romise + 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鐨刣om妯″潡锛屾煡璇㈣妭鐐逛俊鎭� + 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鐨勫簱锛岀敤浜庤幏鍙杁om鐨勫昂瀵镐俊鎭� +const dom = uni.requireNativePlugin('dom'); +const bindingX = uni.requireNativePlugin('bindingx'); +const animation = uni.requireNativePlugin('animation'); + +export default { + data() { + return { + // 鎵�鏈夋寜閽殑鎬诲搴� + buttonsWidth: 0, + // 鏄惁姝e湪绉诲姩涓� + 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) { + // 濡傛灉褰撳墠姝e湪绉诲姩涓紝鎴栬�卍isabled鐘舵�侊紝鍒欒繑鍥� + 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杩斿洖涓�涓猵romise + 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鐨刣om妯″潡锛屾煡璇㈣妭鐐逛俊鎭� + 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 + }, + // 鏍囪瘑绗︼紝濡傛灉鏄痸-for锛屽彲鐢╥ndex绱㈠紩鍊� + 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 + } + }, + // 鍔ㄧ敾杩囨浮鏃堕棿锛屽崟浣峬s + 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 鏍囪瘑绗︼紝濡傛灉鏄痸-for锛屽彲鐢╥ndex绱㈠紩 + * @property {Boolean} disabled 鏄惁绂佺敤锛堥粯璁� false 锛� + * @property {Boolean} autoClose 鏄惁鑷姩鍏抽棴鍏朵粬swipe鎸夐挳缁勶紙榛樿 true 锛� + * @property {Number} threshold 婊戝姩璺濈闃堝�硷紝鍙湁澶т簬姝ゅ�硷紝鎵嶈璁や负鏄鎵撳紑鑿滃崟锛堥粯璁� 30 锛� + * @property {Array} options 鍙充晶鎸夐挳鍐呭 + * @property {String | Number} duration 鍔ㄧ敾杩囨浮鏃堕棿锛屽崟浣峬s锛堥粯璁� 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: {}, + // 鐖剁粍浠秛-swipe-action鐨勫弬鏁� + parentData: { + autoClose: true, + }, + // 褰撳墠鐘舵�侊紝open-鎵撳紑锛宑lose-鍏抽棴 + 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鐨勫彉閲忥紝閮芥槸瀛愮粍浠秛-swipe-action-item闇�瑕佺敤鍒扮殑锛岀敱浜庡ご鏉″皬绋嬪簭鐨勫吋瀹规�у樊寮傦紝瀛愮粍浠舵棤娉曞疄鏃剁洃鍚埗缁勪欢鍙傛暟鐨勫彉鍖� + // 鎵�浠ラ渶瑕佹墜鍔ㄩ�氱煡瀛愮粍浠讹紝杩欓噷杩斿洖涓�涓猵arentData鍙橀噺锛屼緵watch鐩戝惉锛屽湪鍏朵腑鍘婚�氱煡姣忎竴涓瓙缁勪欢閲嶆柊浠庣埗缁勪欢(u-swipe-action-item) + // 鎷夊彇鐖剁粍浠舵柊鐨勫彉鍖栧悗鐨勫弬鏁� + parentData() { + return [this.autoClose] + } + }, + watch: { + // 褰撶埗缁勪欢闇�瑕佸瓙缁勪欢闇�瑕佸叡浜殑鍙傛暟鍙戠敓浜嗗彉鍖栵紝鎵嬪姩閫氱煡瀛愮粍浠� + parentData() { + if (this.children.length) { + this.children.map(child => { + // 鍒ゆ柇瀛愮粍浠�(u-swipe-action-item)濡傛灉鏈塽pdateParentData鏂规硶鐨勮瘽锛屽氨灏辨墽琛�(鎵ц鐨勭粨鏋滄槸瀛愮粍浠堕噸鏂颁粠鐖剁粍浠舵媺鍙栦簡鏈�鏂扮殑鍊�) + 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-绾垮瀷锛宒ot-鐐瑰瀷 + 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锛宭eft锛宺ight杩涜瀹氫綅 + indicatorStyle: { + type: [String, Object], + default: uni.$u.props.swiper.indicatorStyle + }, + // 鎸囩ず鍣ㄦā寮忥紝line-绾垮瀷锛宒ot-鐐瑰瀷 + 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銆乴inear銆乪aseInCubic銆乪aseOutCubic銆乪aseInOutCubic + // 鍙寰俊灏忕▼搴忔湁鏁� + 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 + }, + // 鏄惁鏄剧ず鏍囬锛岃姹傛暟缁勫璞′腑鏈塼itle灞炴�� + 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)]" + > + <!-- 鍦╪vue涓紝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锛宭eft锛宺ight杩涜瀹氫綅 + * @property {String} indicatorMode 鎸囩ず鍣ㄦā寮忥紙榛樿 'line' 锛� + * @property {Boolean} autoplay 鏄惁鑷姩鍒囨崲锛堥粯璁� true 锛� + * @property {String | Number} current 褰撳墠鎵�鍦ㄦ粦鍧楃殑 index锛堥粯璁� 0 锛� + * @property {String} currentItemId 褰撳墠鎵�鍦ㄦ粦鍧楃殑 item-id 锛屼笉鑳戒笌 current 琚悓鏃舵寚瀹� + * @property {String | Number} interval 婊戝潡鑷姩鍒囨崲鏃堕棿闂撮殧锛坢s锛夛紙榛樿 3000 锛� + * @property {String | Number} duration 婊戝潡鍒囨崲杩囩▼鎵�闇�鏃堕棿锛坢s锛夛紙榛樿 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 鏄惁鏄剧ず鏍囬锛岃姹傛暟缁勫璞′腑鏈塼itle灞炴�э紙榛樿 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() + } + }, + // 褰撲竴涓疆鎾璱tem涓鸿棰戞椂锛岃幏鍙栧畠鐨勮棰戞捣鎶� + 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 鍦╯witch鎵撳紑鎴栧叧闂椂瑙﹀彂 + * @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銆乤ctiveValue浜岃�呬箣涓�') + } + } + } + }, + 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 = {} + // 濡傛灉鑷畾涔夐潪婵�娲婚鑹诧紝灏唍ode鍦嗙偣鐨勫昂瀵稿噺灏戜袱涓儚绱狅紝璁╁叾涓庡杈规璺濈鏇村ぇ涓�鐐� + 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 = {} + // 杩欓噷閰嶇疆涓�涓浣欑殑鍏冪礌鍦℉TML涓紝鏄负浜嗚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) + } + // 鏀惧埌涓嬩竴涓敓鍛藉懆鏈燂紝鍥犱负鍙屽悜缁戝畾鐨剉alue淇敼鐖剁粍浠剁姸鎬侀渶瑕佹椂闂达紝涓旀槸寮傛鐨� + 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椤圭洰锛屽鑷碽ug濂囧锛岃繖蹇呴』瑕佸啓杩欎竴琛岋紝 + // 鍚﹀垯鍦╥OS涓婏紝鐐瑰嚮椤甸潰浠绘剰鍦版柟锛岄兘浼氳Е鍙憇witch鐨勭偣鍑讳簨浠� + 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鏍囩鐨勫悕绉帮紝浣滀负涓巙-tabbar鐨剉alue鍙傛暟鍖归厤鐨勬爣璇嗙 + 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 + }, + // 鏄惁鏄剧ず鍦嗙偣锛屽皢浼氳鐩朾adge鍙傛暟 + dot: { + type: Boolean, + default: uni.$u.props.tabbarItem.dot + }, + // 鎻忚堪鏂囨湰 + text: { + type: String, + default: uni.$u.props.tabbarItem.text + }, + // 鎺у埗寰芥爣鐨勪綅缃紝瀵硅薄鎴栬�呭瓧绗︿覆褰㈠紡锛屽彲浠ヨ缃畉op鍜宺ight灞炴�� + 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 姝ょ粍浠舵彁渚涗簡鑷畾涔塼abbar鐨勮兘鍔涖�� + * @tutorial https://www.uviewui.com/components/tabbar.html + * @property {String | Number} name item鏍囩鐨勫悕绉帮紝浣滀负涓巙-tabbar鐨剉alue鍙傛暟鍖归厤鐨勬爣璇嗙 + * @property {String} icon uView鍐呯疆鍥炬爣鎴栬�呯粷瀵硅矾寰勭殑鍥剧墖 + * @property {String | Number} badge 鍙充笂瑙掔殑瑙掓爣鎻愮ず淇℃伅 + * @property {Boolean} dot 鏄惁鏄剧ず鍦嗙偣锛屽皢浼氳鐩朾adge鍙傛暟锛堥粯璁� false 锛� + * @property {String} text 鎻忚堪鏂囨湰 + * @property {Object | String} badgeStyle 鎺у埗寰芥爣鐨勪綅缃紝瀵硅薄鎴栬�呭瓧绗︿覆褰㈠紡锛屽彲浠ヨ缃畉op鍜宺ight灞炴�э紙榛樿 '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() { + // 鏀粯瀹濆皬绋嬪簭涓嶆敮鎸乸rovide/inject锛屾墍浠ヤ娇鐢ㄨ繖涓柟娉曡幏鍙栨暣涓埗缁勪欢锛屽湪created瀹氫箟锛岄伩鍏嶅惊鐜紩鐢� + this.updateParentData() + if (!this.parent) { + uni.$u.error('u-tabbar-item蹇呴』鎼厤u-tabbar缁勪欢浣跨敤') + } + // 鏈瓙缁勪欢鍦╱-tabbar鐨刢hildren鏁扮粍涓殑绱㈠紩 + const index = this.parent.children.indexOf(this) + // 鍒ゆ柇鏈粍浠剁殑name(濡傛灉娌℃湁瀹氫箟name锛屽氨鐢╥ndex绱㈠紩)鏄惁绛変簬鐖剁粍浠剁殑value鍙傛暟 + this.isActive = (this.name || index) === this.parentData.value + }, + updateParentData() { + // 姝ゆ柟娉曞湪mixin涓� + this.getParentData('u-tabbar') + }, + // 姝ゆ柟娉曞皢浼氳鐖剁粍浠秛-tabbar璋冪敤 + updateFromParent() { + // 閲嶆柊鍒濆鍖� + this.init() + }, + clickHandler() { + this.$nextTick(() => { + const index = this.parent.children.indexOf(this) + const name = this.name || index + // 鐐瑰嚮鐨刬tem涓洪潪婵�娲荤殑item鎵嶅彂鍑篶hange浜嬩欢 + 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 + }, + // 鏄惁涓篿PhoneX鐣欏嚭搴曢儴瀹夊叏璺濈 + 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 姝ょ粍浠舵彁渚涗簡鑷畾涔塼abbar鐨勮兘鍔涖�� + * @tutorial https://www.uviewui.com/components/tabbar.html + * @property {String | Number} value 褰撳墠鍖归厤椤圭殑name + * @property {Boolean} safeAreaInsetBottom 鏄惁涓篿PhoneX鐣欏嚭搴曢儴瀹夊叏璺濈锛堥粯璁� 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)) + }, + // 鐩戝惉澶氫釜鍙傛暟鐨勫彉鍖栵紝閫氳繃鍦╟omputed鎵ц瀵瑰簲鐨勬搷浣� + updateChild() { + return [this.value, this.activeColor, this.inactiveColor] + }, + updatePlaceholder() { + return [this.fixed, this.placeholder] + } + }, + watch: { + updateChild() { + // 濡傛灉updateChildren涓殑鍏冪礌鍙戠敓浜嗗彉鍖栵紝鍒欐墽琛屽瓙鍏冪礌鍒濆鍖栨搷浣� + this.updateChildren() + }, + updatePlaceholder() { + // 濡傛灉fixed锛宲laceholder绛夊弬鏁板彂鐢熷彉鍖栵紝閲嶆柊璁$畻鍗犱綅鍏冪礌鐨勯珮搴� + this.setPlaceholderHeight() + } + }, + created() { + this.children = [] + }, + mounted() { + this.setPlaceholderHeight() + }, + methods: { + updateChildren() { + // 濡傛灉瀛樺湪瀛愬厓绱狅紝鍒欐墽琛屽瓙鍏冪礌鐨剈pdateFromParent杩涜鏇存柊鏁版嵁 + 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 琛ㄦ牸缁勪欢涓�鑸敤浜庡睍绀哄ぇ閲忕粨鏋勫寲鏁版嵁鐨勫満鏅� 鏈粍浠舵爣绛剧被浼糎TML鐨則able琛ㄦ牸锛岀敱table銆乼r銆乼h銆乼d鍥涗釜缁勪欢缁勬垚 + * @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涓嬶紝鏃犳硶鍦╯tyle鏍峰紡涓�氳繃!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); + // 鑾峰彇涓嬪垝绾跨殑鏁板�紁x琛ㄧず娉� + 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 + + // 濡傛灉鏄涓�娆℃墽琛屾鏂规硶锛岃婊戝潡鍦ㄥ垵濮嬪寲鏃讹紝鐬棿婊戝姩鍒扮涓�涓猼ab item鐨勪腑闂� + // 杩欓噷闇�瑕佷竴涓畾鏃跺櫒锛屽洜涓哄湪闈瀗vue涓嬶紝鏄洿鎺ラ�氳繃style缁戝畾杩囨浮鏃堕棿锛岄渶瑕佺瓑鍏惰繃娓″畬鎴愬悗锛屽啀璁剧疆涓篺alse(闈炵涓�娆$Щ鍔ㄦ粦鍧�) + 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) { + // 鍥犱负鏍囩鍙兘涓篸isabled鐘舵�侊紝鎵�浠lick鏄竴瀹氫細鍙戝嚭鐨勶紝浣嗘槸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鑿滃崟鐨剋idth鍜宭eft(涓哄厓绱犲乏杈圭晫鍒扮埗鍏冪礌宸﹁竟鐣岀殑璺濈)绛変俊鎭� + 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() { + // 濡傛灉涓嶅瓨鍦╨ist锛屽垯涓嶅鐞� + 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 + // 鍙﹀璁$畻姣忎竴涓猧tem鐨勪腑蹇冪偣X杞村潗鏍� + this.list[index].rect = item + }) + // 鑾峰彇浜唗abs鐨勫昂瀵镐箣鍚庯紝璁剧疆婊戝潡鐨勪綅缃� + 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涓簎View鑷甫鐨勮妭鐐规煡璇㈢畝鍖栨柟娉曪紝璇﹁鏂囨。浠嬬粛锛歨ttps://www.uviewui.com/js/getRect.html + // 缁勪欢鍐呴儴涓�鑸敤this.$uGetRect锛屽澶栫殑涓簎ni.$u.getRect锛屼簩鑰呭姛鑳戒竴鑷达紝鍚嶇О涓嶅悓 + return new Promise(resolve => { + this.$uGetRect(`.${el}`).then(size => { + resolve(size) + }) + }) + // #endif + + // #ifdef APP-NVUE + // nvue涓嬶紝浣跨敤dom妯″潡鏌ヨ鍏冪礌楂樺害 + // 杩斿洖涓�涓猵romise锛岃璋冪敤姝ゆ柟娉曠殑涓讳綋鑳戒娇鐢╰hen鍥炶皟 + 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銆乸rimary銆乻uccess銆亀arning銆乪rror + type: { + type: String, + default: uni.$u.props.tag.type + }, + // 涓嶅彲鐢� + disabled: { + type: [Boolean, String], + default: uni.$u.props.tag.disabled + }, + // 鏍囩鐨勫ぇ灏忥紝large锛宮edium锛宮ini + 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 + }, + // // 妯″紡閫夋嫨锛宒ark|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銆乸rimary銆乻uccess銆亀arning銆乪rror 锛堥粯璁� 'primary' 锛� + * @property {Boolean | String} disabled 涓嶅彲鐢紙榛樿 false 锛� + * @property {String} size 鏍囩鐨勫ぇ灏忥紝large锛宮edium锛宮ini 锛堥粯璁� '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 鏄惁鍙叧闂紝璁剧疆涓簍rue锛屾枃瀛楀彸杈逛細鍑虹幇涓�涓叧闂浘鏍囷紙榛樿 false 锛� + * @property {Boolean} show 鏍囩鏄剧ず涓庡惁锛堥粯璁� true 锛� + * @property {String} icon 鍐呯疆鍥炬爣锛屾垨缁濆璺緞鐨勫浘鐗� + * @event {Function(index)} click 鐐瑰嚮鏍囩鏃惰Е鍙� index: 浼犻�掔殑index鍙傛暟鍊� + * @event {Function(index)} close closable涓簍rue鏃讹紝鐐瑰嚮鏍囩鍏抽棴鎸夐挳瑙﹀彂 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-浠锋牸锛宲hone-鎵嬫満鍙凤紝name-濮撳悕锛宒ate-鏃ユ湡锛宭ink-瓒呴摼鎺� + 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 + }, + // 鏄惁绮椾綋锛岄粯璁ormal + 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 + }, + // 鏂囨湰瀵归綈鏂瑰紡锛屽彲閫夊�糽eft|center|right + align: { + type: String, + default: uni.$u.props.text.align + }, + // 鏂囧瓧鎹㈣锛屽彲閫夊�糱reak-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-浠锋牸锛宲hone-鎵嬫満鍙凤紝name-濮撳悕锛宒ate-鏃ユ湡锛宭ink-瓒呴摼鎺� + * @property {String} href mode=link涓嬶紝閰嶇疆鐨勯摼鎺� + * @property {String | Function} format 鏍煎紡鍖栬鍒� + * @property {Boolean} call mode=phone鏃讹紝鐐瑰嚮鏂囨湰鏄惁鎷ㄦ墦鐢佃瘽锛堥粯璁� false 锛� + * @property {String} openType 灏忕▼搴忕殑鎵撳紑鏂瑰紡 + * @property {Boolean} bold 鏄惁绮椾綋锛岄粯璁ormal锛堥粯璁� 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 鏂囨湰瀵归綈鏂瑰紡锛屽彲閫夊�糽eft|center|right锛堥粯璁� 'left' 锛� + * @property {String} wordWrap 鏂囧瓧鎹㈣锛屽彲閫夊�糱reak-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鍙傛暟闇�瑕佷负閲戦鏍煎紡'); + } + // 杩涜鏍煎紡鍖栵紝鍒ゆ柇鐢ㄦ埛浼犲叆鐨刦ormat鍙傛暟涓烘鍒欙紝鎴栬�呭嚱鏁帮紝濡傛灉娌℃湁浼犲叆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鍙傛暟闇�瑕佷负鏃ユ湡鎴栨椂闂存埑鏍煎紡') + // 杩涜鏍煎紡鍖栵紝鍒ゆ柇鐢ㄦ埛浼犲叆鐨刦ormat鍙傛暟涓烘鍒欙紝鎴栬�呭嚱鏁帮紝濡傛灉娌℃湁浼犲叆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('鎵嬫満鍙锋ā寮忎笅锛宼ext鍙傛暟闇�瑕佷负鎵嬫満鍙风爜鏍煎紡') + if (uni.$u.test.func(format)) { + // 濡傛灉鐢ㄦ埛浼犲叆鐨勬槸鍑芥暟锛屼娇鐢ㄥ嚱鏁版牸寮忓寲 + return format(text) + } if (format === 'encrypt') { + // 濡傛灉format涓篹ncrypt锛屽垯灏嗘墜鏈哄彿杩涜鏄熷彿鍔犲瘑澶勭悊 + 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涓篹ncrypt锛屽垯灏嗗鍚嶈繘琛屾槦鍙峰姞瀵嗗鐞� + return this.formatName(text) + } + return text + } if (mode === 'link') { + // 鍒ゆ柇鏄惁鍚堟硶鐨勫瓧绗︾矖 + !uni.$u.test.url(href) && uni.$u.error('瓒呴摼鎺ユā寮忎笅锛宧ref鍙傛暟闇�瑕佷负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鐨勬牱寮忕被锛屾敞鎰忛〉闈㈡垨缁勪欢鐨剆tyle涓啓浜唖coped鏃讹紝闇�瑕佸湪绫诲悕鍓嶅啓/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鍜孒5鏈夋晥 + 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 + }, + // 鏄惁鑷姩鑾峰彇鐒︾偣锛宯vue涓嶆敮鎸侊紝H5鍙栧喅浜庢祻瑙堝櫒鐨勫疄鐜� + focus: { + type: Boolean, + default: uni.$u.props.textarea.focus + }, + // 鏄惁鑷姩澧炲姞楂樺害 + autoHeight: { + type: Boolean, + default: uni.$u.props.textarea.autoHeight + }, + // 濡傛灉textarea鏄湪涓�涓猵osition:fixed鐨勫尯鍩燂紝闇�瑕佹樉绀烘寚瀹氬睘鎬ixed涓簍rue + 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 + }, + // 鍏夋爣璧峰浣嶇疆锛岃嚜鍔ㄨ仛鐒︽椂鏈夋晥锛岄渶涓巗election-end鎼厤浣跨敤 + selectionStart: { + type: Number, + default: uni.$u.props.textarea.selectionStart + }, + // 鍏夋爣缁撴潫浣嶇疆锛岃嚜鍔ㄨ仛鐒︽椂鏈夋晥锛岄渶涓巗election-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 + }, + // 杈规绫诲瀷锛宻urround-鍥涘懆杈规锛宐ottom-搴曢儴杈规 + 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鐨勬牱寮忕被锛屾敞鎰忛〉闈㈡垨缁勪欢鐨剆tyle涓啓浜唖coped鏃讹紝闇�瑕佸湪绫诲悕鍓嶅啓/deep/ 锛� 榛樿 'input-placeholder' 锛� + * @property {String | Object} placeholderStyle 鎸囧畾placeholder鐨勬牱寮忥紝瀛楃涓�/瀵硅薄褰㈠紡锛屽"color: red;" + * @property {String | Number} height 杈撳叆妗嗛珮搴︼紙榛樿 70 锛� + * @property {String} confirmType 璁剧疆閿洏鍙充笅瑙掓寜閽殑鏂囧瓧锛屼粎寰俊灏忕▼搴忥紝App-vue鍜孒5鏈夋晥锛堥粯璁� 'done' 锛� + * @property {Boolean} disabled 鏄惁绂佺敤锛堥粯璁� false 锛� + * @property {Boolean} count 鏄惁鏄剧ず缁熻瀛楁暟锛堥粯璁� false 锛� + * @property {Boolean} focus 鏄惁鑷姩鑾峰彇鐒︾偣锛宯vue涓嶆敮鎸侊紝H5鍙栧喅浜庢祻瑙堝櫒鐨勫疄鐜帮紙榛樿 false 锛� + * @property {Boolean | Function} autoHeight 鏄惁鑷姩澧炲姞楂樺害锛堥粯璁� false 锛� + * @property {Boolean} fixed 濡傛灉textarea鏄湪涓�涓猵osition:fixed鐨勫尯鍩燂紝闇�瑕佹樉绀烘寚瀹氬睘鎬ixed涓簍rue锛堥粯璁� false 锛� + * @property {Number} cursorSpacing 鎸囧畾鍏夋爣涓庨敭鐩樼殑璺濈锛堥粯璁� 0 锛� + * @property {String | Number} cursor 鎸囧畾focus鏃剁殑鍏夋爣浣嶇疆 + * @property {Function} formatter 鍐呭寮忓寲鍑芥暟 + * @property {Boolean} showConfirmBar 鏄惁鏄剧ず閿洏涓婃柟甯︽湁鈥濆畬鎴愨�滄寜閽偅涓�鏍忥紝锛堥粯璁� true 锛� + * @property {Number} selectionStart 鍏夋爣璧峰浣嶇疆锛岃嚜鍔ㄨ仛鐒︽椂鏈夋晥锛岄渶涓巗election-end鎼厤浣跨敤锛岋紙榛樿 -1 锛� + * @property {Number | Number} selectionEnd 鍏夋爣缁撴潫浣嶇疆锛岃嚜鍔ㄨ仛鐒︽椂鏈夋晥锛岄渶涓巗election-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 杈规绫诲瀷锛宻urround-鍥涘懆杈规锛宯one-鏃犺竟妗嗭紝bottom-搴曢儴杈规锛堥粯璁� 'surround' 锛� + * @property {Boolean} ignoreCompositionEvent 鏄惁蹇界暐缁勪欢鍐呭鏂囨湰鍚堟垚绯荤粺浜嬩欢鐨勫鐞� + * + * @event {Function(e)} focus 杈撳叆妗嗚仛鐒︽椂瑙﹀彂锛宔vent.detail = { value, height }锛宧eight 涓洪敭鐩橀珮搴� + * @event {Function(e)} blur 杈撳叆妗嗗け鍘荤劍鐐规椂瑙﹀彂锛宔vent.detail = {value, cursor} + * @event {Function(e)} linechange 杈撳叆妗嗚鏁板彉鍖栨椂璋冪敤锛宔vent.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鏄惁绗竴娆″彉鍖栵紝鍦╳atch涓紝鐢变簬鍔犲叆immediate灞炴�э紝浼氬湪绗竴娆¤Е鍙戯紝姝ゆ椂涓嶅簲璇ヨ涓簐alue鍙戠敓浜嗗彉鍖� + firstChange: true, + // value缁戝畾鍊肩殑鍙樺寲鏄敱鍐呴儴杩樻槸澶栭儴寮曡捣鐨� + changeFromInner: false, + // 杩囨护澶勭悊鏂规硶 + innerFormatter: value => value + } + }, + watch: { + value: { + immediate: true, + handler(newVal, oldVal) { + this.innerValue = newVal; + /* #ifdef H5 */ + // 鍦℉5涓紝澶栭儴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鍦ㄥ畨鍗搉vue涓婄殑宸紓鎬э紝闇�瑕侀澶栧啀璋冩暣鍏跺唴杈硅窛 + 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鐨勫崟鍚戞暟鎹祦鐗规�э紝闇�瑕佸厛灏唅nnerValue鍊艰缃负褰撳墠鍊硷紝鍐嶅湪$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 姝ょ粍浠惰〃鐜板舰寮忕被浼紆ni鐨剈ni.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 灞曠ず鏃堕棿锛屽崟浣峬s 锛堥粯璁� 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锛屽闇�涓�杩涘叆椤甸潰灏辨樉绀簍oast锛岃鍦╫nReady鐢熷懡鍛ㄦ湡璋冪敤 + * @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: '', // 涓婚绫诲瀷锛宲rimary锛宻uccess锛宔rror锛寃arning锛宐lack + duration: 2000, // 鏄剧ず鐨勬椂闂达紝姣 + icon: true, // 鏄剧ず鐨勫浘鏍� + position: 'center', // toast鍑虹幇鐨勪綅缃� + complete: null, // 鎵ц瀹屽悗鐨勫洖璋冨嚱鏁� + overlay: false, // 鏄惁闃叉瑙︽懜绌块�� + loading: false, // 鏄惁鍔犺浇涓姸鎬� + }, + tmpConfig: {}, // 灏嗙敤鎴烽厤缃拰鍐呯疆閰嶇疆鍚堝苟鍚庣殑涓存椂閰嶇疆鍙橀噺 + } + }, + computed: { + iconName() { + // 鍙湁涓嶄负none锛屽苟涓攖ype涓篹rror|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鍙傛暟杩涜涓�涓�忔槑搴﹀鐞嗭紝璇ユ柟娉曡姹備紶鍏ョ殑棰滆壊鍊� + // 蹇呴』涓簉gb鏍煎紡鐨勶紝鎵�浠ヨ繖閲屽仛涓�涓鐞� + color = uni.$u.hexToRgb(uni.$u.color[this.tmpConfig.type]) + } + return color + }, + // 鍐呭鐩掑瓙鐨勬牱寮� + contentStyle() { + const windowHeight = uni.$u.sys().windowHeight, style = {} + let value = 0 + // 鏍规嵁top鍜宐ottom锛屽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() { + // 閫氳繃涓婚鐨勫舰寮忚皟鐢╰oast锛屾壒閲忕敓鎴愭柟娉曞嚱鏁� + ['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) { + // 涓嶅皢缁撴灉鍚堝苟鍒皌his.config鍙橀噺锛岄伩鍏嶅娆¤皟鐢╱-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 + }, + // 鐐瑰嚮澶嶅埗鎸夐挳鏃讹紝澶嶅埗鐨勬枃鏈紝涓虹┖鍒欎娇鐢╰ext鍊� + 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-涓婃柟锛宐ottom-涓嬫柟 + direction: { + type: String, + default: uni.$u.props.tooltip.direction + }, + // 寮瑰嚭鎻愮ず鐨剒-index锛宯vue鏃犳晥 + 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 鐐瑰嚮澶嶅埗鎸夐挳鏃讹紝澶嶅埗鐨勬枃鏈紝涓虹┖鍒欎娇鐢╰ext鍊� + * @property {String | Number} size 鏂囨湰澶у皬锛堥粯璁� 14 锛� + * @property {String} color 瀛椾綋棰滆壊锛堥粯璁� '#606266' 锛� + * @property {String} bgColor 寮瑰嚭鎻愮ず妗嗘椂锛屾枃鏈殑鑳屾櫙鑹诧紙榛樿 'transparent' 锛� + * @property {String} direction 寮瑰嚭鎻愮ず鐨勬柟鍚戯紝top-涓婃柟锛宐ottom-涓嬫柟锛堥粯璁� 'top' 锛� + * @property {String | Number} zIndex 寮瑰嚭鎻愮ず鐨剒-index锛宯vue鏃犳晥锛堥粯璁� 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娴忚鍣ㄦ槸鑷甫绯荤粺澶嶅埗鍔熻兘鐨勶紝鍦℉5鐜 + // 褰撲竴浜涗緷璧栧弬鏁板彉鍖栨椂锛岄渶瑕侀噸鏂拌绠楁皵娉″拰鎸囩ず鍣ㄧ殑浣嶇疆淇℃伅 + 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涓簎View鑷甫鐨勮妭鐐规煡璇㈢畝鍖栨柟娉曪紝璇﹁鏂囨。浠嬬粛锛歨ttps://www.uviewui.com/js/getRect.html + // 缁勪欢鍐呴儴涓�鑸敤this.$uGetRect锛屽澶栫殑涓簎ni.$u.getRect锛屼簩鑰呭姛鑳戒竴鑷达紝鍚嶇О涓嶅悓 + return new Promise(resolve => { + this.$uGetRect(`#${ref}`).then(size => { + resolve(size) + }) + }) + // #endif + + // #ifdef APP-NVUE + // nvue涓嬶紝浣跨敤dom妯″潡鏌ヨ鍏冪礌楂樺害 + // 杩斿洖涓�涓猵romise锛岃璋冪敤姝ゆ柟娉曠殑涓讳綋鑳戒娇鐢╰hen鍥炶皟 + 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瀛楁锛屽鏋滄病鏈夛紝鍒欓粯璁や娇鐢╰ext瀛楁褰撳仛澶嶅埗鐨勫唴瀹� + 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') + // 鍦ㄥ崟椤靛簲鐢ㄤ腑锛岄渶瑕侀攢姣丏OM鐨勭洃鍚� + clipboard.destroy() + }) + clipboard.on('error', (e) => { + this.showToast && uni.$u.toast('澶嶅埗澶辫触') + clipboard.off('success') + clipboard.off('error') + // 鍦ㄥ崟椤靛簲鐢ㄤ腑锛岄渶瑕侀攢姣丏OM鐨勭洃鍚� + 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 @@ +// 瀹氫箟涓�涓竴瀹氭椂闂村悗鑷姩鎴愬姛鐨刾romise锛岃璋冪敤nextTick鏂规硶澶勶紝杩涘叆涓嬩竴涓猼hen鏂规硶 +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)鐨刟nimation鍔ㄧ敾妯″潡锛屾枃妗h锛� +// 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(() => { + // 鍔ㄧ敾姝e湪绂诲満鐨勭姸鎬� + 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 + // 鍦╪vue瀹夊崜涓婏紝鐢变簬娓叉煋閫熷害鎱紝鍦ㄥ脊绐楋紝閿洏锛屾棩鍘嗙瓑缁勪欢涓紝娓叉煋鍏朵腑鐨勫唴瀹归渶瑕佹椂闂� + // 瀵艰嚧鍑虹幇寮圭獥鍗¢】锛岃繖閲岃鍏朵竴寮�濮嬩负閫忔槑鐘舵�侊紝绛変竴瀹氭椂闂存覆鏌撳畬鎴愬悗锛屽啀璁╁叾闅愯棌璧锋潵锛屽啀璁╁叾鎸夋甯搁�昏緫鍑虹幇 + this.viewStyle = { + opacity: 0 + } + // 绛夊緟寮圭獥鍐呭娓叉煋瀹屾垚 + this.$nextTick(() => { + // 鍚堝苟鏍峰紡 + this.viewStyle = currentStyle.enter + Promise.resolve() + .then(nextTick) + .then(() => { + // 缁勪欢寮�濮嬭繘鍏ュ墠鐨勪簨浠� + this.$emit('enter') + // nvue鐨則ransition鍔ㄧ敾妯″潡闇�瑕侀�氳繃ref璋冪敤缁勪欢锛屾敞鎰忔澶勭殑ref涓嶅悓浜巚ue鐨則his.$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 + // 鍔ㄧ敾姝e湪绂诲満鐨勭姸鎬� + 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'; +// 缁勪欢鐨刴ethods鏂规硶锛岀敱浜庡唴瀹硅緝闀匡紝鍐欏湪澶栭儴鏂囦欢涓�氳繃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 + // 閬垮厤鑷畾涔夋牱寮忓奖鍝嶅埌鍔ㄧ敾灞炴�э紝鎵�浠ュ啓鍦╲iewStyle鍓嶉潰 + ...uni.$u.addStyle(customStyle), + ...viewStyle + } + } + }, + // 灏唌ixin鎸傚湪鍒扮粍浠朵腑锛寀ni.$u.mixin瀹為檯涓婁负涓�涓獀ue鏍煎紡瀵硅薄 + mixins: [uni.$u.mpMixin, uni.$u.mixin, transition, props], + watch: { + show: { + handler(newVal) { + // vue鍜宯vue鍒嗗埆鎵ц涓嶅悓鐨勬柟娉� + // #ifdef APP-NVUE + newVal ? this.nvueEnter() : this.nvueLeave() + // #endif + // #ifndef APP-NVUE + newVal ? this.vueEnter() : this.vueLeave() + // #endif + }, + // 琛ㄧず鍚屾椂鐩戝惉鍒濆鍖栨椂鐨刾rops鐨剆how鐨勬剰鎬� + 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('鍙湁寰俊灏忕▼搴忔墠鏀寔鎶奱ccept閰嶇疆涓篴ll銆乵edia涔嬩竴') + } + // #endif + // #ifndef H5 || MP-WEIXIN + if (val === 'file') { + uni.$u.error('鍙湁寰俊灏忕▼搴忓拰H5(HX2.9.9)鎵嶆敮鎸佹妸accept閰嶇疆涓篺ile') + } + // #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 + }, + // 鍥剧墖鎴栬棰戞嬀鍙栨ā寮忥紝褰揳ccept涓篿mage绫诲瀷鏃惰缃甤apture鍙�夐澶朿amera鍙互鐩存帴璋冭捣鎽勫儚澶� + capture: { + type: [String, Array], + default: uni.$u.props.upload.capture + }, + // 褰揳ccept涓簐ideo鏃剁敓鏁堬紝鏄惁鍘嬬缉瑙嗛锛岄粯璁や负true + compressed: { + type: Boolean, + default: uni.$u.props.upload.compressed + }, + // 褰揳ccept涓簐ideo鏃剁敓鏁堬紝鍙�夊�间负back鎴杅ront + camera: { + type: String, + default: uni.$u.props.upload.camera + }, + // 褰揳ccept涓簐ideo鏃剁敓鏁堬紝鎷嶆憚瑙嗛鏈�闀挎媿鎽勬椂闂达紝鍗曚綅绉� + 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 + }, + // 棰勮涓婁紶鐨勫浘鐗囨椂鐨勮鍓ā寮忥紝鍜宨mage缁勪欢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 鍥剧墖鎴栬棰戞嬀鍙栨ā寮忥紝褰揳ccept涓篿mage绫诲瀷鏃惰缃甤apture鍙�夐澶朿amera鍙互鐩存帴璋冭捣鎽勫儚澶达紙榛樿 ['album', 'camera'] 锛� + * @property {Boolean} compressed 褰揳ccept涓簐ideo鏃剁敓鏁堬紝鏄惁鍘嬬缉瑙嗛锛岄粯璁や负true锛堥粯璁� true 锛� + * @property {String} camera 褰揳ccept涓簐ideo鏃剁敓鏁堬紝鍙�夊�间负back鎴杅ront锛堥粯璁� 'back' 锛� + * @property {Number} maxDuration 褰揳ccept涓簐ideo鏃剁敓鏁堬紝鎷嶆憚瑙嗛鏈�闀挎媿鎽勬椂闂达紝鍗曚綅绉掞紙榛樿 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 棰勮涓婁紶鐨勫浘鐗囨椂鐨勮鍓ā寮忥紝鍜宨mage缁勪欢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涓烘湰鍦伴�夋嫨鐨刡lob鏂囦欢鐨勮瘽锛屾棤娉曞垽鏂叾涓簐ideo杩樻槸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({ + // 鍏坒ilter鎵惧嚭涓哄浘鐗囩殑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(閮ㄩ棬涓氱哗鑰冩牳)鐨刲aji浜х墿锛屼笉鏀寔css缁樺埗涓夎褰� + // 鎵�浠ュ湪nvue涓嬩娇鐢ㄥ浘鐗囷紝闈瀗vue涓嬩娇鐢╟ss瀹炵幇 + /* #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 + // 闇�瑕乭x2.9.9浠ヤ笂鎵嶆敮鎸乽ni.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 + // 闇�瑕乭x2.9.9浠ヤ笂鎵嶆敮鎸乽ni.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 @@ +// 鐪嬪埌姝ゆ姤閿欙紝鏄洜涓烘病鏈夐厤缃畍ue.config.js鐨勩�恡ranspileDependencies銆戯紝璇﹁锛歨ttps://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-鍗佸叚杩涘埗棰滆壊杞瑀gb棰滆壊,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' +// 鍚勪釜闇�瑕乫ixed鐨勫湴鏂圭殑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鎸傝浇鍒皍ni瀵硅薄涓� +uni.$u = $u + +const install = (Vue) => { + // 鏃堕棿鏍煎紡鍖栵紝鍚屾椂涓や釜鍚嶇О锛宒ate鍜宼imeFormat + 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)) + // 鍚屾椂鎸傝浇鍒皍ni鍜孷ue.prototype涓� + // #ifndef APP-NVUE + // 鍙湁vue锛屾寕杞藉埌Vue.prototype鎵嶆湁鎰忎箟锛屽洜涓簄vue涓叏灞�Vue.prototype鍜孷ue.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"; + +// 闈瀗vue鐨勬牱寮� +/* #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瀵煎嚭渚沯s浣跨敤锛屼絾鏄浣昻vue涓嶆敮鎸� + 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' + }, + // 榛樿鍗曚綅锛屽彲浠ラ�氳繃閰嶇疆涓簉px锛岄偅涔堝湪鐢ㄤ簬浼犲叆缁勪欢澶у皬鍙傛暟涓烘暟鍊兼椂锛屽氨榛樿涓簉px + 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鍙傛暟 + * 鍊熸鐢ㄦ埛鍙互鍏ㄥ眬瑕嗙洊缁勪欢鐨刾rops榛樿鍊� + * 鏃犻渶鍦ㄦ瘡涓紩鍏ョ粍浠剁殑椤甸潰涓兘閰嶇疆涓�娆� + */ +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缁勪欢鐨刾rops + 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缁勪欢鐨刾rops + 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瓒呴摼鎺ョ粍浠秔rops鍙傛暟 + 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: '姝e湪鍔犺浇', + 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: '姝e湪鍔犺浇...', + 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鍔ㄧ敾缁勪欢鐨刾rops + 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鍦℉5涓悇API鐨剒-index鍊煎涓嬶細 +/** + * actionsheet: 999 + * modal: 999 + * navigate: 998 + * tabbar: 998 + * toast: 999 + */ + +export default { + toast: 10090, + noNetwork: 10080, + // popup鍖呭惈popup锛宎ctionsheet锛宬eyboard锛宲icker鐨勫�� + 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鐨剆tyle鏍囩鍔犱笂銆恖ang="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椤甸潰缂栬瘧鍒癏5鏃讹紝 +// App.vue鐨勬牱寮忎細琚玼ni-app鐨剉iew鍏冪礌鐨勮嚜甯order灞炴�ц鐩栵紝瀵艰嚧鏃犳晥 +// 缁间笂锛岃繖鏄痷ni-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銆乼ext鍏冪礌涓�鏍� +.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鏄熀浜巒vue鐜杩涜寮�鍙戠殑锛屾鐜涓櫘閫氬厓绱犻粯璁や负flex-direction: column; +// 鎵�浠ュ湪闈瀗vue涓紝闇�瑕佸鍏冪礌杩涜閲嶇疆涓篺lex-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 */ +// 姝ゅ涓簐ue鐗堟湰鐨勭畝鍐欙紝鍥犱负nvue涓嶆敮鎸佸悓鏃朵綔鐢ㄤ簬涓や釜绫诲悕鐨勬牱寮忓啓娉� +// nvue涓嬪彧鑳藉啓鎴恈lass="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鐨刴ixin鍔熻兘锛屾妸鍘熸潵闇�瑕佸啓4琛岀殑css锛屽彉鎴愪竴琛� +// 鐩殑鏄繚鎸佷唬鐮佸共鍑�鏁存磥锛屼笉鑷充簬鍦╪vue涓嬶紝鍒板閮借鍐檇isplay: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绔痷ni.toast()鐨勫眰绾э紝閬垮厤琚玼View鐨刴odal绛夐伄鐩� +/* #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) // 杞崲涓簉gb鏁扮粍妯″紡 + 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 +} + +// 灏唄ex琛ㄧず鏂瑰紡杞崲涓簉gb琛ㄧず鏂瑰紡(杩欓噷杩斿洖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 +} + +// 灏唕gb琛ㄧず鏂瑰紡杞崲涓篽ex琛ㄧず鏂瑰紡 +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棰滆壊鍗佸叚杩涘埗杞崲涓簉gb鎴杛gba,杩斿洖鐨勬牸寮忎负 rgba锛�255锛�255锛�255锛�0.5锛夊瓧绗︿覆 +* sHex涓轰紶鍏ョ殑鍗佸叚杩涘埗鐨勮壊鍊� +* alpha涓簉gba鐨勯�忔槑搴� +*/ +function colorToRgba(color, alpha) { + color = rgbToHex(color) + // 鍗佸叚杩涘埗棰滆壊鍊肩殑姝e垯琛ㄨ揪寮� + 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 { + // 璁剧疆瀹氭椂鍣紝褰撴渶鍚庝竴娆℃搷浣滃悗锛宼imeout涓嶄細鍐嶈娓呴櫎锛屾墍浠ュ湪寤舵椂wait姣鍚庢墽琛宖unc鍥炶皟鏂规硶 + 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锛涘鏋渧alue澶т簬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"杩橀渶瑕佺敤杩噓ni.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锛屽厛鍙栧嚭鍏舵暟鍊奸儴鍒嗭紝鍐嶈浆涓簆x鍊� + 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涓轰綅杩愮畻,鑳藉幓鎺墄鐨勫皬鏁颁綅,杩斿洖鏁存暟浣� + for (let i = 0; i < len; i++) uuid[i] = chars[0 | Math.random() * radix] + } else { + let r + // rfc4122鏍囧噯瑕佹眰杩斿洖鐨剈uid涓�,鏌愪簺浣嶄负鍥哄畾鐨勫瓧绗� + 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鏇夸唬,鍥犱负绗竴涓瓧绗︿负鏁板�兼椂,璇uuid涓嶈兘鐢ㄤ綔id鎴栬�卌lass + if (firstU) { + uuid.shift() + return `u${uuid.join('')}` + } + return uuid.join('') +} + +/** +* @description 鑾峰彇鐖剁粍浠剁殑鍙傛暟锛屽洜涓烘敮浠樺疂灏忕▼搴忎笉鏀寔provide/inject鐨勫啓娉� + this.$parent鍦ㄩ潪H5涓紝鍙互鍑嗙‘鑾峰彇鍒扮埗缁勪欢锛屼絾鏄湪H5涓紝闇�瑕佸娆his.$parent.$parent.xxx + 杩欓噷榛樿鍊肩瓑浜巙ndefined鏈夊畠鐨勫惈涔夛紝鍥犱负鏈�椤跺眰鍏冪礌(缁勪欢)鐨�$parent灏辨槸undefined锛屾剰鍛崇潃涓嶄紶name + 鍊�(榛樿涓簎ndefined)锛屽氨鏄煡鎵炬渶椤跺眰鐨�$parent +* @param {string|undefined} name 鐖剁粍浠剁殑鍙傛暟鍚� +*/ +function $parent(name = undefined) { + let parent = this.$parent + // 閫氳繃while鍘嗛亶锛岃繖閲屼富瑕佹槸涓轰簡H5闇�瑕佸灞傝В鏋愮殑闂 + while (parent) { + // 鐖剁粍浠� + if (parent.$options && parent.$options.name !== name) { + // 濡傛灉缁勪欢鐨刵ame涓嶇浉绛夛紝缁х画涓婁竴绾у鎵� + parent = parent.$parent + } else { + return parent + } + } + return false +} + +/** + * @description 鏍峰紡杞崲 + * 瀵硅薄杞瓧绗︿覆锛屾垨鑰呭瓧绗︿覆杞璞� + * @param {object | string} customStyle 闇�瑕佽浆鎹㈢殑鐩爣 + * @param {String} target 杞崲鐨勭洰鐨勶紝object-杞负瀵硅薄锛宻tring-杞负瀛楃涓� + * @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) { + // 椹煎嘲杞负涓垝绾跨殑褰㈠紡锛屽惁鍒檆ss鍐呰仈鏍峰紡锛屾棤娉曡瘑鍒┘宄版牱寮忓睘鎬у悕 + const key = i.replace(/([A-Z])/g, '-$1').toLowerCase() + string += `${key}:${customStyle[i]};` + } + // 鍘婚櫎涓ょ绌烘牸 + return trim(string) +} + +/** + * @description 娣诲姞鍗曚綅锛屽鏋滄湁rpx锛寀px锛�%锛宲x绛夊崟浣嶇粨灏炬垨鑰呭�间负auto锛岀洿鎺ヨ繑鍥烇紝鍚﹀垯鍔犱笂px鍗曚綅缁撳熬 + * @param {string|number} value 闇�瑕佹坊鍔犲崟浣嶇殑鍊� + * @param {string} unit 娣诲姞鐨勫崟浣嶅悕 姣斿px + */ +function addUnit(value = 'auto', unit = uni?.$u?.config?.unit ?? 'px') { + value = String(value) + // 鐢╱View鍐呯疆楠岃瘉瑙勫垯涓殑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} 娣卞害鍚堝苟鍚庣殑瀵硅薄鎴栬�協alse锛堝叆鍙傛湁涓嶆槸瀵硅薄锛� + */ +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 = []) { + // 鍘熺悊鏄痵ort鎺掑簭,Math.random()浜х敓0<= x < 1涔嬮棿鐨勬暟,浼氬鑷磝-0.05澶т簬鎴栬�呭皬浜�0 + return array.sort(() => Math.random() - 0.5) +} + +// padStart 鐨� polyfill锛屽洜涓烘煇浜涙満鍨嬫垨鎯呭喌锛岃繕鏃犳硶鏀寔es7鐨刾adStart锛屾瘮濡傜數鑴戠増鐨勫井淇″皬绋嬪簭 +// 鎵�浠ヨ繖閲屽仛涓�涓吋瀹筽olyfill鐨勫吋瀹瑰鐞� +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骞磎m鏈坉d鏃yyyy骞磎m鏈坉d鏃� hh鏃禡M鍒嗙瓑,鍙嚜瀹氫箟缁勫悎 榛樿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鏃犳硶瑙f瀽锛岄渶鍋氬吋瀹� + else if (typeof dateTime === 'string' && /^\d+$/.test(dateTime.trim())) { + date = new Date(Number(dateTime)) + } + // 澶勭悊骞冲彴鎬у樊寮傦紝鍦⊿afari/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 + * 鏍煎紡鍖栬鍒欏鏋滀负鏃堕棿鏍煎紡瀛楃涓诧紝瓒呭嚭涓�瀹氭椂闂磋寖鍥达紝杩斿洖鍥哄畾鐨勬椂闂存牸寮忥紱 + * 濡傛灉涓哄竷灏斿�糵alse锛屾棤璁轰粈涔堟椂闂达紝閮借繑鍥炲涔呬互鍓嶇殑鏍煎紡 + * @returns {string} 杞寲鍚庣殑鍐呭 + */ +function timeFrom(timestamp = null, format = 'yyyy-mm-dd') { + if (timestamp == null) timestamp = Number(new Date()) + timestamp = parseInt(timestamp) + // 鍒ゆ柇鐢ㄦ埛杈撳叆鐨勬椂闂存埑鏄杩樻槸姣,涓�鑸墠绔痡s鑾峰彇鐨勬椂闂存埑鏄绉�(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涓篺alse锛屽垯鏃犺浠�涔堟椂闂存埑锛岄兘鏄剧ず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 瀵硅薄杞瑄rl鍙傛暟 + * @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) { + // 濡傛灉闈為缃��,榛樿涓簊uccess + if (['primary', 'info', 'error', 'warning', 'success'].indexOf(type) == -1) type = 'success' + let iconName = '' + // 鐩墠(2019-12-12),info鍜宲rimary浣跨敤鍚屼竴涓浘鏍� + 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,鍦╥con缁勪欢搴撲腑,瀹炰綋鐨勭被鍚嶆槸鍚庨潰鍔�-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鍗曚綅锛屽皬浜庝竴瀹氬�硷紝璁や负鏄痵鍗曚綅 + * 姣斿浠�30浣嶉槇鍊硷紝閭d箞300澶т簬30锛屽彲浠ョ悊瑙d负鐢ㄦ埛鎯宠鐨勬槸300ms锛岃�屼笉鏄兂鑺�300s鍘绘墽琛屼竴涓姩鐢� + * @param {String|number} value 姣斿: "1s"|"100ms"|1|100 + * @param {boolean} unit 鎻愮ず: 濡傛灉鏄痜alse 榛樿杩斿洖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 鍦╱-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') + // 濡傛灉鍙戠敓鍙樺寲鐨刬nput鎴栬�卼extarea绛夛紝鍏剁埗缁勪欢涓湁u-form-item鎴栬�卽-form绛夛紝灏辨墽琛宖orm鐨剉alidate鏂规硶 + // 鍚屾椂灏唂orm-item鐨刾ros浼犻�掔粰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) { + // 鏈�鍚庝竴涓睘鎬ey + if (keys.length === 1) { + _obj[keys[0]] = v + return + } + // 0~length-1涓猭ey + 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鏃剁殑涓�浜涙椂鏈�)锛宲ages鍙兘涓虹┖鏁扮粍 + 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 @@ +/** + * 娉ㄦ剰锛� + * 姝ら儴鍒嗗唴瀹癸紝鍦╲ue-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 = /^[浜触娌笣鍐�璞簯杈介粦婀樼殩椴佹柊鑻忔禉璧i剛妗傜敇鏅嬭挋闄曞悏闂借吹绮ら潚钘忓窛瀹佺惣浣块A-Z]{1}[A-Z]{1}(([0-9]{5}[DF]$)|([DF][A-HJ-NP-Z0-9][0-9]{4}$))/ + // 鏃ц溅鐗� + const creg = /^[浜触娌笣鍐�璞簯杈介粦婀樼殩椴佹柊鑻忔禉璧i剛妗傜敇鏅嬭挋闄曞悏闂借吹绮ら潚钘忓窛瀹佺惣浣块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 + // 濡傛灉鏄潪绔嬪嵆鎵ц锛屽垯鍦╳ait姣鍐呯殑缁撴潫澶勬墽琛� + 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] - 鍏ㄥ眬榛樿鐨刣ataType + * @param {String} arg.responseType = [text|arraybuffer] - 鍏ㄥ眬榛樿鐨剅esponseType銆傛敮浠樺疂灏忕▼搴忎笉鏀寔 + * @param {Object} arg.custom - 鍏ㄥ眬榛樿鐨勮嚜瀹氫箟鍙傛暟 + * @param {Number} arg.timeout - 鍏ㄥ眬榛樿鐨勮秴鏃舵椂闂达紝鍗曚綅 ms銆傞粯璁�60000銆侶5(HBuilderX 2.9.9+)銆丄PP(HBuilderX 2.9.9+)銆佸井淇″皬绋嬪簭锛�2.10.0锛夈�佹敮浠樺疂灏忕▼搴� + * @param {Boolean} arg.sslVerify - 鍏ㄥ眬榛樿鐨勬槸鍚﹂獙璇� ssl 璇佷功銆傞粯璁rue.浠匒pp瀹夊崜绔敮鎸侊紙HBuilderX 2.3.3+锛� + * @param {Boolean} arg.withCredentials - 鍏ㄥ眬榛樿鐨勮法鍩熻姹傛椂鏄惁鎼哄甫鍑瘉锛坈ookies锛夈�傞粯璁alse銆備粎H5鏀寔锛圚BuilderX 2.6.15+锛� + * @param {Boolean} arg.firstIpv4 - 鍏―NS瑙f瀽鏃朵紭鍏堜娇鐢╥pv4銆傞粯璁alse銆備粎 App-Android 鏀寔 (HBuilderX 2.8.0+) + * @param {Function(statusCode):Boolean} arg.validateStatus - 鍏ㄥ眬榛樿鐨勮嚜瀹氫箟楠岃瘉鍣ㄣ�傞粯璁tatusCode >= 200 && statusCode < 300 + */ + constructor(arg = {}) { + if (!isPlainObject(arg)) { + arg = {} + console.warn('璁剧疆鍏ㄥ眬鍙傛暟蹇呴』鎺ユ敹涓�涓狾bject') + } + 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; + /** 璇锋眰鏈嶅姟鍣ㄦ帴鍙e湴鍧� */ + url?: string; + + /** 璇锋眰鏌ヨ鍙傛暟锛岃嚜鍔ㄦ嫾鎺ヤ负鏌ヨ瀛楃涓� */ + params?: AnyObject; + /** 璇锋眰浣撳弬鏁� */ + data?: AnyObject; + + /** 鏂囦欢瀵瑰簲鐨� key */ + name?: string; + /** HTTP 璇锋眰涓叾浠栭澶栫殑 form data */ + formData?: AnyObject; + /** 瑕佷笂浼犳枃浠惰祫婧愮殑璺緞銆� */ + filePath?: string; + /** 闇�瑕佷笂浼犵殑鏂囦欢鍒楄〃銆備娇鐢� files 鏃讹紝filePath 鍜� name 涓嶇敓鏁堬紝App銆丠5锛� 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瑙f瀽鏃朵紭鍏堜娇鐢╥pv4锛屼粎 App-Android 鏀寔 (HBuilderX 2.8.0+) */ + firstIpv4?: boolean; + /** 楠岃瘉 ssl 璇佷功 浠�5+App瀹夊崜绔敮鎸侊紙HBuilderX 2.3.3+锛� */ + sslVerify?: boolean; + /** 璺ㄥ煙璇锋眰鏃舵槸鍚︽惡甯﹀嚟璇侊紙cookies锛変粎H5鏀寔锛圚BuilderX 2.6.15+锛� */ + withCredentials?: boolean; + + /** 杩斿洖褰撳墠璇锋眰鐨則ask, 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) + } + } + } +} + +/** + * 鏄惁涓篵oolean 鍊� + * @param val + * @returns {boolean} + */ +export function isBoolean(val) { + return typeof val === 'boolean' +} + +/** + * 鏄惁涓虹湡姝g殑瀵硅薄{} 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涓婏紝鍥犱负杩欐柟娉曢渶瑕佷娇鐢╥n(this)锛屾墍浠ユ棤娉曟妸瀹冪嫭绔嬫垚涓�涓崟鐙殑鏂囦欢瀵煎嚭 + this.$u.getRect = this.$uGetRect + }, + created() { + // 缁勪欢褰撲腑锛屽彧鏈塩reated澹版槑鍛ㄦ湡锛屼负浜嗚兘鍦ㄧ粍浠朵娇鐢紝鏁呬篃鍦╟reated涓皢鏂规硶鎸傝浇鍒�$u + this.$u.getRect = this.$uGetRect + }, + computed: { + // 鍦�2.x鐗堟湰涓紝灏嗕細鎶�$u鎸傝浇鍒皍ni瀵硅薄涓嬶紝瀵艰嚧鍦ㄦā鏉夸腑鏃犳硶浣跨敤uni.$u.xxx褰㈠紡 + // 鎵�浠ヨ繖閲岄�氳繃computed璁$畻灞炴�у皢鍏堕檮鍔犲埌this.$u涓婏紝灏卞彲浠ュ湪妯℃澘鎴栬�卝s涓娇鐢╱ni.$u.xxx + // 鍙湪nvue鐜閫氳繃姝ゆ柟寮忓紩鍏ュ畬鏁寸殑$u锛屽叾浠栧钩鍙颁細鍑虹幇鎬ц兘闂锛岄潪nvue鍒欐寜闇�寮曞叆锛堜富瑕佸師鍥犳槸props杩囧ぇ锛� + $u() { + // #ifndef APP-NVUE + // 鍦ㄩ潪nvue绔紝绉婚櫎props锛宧ttp锛宮ixin绛夊璞★紝閬垮厤鍦ㄥ皬绋嬪簭setData鏃舵暟鎹繃澶у奖鍝嶆�ц兘 + return uni.$u.deepMerge(uni.$u, { + props: undefined, + http: undefined, + mixin: undefined + }) + // #endif + // #ifdef APP-NVUE + return uni.$u + // #endif + }, + /** + * 鐢熸垚bem瑙勫垯绫诲悕 + * 鐢变簬寰俊灏忕▼搴忥紝H5锛宯vue涔嬮棿缁戝畾class鐨勫樊寮傦紝鏃犳硶閫氳繃:class="[bem()]"鐨勫舰寮忚繘琛屽悓鐢� + * 鏁呴噰鐢ㄥ涓嬫姌涓仛娉曪紝鏈�鍚庤繑鍥炵殑鏄暟缁勶紙涓�鑸钩鍙帮級鎴栧瓧绗︿覆锛堟敮浠樺疂鍜屽瓧鑺傝烦鍔ㄥ钩鍙帮級锛岀被浼糩'a', 'b', 'c']鎴�'a b c'鐨勫舰寮� + * @param {String} name 缁勪欢鍚嶇О + * @param {Array} fixed 涓�鐩翠細瀛樺湪鐨勭被鍚� + * @param {Array} change 浼氭牴鎹彉閲忓�间负true鎴栬�協alse鑰屽嚭鐜版垨鑰呴殣钘忕殑绫诲悕 + * @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) => { + // 杩欓噷鐨勭被鍚嶏紝浼氭牴鎹畉his[item]鐨勫�间负true鎴栬�協alse锛岃�岃繘琛屾坊鍔犳垨鑰呯Щ闄ゆ煇涓�涓被 + this[item] ? (classes[prefix + item] = this[item]) : (delete classes[prefix + item]) + }) + } + return Object.keys(classes) + // 鏀粯瀹濓紝澶存潯灏忕▼搴忔棤娉曞姩鎬佺粦瀹氫竴涓暟缁勭被鍚嶏紝鍚﹀垯瑙f瀽鍑烘潵鐨勭粨鏋滀細甯︽湁","锛岃�屽鑷村け鏁� + // #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 + }) + } + }, + // 鏌ヨ鑺傜偣淇℃伅 + // 鐩墠姝ゆ柟娉曞湪鏀粯瀹濆皬绋嬪簭涓棤娉曡幏鍙栫粍浠惰窡鎺ョ偣鐨勫昂瀵革紝涓烘敮浠樺疂鐨刡ug(2020-07-21) + // 瑙e喅鍔炴硶涓哄湪缁勪欢鏍归儴鍐嶅涓�涓病鏈変换浣曚綔鐢ㄧ殑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 = '') { + // 閬垮厤鍦╟reated涓幓瀹氫箟parent鍙橀噺 + if (!this.parent) this.parent = {} + // 杩欓噷鐨勬湰璐ㄥ師鐞嗘槸锛岄�氳繃鑾峰彇鐖剁粍浠跺疄渚�(涔熷嵆绫讳技u-radio鐨勭埗缁勪欢u-radio-group鐨則his) + // 灏嗙埗缁勪欢this涓搴旂殑鍙傛暟锛岃祴鍊肩粰鏈粍浠�(u-radio鐨則his)鐨刾arentData瀵硅薄涓搴旂殑灞炴�� + // 涔嬫墍浠ラ渶瑕佽繖涔堝仛锛屾槸鍥犱负鎵�鏈夌涓紝澶存潯灏忕▼搴忎笉鏀寔閫氳繃this.parent.xxx鍘荤洃鍚埗缁勪欢鍙傛暟鐨勫彉鍖� + // 姝ゅ骞朵笉浼氳嚜鍔ㄦ洿鏂板瓙缁勪欢鐨勬暟鎹紝鑰屾槸渚濊禆鐖剁粍浠秛-radio-group鍘荤洃鍚琩ata鐨勫彉鍖栵紝鎵嬪姩璋冪敤鏇存柊瀛愮粍浠剁殑鏂规硶鍘婚噸鏂拌幏鍙� + 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涓殑灞炴�э紝灏唒arent涓殑鍚屽悕灞炴�ц祴鍊肩粰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鍜宑hldren锛屼竴鑸湪checkbox鍜宑heckbox-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 + // 灏嗚嚜瀹氫箟鑺傜偣璁剧疆鎴愯櫄鎷熺殑锛屾洿鍔犳帴杩慥ue缁勪欢鐨勮〃鐜帮紝鑳芥洿濂界殑浣跨敤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鎴栬�卲adding鐨勫崟浣嶏紝姣斿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' // 姝e垯鍖归厤鐮佺偣鑼冨洿浠嶶+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鐨勬枃瀛條ength灞炴�т笉鍑嗙‘鐨刡ug锛屽"馉馉馉".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銆丄ttribution 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骞撮棸鏈堟槸鍝釜鏈堬紱鑻骞存病鏈夐棸鏈� 鍒欒繑鍥�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涓洪棸鏈堟椂鐨勫ぉ鏁拌浣跨敤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骞磎鏈堢殑澶╂暟 + * @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)锛沶浜屽崄鍥涜妭姘斾腑鐨勭鍑犱釜鑺傛皵(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] + }, + + /** + * 浼犲叆闃冲巻骞存湀鏃ヨ幏寰楄缁嗙殑鍏巻銆佸啘鍘唎bject淇℃伅 <=>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杞崲涓烘暟瀛楀彉涓篘aN + } + // 鍏巻浼犲弬鏈�涓嬮檺 + 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)// 璁$畻鍐滃巻鏅�氭湀澶╂暟 + } + // 瑙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 } + }, + + /** + * 浼犲叆鍐滃巻骞存湀鏃ヤ互鍙婁紶鍏ョ殑鏈堜唤鏄惁闂版湀鑾峰緱璇︾粏鐨勫叕鍘嗐�佸啘鍘唎bject淇℃伅 <=>JSON + * @param y lunar year + * @param m lunar month + * @param d lunar day + * @param isLeapMonth lunar month is leap or not.[濡傛灉鏄啘鍘嗛棸鏈堢鍥涗釜鍙傛暟璧嬪�紅rue鍗冲彲] + * @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 // 鑾峰彇褰撳墠缁勪欢瀹炰緥鐨刵ame + // 濡傛灉褰撳墠鏈夎妭鐐� && 褰撳墠娌″悕绉� 涓� 褰撳墠鍚嶇О绛変簬闇�瑕佷紶杩涙潵鐨勫悕绉扮殑鏃跺�欏氨鍘绘煡鎵惧綋鍓嶇殑鑺傜偣 + // 寰幆鍑哄綋鍓嶅悕绉扮殑涓�鏍风殑缁勪欢瀹炰緥 + 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 @@ +/** + * 璺敱璺宠浆鏂规硶锛岃鏂规硶鐩稿浜庣洿鎺ヤ娇鐢╱ni.xxx鐨勫ソ澶勬槸浣跨敤鏇村姞绠�鍗曞揩鎹� + * 骞朵笖甯︽湁璺敱鎷︽埅鍔熻兘 + */ + +class Router { + constructor() { + // 鍘熷灞炴�у畾涔� + this.config = { + type: 'navigateTo', + url: '', + delta: 1, // navigateBack椤甸潰鍚庨��鏃�,鍥為��鐨勫眰鏁� + params: {}, // 浼犻�掔殑鍙傛暟 + animationType: 'pop-in', // 绐楀彛鍔ㄧ敾,鍙湪APP鏈夋晥 + animationDuration: 300, // 绐楀彛鍔ㄧ敾鎸佺画鏃堕棿,鍗曚綅姣,鍙湪APP鏈夋晥 + intercept: false // 鏄惁闇�瑕佹嫤鎴� + } + // 鍥犱负route鏂规硶鏄渶瑕佸澶栬祴鍊肩粰鍙﹀鐨勫璞′娇鐢紝鍚屾椂route鍐呴儴鏈変娇鐢╰his锛屼細瀵艰嚧route澶卞幓涓婁笅鏂� + // 杩欓噷鍦ㄦ瀯閫犲嚱鏁颁腑杩涜this缁戝畾 + this.route = this.route.bind(this) + } + + // 鍒ゆ柇url鍓嶉潰鏄惁鏈�"/"锛屽鏋滄病鏈夊垯鍔犱笂锛屽惁鍒欐棤娉曡烦杞� + addRootPath(url) { + return url[0] === '/' ? url : `/${url}` + } + + // 鏁村悎璺敱鍙傛暟 + mixinParam(url, params) { + url = url && this.addRootPath(url) + + // 浣跨敤姝e垯鍖归厤锛屼富瑕佷緷鎹槸鍒ゆ柇鏄惁鏈�"/","?","="绛夛紝濡傗��/page/index/index?name=mary" + // 濡傛灉鏈塽rl涓湁get鍙傛暟锛岃浆鎹㈠悗鏃犻渶甯︿笂"?" + let query = '' + if (/.*\/.*\?.*=.*/.test(url)) { + // object瀵硅薄杞负get绫诲瀷鐨勫弬鏁� + query = uni.$u.queryParams(params, false) + // 鍥犱负宸叉湁get鍙傛暟,鎵�浠ュ悗闈㈡嫾鎺ョ殑鍙傛暟闇�瑕佸甫涓�"&"闅斿紑 + return url += `&${query}` + } + // 鐩存帴鎷兼帴鍙傛暟锛屽洜涓烘澶剈rl涓病鏈夊悗闈㈢殑query鍙傛暟锛屼篃灏辨病鏈�"?/&"涔嬬被鐨勭鍙� + query = uni.$u.queryParams(params) + return url += query + } + + // 瀵瑰鐨勬柟娉曞悕绉� + async route(options = {}, params = {}) { + // 鍚堝苟鐢ㄦ埛鐨勯厤缃拰鍐呴儴鐨勯粯璁ら厤缃� + let mergeConfig = {} + + if (typeof options === 'string') { + // 濡傛灉options涓哄瓧绗︿覆锛屽垯涓簉oute(url, params)鐨勫舰寮� + mergeConfig.url = this.mixinParam(options, params) + mergeConfig.type = 'navigateTo' + } else { + mergeConfig = uni.$u.deepMerge(this.config, options) + // 鍚﹀垯姝e父浣跨敤mergeConfig涓殑url鍜宲arams杩涜鎷兼帴 + 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') { + // 瀹氫竴涓猵romise锛屾牴鎹敤鎴锋墽琛宺esolve(true)鎴栬�卹esolve(false)鏉ュ喅瀹氭槸鍚﹁繘琛岃矾鐢辫烦杞� + const isNext = await new Promise((resolve, reject) => { + uni.$u.routeIntercept(mergeConfig, resolve) + }) + // 濡傛灉isNext涓簍rue锛屽垯鎵ц璺敱璺宠浆 + isNext && this.openPage(mergeConfig) + } else { + this.openPage(mergeConfig) + } + } + + // 鎵ц璺敱璺宠浆 + openPage(config) { + // 瑙f瀯鍙傛暟 + 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宸插畬缇庡吋瀹筺vue锛屽叏闈㈢殑缁勪欢鍜屼究鎹风殑宸ュ叿浼氳鎮ㄤ俊鎵嬫媹鏉ワ紝濡傞奔寰楁按", + "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涓紩鍏ョ殑鏍峰紡浼氬悓鏃舵贩鍏ュ埌鍏ㄥ眬鏍峰紡鏂囦欢鍜屽崟鐙瘡涓�涓〉闈㈢殑鏍峰紡涓紝閫犳垚寰俊绋嬪簭鍖呭お澶э紝 +// 鏁卽ni.scss鍙缓璁斁scss鍙橀噺鍚嶇浉鍏虫牱寮忥紝鍏朵粬鐨勬牱寮忓彲浠ラ�氳繃main.js鎴栬�匒pp.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; +} -- Gitblit v1.9.1