From 198738cff23a356346f53fa95b8bd00cfff594aa Mon Sep 17 00:00:00 2001 From: Lufaneng Date: Fri, 12 Sep 2025 17:01:41 +0800 Subject: [PATCH] init --- .commitlintrc.js | 93 ++ .editorconfig | 15 + .env.development | 8 + .env.production | 2 + .gitignore | 9 + .husky/commit-msg | 1 + .husky/pre-commit | 1 + .lintstagedrc.js | 3 + .prettierignore | 10 + .prettierrc.js | 47 + App.vue | 46 + LICENSE | 21 + README.md | 1 + api/index.js | 4 + api/modules/auth.js | 30 + api/modules/user.js | 16 + components/HeaderCustom/HeaderCustom.vue | 54 + components/IconFont/IconFont.vue | 36 + components/IconFont/iconfont.css | 19 + components/IconFont/iconfont.json | 16 + components/IconFont/iconfont.ttf | Bin 0 -> 1636 bytes components/IconFont/iconfont.woff | Bin 0 -> 1044 bytes components/IconFont/iconfont.woff2 | Bin 0 -> 668 bytes components/LangSelect/LangSelect.vue | 58 + components/Login/Login.vue | 307 ++++ components/UploadFile/UploadFile.vue | 426 ++++++ components/UploadFile/example.vue | 191 +++ hooks/usePermission.js | 10 + index.html | 24 + locale/en.json | 8 + locale/index.js | 23 + locale/ja.json | 8 + locale/uni-app.ja.json | 36 + locale/zh-Hans.json | 8 + locale/zh-Hant.json | 8 + main.js | 11 + manifest.json | 100 ++ package.json | 38 + pages.json | 120 ++ pages/consumption/consumption.vue | 380 +++++ pages/index/index.vue | 342 +++++ pages/index/index1.vue | 517 +++++++ pages/login/login.vue | 214 +++ pages/mine/mine.vue | 457 ++++++ pages/order/order.vue | 528 +++++++ pagesA/edit-profile/edit-profile.vue | 460 ++++++ pagesA/generate-record/generate-record.vue | 351 +++++ pagesA/user-agreement/user-agreement.vue | 47 + plugins/index.js | 17 + plugins/permission.js | 56 + plugins/ui.js | 28 + router/index.js | 91 ++ static/imgs/code.png | Bin 0 -> 799 bytes static/imgs/indexImg.png | Bin 0 -> 101955 bytes static/imgs/phone.png | Bin 0 -> 596 bytes static/json/regions.js | 1 + static/tabbar/appointment.png | Bin 0 -> 4455 bytes static/tabbar/appointment_HL.png | Bin 0 -> 4418 bytes static/tabbar/index.png | Bin 0 -> 4199 bytes static/tabbar/index_HL.png | Bin 0 -> 4230 bytes static/tabbar/mine.png | Bin 0 -> 4238 bytes static/tabbar/mine_HL.png | Bin 0 -> 4207 bytes store/index.js | 12 + store/modules/auth.js | 69 + store/modules/user.js | 32 + tsconfig.json | 33 + uni.scss | 79 + uni_modules/uv-action-sheet/changelog.md | 7 + .../components/uv-action-sheet/props.js | 50 + .../uv-action-sheet/uv-action-sheet.vue | 280 ++++ uni_modules/uv-action-sheet/package.json | 92 ++ uni_modules/uv-action-sheet/readme.md | 13 + uni_modules/uv-album/changelog.md | 10 + .../uv-album/components/uv-album/uv-album.vue | 312 ++++ uni_modules/uv-album/package.json | 88 ++ uni_modules/uv-album/readme.md | 21 + uni_modules/uv-alert/changelog.md | 7 + .../uv-alert/components/uv-alert/props.js | 45 + .../uv-alert/components/uv-alert/uv-alert.vue | 246 +++ uni_modules/uv-alert/package.json | 88 ++ uni_modules/uv-alert/readme.md | 15 + uni_modules/uv-avatar/changelog.md | 13 + .../components/uv-avatar-group/props.js | 53 + .../uv-avatar-group/uv-avatar-group.vue | 106 ++ .../uv-avatar/components/uv-avatar/props.js | 80 + .../components/uv-avatar/uv-avatar.vue | 175 +++ uni_modules/uv-avatar/package.json | 89 ++ uni_modules/uv-avatar/readme.md | 11 + uni_modules/uv-back-top/changelog.md | 8 + .../components/uv-back-top/props.js | 58 + .../components/uv-back-top/uv-back-top.vue | 116 ++ uni_modules/uv-back-top/package.json | 89 ++ uni_modules/uv-back-top/readme.md | 11 + uni_modules/uv-badge/changelog.md | 7 + .../uv-badge/components/uv-badge/props.js | 73 + .../uv-badge/components/uv-badge/uv-badge.vue | 176 +++ uni_modules/uv-badge/package.json | 87 ++ uni_modules/uv-badge/readme.md | 11 + uni_modules/uv-button/changelog.md | 33 + .../uv-button/components/uv-button/nvue.scss | 46 + .../uv-button/components/uv-button/props.js | 163 ++ .../components/uv-button/uv-button.vue | 528 +++++++ .../uv-button/components/uv-button/vue.scss | 93 ++ uni_modules/uv-button/package.json | 89 ++ uni_modules/uv-button/readme.md | 19 + uni_modules/uv-calendar/changelog.md | 16 + .../components/uv-calendar/calendar.js | 546 +++++++ .../components/uv-calendar/header.vue | 104 ++ .../components/uv-calendar/month.vue | 616 ++++++++ .../components/uv-calendar/props.js | 145 ++ .../components/uv-calendar/uv-calendar.vue | 390 +++++ uni_modules/uv-calendar/package.json | 89 ++ uni_modules/uv-calendar/readme.md | 21 + uni_modules/uv-calendars/changelog.md | 40 + .../components/uv-calendars/calendar-body.vue | 376 +++++ .../components/uv-calendars/calendar-item.vue | 248 +++ .../components/uv-calendars/calendar.js | 546 +++++++ .../components/uv-calendars/i18n/en.json | 12 + .../components/uv-calendars/i18n/index.js | 8 + .../components/uv-calendars/i18n/zh-Hans.json | 12 + .../components/uv-calendars/i18n/zh-Hant.json | 12 + .../components/uv-calendars/util.js | 435 ++++++ .../components/uv-calendars/uv-calendars.vue | 452 ++++++ uni_modules/uv-calendars/package.json | 89 ++ uni_modules/uv-calendars/readme.md | 23 + uni_modules/uv-cell/changelog.md | 13 + .../uv-cell/components/uv-cell-group/props.js | 15 + .../uv-cell-group/uv-cell-group.vue | 63 + .../uv-cell/components/uv-cell/props.js | 116 ++ .../uv-cell/components/uv-cell/uv-cell.vue | 209 +++ uni_modules/uv-cell/package.json | 89 ++ uni_modules/uv-cell/readme.md | 11 + uni_modules/uv-checkbox/changelog.md | 34 + .../components/uv-checkbox-group/props.js | 84 ++ .../uv-checkbox-group/uv-checkbox-group.vue | 119 ++ .../components/uv-checkbox/props.js | 70 + .../components/uv-checkbox/uv-checkbox.vue | 370 +++++ uni_modules/uv-checkbox/package.json | 88 ++ uni_modules/uv-checkbox/readme.md | 19 + uni_modules/uv-code-input/changelog.md | 13 + .../components/uv-code-input/props.js | 83 + .../uv-code-input/uv-code-input.vue | 272 ++++ uni_modules/uv-code-input/package.json | 87 ++ uni_modules/uv-code-input/readme.md | 19 + uni_modules/uv-code/changelog.md | 9 + .../uv-code/components/uv-code/props.js | 35 + .../uv-code/components/uv-code/uv-code.vue | 136 ++ uni_modules/uv-code/package.json | 87 ++ uni_modules/uv-code/readme.md | 11 + uni_modules/uv-collapse/changelog.md | 5 + .../components/uv-collapse-item/props.js | 60 + .../uv-collapse-item/uv-collapse-item.vue | 229 +++ .../components/uv-collapse/props.js | 20 + .../components/uv-collapse/uv-collapse.vue | 86 ++ uni_modules/uv-collapse/package.json | 89 ++ uni_modules/uv-collapse/readme.md | 11 + uni_modules/uv-count-down/changelog.md | 9 + .../components/uv-count-down/props.js | 25 + .../components/uv-count-down/utils.js | 62 + .../uv-count-down/uv-count-down.vue | 169 +++ uni_modules/uv-count-down/package.json | 87 ++ uni_modules/uv-count-down/readme.md | 11 + uni_modules/uv-count-to/changelog.md | 13 + .../components/uv-count-to/props.js | 60 + .../components/uv-count-to/uv-count-to.vue | 187 +++ uni_modules/uv-count-to/package.json | 87 ++ uni_modules/uv-count-to/readme.md | 11 + uni_modules/uv-datetime-picker/changelog.md | 28 + .../components/uv-datetime-picker/props.js | 130 ++ .../uv-datetime-picker/uv-datetime-picker.vue | 355 +++++ uni_modules/uv-datetime-picker/package.json | 88 ++ uni_modules/uv-datetime-picker/readme.md | 19 + uni_modules/uv-divider/changelog.md | 11 + .../uv-divider/components/uv-divider/props.js | 45 + .../components/uv-divider/uv-divider.vue | 113 ++ uni_modules/uv-divider/package.json | 88 ++ uni_modules/uv-divider/readme.md | 11 + uni_modules/uv-drop-down/changelog.md | 13 + .../uv-drop-down-item/uv-drop-down-item.vue | 169 +++ .../uv-drop-down-popup/uv-drop-down-popup.vue | 242 +++ .../components/uv-drop-down/uv-drop-down.vue | 135 ++ uni_modules/uv-drop-down/package.json | 91 ++ uni_modules/uv-drop-down/readme.md | 23 + uni_modules/uv-empty/changelog.md | 13 + .../uv-empty/components/uv-empty/props.js | 60 + .../uv-empty/components/uv-empty/uv-empty.vue | 126 ++ uni_modules/uv-empty/package.json | 88 ++ uni_modules/uv-empty/readme.md | 19 + uni_modules/uv-form/changelog.md | 23 + .../uv-form/components/uv-form-item/props.js | 49 + .../components/uv-form-item/uv-form-item.vue | 226 +++ .../uv-form/components/uv-form/props.js | 46 + .../uv-form/components/uv-form/uv-form.vue | 209 +++ .../uv-form/components/uv-form/valid.js | 1343 +++++++++++++++++ uni_modules/uv-form/package.json | 93 ++ uni_modules/uv-form/readme.md | 19 + uni_modules/uv-gap/changelog.md | 5 + uni_modules/uv-gap/components/uv-gap/props.js | 25 + .../uv-gap/components/uv-gap/uv-gap.vue | 36 + uni_modules/uv-gap/package.json | 87 ++ uni_modules/uv-gap/readme.md | 12 + uni_modules/uv-grid/changelog.md | 21 + .../uv-grid/components/uv-grid-item/props.js | 15 + .../components/uv-grid-item/uv-grid-item.vue | 226 +++ .../uv-grid/components/uv-grid/props.js | 20 + .../uv-grid/components/uv-grid/uv-grid.vue | 100 ++ uni_modules/uv-grid/package.json | 88 ++ uni_modules/uv-grid/readme.md | 17 + uni_modules/uv-icon/changelog.md | 31 + .../uv-icon/components/uv-icon/icons.js | 160 ++ .../uv-icon/components/uv-icon/props.js | 90 ++ .../uv-icon/components/uv-icon/uv-icon.vue | 226 +++ .../uv-icon/components/uv-icon/uvicons.ttf | Bin 0 -> 39632 bytes uni_modules/uv-icon/package.json | 83 + uni_modules/uv-icon/readme.md | 15 + uni_modules/uv-image/changelog.md | 36 + .../uv-image/components/uv-image/props.js | 95 ++ .../uv-image/components/uv-image/uv-image.vue | 287 ++++ uni_modules/uv-image/package.json | 89 ++ uni_modules/uv-image/readme.md | 15 + uni_modules/uv-index-list/changelog.md | 18 + .../components/uv-index-anchor/props.js | 30 + .../uv-index-anchor/uv-index-anchor.vue | 98 ++ .../uv-index-item/uv-index-item.vue | 87 ++ .../components/uv-index-list/props.js | 30 + .../uv-index-list/uv-index-list.vue | 461 ++++++ uni_modules/uv-index-list/package.json | 88 ++ uni_modules/uv-index-list/readme.md | 19 + uni_modules/uv-input/changelog.md | 29 + .../uv-input/components/uv-input/props.js | 175 +++ .../uv-input/components/uv-input/uv-input.vue | 348 +++++ uni_modules/uv-input/package.json | 88 ++ uni_modules/uv-input/readme.md | 19 + uni_modules/uv-keyboard/changelog.md | 17 + .../components/uv-keyboard-car/props.js | 24 + .../uv-keyboard-car/uv-keyboard-car.vue | 347 +++++ .../components/uv-keyboard-number/props.js | 19 + .../uv-keyboard-number/uv-keyboard-number.vue | 201 +++ .../components/uv-keyboard/props.js | 95 ++ .../components/uv-keyboard/uv-keyboard.vue | 180 +++ uni_modules/uv-keyboard/package.json | 89 ++ uni_modules/uv-keyboard/readme.md | 19 + uni_modules/uv-line-progress/changelog.md | 7 + .../components/uv-line-progress/props.js | 29 + .../uv-line-progress/uv-line-progress.vue | 146 ++ uni_modules/uv-line-progress/package.json | 87 ++ uni_modules/uv-line-progress/readme.md | 11 + uni_modules/uv-line/changelog.md | 5 + .../uv-line/components/uv-line/props.js | 34 + .../uv-line/components/uv-line/uv-line.vue | 60 + uni_modules/uv-line/package.json | 87 ++ uni_modules/uv-line/readme.md | 11 + uni_modules/uv-link/changelog.md | 7 + .../uv-link/components/uv-link/props.js | 40 + .../uv-link/components/uv-link/uv-link.vue | 83 + uni_modules/uv-link/package.json | 87 ++ uni_modules/uv-link/readme.md | 11 + uni_modules/uv-list/changelog.md | 25 + .../components/uv-list-item/uv-list-item.vue | 535 +++++++ .../uv-list/components/uv-list/uv-list.vue | 147 ++ uni_modules/uv-list/package.json | 87 ++ uni_modules/uv-list/readme.md | 27 + uni_modules/uv-load-more/changelog.md | 7 + .../components/uv-load-more/props.js | 95 ++ .../components/uv-load-more/uv-load-more.vue | 152 ++ uni_modules/uv-load-more/package.json | 89 ++ uni_modules/uv-load-more/readme.md | 11 + uni_modules/uv-loading-icon/changelog.md | 9 + .../components/uv-loading-icon/props.js | 67 + .../uv-loading-icon/uv-loading-icon.vue | 347 +++++ uni_modules/uv-loading-icon/package.json | 87 ++ uni_modules/uv-loading-icon/readme.md | 19 + uni_modules/uv-loading-page/changelog.md | 11 + .../components/uv-loading-page/props.js | 55 + .../uv-loading-page/uv-loading-page.vue | 96 ++ uni_modules/uv-loading-page/package.json | 89 ++ uni_modules/uv-loading-page/readme.md | 11 + uni_modules/uv-modal/changelog.md | 28 + .../uv-modal/components/uv-modal/props.js | 90 ++ .../uv-modal/components/uv-modal/uv-modal.vue | 245 +++ uni_modules/uv-modal/package.json | 90 ++ uni_modules/uv-modal/readme.md | 23 + uni_modules/uv-navbar/changelog.md | 17 + .../uv-navbar/components/uv-navbar/props.js | 89 ++ .../components/uv-navbar/uv-navbar.vue | 245 +++ uni_modules/uv-navbar/package.json | 89 ++ uni_modules/uv-navbar/readme.md | 19 + uni_modules/uv-no-network/changelog.md | 5 + .../components/uv-no-network/props.js | 20 + .../uv-no-network/uv-no-network.vue | 222 +++ uni_modules/uv-no-network/package.json | 90 ++ uni_modules/uv-no-network/readme.md | 11 + uni_modules/uv-notice-bar/changelog.md | 19 + .../components/uv-column-notice/props.js | 61 + .../uv-column-notice/uv-column-notice.vue | 176 +++ .../components/uv-notice-bar/props.js | 76 + .../uv-notice-bar/uv-notice-bar.vue | 110 ++ .../components/uv-row-notice/props.js | 40 + .../uv-row-notice/uv-row-notice.vue | 341 +++++ uni_modules/uv-notice-bar/package.json | 88 ++ uni_modules/uv-notice-bar/readme.md | 19 + uni_modules/uv-notify/changelog.md | 9 + .../uv-notify/components/uv-notify/props.js | 45 + .../components/uv-notify/uv-notify.vue | 220 +++ uni_modules/uv-notify/package.json | 90 ++ uni_modules/uv-notify/readme.md | 11 + uni_modules/uv-number-box/changelog.md | 7 + .../components/uv-number-box/props.js | 113 ++ .../uv-number-box/uv-number-box.vue | 395 +++++ uni_modules/uv-number-box/package.json | 88 ++ uni_modules/uv-number-box/readme.md | 11 + uni_modules/uv-overlay/changelog.md | 9 + .../uv-overlay/components/uv-overlay/props.js | 25 + .../components/uv-overlay/uv-overlay.vue | 85 ++ uni_modules/uv-overlay/package.json | 88 ++ uni_modules/uv-overlay/readme.md | 11 + uni_modules/uv-parse/changelog.md | 13 + .../components/uv-parse/node/node.vue | 576 +++++++ .../uv-parse/components/uv-parse/parser.js | 1335 ++++++++++++++++ .../uv-parse/components/uv-parse/uv-parse.vue | 498 ++++++ uni_modules/uv-parse/package.json | 87 ++ uni_modules/uv-parse/readme.md | 21 + .../static/app-plus/uv-parse/js/handler.js | 224 +++ .../app-plus/uv-parse/js/uni.webview.min.js | 19 + .../static/app-plus/uv-parse/local.html | 1 + uni_modules/uv-pick-color/changelog.md | 18 + .../components/uv-pick-color/colors.js | 217 +++ .../components/uv-pick-color/props.js | 47 + .../uv-pick-color/uv-pick-color.vue | 551 +++++++ uni_modules/uv-pick-color/package.json | 89 ++ uni_modules/uv-pick-color/readme.md | 19 + uni_modules/uv-picker/changelog.md | 33 + .../uv-picker/components/uv-picker/props.js | 95 ++ .../components/uv-picker/uv-picker.vue | 330 ++++ uni_modules/uv-picker/package.json | 90 ++ uni_modules/uv-picker/readme.md | 21 + uni_modules/uv-popup/changelog.md | 18 + .../uv-popup/components/uv-popup/keypress.js | 45 + .../uv-popup/components/uv-popup/uv-popup.vue | 539 +++++++ uni_modules/uv-popup/package.json | 92 ++ uni_modules/uv-popup/readme.md | 21 + uni_modules/uv-qrcode/changelog.md | 13 + .../uv-qrcode/components/uv-qrcode/cache.js | 1 + .../uv-qrcode/gcanvas/bridge/bridge-weex.js | 241 +++ .../context-2d/FillStyleLinearGradient.js | 18 + .../gcanvas/context-2d/FillStylePattern.js | 8 + .../context-2d/FillStyleRadialGradient.js | 17 + .../gcanvas/context-2d/RenderingContext.js | 666 ++++++++ .../gcanvas/context-webgl/ActiveInfo.js | 11 + .../uv-qrcode/gcanvas/context-webgl/Buffer.js | 21 + .../gcanvas/context-webgl/Framebuffer.js | 21 + .../uv-qrcode/gcanvas/context-webgl/GLenum.js | 298 ++++ .../gcanvas/context-webgl/GLmethod.js | 142 ++ .../uv-qrcode/gcanvas/context-webgl/GLtype.js | 23 + .../gcanvas/context-webgl/Program.js | 21 + .../gcanvas/context-webgl/Renderbuffer.js | 21 + .../gcanvas/context-webgl/RenderingContext.js | 1191 +++++++++++++++ .../uv-qrcode/gcanvas/context-webgl/Shader.js | 22 + .../context-webgl/ShaderPrecisionFormat.js | 11 + .../gcanvas/context-webgl/Texture.js | 22 + .../gcanvas/context-webgl/UniformLocation.js | 22 + .../gcanvas/context-webgl/classUtils.js | 3 + .../uv-qrcode/gcanvas/env/canvas.js | 74 + .../components/uv-qrcode/gcanvas/env/image.js | 96 ++ .../components/uv-qrcode/gcanvas/env/tool.js | 24 + .../components/uv-qrcode/gcanvas/index.js | 39 + .../uv-qrcode/components/uv-qrcode/props.js | 85 ++ .../uv-qrcode/components/uv-qrcode/qrcode.js | 34 + .../uv-qrcode/components/uv-qrcode/queue.js | 41 + .../components/uv-qrcode/uv-qrcode.vue | 1038 +++++++++++++ uni_modules/uv-qrcode/package.json | 87 ++ uni_modules/uv-qrcode/readme.md | 21 + uni_modules/uv-radio/changelog.md | 31 + .../components/uv-radio-group/props.js | 89 ++ .../uv-radio-group/uv-radio-group.vue | 115 ++ .../uv-radio/components/uv-radio/props.js | 65 + .../uv-radio/components/uv-radio/uv-radio.vue | 348 +++++ uni_modules/uv-radio/package.json | 88 ++ uni_modules/uv-radio/readme.md | 19 + uni_modules/uv-rate/changelog.md | 17 + .../uv-rate/components/uv-rate/props.js | 73 + .../uv-rate/components/uv-rate/uv-rate.vue | 274 ++++ uni_modules/uv-rate/package.json | 88 ++ uni_modules/uv-rate/readme.md | 19 + uni_modules/uv-read-more/changelog.md | 7 + .../components/uv-read-more/props.js | 62 + .../components/uv-read-more/uv-read-more.vue | 162 ++ uni_modules/uv-read-more/package.json | 89 ++ uni_modules/uv-read-more/readme.md | 11 + uni_modules/uv-row/changelog.md | 5 + uni_modules/uv-row/components/uv-col/props.js | 30 + .../uv-row/components/uv-col/uv-col.vue | 165 ++ uni_modules/uv-row/components/uv-row/props.js | 20 + .../uv-row/components/uv-row/uv-row.vue | 95 ++ uni_modules/uv-row/package.json | 87 ++ uni_modules/uv-row/readme.md | 11 + uni_modules/uv-safe-bottom/changelog.md | 11 + .../uv-safe-bottom/uv-safe-bottom.vue | 67 + uni_modules/uv-safe-bottom/package.json | 87 ++ uni_modules/uv-safe-bottom/readme.md | 11 + uni_modules/uv-scroll-list/changelog.md | 12 + .../components/uv-scroll-list/nvue.js | 29 + .../components/uv-scroll-list/props.js | 35 + .../components/uv-scroll-list/scrollWxs.wxs | 51 + .../uv-scroll-list/uv-scroll-list.vue | 218 +++ uni_modules/uv-scroll-list/package.json | 87 ++ uni_modules/uv-scroll-list/readme.md | 19 + uni_modules/uv-search/changelog.md | 25 + .../uv-search/components/uv-search/props.js | 127 ++ .../components/uv-search/uv-search.vue | 311 ++++ uni_modules/uv-search/package.json | 89 ++ uni_modules/uv-search/readme.md | 19 + uni_modules/uv-skeleton/changelog.md | 9 + .../components/uv-skeleton/props.js | 65 + .../components/uv-skeleton/uv-skeleton.vue | 250 +++ uni_modules/uv-skeleton/package.json | 87 ++ uni_modules/uv-skeleton/readme.md | 11 + uni_modules/uv-skeletons/changelog.md | 4 + .../components/uv-skeletons/uv-skeletons.vue | 247 +++ uni_modules/uv-skeletons/package.json | 88 ++ uni_modules/uv-skeletons/readme.md | 23 + uni_modules/uv-slider/changelog.md | 9 + .../uv-slider/components/uv-slider/props.js | 58 + .../components/uv-slider/uv-slider.vue | 58 + uni_modules/uv-slider/package.json | 87 ++ uni_modules/uv-slider/readme.md | 15 + uni_modules/uv-status-bar/changelog.md | 7 + .../components/uv-status-bar/props.js | 8 + .../uv-status-bar/uv-status-bar.vue | 54 + uni_modules/uv-status-bar/package.json | 87 ++ uni_modules/uv-status-bar/readme.md | 10 + uni_modules/uv-steps/changelog.md | 10 + .../components/uv-steps-item/props.js | 25 + .../uv-steps-item/uv-steps-item.vue | 347 +++++ .../uv-steps/components/uv-steps/props.js | 40 + .../uv-steps/components/uv-steps/uv-steps.vue | 83 + uni_modules/uv-steps/package.json | 89 ++ uni_modules/uv-steps/readme.md | 11 + uni_modules/uv-sticky/changelog.md | 11 + .../uv-sticky/components/uv-sticky/props.js | 41 + .../components/uv-sticky/uv-sticky.vue | 223 +++ uni_modules/uv-sticky/package.json | 87 ++ uni_modules/uv-sticky/readme.md | 11 + uni_modules/uv-subsection/changelog.md | 10 + .../components/uv-subsection/props.js | 54 + .../uv-subsection/uv-subsection.vue | 269 ++++ uni_modules/uv-subsection/package.json | 87 ++ uni_modules/uv-subsection/readme.md | 11 + uni_modules/uv-swipe-action/changelog.md | 11 + .../uv-swipe-action-item/index - backup.wxs | 256 ++++ .../components/uv-swipe-action-item/index.wxs | 225 +++ .../uv-swipe-action-item/nvue - backup.js | 264 ++++ .../components/uv-swipe-action-item/nvue.js | 182 +++ .../components/uv-swipe-action-item/props.js | 40 + .../uv-swipe-action-item.vue | 200 +++ .../components/uv-swipe-action-item/wxs.js | 15 + .../components/uv-swipe-action/props.js | 10 + .../uv-swipe-action/uv-swipe-action.vue | 65 + uni_modules/uv-swipe-action/package.json | 88 ++ uni_modules/uv-swipe-action/readme.md | 11 + uni_modules/uv-swiper/changelog.md | 16 + .../components/uv-swiper-indicator/props.js | 30 + .../uv-swiper-indicator.vue | 112 ++ .../uv-swiper/components/uv-swiper/props.js | 136 ++ .../components/uv-swiper/uv-swiper.vue | 263 ++++ uni_modules/uv-swiper/package.json | 88 ++ uni_modules/uv-swiper/readme.md | 19 + uni_modules/uv-switch/changelog.md | 14 + .../uv-switch/components/uv-switch/props.js | 58 + .../components/uv-switch/uv-switch.vue | 192 +++ uni_modules/uv-switch/package.json | 88 ++ uni_modules/uv-switch/readme.md | 19 + uni_modules/uv-tabbar/changelog.md | 14 + .../components/uv-tabbar-item/props.js | 40 + .../uv-tabbar-item/uv-tabbar-item.vue | 146 ++ .../uv-tabbar/components/uv-tabbar/props.js | 50 + .../components/uv-tabbar/uv-tabbar.vue | 146 ++ uni_modules/uv-tabbar/package.json | 90 ++ uni_modules/uv-tabbar/readme.md | 21 + uni_modules/uv-tabs/changelog.md | 22 + .../uv-tabs/components/uv-tabs/props.js | 71 + .../uv-tabs/components/uv-tabs/uv-tabs.vue | 390 +++++ uni_modules/uv-tabs/package.json | 90 ++ uni_modules/uv-tabs/readme.md | 19 + uni_modules/uv-tags/changelog.md | 10 + .../uv-tags/components/uv-tags/props.js | 95 ++ .../uv-tags/components/uv-tags/uv-tags.vue | 379 +++++ uni_modules/uv-tags/package.json | 89 ++ uni_modules/uv-tags/readme.md | 11 + uni_modules/uv-text/changelog.md | 11 + .../uv-text/components/uv-text/props.js | 113 ++ .../uv-text/components/uv-text/uv-text.vue | 218 +++ .../uv-text/components/uv-text/value.js | 87 ++ uni_modules/uv-text/package.json | 89 ++ uni_modules/uv-text/readme.md | 17 + uni_modules/uv-textarea/changelog.md | 28 + .../components/uv-textarea/props.js | 138 ++ .../components/uv-textarea/uv-textarea.vue | 238 +++ uni_modules/uv-textarea/package.json | 87 ++ uni_modules/uv-textarea/readme.md | 19 + uni_modules/uv-toast/changelog.md | 10 + .../uv-toast/components/uv-toast/uv-toast.vue | 333 ++++ uni_modules/uv-toast/package.json | 90 ++ uni_modules/uv-toast/readme.md | 11 + uni_modules/uv-toolbar/changelog.md | 2 + .../uv-toolbar/components/uv-toolbar/props.js | 40 + .../components/uv-toolbar/uv-toolbar.vue | 109 ++ uni_modules/uv-toolbar/package.json | 87 ++ uni_modules/uv-toolbar/readme.md | 31 + uni_modules/uv-tooltip/changelog.md | 13 + .../uv-tooltip/components/uv-tooltip/props.js | 60 + .../components/uv-tooltip/uv-tooltip.vue | 372 +++++ uni_modules/uv-tooltip/package.json | 90 ++ uni_modules/uv-tooltip/readme.md | 11 + uni_modules/uv-transition/changelog.md | 19 + .../uv-transition/createAnimation.js | 131 ++ .../components/uv-transition/props.js | 31 + .../uv-transition/uv-transition.vue | 320 ++++ uni_modules/uv-transition/package.json | 87 ++ uni_modules/uv-transition/readme.md | 15 + uni_modules/uv-ui-tools/changelog.md | 76 + .../components/uv-ui-tools/uv-ui-tools.vue | 6 + uni_modules/uv-ui-tools/index.js | 79 + uni_modules/uv-ui-tools/index.scss | 7 + uni_modules/uv-ui-tools/libs/config/config.js | 34 + uni_modules/uv-ui-tools/libs/css/color.scss | 32 + uni_modules/uv-ui-tools/libs/css/common.scss | 100 ++ .../uv-ui-tools/libs/css/components.scss | 23 + .../uv-ui-tools/libs/css/variable.scss | 111 ++ uni_modules/uv-ui-tools/libs/css/vue.scss | 40 + .../libs/function/colorGradient.js | 134 ++ .../uv-ui-tools/libs/function/debounce.js | 29 + .../uv-ui-tools/libs/function/digit.js | 167 ++ .../uv-ui-tools/libs/function/index.js | 734 +++++++++ .../uv-ui-tools/libs/function/platform.js | 75 + uni_modules/uv-ui-tools/libs/function/test.js | 287 ++++ .../uv-ui-tools/libs/function/throttle.js | 30 + .../libs/luch-request/adapters/index.js | 132 ++ .../luch-request/core/InterceptorManager.js | 51 + .../libs/luch-request/core/Request.js | 201 +++ .../libs/luch-request/core/buildFullPath.js | 20 + .../libs/luch-request/core/defaults.js | 33 + .../libs/luch-request/core/dispatchRequest.js | 6 + .../libs/luch-request/core/mergeConfig.js | 126 ++ .../libs/luch-request/core/settle.js | 16 + .../libs/luch-request/helpers/buildURL.js | 64 + .../libs/luch-request/helpers/combineURLs.js | 14 + .../luch-request/helpers/isAbsoluteURL.js | 14 + .../uv-ui-tools/libs/luch-request/index.d.ts | 197 +++ .../uv-ui-tools/libs/luch-request/index.js | 2 + .../uv-ui-tools/libs/luch-request/utils.js | 135 ++ .../libs/luch-request/utils/clone.js | 264 ++++ uni_modules/uv-ui-tools/libs/mixin/button.js | 13 + uni_modules/uv-ui-tools/libs/mixin/mixin.js | 172 +++ uni_modules/uv-ui-tools/libs/mixin/mpMixin.js | 8 + uni_modules/uv-ui-tools/libs/mixin/mpShare.js | 13 + .../uv-ui-tools/libs/mixin/openType.js | 47 + uni_modules/uv-ui-tools/libs/mixin/touch.js | 59 + uni_modules/uv-ui-tools/libs/util/dayjs.js | 216 +++ uni_modules/uv-ui-tools/libs/util/route.js | 126 ++ uni_modules/uv-ui-tools/package.json | 81 + uni_modules/uv-ui-tools/readme.md | 23 + uni_modules/uv-ui-tools/theme.scss | 43 + uni_modules/uv-ui/changelog.md | 353 +++++ uni_modules/uv-ui/components/uv-ui/uv-ui.vue | 7 + uni_modules/uv-ui/package.json | 162 ++ uni_modules/uv-ui/readme.md | 164 ++ uni_modules/uv-upload/changelog.md | 17 + .../uv-preview-video/uv-preview-video.vue | 52 + .../uv-upload/components/uv-upload/mixin.js | 22 + .../uv-upload/components/uv-upload/props.js | 130 ++ .../uv-upload/components/uv-upload/utils.js | 151 ++ .../components/uv-upload/uv-upload.vue | 488 ++++++ uni_modules/uv-upload/package.json | 90 ++ uni_modules/uv-upload/readme.md | 11 + uni_modules/uv-vtabs/changelog.md | 20 + .../uv-vtabs-item/uv-vtabs-item.vue | 68 + .../uv-vtabs/components/uv-vtabs/props.js | 79 + .../uv-vtabs/components/uv-vtabs/uv-vtabs.vue | 438 ++++++ uni_modules/uv-vtabs/package.json | 87 ++ uni_modules/uv-vtabs/readme.md | 19 + uni_modules/uv-waterfall/changelog.md | 24 + .../components/uv-waterfall/props.js | 69 + .../components/uv-waterfall/uv-waterfall.vue | 265 ++++ uni_modules/uv-waterfall/package.json | 89 ++ uni_modules/uv-waterfall/readme.md | 19 + utils/cache.js | 59 + utils/index.js | 228 +++ utils/request.js | 286 ++++ vite.config.js | 38 + 590 files changed, 60161 insertions(+) create mode 100644 .commitlintrc.js create mode 100644 .editorconfig create mode 100644 .env.development create mode 100644 .env.production create mode 100644 .gitignore create mode 100644 .husky/commit-msg create mode 100644 .husky/pre-commit create mode 100644 .lintstagedrc.js create mode 100644 .prettierignore create mode 100644 .prettierrc.js create mode 100644 App.vue create mode 100644 LICENSE create mode 100644 README.md create mode 100644 api/index.js create mode 100644 api/modules/auth.js create mode 100644 api/modules/user.js create mode 100644 components/HeaderCustom/HeaderCustom.vue create mode 100644 components/IconFont/IconFont.vue create mode 100644 components/IconFont/iconfont.css create mode 100644 components/IconFont/iconfont.json create mode 100644 components/IconFont/iconfont.ttf create mode 100644 components/IconFont/iconfont.woff create mode 100644 components/IconFont/iconfont.woff2 create mode 100644 components/LangSelect/LangSelect.vue create mode 100644 components/Login/Login.vue create mode 100644 components/UploadFile/UploadFile.vue create mode 100644 components/UploadFile/example.vue create mode 100644 hooks/usePermission.js create mode 100644 index.html create mode 100644 locale/en.json create mode 100644 locale/index.js create mode 100644 locale/ja.json create mode 100644 locale/uni-app.ja.json create mode 100644 locale/zh-Hans.json create mode 100644 locale/zh-Hant.json create mode 100644 main.js create mode 100644 manifest.json create mode 100644 package.json create mode 100644 pages.json create mode 100644 pages/consumption/consumption.vue create mode 100644 pages/index/index.vue create mode 100644 pages/index/index1.vue create mode 100644 pages/login/login.vue create mode 100644 pages/mine/mine.vue create mode 100644 pages/order/order.vue create mode 100644 pagesA/edit-profile/edit-profile.vue create mode 100644 pagesA/generate-record/generate-record.vue create mode 100644 pagesA/user-agreement/user-agreement.vue create mode 100644 plugins/index.js create mode 100644 plugins/permission.js create mode 100644 plugins/ui.js create mode 100644 router/index.js create mode 100644 static/imgs/code.png create mode 100644 static/imgs/indexImg.png create mode 100644 static/imgs/phone.png create mode 100644 static/json/regions.js create mode 100644 static/tabbar/appointment.png create mode 100644 static/tabbar/appointment_HL.png create mode 100644 static/tabbar/index.png create mode 100644 static/tabbar/index_HL.png create mode 100644 static/tabbar/mine.png create mode 100644 static/tabbar/mine_HL.png create mode 100644 store/index.js create mode 100644 store/modules/auth.js create mode 100644 store/modules/user.js create mode 100644 tsconfig.json create mode 100644 uni.scss create mode 100644 uni_modules/uv-action-sheet/changelog.md create mode 100644 uni_modules/uv-action-sheet/components/uv-action-sheet/props.js create mode 100644 uni_modules/uv-action-sheet/components/uv-action-sheet/uv-action-sheet.vue create mode 100644 uni_modules/uv-action-sheet/package.json create mode 100644 uni_modules/uv-action-sheet/readme.md create mode 100644 uni_modules/uv-album/changelog.md create mode 100644 uni_modules/uv-album/components/uv-album/uv-album.vue create mode 100644 uni_modules/uv-album/package.json create mode 100644 uni_modules/uv-album/readme.md create mode 100644 uni_modules/uv-alert/changelog.md create mode 100644 uni_modules/uv-alert/components/uv-alert/props.js create mode 100644 uni_modules/uv-alert/components/uv-alert/uv-alert.vue create mode 100644 uni_modules/uv-alert/package.json create mode 100644 uni_modules/uv-alert/readme.md create mode 100644 uni_modules/uv-avatar/changelog.md create mode 100644 uni_modules/uv-avatar/components/uv-avatar-group/props.js create mode 100644 uni_modules/uv-avatar/components/uv-avatar-group/uv-avatar-group.vue create mode 100644 uni_modules/uv-avatar/components/uv-avatar/props.js create mode 100644 uni_modules/uv-avatar/components/uv-avatar/uv-avatar.vue create mode 100644 uni_modules/uv-avatar/package.json create mode 100644 uni_modules/uv-avatar/readme.md create mode 100644 uni_modules/uv-back-top/changelog.md create mode 100644 uni_modules/uv-back-top/components/uv-back-top/props.js create mode 100644 uni_modules/uv-back-top/components/uv-back-top/uv-back-top.vue create mode 100644 uni_modules/uv-back-top/package.json create mode 100644 uni_modules/uv-back-top/readme.md create mode 100644 uni_modules/uv-badge/changelog.md create mode 100644 uni_modules/uv-badge/components/uv-badge/props.js create mode 100644 uni_modules/uv-badge/components/uv-badge/uv-badge.vue create mode 100644 uni_modules/uv-badge/package.json create mode 100644 uni_modules/uv-badge/readme.md create mode 100644 uni_modules/uv-button/changelog.md create mode 100644 uni_modules/uv-button/components/uv-button/nvue.scss create mode 100644 uni_modules/uv-button/components/uv-button/props.js create mode 100644 uni_modules/uv-button/components/uv-button/uv-button.vue create mode 100644 uni_modules/uv-button/components/uv-button/vue.scss create mode 100644 uni_modules/uv-button/package.json create mode 100644 uni_modules/uv-button/readme.md create mode 100644 uni_modules/uv-calendar/changelog.md create mode 100644 uni_modules/uv-calendar/components/uv-calendar/calendar.js create mode 100644 uni_modules/uv-calendar/components/uv-calendar/header.vue create mode 100644 uni_modules/uv-calendar/components/uv-calendar/month.vue create mode 100644 uni_modules/uv-calendar/components/uv-calendar/props.js create mode 100644 uni_modules/uv-calendar/components/uv-calendar/uv-calendar.vue create mode 100644 uni_modules/uv-calendar/package.json create mode 100644 uni_modules/uv-calendar/readme.md create mode 100644 uni_modules/uv-calendars/changelog.md create mode 100644 uni_modules/uv-calendars/components/uv-calendars/calendar-body.vue create mode 100644 uni_modules/uv-calendars/components/uv-calendars/calendar-item.vue create mode 100644 uni_modules/uv-calendars/components/uv-calendars/calendar.js create mode 100644 uni_modules/uv-calendars/components/uv-calendars/i18n/en.json create mode 100644 uni_modules/uv-calendars/components/uv-calendars/i18n/index.js create mode 100644 uni_modules/uv-calendars/components/uv-calendars/i18n/zh-Hans.json create mode 100644 uni_modules/uv-calendars/components/uv-calendars/i18n/zh-Hant.json create mode 100644 uni_modules/uv-calendars/components/uv-calendars/util.js create mode 100644 uni_modules/uv-calendars/components/uv-calendars/uv-calendars.vue create mode 100644 uni_modules/uv-calendars/package.json create mode 100644 uni_modules/uv-calendars/readme.md create mode 100644 uni_modules/uv-cell/changelog.md create mode 100644 uni_modules/uv-cell/components/uv-cell-group/props.js create mode 100644 uni_modules/uv-cell/components/uv-cell-group/uv-cell-group.vue create mode 100644 uni_modules/uv-cell/components/uv-cell/props.js create mode 100644 uni_modules/uv-cell/components/uv-cell/uv-cell.vue create mode 100644 uni_modules/uv-cell/package.json create mode 100644 uni_modules/uv-cell/readme.md create mode 100644 uni_modules/uv-checkbox/changelog.md create mode 100644 uni_modules/uv-checkbox/components/uv-checkbox-group/props.js create mode 100644 uni_modules/uv-checkbox/components/uv-checkbox-group/uv-checkbox-group.vue create mode 100644 uni_modules/uv-checkbox/components/uv-checkbox/props.js create mode 100644 uni_modules/uv-checkbox/components/uv-checkbox/uv-checkbox.vue create mode 100644 uni_modules/uv-checkbox/package.json create mode 100644 uni_modules/uv-checkbox/readme.md create mode 100644 uni_modules/uv-code-input/changelog.md create mode 100644 uni_modules/uv-code-input/components/uv-code-input/props.js create mode 100644 uni_modules/uv-code-input/components/uv-code-input/uv-code-input.vue create mode 100644 uni_modules/uv-code-input/package.json create mode 100644 uni_modules/uv-code-input/readme.md create mode 100644 uni_modules/uv-code/changelog.md create mode 100644 uni_modules/uv-code/components/uv-code/props.js create mode 100644 uni_modules/uv-code/components/uv-code/uv-code.vue create mode 100644 uni_modules/uv-code/package.json create mode 100644 uni_modules/uv-code/readme.md create mode 100644 uni_modules/uv-collapse/changelog.md create mode 100644 uni_modules/uv-collapse/components/uv-collapse-item/props.js create mode 100644 uni_modules/uv-collapse/components/uv-collapse-item/uv-collapse-item.vue create mode 100644 uni_modules/uv-collapse/components/uv-collapse/props.js create mode 100644 uni_modules/uv-collapse/components/uv-collapse/uv-collapse.vue create mode 100644 uni_modules/uv-collapse/package.json create mode 100644 uni_modules/uv-collapse/readme.md create mode 100644 uni_modules/uv-count-down/changelog.md create mode 100644 uni_modules/uv-count-down/components/uv-count-down/props.js create mode 100644 uni_modules/uv-count-down/components/uv-count-down/utils.js create mode 100644 uni_modules/uv-count-down/components/uv-count-down/uv-count-down.vue create mode 100644 uni_modules/uv-count-down/package.json create mode 100644 uni_modules/uv-count-down/readme.md create mode 100644 uni_modules/uv-count-to/changelog.md create mode 100644 uni_modules/uv-count-to/components/uv-count-to/props.js create mode 100644 uni_modules/uv-count-to/components/uv-count-to/uv-count-to.vue create mode 100644 uni_modules/uv-count-to/package.json create mode 100644 uni_modules/uv-count-to/readme.md create mode 100644 uni_modules/uv-datetime-picker/changelog.md create mode 100644 uni_modules/uv-datetime-picker/components/uv-datetime-picker/props.js create mode 100644 uni_modules/uv-datetime-picker/components/uv-datetime-picker/uv-datetime-picker.vue create mode 100644 uni_modules/uv-datetime-picker/package.json create mode 100644 uni_modules/uv-datetime-picker/readme.md create mode 100644 uni_modules/uv-divider/changelog.md create mode 100644 uni_modules/uv-divider/components/uv-divider/props.js create mode 100644 uni_modules/uv-divider/components/uv-divider/uv-divider.vue create mode 100644 uni_modules/uv-divider/package.json create mode 100644 uni_modules/uv-divider/readme.md create mode 100644 uni_modules/uv-drop-down/changelog.md create mode 100644 uni_modules/uv-drop-down/components/uv-drop-down-item/uv-drop-down-item.vue create mode 100644 uni_modules/uv-drop-down/components/uv-drop-down-popup/uv-drop-down-popup.vue create mode 100644 uni_modules/uv-drop-down/components/uv-drop-down/uv-drop-down.vue create mode 100644 uni_modules/uv-drop-down/package.json create mode 100644 uni_modules/uv-drop-down/readme.md create mode 100644 uni_modules/uv-empty/changelog.md create mode 100644 uni_modules/uv-empty/components/uv-empty/props.js create mode 100644 uni_modules/uv-empty/components/uv-empty/uv-empty.vue create mode 100644 uni_modules/uv-empty/package.json create mode 100644 uni_modules/uv-empty/readme.md create mode 100644 uni_modules/uv-form/changelog.md create mode 100644 uni_modules/uv-form/components/uv-form-item/props.js create mode 100644 uni_modules/uv-form/components/uv-form-item/uv-form-item.vue create mode 100644 uni_modules/uv-form/components/uv-form/props.js create mode 100644 uni_modules/uv-form/components/uv-form/uv-form.vue create mode 100644 uni_modules/uv-form/components/uv-form/valid.js create mode 100644 uni_modules/uv-form/package.json create mode 100644 uni_modules/uv-form/readme.md create mode 100644 uni_modules/uv-gap/changelog.md create mode 100644 uni_modules/uv-gap/components/uv-gap/props.js create mode 100644 uni_modules/uv-gap/components/uv-gap/uv-gap.vue create mode 100644 uni_modules/uv-gap/package.json create mode 100644 uni_modules/uv-gap/readme.md create mode 100644 uni_modules/uv-grid/changelog.md create mode 100644 uni_modules/uv-grid/components/uv-grid-item/props.js create mode 100644 uni_modules/uv-grid/components/uv-grid-item/uv-grid-item.vue create mode 100644 uni_modules/uv-grid/components/uv-grid/props.js create mode 100644 uni_modules/uv-grid/components/uv-grid/uv-grid.vue create mode 100644 uni_modules/uv-grid/package.json create mode 100644 uni_modules/uv-grid/readme.md create mode 100644 uni_modules/uv-icon/changelog.md create mode 100644 uni_modules/uv-icon/components/uv-icon/icons.js create mode 100644 uni_modules/uv-icon/components/uv-icon/props.js create mode 100644 uni_modules/uv-icon/components/uv-icon/uv-icon.vue create mode 100644 uni_modules/uv-icon/components/uv-icon/uvicons.ttf create mode 100644 uni_modules/uv-icon/package.json create mode 100644 uni_modules/uv-icon/readme.md create mode 100644 uni_modules/uv-image/changelog.md create mode 100644 uni_modules/uv-image/components/uv-image/props.js create mode 100644 uni_modules/uv-image/components/uv-image/uv-image.vue create mode 100644 uni_modules/uv-image/package.json create mode 100644 uni_modules/uv-image/readme.md create mode 100644 uni_modules/uv-index-list/changelog.md create mode 100644 uni_modules/uv-index-list/components/uv-index-anchor/props.js create mode 100644 uni_modules/uv-index-list/components/uv-index-anchor/uv-index-anchor.vue create mode 100644 uni_modules/uv-index-list/components/uv-index-item/uv-index-item.vue create mode 100644 uni_modules/uv-index-list/components/uv-index-list/props.js create mode 100644 uni_modules/uv-index-list/components/uv-index-list/uv-index-list.vue create mode 100644 uni_modules/uv-index-list/package.json create mode 100644 uni_modules/uv-index-list/readme.md create mode 100644 uni_modules/uv-input/changelog.md create mode 100644 uni_modules/uv-input/components/uv-input/props.js create mode 100644 uni_modules/uv-input/components/uv-input/uv-input.vue create mode 100644 uni_modules/uv-input/package.json create mode 100644 uni_modules/uv-input/readme.md create mode 100644 uni_modules/uv-keyboard/changelog.md create mode 100644 uni_modules/uv-keyboard/components/uv-keyboard-car/props.js create mode 100644 uni_modules/uv-keyboard/components/uv-keyboard-car/uv-keyboard-car.vue create mode 100644 uni_modules/uv-keyboard/components/uv-keyboard-number/props.js create mode 100644 uni_modules/uv-keyboard/components/uv-keyboard-number/uv-keyboard-number.vue create mode 100644 uni_modules/uv-keyboard/components/uv-keyboard/props.js create mode 100644 uni_modules/uv-keyboard/components/uv-keyboard/uv-keyboard.vue create mode 100644 uni_modules/uv-keyboard/package.json create mode 100644 uni_modules/uv-keyboard/readme.md create mode 100644 uni_modules/uv-line-progress/changelog.md create mode 100644 uni_modules/uv-line-progress/components/uv-line-progress/props.js create mode 100644 uni_modules/uv-line-progress/components/uv-line-progress/uv-line-progress.vue create mode 100644 uni_modules/uv-line-progress/package.json create mode 100644 uni_modules/uv-line-progress/readme.md create mode 100644 uni_modules/uv-line/changelog.md create mode 100644 uni_modules/uv-line/components/uv-line/props.js create mode 100644 uni_modules/uv-line/components/uv-line/uv-line.vue create mode 100644 uni_modules/uv-line/package.json create mode 100644 uni_modules/uv-line/readme.md create mode 100644 uni_modules/uv-link/changelog.md create mode 100644 uni_modules/uv-link/components/uv-link/props.js create mode 100644 uni_modules/uv-link/components/uv-link/uv-link.vue create mode 100644 uni_modules/uv-link/package.json create mode 100644 uni_modules/uv-link/readme.md create mode 100644 uni_modules/uv-list/changelog.md create mode 100644 uni_modules/uv-list/components/uv-list-item/uv-list-item.vue create mode 100644 uni_modules/uv-list/components/uv-list/uv-list.vue create mode 100644 uni_modules/uv-list/package.json create mode 100644 uni_modules/uv-list/readme.md create mode 100644 uni_modules/uv-load-more/changelog.md create mode 100644 uni_modules/uv-load-more/components/uv-load-more/props.js create mode 100644 uni_modules/uv-load-more/components/uv-load-more/uv-load-more.vue create mode 100644 uni_modules/uv-load-more/package.json create mode 100644 uni_modules/uv-load-more/readme.md create mode 100644 uni_modules/uv-loading-icon/changelog.md create mode 100644 uni_modules/uv-loading-icon/components/uv-loading-icon/props.js create mode 100644 uni_modules/uv-loading-icon/components/uv-loading-icon/uv-loading-icon.vue create mode 100644 uni_modules/uv-loading-icon/package.json create mode 100644 uni_modules/uv-loading-icon/readme.md create mode 100644 uni_modules/uv-loading-page/changelog.md create mode 100644 uni_modules/uv-loading-page/components/uv-loading-page/props.js create mode 100644 uni_modules/uv-loading-page/components/uv-loading-page/uv-loading-page.vue create mode 100644 uni_modules/uv-loading-page/package.json create mode 100644 uni_modules/uv-loading-page/readme.md create mode 100644 uni_modules/uv-modal/changelog.md create mode 100644 uni_modules/uv-modal/components/uv-modal/props.js create mode 100644 uni_modules/uv-modal/components/uv-modal/uv-modal.vue create mode 100644 uni_modules/uv-modal/package.json create mode 100644 uni_modules/uv-modal/readme.md create mode 100644 uni_modules/uv-navbar/changelog.md create mode 100644 uni_modules/uv-navbar/components/uv-navbar/props.js create mode 100644 uni_modules/uv-navbar/components/uv-navbar/uv-navbar.vue create mode 100644 uni_modules/uv-navbar/package.json create mode 100644 uni_modules/uv-navbar/readme.md create mode 100644 uni_modules/uv-no-network/changelog.md create mode 100644 uni_modules/uv-no-network/components/uv-no-network/props.js create mode 100644 uni_modules/uv-no-network/components/uv-no-network/uv-no-network.vue create mode 100644 uni_modules/uv-no-network/package.json create mode 100644 uni_modules/uv-no-network/readme.md create mode 100644 uni_modules/uv-notice-bar/changelog.md create mode 100644 uni_modules/uv-notice-bar/components/uv-column-notice/props.js create mode 100644 uni_modules/uv-notice-bar/components/uv-column-notice/uv-column-notice.vue create mode 100644 uni_modules/uv-notice-bar/components/uv-notice-bar/props.js create mode 100644 uni_modules/uv-notice-bar/components/uv-notice-bar/uv-notice-bar.vue create mode 100644 uni_modules/uv-notice-bar/components/uv-row-notice/props.js create mode 100644 uni_modules/uv-notice-bar/components/uv-row-notice/uv-row-notice.vue create mode 100644 uni_modules/uv-notice-bar/package.json create mode 100644 uni_modules/uv-notice-bar/readme.md create mode 100644 uni_modules/uv-notify/changelog.md create mode 100644 uni_modules/uv-notify/components/uv-notify/props.js create mode 100644 uni_modules/uv-notify/components/uv-notify/uv-notify.vue create mode 100644 uni_modules/uv-notify/package.json create mode 100644 uni_modules/uv-notify/readme.md create mode 100644 uni_modules/uv-number-box/changelog.md create mode 100644 uni_modules/uv-number-box/components/uv-number-box/props.js create mode 100644 uni_modules/uv-number-box/components/uv-number-box/uv-number-box.vue create mode 100644 uni_modules/uv-number-box/package.json create mode 100644 uni_modules/uv-number-box/readme.md create mode 100644 uni_modules/uv-overlay/changelog.md create mode 100644 uni_modules/uv-overlay/components/uv-overlay/props.js create mode 100644 uni_modules/uv-overlay/components/uv-overlay/uv-overlay.vue create mode 100644 uni_modules/uv-overlay/package.json create mode 100644 uni_modules/uv-overlay/readme.md create mode 100644 uni_modules/uv-parse/changelog.md create mode 100644 uni_modules/uv-parse/components/uv-parse/node/node.vue create mode 100644 uni_modules/uv-parse/components/uv-parse/parser.js create mode 100644 uni_modules/uv-parse/components/uv-parse/uv-parse.vue create mode 100644 uni_modules/uv-parse/package.json create mode 100644 uni_modules/uv-parse/readme.md create mode 100644 uni_modules/uv-parse/static/app-plus/uv-parse/js/handler.js create mode 100644 uni_modules/uv-parse/static/app-plus/uv-parse/js/uni.webview.min.js create mode 100644 uni_modules/uv-parse/static/app-plus/uv-parse/local.html create mode 100644 uni_modules/uv-pick-color/changelog.md create mode 100644 uni_modules/uv-pick-color/components/uv-pick-color/colors.js create mode 100644 uni_modules/uv-pick-color/components/uv-pick-color/props.js create mode 100644 uni_modules/uv-pick-color/components/uv-pick-color/uv-pick-color.vue create mode 100644 uni_modules/uv-pick-color/package.json create mode 100644 uni_modules/uv-pick-color/readme.md create mode 100644 uni_modules/uv-picker/changelog.md create mode 100644 uni_modules/uv-picker/components/uv-picker/props.js create mode 100644 uni_modules/uv-picker/components/uv-picker/uv-picker.vue create mode 100644 uni_modules/uv-picker/package.json create mode 100644 uni_modules/uv-picker/readme.md create mode 100644 uni_modules/uv-popup/changelog.md create mode 100644 uni_modules/uv-popup/components/uv-popup/keypress.js create mode 100644 uni_modules/uv-popup/components/uv-popup/uv-popup.vue create mode 100644 uni_modules/uv-popup/package.json create mode 100644 uni_modules/uv-popup/readme.md create mode 100644 uni_modules/uv-qrcode/changelog.md create mode 100644 uni_modules/uv-qrcode/components/uv-qrcode/cache.js create mode 100644 uni_modules/uv-qrcode/components/uv-qrcode/gcanvas/bridge/bridge-weex.js create mode 100644 uni_modules/uv-qrcode/components/uv-qrcode/gcanvas/context-2d/FillStyleLinearGradient.js create mode 100644 uni_modules/uv-qrcode/components/uv-qrcode/gcanvas/context-2d/FillStylePattern.js create mode 100644 uni_modules/uv-qrcode/components/uv-qrcode/gcanvas/context-2d/FillStyleRadialGradient.js create mode 100644 uni_modules/uv-qrcode/components/uv-qrcode/gcanvas/context-2d/RenderingContext.js create mode 100644 uni_modules/uv-qrcode/components/uv-qrcode/gcanvas/context-webgl/ActiveInfo.js create mode 100644 uni_modules/uv-qrcode/components/uv-qrcode/gcanvas/context-webgl/Buffer.js create mode 100644 uni_modules/uv-qrcode/components/uv-qrcode/gcanvas/context-webgl/Framebuffer.js create mode 100644 uni_modules/uv-qrcode/components/uv-qrcode/gcanvas/context-webgl/GLenum.js create mode 100644 uni_modules/uv-qrcode/components/uv-qrcode/gcanvas/context-webgl/GLmethod.js create mode 100644 uni_modules/uv-qrcode/components/uv-qrcode/gcanvas/context-webgl/GLtype.js create mode 100644 uni_modules/uv-qrcode/components/uv-qrcode/gcanvas/context-webgl/Program.js create mode 100644 uni_modules/uv-qrcode/components/uv-qrcode/gcanvas/context-webgl/Renderbuffer.js create mode 100644 uni_modules/uv-qrcode/components/uv-qrcode/gcanvas/context-webgl/RenderingContext.js create mode 100644 uni_modules/uv-qrcode/components/uv-qrcode/gcanvas/context-webgl/Shader.js create mode 100644 uni_modules/uv-qrcode/components/uv-qrcode/gcanvas/context-webgl/ShaderPrecisionFormat.js create mode 100644 uni_modules/uv-qrcode/components/uv-qrcode/gcanvas/context-webgl/Texture.js create mode 100644 uni_modules/uv-qrcode/components/uv-qrcode/gcanvas/context-webgl/UniformLocation.js create mode 100644 uni_modules/uv-qrcode/components/uv-qrcode/gcanvas/context-webgl/classUtils.js create mode 100644 uni_modules/uv-qrcode/components/uv-qrcode/gcanvas/env/canvas.js create mode 100644 uni_modules/uv-qrcode/components/uv-qrcode/gcanvas/env/image.js create mode 100644 uni_modules/uv-qrcode/components/uv-qrcode/gcanvas/env/tool.js create mode 100644 uni_modules/uv-qrcode/components/uv-qrcode/gcanvas/index.js create mode 100644 uni_modules/uv-qrcode/components/uv-qrcode/props.js create mode 100644 uni_modules/uv-qrcode/components/uv-qrcode/qrcode.js create mode 100644 uni_modules/uv-qrcode/components/uv-qrcode/queue.js create mode 100644 uni_modules/uv-qrcode/components/uv-qrcode/uv-qrcode.vue create mode 100644 uni_modules/uv-qrcode/package.json create mode 100644 uni_modules/uv-qrcode/readme.md create mode 100644 uni_modules/uv-radio/changelog.md create mode 100644 uni_modules/uv-radio/components/uv-radio-group/props.js create mode 100644 uni_modules/uv-radio/components/uv-radio-group/uv-radio-group.vue create mode 100644 uni_modules/uv-radio/components/uv-radio/props.js create mode 100644 uni_modules/uv-radio/components/uv-radio/uv-radio.vue create mode 100644 uni_modules/uv-radio/package.json create mode 100644 uni_modules/uv-radio/readme.md create mode 100644 uni_modules/uv-rate/changelog.md create mode 100644 uni_modules/uv-rate/components/uv-rate/props.js create mode 100644 uni_modules/uv-rate/components/uv-rate/uv-rate.vue create mode 100644 uni_modules/uv-rate/package.json create mode 100644 uni_modules/uv-rate/readme.md create mode 100644 uni_modules/uv-read-more/changelog.md create mode 100644 uni_modules/uv-read-more/components/uv-read-more/props.js create mode 100644 uni_modules/uv-read-more/components/uv-read-more/uv-read-more.vue create mode 100644 uni_modules/uv-read-more/package.json create mode 100644 uni_modules/uv-read-more/readme.md create mode 100644 uni_modules/uv-row/changelog.md create mode 100644 uni_modules/uv-row/components/uv-col/props.js create mode 100644 uni_modules/uv-row/components/uv-col/uv-col.vue create mode 100644 uni_modules/uv-row/components/uv-row/props.js create mode 100644 uni_modules/uv-row/components/uv-row/uv-row.vue create mode 100644 uni_modules/uv-row/package.json create mode 100644 uni_modules/uv-row/readme.md create mode 100644 uni_modules/uv-safe-bottom/changelog.md create mode 100644 uni_modules/uv-safe-bottom/components/uv-safe-bottom/uv-safe-bottom.vue create mode 100644 uni_modules/uv-safe-bottom/package.json create mode 100644 uni_modules/uv-safe-bottom/readme.md create mode 100644 uni_modules/uv-scroll-list/changelog.md create mode 100644 uni_modules/uv-scroll-list/components/uv-scroll-list/nvue.js create mode 100644 uni_modules/uv-scroll-list/components/uv-scroll-list/props.js create mode 100644 uni_modules/uv-scroll-list/components/uv-scroll-list/scrollWxs.wxs create mode 100644 uni_modules/uv-scroll-list/components/uv-scroll-list/uv-scroll-list.vue create mode 100644 uni_modules/uv-scroll-list/package.json create mode 100644 uni_modules/uv-scroll-list/readme.md create mode 100644 uni_modules/uv-search/changelog.md create mode 100644 uni_modules/uv-search/components/uv-search/props.js create mode 100644 uni_modules/uv-search/components/uv-search/uv-search.vue create mode 100644 uni_modules/uv-search/package.json create mode 100644 uni_modules/uv-search/readme.md create mode 100644 uni_modules/uv-skeleton/changelog.md create mode 100644 uni_modules/uv-skeleton/components/uv-skeleton/props.js create mode 100644 uni_modules/uv-skeleton/components/uv-skeleton/uv-skeleton.vue create mode 100644 uni_modules/uv-skeleton/package.json create mode 100644 uni_modules/uv-skeleton/readme.md create mode 100644 uni_modules/uv-skeletons/changelog.md create mode 100644 uni_modules/uv-skeletons/components/uv-skeletons/uv-skeletons.vue create mode 100644 uni_modules/uv-skeletons/package.json create mode 100644 uni_modules/uv-skeletons/readme.md create mode 100644 uni_modules/uv-slider/changelog.md create mode 100644 uni_modules/uv-slider/components/uv-slider/props.js create mode 100644 uni_modules/uv-slider/components/uv-slider/uv-slider.vue create mode 100644 uni_modules/uv-slider/package.json create mode 100644 uni_modules/uv-slider/readme.md create mode 100644 uni_modules/uv-status-bar/changelog.md create mode 100644 uni_modules/uv-status-bar/components/uv-status-bar/props.js create mode 100644 uni_modules/uv-status-bar/components/uv-status-bar/uv-status-bar.vue create mode 100644 uni_modules/uv-status-bar/package.json create mode 100644 uni_modules/uv-status-bar/readme.md create mode 100644 uni_modules/uv-steps/changelog.md create mode 100644 uni_modules/uv-steps/components/uv-steps-item/props.js create mode 100644 uni_modules/uv-steps/components/uv-steps-item/uv-steps-item.vue create mode 100644 uni_modules/uv-steps/components/uv-steps/props.js create mode 100644 uni_modules/uv-steps/components/uv-steps/uv-steps.vue create mode 100644 uni_modules/uv-steps/package.json create mode 100644 uni_modules/uv-steps/readme.md create mode 100644 uni_modules/uv-sticky/changelog.md create mode 100644 uni_modules/uv-sticky/components/uv-sticky/props.js create mode 100644 uni_modules/uv-sticky/components/uv-sticky/uv-sticky.vue create mode 100644 uni_modules/uv-sticky/package.json create mode 100644 uni_modules/uv-sticky/readme.md create mode 100644 uni_modules/uv-subsection/changelog.md create mode 100644 uni_modules/uv-subsection/components/uv-subsection/props.js create mode 100644 uni_modules/uv-subsection/components/uv-subsection/uv-subsection.vue create mode 100644 uni_modules/uv-subsection/package.json create mode 100644 uni_modules/uv-subsection/readme.md create mode 100644 uni_modules/uv-swipe-action/changelog.md create mode 100644 uni_modules/uv-swipe-action/components/uv-swipe-action-item/index - backup.wxs create mode 100644 uni_modules/uv-swipe-action/components/uv-swipe-action-item/index.wxs create mode 100644 uni_modules/uv-swipe-action/components/uv-swipe-action-item/nvue - backup.js create mode 100644 uni_modules/uv-swipe-action/components/uv-swipe-action-item/nvue.js create mode 100644 uni_modules/uv-swipe-action/components/uv-swipe-action-item/props.js create mode 100644 uni_modules/uv-swipe-action/components/uv-swipe-action-item/uv-swipe-action-item.vue create mode 100644 uni_modules/uv-swipe-action/components/uv-swipe-action-item/wxs.js create mode 100644 uni_modules/uv-swipe-action/components/uv-swipe-action/props.js create mode 100644 uni_modules/uv-swipe-action/components/uv-swipe-action/uv-swipe-action.vue create mode 100644 uni_modules/uv-swipe-action/package.json create mode 100644 uni_modules/uv-swipe-action/readme.md create mode 100644 uni_modules/uv-swiper/changelog.md create mode 100644 uni_modules/uv-swiper/components/uv-swiper-indicator/props.js create mode 100644 uni_modules/uv-swiper/components/uv-swiper-indicator/uv-swiper-indicator.vue create mode 100644 uni_modules/uv-swiper/components/uv-swiper/props.js create mode 100644 uni_modules/uv-swiper/components/uv-swiper/uv-swiper.vue create mode 100644 uni_modules/uv-swiper/package.json create mode 100644 uni_modules/uv-swiper/readme.md create mode 100644 uni_modules/uv-switch/changelog.md create mode 100644 uni_modules/uv-switch/components/uv-switch/props.js create mode 100644 uni_modules/uv-switch/components/uv-switch/uv-switch.vue create mode 100644 uni_modules/uv-switch/package.json create mode 100644 uni_modules/uv-switch/readme.md create mode 100644 uni_modules/uv-tabbar/changelog.md create mode 100644 uni_modules/uv-tabbar/components/uv-tabbar-item/props.js create mode 100644 uni_modules/uv-tabbar/components/uv-tabbar-item/uv-tabbar-item.vue create mode 100644 uni_modules/uv-tabbar/components/uv-tabbar/props.js create mode 100644 uni_modules/uv-tabbar/components/uv-tabbar/uv-tabbar.vue create mode 100644 uni_modules/uv-tabbar/package.json create mode 100644 uni_modules/uv-tabbar/readme.md create mode 100644 uni_modules/uv-tabs/changelog.md create mode 100644 uni_modules/uv-tabs/components/uv-tabs/props.js create mode 100644 uni_modules/uv-tabs/components/uv-tabs/uv-tabs.vue create mode 100644 uni_modules/uv-tabs/package.json create mode 100644 uni_modules/uv-tabs/readme.md create mode 100644 uni_modules/uv-tags/changelog.md create mode 100644 uni_modules/uv-tags/components/uv-tags/props.js create mode 100644 uni_modules/uv-tags/components/uv-tags/uv-tags.vue create mode 100644 uni_modules/uv-tags/package.json create mode 100644 uni_modules/uv-tags/readme.md create mode 100644 uni_modules/uv-text/changelog.md create mode 100644 uni_modules/uv-text/components/uv-text/props.js create mode 100644 uni_modules/uv-text/components/uv-text/uv-text.vue create mode 100644 uni_modules/uv-text/components/uv-text/value.js create mode 100644 uni_modules/uv-text/package.json create mode 100644 uni_modules/uv-text/readme.md create mode 100644 uni_modules/uv-textarea/changelog.md create mode 100644 uni_modules/uv-textarea/components/uv-textarea/props.js create mode 100644 uni_modules/uv-textarea/components/uv-textarea/uv-textarea.vue create mode 100644 uni_modules/uv-textarea/package.json create mode 100644 uni_modules/uv-textarea/readme.md create mode 100644 uni_modules/uv-toast/changelog.md create mode 100644 uni_modules/uv-toast/components/uv-toast/uv-toast.vue create mode 100644 uni_modules/uv-toast/package.json create mode 100644 uni_modules/uv-toast/readme.md create mode 100644 uni_modules/uv-toolbar/changelog.md create mode 100644 uni_modules/uv-toolbar/components/uv-toolbar/props.js create mode 100644 uni_modules/uv-toolbar/components/uv-toolbar/uv-toolbar.vue create mode 100644 uni_modules/uv-toolbar/package.json create mode 100644 uni_modules/uv-toolbar/readme.md create mode 100644 uni_modules/uv-tooltip/changelog.md create mode 100644 uni_modules/uv-tooltip/components/uv-tooltip/props.js create mode 100644 uni_modules/uv-tooltip/components/uv-tooltip/uv-tooltip.vue create mode 100644 uni_modules/uv-tooltip/package.json create mode 100644 uni_modules/uv-tooltip/readme.md create mode 100644 uni_modules/uv-transition/changelog.md create mode 100644 uni_modules/uv-transition/components/uv-transition/createAnimation.js create mode 100644 uni_modules/uv-transition/components/uv-transition/props.js create mode 100644 uni_modules/uv-transition/components/uv-transition/uv-transition.vue create mode 100644 uni_modules/uv-transition/package.json create mode 100644 uni_modules/uv-transition/readme.md create mode 100644 uni_modules/uv-ui-tools/changelog.md create mode 100644 uni_modules/uv-ui-tools/components/uv-ui-tools/uv-ui-tools.vue create mode 100644 uni_modules/uv-ui-tools/index.js create mode 100644 uni_modules/uv-ui-tools/index.scss create mode 100644 uni_modules/uv-ui-tools/libs/config/config.js create mode 100644 uni_modules/uv-ui-tools/libs/css/color.scss create mode 100644 uni_modules/uv-ui-tools/libs/css/common.scss create mode 100644 uni_modules/uv-ui-tools/libs/css/components.scss create mode 100644 uni_modules/uv-ui-tools/libs/css/variable.scss create mode 100644 uni_modules/uv-ui-tools/libs/css/vue.scss create mode 100644 uni_modules/uv-ui-tools/libs/function/colorGradient.js create mode 100644 uni_modules/uv-ui-tools/libs/function/debounce.js create mode 100644 uni_modules/uv-ui-tools/libs/function/digit.js create mode 100644 uni_modules/uv-ui-tools/libs/function/index.js create mode 100644 uni_modules/uv-ui-tools/libs/function/platform.js create mode 100644 uni_modules/uv-ui-tools/libs/function/test.js create mode 100644 uni_modules/uv-ui-tools/libs/function/throttle.js create mode 100644 uni_modules/uv-ui-tools/libs/luch-request/adapters/index.js create mode 100644 uni_modules/uv-ui-tools/libs/luch-request/core/InterceptorManager.js create mode 100644 uni_modules/uv-ui-tools/libs/luch-request/core/Request.js create mode 100644 uni_modules/uv-ui-tools/libs/luch-request/core/buildFullPath.js create mode 100644 uni_modules/uv-ui-tools/libs/luch-request/core/defaults.js create mode 100644 uni_modules/uv-ui-tools/libs/luch-request/core/dispatchRequest.js create mode 100644 uni_modules/uv-ui-tools/libs/luch-request/core/mergeConfig.js create mode 100644 uni_modules/uv-ui-tools/libs/luch-request/core/settle.js create mode 100644 uni_modules/uv-ui-tools/libs/luch-request/helpers/buildURL.js create mode 100644 uni_modules/uv-ui-tools/libs/luch-request/helpers/combineURLs.js create mode 100644 uni_modules/uv-ui-tools/libs/luch-request/helpers/isAbsoluteURL.js create mode 100644 uni_modules/uv-ui-tools/libs/luch-request/index.d.ts create mode 100644 uni_modules/uv-ui-tools/libs/luch-request/index.js create mode 100644 uni_modules/uv-ui-tools/libs/luch-request/utils.js create mode 100644 uni_modules/uv-ui-tools/libs/luch-request/utils/clone.js create mode 100644 uni_modules/uv-ui-tools/libs/mixin/button.js create mode 100644 uni_modules/uv-ui-tools/libs/mixin/mixin.js create mode 100644 uni_modules/uv-ui-tools/libs/mixin/mpMixin.js create mode 100644 uni_modules/uv-ui-tools/libs/mixin/mpShare.js create mode 100644 uni_modules/uv-ui-tools/libs/mixin/openType.js create mode 100644 uni_modules/uv-ui-tools/libs/mixin/touch.js create mode 100644 uni_modules/uv-ui-tools/libs/util/dayjs.js create mode 100644 uni_modules/uv-ui-tools/libs/util/route.js create mode 100644 uni_modules/uv-ui-tools/package.json create mode 100644 uni_modules/uv-ui-tools/readme.md create mode 100644 uni_modules/uv-ui-tools/theme.scss create mode 100644 uni_modules/uv-ui/changelog.md create mode 100644 uni_modules/uv-ui/components/uv-ui/uv-ui.vue create mode 100644 uni_modules/uv-ui/package.json create mode 100644 uni_modules/uv-ui/readme.md create mode 100644 uni_modules/uv-upload/changelog.md create mode 100644 uni_modules/uv-upload/components/uv-preview-video/uv-preview-video.vue create mode 100644 uni_modules/uv-upload/components/uv-upload/mixin.js create mode 100644 uni_modules/uv-upload/components/uv-upload/props.js create mode 100644 uni_modules/uv-upload/components/uv-upload/utils.js create mode 100644 uni_modules/uv-upload/components/uv-upload/uv-upload.vue create mode 100644 uni_modules/uv-upload/package.json create mode 100644 uni_modules/uv-upload/readme.md create mode 100644 uni_modules/uv-vtabs/changelog.md create mode 100644 uni_modules/uv-vtabs/components/uv-vtabs-item/uv-vtabs-item.vue create mode 100644 uni_modules/uv-vtabs/components/uv-vtabs/props.js create mode 100644 uni_modules/uv-vtabs/components/uv-vtabs/uv-vtabs.vue create mode 100644 uni_modules/uv-vtabs/package.json create mode 100644 uni_modules/uv-vtabs/readme.md create mode 100644 uni_modules/uv-waterfall/changelog.md create mode 100644 uni_modules/uv-waterfall/components/uv-waterfall/props.js create mode 100644 uni_modules/uv-waterfall/components/uv-waterfall/uv-waterfall.vue create mode 100644 uni_modules/uv-waterfall/package.json create mode 100644 uni_modules/uv-waterfall/readme.md create mode 100644 utils/cache.js create mode 100644 utils/index.js create mode 100644 utils/request.js create mode 100644 vite.config.js diff --git a/.commitlintrc.js b/.commitlintrc.js new file mode 100644 index 0000000..89f188e --- /dev/null +++ b/.commitlintrc.js @@ -0,0 +1,93 @@ +module.exports = { + // 继承的规则 + extends: ["@commitlint/config-conventional"], + // 自定义规则 + rules: { + // @see https://commitlint.js.org/#/reference-rules + + // 提交类型枚举,git提交type必须是以下类型 + "type-enum": [ + 2, + "always", + [ + "feat", // 新增功能 + "fix", // 修复缺陷 + "docs", // 文档变更 + "style", // 代码格式(不影响功能,例如空格、分号等格式修正) + "refactor", // 代码重构(不包括 bug 修复、功能新增) + "perf", // 性能优化 + "test", // 添加疏漏测试或已有测试改动 + "build", // 构建流程、外部依赖变更(如升级 npm 包、修改 webpack 配置等) + "ci", // 修改 CI 配置、脚本 + "revert", // 回滚 commit + "chore", // 对构建过程或辅助工具和库的更改(不影响源文件、测试用例) + ], + ], + "subject-case": [0], // subject大小写不做校验 + }, + + prompt: { + messages: { + type: "选择你要提交的类型 :", + scope: "选择一个提交范围(可选):", + customScope: "请输入自定义的提交范围 :", + subject: "填写简短精炼的变更描述 :\n", + body: '填写更加详细的变更描述(可选)。使用 "|" 换行 :\n', + breaking: '列举非兼容性重大的变更(可选)。使用 "|" 换行 :\n', + footerPrefixesSelect: "选择关联issue前缀(可选):", + customFooterPrefix: "输入自定义issue前缀 :", + footer: "列举关联issue (可选) 例如: #31, #I3244 :\n", + generatingByAI: "正在通过 AI 生成你的提交简短描述...", + generatedSelectByAI: "选择一个 AI 生成的简短描述:", + confirmCommit: "是否提交或修改commit ?", + }, + // prettier-ignore + types: [ + { value: "feat", name: "特性: ✨ 新增功能", emoji: ":sparkles:" }, + { value: "fix", name: "修复: 🐛 修复缺陷", emoji: ":bug:" }, + { value: "docs", name: "文档: 📝 文档变更(更新README文件,或者注释)", emoji: ":memo:" }, + { value: "style", name: "格式: 🌈 代码格式(空格、格式化、缺失的分号等)", emoji: ":lipstick:" }, + { value: "refactor", name: "重构: 🔄 代码重构(不修复错误也不添加特性的代码更改)", emoji: ":recycle:" }, + { value: "perf", name: "性能: 🚀 性能优化", emoji: ":zap:" }, + { value: "test", name: "测试: 🧪 添加疏漏测试或已有测试改动", emoji: ":white_check_mark:"}, + { value: "build", name: "构建: 📦️ 构建流程、外部依赖变更(如升级 npm 包、修改 vite 配置等)", emoji: ":package:"}, + { value: "ci", name: "集成: ⚙️ 修改 CI 配置、脚本", emoji: ":ferris_wheel:"}, + { value: "revert", name: "回退: ↩️ 回滚 commit",emoji: ":rewind:"}, + { value: "chore", name: "其他: 🛠️ 对构建过程或辅助工具和库的更改(不影响源文件、测试用例)", emoji: ":hammer:"}, + ], + useEmoji: true, + emojiAlign: "center", + useAI: false, + aiNumber: 1, + themeColorCode: "", + scopes: [], + allowCustomScopes: true, + allowEmptyScopes: true, + customScopesAlign: "bottom", + customScopesAlias: "custom", + emptyScopesAlias: "empty", + upperCaseSubject: false, + markBreakingChangeMode: false, + allowBreakingChanges: ["feat", "fix"], + breaklineNumber: 100, + breaklineChar: "|", + skipQuestions: [], + issuePrefixes: [ + { value: "closed", name: "closed: ISSUES has been processed" }, + ], + customIssuePrefixAlign: "top", + emptyIssuePrefixAlias: "skip", + customIssuePrefixAlias: "custom", + allowCustomIssuePrefix: true, + allowEmptyIssuePrefix: true, + confirmColorize: true, + maxHeaderLength: Infinity, + maxSubjectLength: Infinity, + minSubjectLength: 0, + scopeOverrides: undefined, + defaultBody: "", + defaultIssues: "", + defaultScope: "", + defaultSubject: "", + }, +}; diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..00ee2de --- /dev/null +++ b/.editorconfig @@ -0,0 +1,15 @@ +# http://editorconfig.org +root = true + +# 表示所有文件适用 +[*] +charset = utf-8 # 设置文件字符集为 utf-8 +end_of_line = lf # 控制换行类型(lf | cr | crlf) +indent_style = space # 缩进风格(tab | space) +indent_size = 2 # 缩进大小 +insert_final_newline = true # 始终在文件末尾插入一个新行 + +# 表示仅 md 文件适用以下规则 +[*.md] +max_line_length = off # 关闭最大行长度限制 +trim_trailing_whitespace = false # 关闭末尾空格修剪 diff --git a/.env.development b/.env.development new file mode 100644 index 0000000..63dba1e --- /dev/null +++ b/.env.development @@ -0,0 +1,8 @@ +# H5应用端口 +VITE_APP_PORT = 3000 + +# H5代理前缀 +VITE_APP_PROXY_PREFIX = "/dev-api" + +# 接口地址 +VITE_APP_BASE_URL = "http://localhost:8080" diff --git a/.env.production b/.env.production new file mode 100644 index 0000000..f69f521 --- /dev/null +++ b/.env.production @@ -0,0 +1,2 @@ +# 接口地址 +VITE_APP_BASE_URL = "http://prod-api" diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..edef1ea --- /dev/null +++ b/.gitignore @@ -0,0 +1,9 @@ +.idea +.vscode +.hbuilderx +.project +.DS_Store +node_modules +unpackage +package-lock.json +pnpm-lock.yaml \ No newline at end of file diff --git a/.husky/commit-msg b/.husky/commit-msg new file mode 100644 index 0000000..fd2bf70 --- /dev/null +++ b/.husky/commit-msg @@ -0,0 +1 @@ +npx --no-install commitlint --edit $1 diff --git a/.husky/pre-commit b/.husky/pre-commit new file mode 100644 index 0000000..b18d041 --- /dev/null +++ b/.husky/pre-commit @@ -0,0 +1 @@ +npm run lint:lint-staged diff --git a/.lintstagedrc.js b/.lintstagedrc.js new file mode 100644 index 0000000..3242196 --- /dev/null +++ b/.lintstagedrc.js @@ -0,0 +1,3 @@ +module.exports = { + "*.{js,cjs,ts,json,tsx,css,less,scss,vue,html,md}": ["prettier --write"], +}; diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 0000000..a284f7b --- /dev/null +++ b/.prettierignore @@ -0,0 +1,10 @@ +unpackage +node_modules +uni_modules +static +.husky +.hbuilderx +.vscode +.idea +*.sh +*.md diff --git a/.prettierrc.js b/.prettierrc.js new file mode 100644 index 0000000..3c61781 --- /dev/null +++ b/.prettierrc.js @@ -0,0 +1,47 @@ +// Prettier配置文档:https://prettier.io/docs/en/options.html +module.exports = { + // (x)=>{},单个参数箭头函数是否显示小括号。(always:始终显示;avoid:省略括号。默认:always) + arrowParens: "always", + // 开始标签的右尖括号是否跟随在最后一行属性末尾,默认false + bracketSameLine: false, + // 对象字面量的括号之间打印空格 (true - Example: { foo: bar } ; false - Example: {foo:bar}) + bracketSpacing: true, + // 是否格式化一些文件中被嵌入的代码片段的风格(auto|off;默认auto) + embeddedLanguageFormatting: "auto", + // 指定 HTML 文件的空格敏感度 (css|strict|ignore;默认css) + htmlWhitespaceSensitivity: "ignore", + // 当文件已经被 Prettier 格式化之后,是否会在文件顶部插入一个特殊的 @format 标记,默认false + insertPragma: false, + // 在 JSX 中使用单引号替代双引号,默认false + jsxSingleQuote: false, + // 每行最多字符数量,超出换行(默认80) + printWidth: 80, + // 超出打印宽度 (always | never | preserve ) + proseWrap: "preserve", + // 对象属性是否使用引号(as-needed | consistent | preserve;默认as-needed:对象的属性需要加引号才添加;) + quoteProps: "as-needed", + // 是否只格式化在文件顶部包含特定注释(@prettier| @format)的文件,默认false + requirePragma: false, + // 结尾添加分号 + semi: true, + // 使用单引号 (true:单引号;false:双引号) + singleQuote: false, + // 缩进空格数,默认2个空格 + tabWidth: 2, + // 元素末尾是否加逗号,默认es5: ES5中的 objects, arrays 等会添加逗号,TypeScript 中的 type 后不加逗号 + trailingComma: "es5", + // 指定缩进方式,空格或tab,默认false,即使用空格 + useTabs: false, + // vue 文件中是否缩进 diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..f755343 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2024 白開水 + +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/README.md b/README.md new file mode 100644 index 0000000..48ea067 --- /dev/null +++ b/README.md @@ -0,0 +1 @@ +vue3+uniapp+uv-ui \ No newline at end of file diff --git a/api/index.js b/api/index.js new file mode 100644 index 0000000..3ef9985 --- /dev/null +++ b/api/index.js @@ -0,0 +1,4 @@ +import AuthAPI from "./modules/auth"; +import UserAPI from "./modules/user"; + +export { AuthAPI, UserAPI }; diff --git a/api/modules/auth.js b/api/modules/auth.js new file mode 100644 index 0000000..cc9d547 --- /dev/null +++ b/api/modules/auth.js @@ -0,0 +1,30 @@ +import http from "@/utils/request"; + +class AuthAPI { + // 注册 + static signUp(data) { + return http.post("/auth/signup", data, { + custom: { + loading: true, + }, + }); + } + + // 登录 + static signIn(data) { + return http.post("/auth/signin", data, { + custom: { + loading: true, + }, + }); + } + + // 刷新token + static refreshToken(header = {}) { + return http.post("/auth/refresh", undefined, { + header, + }); + } +} + +export default AuthAPI; diff --git a/api/modules/user.js b/api/modules/user.js new file mode 100644 index 0000000..00d5cec --- /dev/null +++ b/api/modules/user.js @@ -0,0 +1,16 @@ +import http from "@/utils/request"; + +class UserAPI { + // test get api + static getUserList(params = {}) { + return http.get("/user/list", { + params, + custom: { + auth: true, + loading: true, + }, + }); + } +} + +export default UserAPI; diff --git a/components/HeaderCustom/HeaderCustom.vue b/components/HeaderCustom/HeaderCustom.vue new file mode 100644 index 0000000..03999f3 --- /dev/null +++ b/components/HeaderCustom/HeaderCustom.vue @@ -0,0 +1,54 @@ + + + + \ No newline at end of file diff --git a/components/IconFont/IconFont.vue b/components/IconFont/IconFont.vue new file mode 100644 index 0000000..98e730c --- /dev/null +++ b/components/IconFont/IconFont.vue @@ -0,0 +1,36 @@ + + + + + diff --git a/components/IconFont/iconfont.css b/components/IconFont/iconfont.css new file mode 100644 index 0000000..babe6c2 --- /dev/null +++ b/components/IconFont/iconfont.css @@ -0,0 +1,19 @@ +@font-face { + font-family: "iconfont"; /* Project id 4657887 */ + src: + url("iconfont.woff2?t=1724050101808") format("woff2"), + url("iconfont.woff?t=1724050101808") format("woff"), + url("iconfont.ttf?t=1724050101808") format("truetype"); +} + +.iconfont { + font-family: "iconfont" !important; + font-size: 16px; + font-style: normal; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +.icon-uniapp:before { + content: "\e624"; +} diff --git a/components/IconFont/iconfont.json b/components/IconFont/iconfont.json new file mode 100644 index 0000000..8c16935 --- /dev/null +++ b/components/IconFont/iconfont.json @@ -0,0 +1,16 @@ +{ + "id": "4657887", + "name": "vue3-uniapp-template", + "font_family": "iconfont", + "css_prefix_text": "icon-", + "description": "", + "glyphs": [ + { + "icon_id": "19317486", + "name": "uniapp", + "font_class": "uniapp", + "unicode": "e624", + "unicode_decimal": 58916 + } + ] +} diff --git a/components/IconFont/iconfont.ttf b/components/IconFont/iconfont.ttf new file mode 100644 index 0000000000000000000000000000000000000000..9010d88724b4c936e8166e3ace3f7e8749b3ce12 GIT binary patch literal 1636 zcmd^9Noy2A6#lBZXED*ZGOmY?#3(A0IPM`TxFjCLHRdE}JJYj-p6;fnBgWH!7e!I; zf)`JM2Ty|FK~G-1dl3;2qoCl$ASlWBRdvr(*#M2!0ZyZ6zohsikPwfE=SJ|tMUE1>f zT7~#M$DS&QOv|`I{G6k&T92+~(?k$oIAvYGXk$?6Mu}6pZeI;V4>r@jhPvh1b!XYb z;U~1e24p4h8&T`)M2)VyXdeV?H=6AxE|`qkZkrj!{39}E$c{gmeQ|LzkAmq`J6JzLc?a0GAB;gbL-&nY{ zip}_mMbJ-K1sMT#Cn}z48sZ*OOng)F#JHQR;xh_@J0(&E*#+cu`B(`rT79j)_~ zMU!qS<{yzNp}HvwbMVE1?Hr`VnD#wMR_)r(m8T_dVq@%MD!$d%=J}JEdU67YBqrVd zV_6)ZeS^M%_^#AVQBPh$^*Ospcbdsg!CKL~yjSFQ_7)DwLT+_VrmcRt_n_Fh+D!la zA;zQ-=Y>|^z^h4GBxu!n~`U-hERD{;GNC~to)r@ zb=gYIOJvy9Nlga%jT)Q8TQyGck5JG!P5yw!UD$?W8h0~dpt{9e#611DuCc%}JknUA z2hTJ%$iLFqBz~iD3ORh#I8A;=<1UPgB^r05UlfmojvYBA>++OUEBap9_oB{v)~QUo zcGyun>$np(YQAUf$Pad?QO9$_PMF4(N+F8MRyp+R)(GP{uIpPt=ubGsC|`}DU}#`K z+f>1XL(!6aPn4Ch(r?jEOihz9*sOba`Z z=Wk}N*C@Tb*mG_*4P0Ti0&9#|k;M@*Qk`f-*XOVjm)PP1D%%9(6zQEuHQp6q2m|~& e=jr(8<8#*IKIWUN|KGwQ*|i4JlU~gZ0^k>HL)wb~ literal 0 HcmV?d00001 diff --git a/components/IconFont/iconfont.woff b/components/IconFont/iconfont.woff new file mode 100644 index 0000000000000000000000000000000000000000..8b46eff1f28ce15c69a1a74808384b01589aabdd GIT binary patch literal 1044 zcmXT-cXMN4WB>vd5e9A$&6Wb;gV?CRJvh{ffq{_&C~6JFAqw59RsO;HMnEwaARmMi zY%D##C+8*>0L40hd~YCK@Z4vcSb9!n8jyVjqy~ihSp3a0QWH}c7?@0ee0?A`)A(MM zo&gjDiUGwL6o6QT{TXvdMs7(3P^<;W2ieWR!N$Ollb;My*8}7Oc|dHyz>u3*0koHC z3Xm@c#0rdj4C;A_xv4<0EkL^+fONXRVw(*G`Nbs+49s7EYUF{~;Mx1E%!)b52`LE) z50VTLHY6t$6@KPSd~n)R=VbDPq=du>11ikQ(uXx3FitiKkh55$Fr!hBq2UwfPoOs$82&e~uroI> zurNq5Fi0{g3Mw*+87msuGZ~4Ai!re&s4JnU7{bKJ7|O`RXr(B{$jr$8 z_aHkHGn0tA6=TCcp#Fc7U%!53WMpFfyM}|EDUgGikr5hJ439SO{(pA#^X;0{2Wg26 zjqdtsvz1=_=hb<0hSx!lomtpJgdzMq_dIa;0K*pKZ-K*yjve^$-=5o=Ie>-LfRUl- z2TK_XFcMfmu?Padc!ZjtkTiiUiOrz9v5}iYQsQ6pPaX#DKt?l=eCtHpyh9EGt@95~ zV40%fwZtSdOjASX%sY zoB8+l&6GXK@NPqU`={N{^==+k-8@Nq$AQHKQ-4j~;9n=UZei!Vg1Ns|7clEr2;wzOmxW ztgU>p8%p$EZ@)e9g=2;gPr^dO*5o*YD@qC literal 0 HcmV?d00001 diff --git a/components/IconFont/iconfont.woff2 b/components/IconFont/iconfont.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..4d21366a911b95917e00ae2171ada0a071376dfd GIT binary patch literal 668 zcmV;N0%QGmPew8T0RR9100Nu<3jhEB00v|L00L3~0RR9100000000000000000000 z0000SR0d!Gf^Z68a{)F2Bm)Qw1^@&g1%zh@FdMH05!I6`WM3a}C(Q+tKtOJwz|2OU z)4Jd#uP&^hUI$PA`~7dvIrBs$eU~O?h}r625_p0}(?+GyyoyLB!cF?IhK4+Wsazpn zO|of@J^<>1a&gXGxd=6qvnP+fkP>7$`8?O;E1(1ZAhHgsXgaWo9uB)Kig0h_Q=fwD zjzBH>5(MzmL>FdYXkvlzk)3Cbkw}KEKbqPzQH}*A9svhaaO>-U0JS)o@W3TV1YV7K^FQWQ&^;pwfHSc39VNI zzH^+=j2!yUL)&(0D)5~ze$-q8fTorL7)_HN3dWVTn()Q?#&|bYx>)wZg3p+$mw7d=&3;fLt#?L0DjjG4vr(v`>EQ*EhGdli5ro7Oi>Pt zml8sm8n_710ykbd;is0t^#Kx`z#{4cDp)5FqTGQY%sp75JRp>L0T*e0z)h5Y@UtYL z-2zky@R3k3YLI{MsutsEIOcmp`%Z$If-j`qQ$H-@T#a9`Ak8sn|Jaq;fT5b + + + + + + + + + + + + diff --git a/components/Login/Login.vue b/components/Login/Login.vue new file mode 100644 index 0000000..c9af66e --- /dev/null +++ b/components/Login/Login.vue @@ -0,0 +1,307 @@ + + + + + diff --git a/components/UploadFile/UploadFile.vue b/components/UploadFile/UploadFile.vue new file mode 100644 index 0000000..32d4dd1 --- /dev/null +++ b/components/UploadFile/UploadFile.vue @@ -0,0 +1,426 @@ + + + + + \ No newline at end of file diff --git a/components/UploadFile/example.vue b/components/UploadFile/example.vue new file mode 100644 index 0000000..9e06ccc --- /dev/null +++ b/components/UploadFile/example.vue @@ -0,0 +1,191 @@ + + + + + + \ No newline at end of file diff --git a/hooks/usePermission.js b/hooks/usePermission.js new file mode 100644 index 0000000..587f7a9 --- /dev/null +++ b/hooks/usePermission.js @@ -0,0 +1,10 @@ +import { hasPerm } from "@/plugins/permission"; +import { currentRoute } from "@/router"; + +// 对某些特殊场景需要在页面onShow生命周期中校验权限: +// 1.微信小程序端点击tabbar的底层逻辑不触发uni.switchTab +// 2.h5在浏览器地址栏输入url后跳转不触发uni的路由api +// 3.首次启动加载的页面不触发uni的路由api +export async function usePermission() { + return hasPerm(currentRoute()); +} diff --git a/index.html b/index.html new file mode 100644 index 0000000..7535993 --- /dev/null +++ b/index.html @@ -0,0 +1,24 @@ + + + + + + + + + + +
+ + + diff --git a/locale/en.json b/locale/en.json new file mode 100644 index 0000000..8c3df39 --- /dev/null +++ b/locale/en.json @@ -0,0 +1,8 @@ +{ + "locale.auto": "System", + "locale.en": "English", + "locale.zh-hans": "Simplified Chinese", + "locale.zh-hant": "Traditional Chinese", + "locale.ja": "Japanese", + "index.demo": "uni-app internationalization demo" +} diff --git a/locale/index.js b/locale/index.js new file mode 100644 index 0000000..274eca7 --- /dev/null +++ b/locale/index.js @@ -0,0 +1,23 @@ +import { createI18n } from "vue-i18n"; // v9.x +import en from "./en.json"; +import ja from "./ja.json"; +import zhHans from "./zh-Hans.json"; +import zhHant from "./zh-Hant.json"; + +const i18n = createI18n({ + legacy: false, // 必须设置false才能使用Composition API + globalInjection: true, // 为每个组件注入$为前缀的全局属性和函数 + locale: uni.getLocale(), + messages: { + en, + "zh-Hans": zhHans, + "zh-Hant": zhHant, + ja, + }, +}); + +export function setupI18n(app) { + app.use(i18n); +} + +export { i18n }; diff --git a/locale/ja.json b/locale/ja.json new file mode 100644 index 0000000..4a991e3 --- /dev/null +++ b/locale/ja.json @@ -0,0 +1,8 @@ +{ + "locale.auto": "システム", + "locale.en": "英語", + "locale.zh-hans": "簡体字中国語", + "locale.zh-hant": "繁体字中国語", + "locale.ja": "日本語", + "index.demo": "uni-app 国際化デモ" +} diff --git a/locale/uni-app.ja.json b/locale/uni-app.ja.json new file mode 100644 index 0000000..41cef76 --- /dev/null +++ b/locale/uni-app.ja.json @@ -0,0 +1,36 @@ +{ + "common": { + "uni.app.quit": "もう一度押すと、アプリケーションが終了します", + "uni.async.error": "サーバーへの接続がタイムアウトしました。画面をクリックして再試行してください", + "uni.showActionSheet.cancel": "キャンセル", + "uni.showToast.unpaired": "使用するには、showToastとhideToastをペアにする必要があることに注意してください", + "uni.showLoading.unpaired": "使用するには、showLoadingとhideLoadingをペアにする必要があることに注意してください", + "uni.showModal.cancel": "キャンセル", + "uni.showModal.confirm": "OK", + "uni.chooseImage.cancel": "キャンセル", + "uni.chooseImage.sourceType.album": "アルバムから選択", + "uni.chooseImage.sourceType.camera": "カメラ", + "uni.chooseVideo.cancel": "キャンセル", + "uni.chooseVideo.sourceType.album": "アルバムから選択", + "uni.chooseVideo.sourceType.camera": "カメラ", + "uni.previewImage.cancel": "キャンセル", + "uni.previewImage.button.save": "画像を保存", + "uni.previewImage.save.success": "画像をアルバムに正常に保存します", + "uni.previewImage.save.fail": "画像をアルバムに保存できませんでした", + "uni.setClipboardData.success": "コンテンツがコピーされました", + "uni.scanCode.title": "スキャンコード", + "uni.scanCode.album": "アルバム", + "uni.scanCode.fail": "認識に失敗しました", + "uni.scanCode.flash.on": "タッチして点灯", + "uni.scanCode.flash.off": "タップして閉じる", + "uni.startSoterAuthentication.authContent": "指紋認識...", + "uni.picker.done": "完了", + "uni.picker.cancel": "キャンセル", + "uni.video.danmu": "「弾幕」", + "uni.video.volume": "ボリューム", + "uni.button.feedback.title": "質問のフィードバック", + "uni.button.feedback.send": "送信" + }, + "ios": {}, + "android": {} +} diff --git a/locale/zh-Hans.json b/locale/zh-Hans.json new file mode 100644 index 0000000..a227eda --- /dev/null +++ b/locale/zh-Hans.json @@ -0,0 +1,8 @@ +{ + "locale.auto": "系统", + "locale.en": "英语", + "locale.zh-hans": "简体中文", + "locale.zh-hant": "繁体中文", + "locale.ja": "日语", + "index.demo": "uni-app 国际化演示" +} diff --git a/locale/zh-Hant.json b/locale/zh-Hant.json new file mode 100644 index 0000000..6e43514 --- /dev/null +++ b/locale/zh-Hant.json @@ -0,0 +1,8 @@ +{ + "locale.auto": "系統", + "locale.en": "英語", + "locale.zh-hans": "簡體中文", + "locale.zh-hant": "繁體中文", + "locale.ja": "日語", + "index.demo": "uni-app 國際化演示" +} diff --git a/main.js b/main.js new file mode 100644 index 0000000..642bf76 --- /dev/null +++ b/main.js @@ -0,0 +1,11 @@ +import App from "./App"; +import { createSSRApp } from "vue"; +import setupPlugins from "@/plugins"; + +export function createApp() { + const app = createSSRApp(App); + app.use(setupPlugins); + return { + app, + }; +} diff --git a/manifest.json b/manifest.json new file mode 100644 index 0000000..8e0d5b3 --- /dev/null +++ b/manifest.json @@ -0,0 +1,100 @@ +{ + "name" : "卡叔电梯", + "appid" : "__UNI__3A16C1C", + "description" : "", + "versionName" : "1.0.0", + "versionCode" : "100", + "transformPx" : false, + /* 5+App特有相关 */ + "app-plus" : { + "usingComponents" : true, + "nvueStyleCompiler" : "uni-app", + "compilerVersion" : 3, + "splashscreen" : { + "alwaysShowBeforeRender" : true, + "waiting" : true, + "autoclose" : true, + "delay" : 0 + }, + /* 模块配置 */ + "modules" : {}, + /* 应用发布信息 */ + "distribute" : { + /* android打包配置 */ + "android" : { + "permissions" : [ + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "" + ], + "minSdkVersion" : 21 + }, + /* ios打包配置 */ + "ios" : {}, + /* SDK配置 */ + "sdkConfigs" : {} + } + }, + /* 快应用特有相关 */ + "quickapp" : {}, + /* 小程序特有相关 */ + "mp-weixin" : { + "appid" : "wx2c04ebae2099b3d2", + "setting" : { + "urlCheck" : false, + "es6" : true, + "postcss" : true, + "minified" : true + }, + "usingComponents" : true, + "permission" : { + "scope.userLocation" : { + "desc" : "获取当前位置" + }, + "scope.userFuzzyLocation" : { + "desc" : "您的位置信息将用于小程序位置接口的效果展示" + } + }, + /* 地理位置相关接口配置项 @see https://developers.weixin.qq.com/community/develop/doc/000a02f2c5026891650e7f40351c01 */ + "requiredPrivateInfos" : [ "getLocation", "chooseLocation" ] + }, + "mp-alipay" : { + "usingComponents" : true + }, + "mp-baidu" : { + "usingComponents" : true + }, + "mp-toutiao" : { + "usingComponents" : true + }, + "uniStatistics" : { + "enable" : false + }, + "vueVersion" : "3", + "h5" : { + "optimization" : { + "treeShaking" : { + "enable" : false + } + }, + "devServer" : { + "https" : false + }, + "router" : { + "mode" : "history" + } + }, + "locale" : "auto" +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..a991c4f --- /dev/null +++ b/package.json @@ -0,0 +1,38 @@ +{ + "name": "lift-wechat", + "version": "1.0.0", + "description": "电梯图纸生成", + "main": "main.js", + "scripts": { + "prepare": "husky", + "lint:prettier": "prettier --write \"**/*.{js,cjs,ts,json,tsx,css,less,scss,vue,html,md}\"", + "lint:lint-staged": "lint-staged", + "commit": "git-cz" + }, + "keywords": [ + "卡叔电梯" + ], + "author": "Lufaneng", + "license": "MIT", + "dependencies": { + "crypto-js": "^4.2.0", + "dayjs": "^1.11.18", + "three": "^0.178.0", + "vue-draggable-plus": "^0.6.0" + }, + "devDependencies": { + "@commitlint/cli": "^19.1.0", + "@commitlint/config-conventional": "^19.1.0", + "@dcloudio/types": "^3.4.11", + "commitizen": "^4.3.0", + "cz-git": "^1.9.0", + "husky": "^9.0.11", + "lint-staged": "^15.2.2", + "prettier": "^3.2.5" + }, + "config": { + "commitizen": { + "path": "node_modules/cz-git" + } + } +} diff --git a/pages.json b/pages.json new file mode 100644 index 0000000..411730d --- /dev/null +++ b/pages.json @@ -0,0 +1,120 @@ +{ + //组件自动引入规则 https://uniapp.dcloud.net.cn/collocation/pages.html#easycom + "easycom": { + "autoscan": true, + "custom": { + "^x-(.*)": "@/components/x-$1/index.vue" + } + }, + "globalStyle": { + "navigationBarTextStyle": "black", + "navigationBarTitleText": "电梯图纸生成", + "navigationBarBackgroundColor": "#fff", + "backgroundColor": "#F8F8F8", + "enablePullDownRefresh": false + }, + "pages": [ + //pages数组中第一项表示应用启动页,参考:https://uniapp.dcloud.io/collocation/pages + { + "path": "pages/login/login", + "style": { + "navigationBarTitleText": "登录" + } + }, + { + "path": "pages/index/index", + "style": { + "navigationBarTitleText": "电梯图纸生成平台" + } + }, + { + "path" : "pages/order/order", + "style" : + { + "navigationBarTitleText" : "订单" + } + }, + { + "path" : "pages/consumption/consumption", + "style" : + { + "navigationBarTitleText" : "消费" + } + }, + { + "path" : "pages/mine/mine", + "style" : + { + "navigationBarTitleText" : "我的" + } + } + ], + "subPackages": [ + { + "root": "pagesA", + "pages": [ + { + "path" : "user-agreement/user-agreement", + "style" : + { + "navigationBarTitleText" : "用户协议", + "navigationStyle": "custom" + } + }, + { + "path" : "generate-record/generate-record", + "style" : + { + "navigationBarTitleText" : "图纸生成记录" + } + }, + { + "path" : "edit-profile/edit-profile", + "style" : + { + "navigationBarTitleText" : "编辑资料" + } + } + ] + } + ], + "preloadRule": { + "pages/index/index": { + "network": "wifi", + "packages": ["pagesA"] + } + }, + "tabBar": { + "color": "#999999", + "selectedColor": "#3F70FF", + "backgroundColor": "#fff", + "position": "bottom", + "borderStyle": "black", + "list": [ + { + "pagePath": "pages/index/index", + "iconPath": "static/tabbar/index.png", + "selectedIconPath": "static/tabbar/index_HL.png", + "text": "首页" + }, + { + "pagePath": "pages/order/order", + "iconPath": "static/tabbar/appointment.png", + "selectedIconPath": "static/tabbar/appointment_HL.png", + "text": "订单" + }, + { + "pagePath": "pages/consumption/consumption", + "iconPath": "static/tabbar/appointment.png", + "selectedIconPath": "static/tabbar/appointment_HL.png", + "text": "消费" + }, + { + "pagePath": "pages/mine/mine", + "iconPath": "static/tabbar/mine.png", + "selectedIconPath": "static/tabbar/mine_HL.png", + "text": "我的" + } + ] + } +} diff --git a/pages/consumption/consumption.vue b/pages/consumption/consumption.vue new file mode 100644 index 0000000..a0578d8 --- /dev/null +++ b/pages/consumption/consumption.vue @@ -0,0 +1,380 @@ + + + + + \ No newline at end of file diff --git a/pages/index/index.vue b/pages/index/index.vue new file mode 100644 index 0000000..defb7d7 --- /dev/null +++ b/pages/index/index.vue @@ -0,0 +1,342 @@ + + + + + + + \ No newline at end of file diff --git a/pages/index/index1.vue b/pages/index/index1.vue new file mode 100644 index 0000000..8ec2551 --- /dev/null +++ b/pages/index/index1.vue @@ -0,0 +1,517 @@ + + + + + \ No newline at end of file diff --git a/pages/login/login.vue b/pages/login/login.vue new file mode 100644 index 0000000..fb5b817 --- /dev/null +++ b/pages/login/login.vue @@ -0,0 +1,214 @@ + + + + + + + \ No newline at end of file diff --git a/pages/mine/mine.vue b/pages/mine/mine.vue new file mode 100644 index 0000000..255f32d --- /dev/null +++ b/pages/mine/mine.vue @@ -0,0 +1,457 @@ + + + + + \ No newline at end of file diff --git a/pages/order/order.vue b/pages/order/order.vue new file mode 100644 index 0000000..cded34e --- /dev/null +++ b/pages/order/order.vue @@ -0,0 +1,528 @@ + + + + + \ No newline at end of file diff --git a/pagesA/edit-profile/edit-profile.vue b/pagesA/edit-profile/edit-profile.vue new file mode 100644 index 0000000..7caedbc --- /dev/null +++ b/pagesA/edit-profile/edit-profile.vue @@ -0,0 +1,460 @@ + + + + + \ No newline at end of file diff --git a/pagesA/generate-record/generate-record.vue b/pagesA/generate-record/generate-record.vue new file mode 100644 index 0000000..1fc5ba5 --- /dev/null +++ b/pagesA/generate-record/generate-record.vue @@ -0,0 +1,351 @@ + + + + + \ No newline at end of file diff --git a/pagesA/user-agreement/user-agreement.vue b/pagesA/user-agreement/user-agreement.vue new file mode 100644 index 0000000..4f911cb --- /dev/null +++ b/pagesA/user-agreement/user-agreement.vue @@ -0,0 +1,47 @@ + + + + + \ No newline at end of file diff --git a/plugins/index.js b/plugins/index.js new file mode 100644 index 0000000..6d53e99 --- /dev/null +++ b/plugins/index.js @@ -0,0 +1,17 @@ +import { setupI18n } from "@/locale"; +import { setupStore } from "@/store"; +import { setupPermission } from "./permission"; +import { setupUI } from "./ui"; + +export default { + install(app) { + // UI扩展配置 + app.use(setupUI); + // 状态管理 + app.use(setupStore); + // 国际化 + app.use(setupI18n); + // 路由拦截 + app.use(setupPermission); + }, +}; diff --git a/plugins/permission.js b/plugins/permission.js new file mode 100644 index 0000000..bed1f8e --- /dev/null +++ b/plugins/permission.js @@ -0,0 +1,56 @@ +import { + ERROR404_PATH, + isPathExists, + LOGIN_PATH, + removeQueryString, + routes, +} from "@/router"; +import { useAuthStore } from "@/store/modules/auth"; + +// 白名单路由 +const whiteList = ["/"]; +routes.forEach((item) => { + if (item.needLogin !== true) { + whiteList.push(item.path); + } +}); + +/** + * 权限校验 + * @param {String} path + * @returns + */ +export function hasPerm(path = "") { + if (!isPathExists(path)) { + uni.redirectTo({ + url: ERROR404_PATH, + }); + return false; + } + const authStore = useAuthStore(); + // 在白名单中或有token,直接放行 + const hasPermission = + whiteList.includes(removeQueryString(path)) || authStore.isLoggedIn; + if (!hasPermission) { + // 将用户的目标路径传递过去,这样可以实现用户登录之后,直接跳转到目标页面 + uni.redirectTo({ + url: `/pages/index/index`, + }); + } + return hasPermission; +} + +export function setupPermission() { + // 注意:拦截uni.switchTab本身没有问题。但是在微信小程序端点击tabbar的底层逻辑并不是触发uni.switchTab。 + // 所以误认为拦截无效,此类场景的解决方案是在tabbar页面的页面生命周期onShow中处理。 + ["navigateTo", "redirectTo", "reLaunch", "switchTab"].forEach((item) => { + // https://uniapp.dcloud.net.cn/api/interceptor.html + uni.addInterceptor(item, { + // 页面跳转前进行拦截, invoke根据返回值进行判断是否继续执行跳转 + invoke(args) { + // args为所拦截api中的参数,比如拦截的是uni.redirectTo(OBJECT),则args对应的是OBJECT参数 + return hasPerm(args.url); + }, + }); + }); +} diff --git a/plugins/ui.js b/plugins/ui.js new file mode 100644 index 0000000..c292db3 --- /dev/null +++ b/plugins/ui.js @@ -0,0 +1,28 @@ +import uvUI from "@/uni_modules/uv-ui-tools"; + +export function setupUI(app) { + // UV扩展配置 https://www.uvui.cn/components/setting.html + app.use(uvUI); + // 调用setConfig方法,方法内部会进行对象属性深度合并,可以放心嵌套配置 + uni.$uv.setConfig({ + // 修改$uv.config对象的属性 + config: { + // 修改默认单位为rpx,相当于执行 uni.$uv.config.unit = 'rpx' + // 用于在传入组件大小参数为数值时,指定默认单位 + unit: "px", + }, + // 修改$uv.props对象的属性 + props: { + // 修改uv-text组件的size参数的默认值,注意:默认值都要用default声明 + text: { + color: { + default: "#303133", + }, + }, + // 其他组件属性配置,具体的参数名称可以去每个组件的props.js中进行查看 + // ...... + }, + }); +} + +export const $uv = uni.$uv; diff --git a/router/index.js b/router/index.js new file mode 100644 index 0000000..52f7240 --- /dev/null +++ b/router/index.js @@ -0,0 +1,91 @@ +import pagesJson from "@/pages.json"; + +// 路径常量 +export const HOME_PATH = "/pages/index/index"; +export const LOGIN_PATH = "/pages/login/login"; +export const ERROR404_PATH = "/pages/404/404"; + +/** + * 解析路由地址 + * @param {object} pagesJson + * @returns [{"path": "/pages/index/index","needLogin": false},...] + */ +function parseRoutes(pagesJson = {}) { + if (!pagesJson.pages) { + pagesJson.pages = []; + } + if (!pagesJson.subPackages) { + pagesJson.subPackages = []; + } + + function parsePages(pages = [], rootPath = "") { + const routes = []; + for (let i = 0; i < pages.length; i++) { + routes.push({ + path: rootPath ? `/${rootPath}/${pages[i].path}` : `/${pages[i].path}`, + needLogin: pages[i].needLogin === true, + }); + } + return routes; + } + + function parseSubPackages(subPackages = []) { + const routes = []; + for (let i = 0; i < subPackages.length; i++) { + routes.push(...parsePages(subPackages[i].pages, subPackages[i].root)); + } + return routes; + } + + return [ + ...parsePages(pagesJson.pages), + ...parseSubPackages(pagesJson.subPackages), + ]; +} +export const routes = parseRoutes(pagesJson); + +/** + * 当前路由 + * @returns {String} + */ +export function currentRoute() { + const pages = getCurrentPages(); + if (pages.length === 0) { + return; + } + const currentPage = pages[pages.length - 1]; + return currentPage?.$page?.fullPath || currentPage.route; +} + +/** + * 去除查询字符串 + * @param {String} path + * @returns + */ +export function removeQueryString(path = "") { + return path.split("?")[0]; +} + +/** + * 路径是否存在 + * @param {String} path + * @returns + */ +export function isPathExists(path = "") { + const cleanPath = removeQueryString(path); + return routes.some((item) => item.path === cleanPath); +} + +/** + * 是否是tabbar页面路径 + * @param {String} path + * @returns + */ +export function isTabBarPath(path = "") { + const cleanPath = removeQueryString(path); + return ( + pagesJson.tabBar?.list?.some( + (item) => `/${item.pagePath}` === cleanPath + ) === true + ); +} diff --git a/static/imgs/code.png b/static/imgs/code.png new file mode 100644 index 0000000000000000000000000000000000000000..32b0a8f0d63db4a1f4db9917abeab01850984692 GIT binary patch literal 799 zcmV+)1K|9LP)Px%*-1n}RCr$Pnp>8GAPk0KWwkqU2h-VsI~uz(XX3##mO@BEg7xBKj|l&lD^TxF z{`iyYcNc)m15Qrh3W2R0pzEh@a_-AH*TEXRbKm3OAFbE3i3fE3^a$eL^tJ}k9Kfxg zeip0etlbhqGXSy6Q(V0T2y*}u;V~Rb5GDXXG`M*#&MDSUy<-7F4L}g>)|p)@lrj!r zg!jgA@FQhR1}cB(A~sn07QQf-vkjloJNJb7Ipvh)0a*FkP`DAWgaUyK zfKtCd%?ltJo`b(*>*4^IK2Tt3Nv8+ko`Xk?d~^@E09+n$g}^a$z})ps&OsN7cA$p~ zfj{B*b?;y5PmTlttPaO!FB_k;0LV5pw|+t!v?F)`Ccb#Qws!zk;y2j~go6r*)7lfE zTJiJIK-0}oy#17Jp|NdjDd|PKqvil!N)#-H3n3?7c(~deK=O8n3ZWn#5+3(a1yIbm zusTFU_BN<64swY^Jn6cPvmGV@2x8ts0SgBM%g>$?ca2r2!p!88ojeW)EAb$<)B^-a zw6LPa@%n2y3oJ0D;X+%nJ^)cH<{&^;PhDt8KxbT=blpzQ0Wb+S3|7a}$(#@`TuVHb zRO2~W075O6W@HqCrg&=nvvR;fuC)6qoWZlI12xtYRwcQ=6acv#CIq}SCfb&#mcLba z@;KLo!D>>t*&U5;l8fD6RH=9Xu!e^JCH)bU`@m`dH5EZ$^8XjP;zc=NnNA}Vv|&&> zzp655S+{FpNUUGw0V_{HcX_qKsN*HpR{`(|`GB(P%YkHdf|xa=Z8FuuhyYTXZ4O`y zPmspFN*T-%wdm|pb7_cI%K@#cLru)9mO(6jjXWWFKUkAT)RJI>kYM%rR4C>EU?G*> zpl)^3B&Zk`roxwXHt~Q|l7!!)e|XII{;B@}P~BPb-X;Jf3$+?^0k9&wm+xL4uop{N dt@HFA@C)~luTVr8D-8eu002ovPDHLkV1nSmW3~VQ literal 0 HcmV?d00001 diff --git a/static/imgs/indexImg.png b/static/imgs/indexImg.png new file mode 100644 index 0000000000000000000000000000000000000000..ea39252c1f3ac745e9ed1228149490b873829b7b GIT binary patch literal 101955 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%0AQZ zf|QPFld1dI!US=Tl!uK_06SgM;n2^7F)Z`K`#WzyF;wAx-2=#hW990COYX}Wx%o8v@>D{ zC}AsZT^oyo_gsjc{(dDRyw1%xUWw7sp*VEx(r6{@f{@%?_9qXM-Ps~P+xakyfGmU7f}iOdKzm^n0NkOfmFnW&jA@uB3!K% zj&`{phJ~zFW{um1lUQX6ub;ndI15}TXd@{i9B4&Aq#sUbrt-ySpQ-bL8f62Hn4Du? znFR&yX?@*fcFIod68XaWxTm*Ii;VIQXDl~`*0izYoxHWBW*`Cx1${m|>L4kZ@UJi~ z%I|?I^CyAEsy@qG!ANDLOEAcW8Zv3joyn$XWC2+yLrw)9@55^mur6P@5_8j2@%R%@ z#6S7(KcV*|&~RgK-5QTS`j`JQ#>ej{8!ctNGv#Dg>|1QgG!m~8NS~)Mi;YaJ1S1XR zq#UeN;@I&M^0NT4ICA)K3=H(e&70$~$Y9lk1_;Q%_G^DXzWd^Lb-?xa_vw0W-?`is8|NHrvS&NY3sI4V31NSfxoN+d&N} zM^je_Y+mqVGG$mcQxlUhJ~?!#;m@uFM|`9vR(^JL6)ooDzS9=TI3Nh=g{ zB`K$#THUS$Qd6z-v+!-C&?}Mcsg-F|i^HtSGOrD&+M{BS~LkruJ?#;F1Pji^^{TgoxGf zk(I^T+(>whB&T44Hu`4avcSPlIZRZ#gMW+WW5tXz0-xgd0;Gd zoroInGfCxLy6`zDJ6KTJ6hoFGd?~az9SCV81s=?2TU=UHRlz}TW{XXkc;=InlbSz> zHD=SURd>fm2jjgLPQ~G4N5tOHX!ae?m22%lf?bKuR+IT9I!e|mE^qvso+k}B0uKiP zp5L&4w%tS6SXzwL=Kfe-uf_7xyfEYA-8(UIU?4hra6q)=T8Eh+A0KqAVK%8YdXWh4 z)}p#?$2#z3S1j8akTAEf5VKP=F*&mkuU((g&uFw*#jn%e(Gy*LgE9KZFUR!vz7{)G zS1kv{b!~nQvlNOCx!DU!RA5e&3NW+HGNVzMbXJL_0bAB7&u*xz zHF~={VtuO?(=$t+E|Ug5g?2}@cQE$BtXY#erp*V1Nb;&I62jFpARx1kTy^p9$DyqKC}d7GULgq zsW@`@h-@&$HEwCqrt9k;Fv|iiA;Gt)MKkwyw$`Jq16BgTIGwY2IISJg*W1_S;z(%e{>_}LPaWm2!vGYC^G@8$-)_0GjunxBow9(yeQr~mo)1j`V7*ckXl{2%|@ z{~j~5SRVT1Q?^sw{hiqPKu%dF-FQjIw_O$jx5$DsJGXS8OLot-pE`XqjvPCo1$XA; z36cFTUAiK6Na+lt)cciR{gwE^4}PeiIXN{G-~GW$x_^&9{K9|gpiVQOwTTClab&Szfmchb0e?Fo-o;dt+_(w(gN~(L5|Y&7~ggWZ&v-*ps9* zpG-8#Y&g67Jg0VgJsKlroLwvs@o6peQZUSnRrfBiGhK5fs^THnqpJ<4zJ2P?24};; zpD)((+t+Tzv4gNIy5sWA$yi*&0kRVGQ`|domMb<2I)}7+ux#2JzcloC{{o5Zhab46 zLV+Ww6N5ayt*tSmuRxyklQgt-*EB@)o_%wPQw$FPLsy2(#)e%%bA>K=d#3}k=8w@~ zUtUr+0LdQrHeT2hli94!2skO!%xk6WstRhr7LhX4cAI{1MXASoa#E6=0f&H1(?#X? zoW)YhG^;_x`-pM^e-Pga!4s(Ssu}|iBm$nSCQ?4Y!W(|)or|%uI3Eu^{80QafAISz zg(qM7^5x6%fB)e>SNUjPijr~uq#91smNUC68?ZF;wCIyV$YzG#R!HRpv6H7x#nI!( zRkj{Ga!6hlWXNnfcUkMY=kI_2FUAjl_;S4d<2U2#^&2|1j~qQB)1~3z5nb=?+qVTD z4D|QM)by0h_0uHLL2w^4M7EPsHP$pGxEPOHP*5bC>7doot}18|#bRboKaEZEoVeEt z&guC|p!H#3yVTOP*XXSXVf$1*1ruZvb-{v=8MB7^`v&ycIdp{2W1LSvBeQncG{6@? zJP0aAyIbR_^G9QO6_fZ@mFkAU+C%y&*4g%^JK#zCQaP$F*iP(V+!IW9*i^8QHwulo zx(804Iej#~^4zO&<<^uPxgz3sKlF3a)z%!-lXKBT^^;@b)vHht-kb7fC?sbPX7J=Q zk+n)G$sE6GO+i^0Wm~(lIbo4BguA=N1QPa+oVvL!7N#fk?)-$e^&P_PXBL=cxQ7|%-`qdV7ot8x zBzZFnCHy7#q=YYuB8J~1*!z^RcWjY&QdUBx;)Y0_ms5dDH(yzFPMa>+@cQbS#39hC zR@XPQaWv0Q8x8j+Gc&5St+;scQY_BT#e)|fj6e8;-&co|EO%~hA>O%oDgN>+Us3t! z;icK_%#z5l-B=JM9Veg}1I|QBGosvJf*?FcnkX!2q}j(#oQNaGkLw=7sU`4Xh;O=# z850Op9=z~CJoo&!;?>vR(!IyF^X9E_HTWKVYHX&a@OZYFwP!W-px@oQdMUfpX7W!6&ETn@;HhK$i=Z$jB`$;|nFnNwDH z$b64LLol|{zPFF2`ZCx+m^nci!<981R4ja)?T{FgxdCsmSSKeYVz{>>P9ErrBV&& z@Z6uDd*rk%9W{S(nFjJ+&@I@w54yxAv*EAOxLAr77J`~=&cBpNQGw1bXfKIYMYg-M zBQ^ldSO&1tl$LxwvtmhXQ}L#IsfpJ)STh*`r3^2DMQjK99I99>r!M1$#N0@RgjoU3 zSQUga>s1!akcYu;k8rBiVvgx1c`b!j!7Xt4?p&E*FEgJq$aJ4ep(`m@Q!=KKg{yho z5=!i2FQF1tRajUS4W^s3;znTBUTBGTuHANq+}9nKZ`~EkLIJrCmIYvm<>HNz@_J@I zd8|H>RArGLQ@q-BS%B=#H9935A?C! zTfR55gTKGPh`CIfLYy>=e_}C+7hN>&@R^0n*tQPHg6s+i1A;o4GV}FB)5+|FfJZR8 za^-5w&(6d>=g!6N{oX$nCds_Ind#}6pP!G{Uwu_SC+ZaxzJ&!}6P)L*n#}ACTfj{4 zEHk_N+cTP`r{(&8;MFSPQOFiRtO-xOrnN#_miiOFw+% zNcv9uaD%^%sO0*M8*+(bHs8_;!LgKRVA#gLi*Tf1%G@u;*odK$HjJgRDOfWH35O&H zT%iQ=fs68x&%kp6s`4Rgp+zZ=^|PfzE<<^%lYltb^p*mMDpT(_CM?tc7fJ1nG z9PC>(?^@fUr?XwY3$;qCGBO=1)y?Q>P2T}r$F{hJVijuaT%jkKLz;Ei81+@c#NKdE z;jCE_lf2;1(9zwiXTyL9%eh-U^Ws4TCw1kb&L#{v1`_3=1*uw=*+F~5u` zEi4R4j<#G46TbL~rf)Ve&5B3{ds^O##iE4FLz?-!V}bV`5SoYxni*iVD!0h?oavgF za2|&*wNy#)6lcEt`9H00Zf>?ASlHaCYF-#w>FV;Lf^em|HD)F!q90q#+K#<0x_fk@ z>t+;s2W45c8a;h|%J>MV1>(?9$7)T1VQFbOdV6|h`zWQ5hEBSvsDRxJw%qAS4-l#O zH%*0L6qL*GwbfMxW&$ZRBJfxitGzAU$&^yAR*SdZdOH^9X5+-E)A0+x_zRMTvzYFV zkIUPc!0_bHyie7@n?HVChYqjLb*^q!RZ8<<_&M-07CsV6FT_f;cT&E2S_&S#WWhQm zIqh3p9y$(LXp6Bf~>#C@d|nsKE#J&OE;P zg+-NiTqpNOP1NEYi=hwqCs`|H!O~cxv+N3B&tF%^g~Zg@Pq~4gX~}O()8r88UC(R zV^lpW3$rnP`*yT+_E->-czJ=eWJ;B0Oe%5PI|IWUC`d6&plSdB4Q)w8K~!qrs6h-d ze{VEV>ALHEx2iEbI;y~;<}K@OWkr9|Y{pl)_yp{s{(UZg>2WM0{%p7%=tZg59@Xs~O)oFBG2U3=hKe~W1Y@st-8Z=y=VWQc z4Fa4hSu8kBfm82Aeio*|mBWUgC-!h)6s6uzq{T(Km)|6TxOiK*4@(+(1G|F%2Uc|P7df!YzQ(;f-_v+GTY9EI-Ecj zWl%a>HodMamViuVRP62eo@gdJJ8}8S)tJ6J5vNX_jQj4pFXm>Zl~oZW9)A2WStj1P zaV_Q-mekZ*StHYS^9FY~GUQ^sVoWW&%9#boqeF|y*cJhlQQ%Aw#<1t$p~Ld&Eo=pi z60g=gI%#_+Uj5N)F)=kAhYlT7LyG_ghIsqV9Z?2HMur`LsSp^fD)CG4(h!1gPHYaP zRS4L3s)IduONwr@B|#c#vd?M+@8W<(iD&4klx6mRD9{F&KOETtwQz66zf=}$Rbw$Z zQWnQ17SqIL?R+FdRd(iM{giIH%0SjgSC=YCsrho61@A+a$~|F;aiDVjJQu+>iF0!J z%N!<4U7i!4nfs!VM$B+bxWa3cB+cl+``V*ho_(o zem5Ib4s`x(3^>5dzqqAYfKr?u9oWc{?U?6v#MGJMCsWq*2A9mZ z$Ywf?3D$pZLG8CPlT&*yHRu{FkX2QIf}>J-rSj#^ee(A^I=lWkrINfQa9d*mLXpaw zs?M%dd{t#Joa|D3rFxHdw=l#Dj$p~DP4G~22$I{Z0N^l-I3 zdWsmNjEc!do$#nM#U`lmEIkq{Rff5M3iSs3p1_Y1Pv$?WE;#M+p)fbRWLYv~S~9Gl zfV^+yxf**Z5|L6#Vj9B{Fdqczv{_K1#(0oNt8vR#RK zFh@80fk3&uyyEgOGgAc!w^Q_-tC+%P5+LqO1-`2H~$O}V>HIjgos57R3U*#!UnoejH23sZn)jZkQ)$1 zX%^;nsxQ;j6c@)P;>dv^1>|eDCu3>d2PVCe()&^WrDWBb`hiKk4+n<%8iq(eV>#FP z%b0hQ;8HyUQ90en<61NXfc{3h=#h{Lwn*z+W&Sw`RsW!A@&Lt^KhRP5SAX&8mn+RJ zPw?<*UdhCKeKm$h4{6aeEgFB;GL?gpkSQDLinb!124n73H=IDKMuQ%JKP;3TIL)}O zjgB6Wo}Xc#WX$~o1H$}Z4zN+-^lHNj@@Nx1j)03Bi!nPjCH}6}I5wtd6PX>~EPFu8PaZO-8JRa3k1PbW!7B;|GTqKnpZiw) zHz@Iou!YWle>d4NbKp8+baYg%WCQ_lYN`)D*Y{s~Mc6Th=I8IdN7)>5YVP6b(tF+WjUanQ;GgT@3 zfNCZ)X#TX?%vD4AoVd#ooh9cnfz}}XnVCWZoaZK__oY5Z z9-C5qCG@h_*mH(itOew3$4o?Me&B*X^`*lzlflyDy)-rvhYtW*bjS7EroC|+u=xe& z-+w4OE*P@l-e^6fFie5J@a*>iP#hDRsyHo}kw8f^DUHp0T$#DY39EZpvbf~F7GwV9 zK#y0h-I{z-0r{`L^6c5pj^3|sY*wEL6iZxu!El~SnbHMu#-Y-q^e5nY zBQz;U!Wrg-;J?VH304F-hFKEeB?8HefDHqapaeG*ZR*S;*@YU%CP_M!L?zpJ0>G@; zR<;e!N;a$6VR(-wPHH#)CJi~AoVXKxJ-sfk$|;wpa7X%V@HrT{V~<`p20TH;<)&t8 zDFcuapm9>N*$G%IIvy-pIQ&?qX7IhyLx*By^pMHt91_)Py!f5(%PWM}hqFz<(&88+DUa!CYMjSnQL;{^ss__uLpuBk4+}x}3Rmx?aAsN1CM;WM#w{*$MIP^wG zhU4z^j8$vJgBs5coU?LPAol?H3f^<6gbLF{7+H?}DNQI*@L-no^)_7l40YMpp!}Uo z4oJb7NBS>le&2Qs4GrrVIj7GEBQLcV4I9?&UQ~mtN1Rsp3JWnV|5zWPYW& zcgal3aq>Rw6B46xkl#y_d?45}Oaw1*6C2zCE~#D#br7IMqe@Xz!A6Vk0$Ho3hFFm2 zpqB@gV3QPc$Sz94jWVnNSiu?dP#3To8M3K+3N{`wtrtY3N$v81^Y#|Wu+3-kD>(VksS_w%utV@>cJ7N_j&xL1H z;Ll1^^DC`Q@$sv-r?2gG9LSWv{JGz+)oLGaZfSm~y{)}Xm|>2(rqNYOJGjUMO%|oN zyV(_Y2^DHapw4p>$uduf&uYA=batnm#VeLVFi^EqCpL{cHkN`iBb_oslY%ZYZh|{m z_QK+l0;u2;7B<n!O z5Xf}YH5K;g2PMoYfjLuE_7rdYoIO)%N_GfGhLepE{=o2vUW3p2y&t?RHUS%lDb(CM znJcxoDLC`F8G4FqUc2rg$}ZE~N(s!uD!ktUDcB3d-mHaBO;9Qx99kH;sYOuFoQlPB z?C6o0xI3whU$Qx8kb7_p3yO_6Ju_#Sbn-pDp$%)423^TOxn?q5@ZGXm)O6+fr+E35? zfYp};$K$gz|B%-#kOq8jHBTGecd}|{^<{dEvR^45_hpJnE#w^~TuKF^o>4vvS20#5 zI*!@1S%31J#eQ+a)&Fd0M*-jOwnsfHbL`SUss!*7zyw1i<}MUB`w3E4O0nmPR=9fh z4>T#hOmbo7We2W%R&FkDKnqM-VP=GeUMTPVdVH0DEZ67aU6NU;jz!=%vSfJ4+*g|W zNrzLS2RsF2v0Kwbj)HNQL$GnWG?J|nkewmlP=@R&Mq+~TUb1B{TdKfi(08b literal 0 HcmV?d00001 diff --git a/static/imgs/phone.png b/static/imgs/phone.png new file mode 100644 index 0000000000000000000000000000000000000000..ee709aa7e5a328dde137a0b43269938203a468d6 GIT binary patch literal 596 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 J3L4|;zW{KQ_`3iA literal 0 HcmV?d00001 diff --git a/static/tabbar/index_HL.png b/static/tabbar/index_HL.png new file mode 100644 index 0000000000000000000000000000000000000000..720fd2c05491303387976a3b6be0acea5eef31be GIT binary patch literal 4230 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 literal 0 HcmV?d00001 diff --git a/store/index.js b/store/index.js new file mode 100644 index 0000000..3cc02ea --- /dev/null +++ b/store/index.js @@ -0,0 +1,12 @@ +import { createPinia } from "pinia"; + +const store = createPinia(); + +export function setupStore(app) { + app.use(store); +} + +export { store }; + +export * from "./modules/user"; +export * from "./modules/auth"; diff --git a/store/modules/auth.js b/store/modules/auth.js new file mode 100644 index 0000000..7efae03 --- /dev/null +++ b/store/modules/auth.js @@ -0,0 +1,69 @@ +import AuthAPI from "@/api/modules/auth"; +import { store } from "@/store"; +import { cache } from "@/utils/cache"; +import { defineStore } from "pinia"; +import { computed, ref, watch } from "vue"; + +export const useAuthStore = defineStore("auth", () => { + const ACCESS_TOKEN_KEY = "accessToken"; + const REFRESH_TOKEN_KEY = "refreshToken"; + const accessToken = ref(cache(ACCESS_TOKEN_KEY) ?? ""); + const refreshToken = ref(cache(REFRESH_TOKEN_KEY) ?? ""); + const isLoggedIn = computed(() => !!accessToken.value); + + watch(accessToken, (newValue) => cache(ACCESS_TOKEN_KEY, newValue || null)); + watch(refreshToken, (newValue) => cache(REFRESH_TOKEN_KEY, newValue || null)); + + // 注册 + async function signUp(payload) { + const response = await AuthAPI.signUp(payload); + const prefix = response.tokenType ? `${response.tokenType} ` : ""; + accessToken.value = prefix + response.accessToken; + refreshToken.value = prefix + response.refreshToken; + return response; + } + + // 登录 + async function signIn(payload) { + const response = await AuthAPI.signIn(payload); + const prefix = response.tokenType ? `${response.tokenType} ` : ""; + accessToken.value = prefix + response.accessToken; + refreshToken.value = prefix + response.refreshToken; + return response; + } + + // 登出 + function signOut() { + accessToken.value = ""; + refreshToken.value = ""; + } + + // 刷新token + async function refresh(payload) { + const response = await AuthAPI.refreshToken(payload); + const prefix = response.tokenType ? `${response.tokenType} ` : ""; + accessToken.value = prefix + response.accessToken; + return response; + } + + function setAccessToken(payload) { + accessToken.value = payload; + } + + return { + accessToken, + refreshToken, + isLoggedIn, + signUp, + signIn, + signOut, + refresh, + setAccessToken + }; +}); + +// 手动提供给 useStore() 函数 pinia 实例 +// https://pinia.vuejs.org/zh/core-concepts/outside-component-usage.html#using-a-store-outside-of-a-component +export function useAuthStoreHook() { + return useAuthStore(store); +} diff --git a/store/modules/user.js b/store/modules/user.js new file mode 100644 index 0000000..4f7f219 --- /dev/null +++ b/store/modules/user.js @@ -0,0 +1,32 @@ +import { defineStore } from "pinia"; +import { ref, watch } from "vue"; +import { cache } from "@/utils/cache"; + +export const useUserStore = defineStore("user", () => { + const userInfo = ref(cache('USERINFO_KEY') ? JSON.parse(cache('USERINFO_KEY')) : { + username: "", + }); + +const adressInfo = ref(cache('ADRESS_KEY') ? JSON.parse(cache('ADRESS_KEY')) : { + latitude: "", + longitude: "", + adress: "", + }); + +watch(userInfo, (newValue) => cache('USERINFO_KEY', newValue ? JSON.stringify(newValue) : null)); +watch(adressInfo, (newValue) => cache('ADRESS_KEY', newValue ? JSON.stringify(newValue) : null)); + +function setUserInfo(payload) { + userInfo.value = payload; +} +function setAdressInfo(payload) { + adressInfo.value = payload; +} + + return { + userInfo, + setUserInfo, + adressInfo, + setAdressInfo + }; +}); diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..8e0f510 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,33 @@ +{ + "compilerOptions": { + "allowJs": true, + "allowSyntheticDefaultImports": true, + "baseUrl": ".", + "esModuleInterop": true, + "forceConsistentCasingInFileNames": true, + "importHelpers": true, + "jsx": "preserve", + "jsxFactory": "h", + "jsxFragmentFactory": "Fragment", + "jsxImportSource": "vue", + "lib": ["esnext", "dom"], + "module": "esnext", + "moduleResolution": "bundler", + "noEmit": true, + "noImplicitThis": true, + "noLib": false, + "paths": { + "@/*": ["./*"] + }, + "resolveJsonModule": true, + "skipLibCheck": true, + "sourceMap": true, + "strict": true, + "target": "esnext", + "types": ["@dcloudio/types"], + "useDefineForClassFields": true, + "verbatimModuleSyntax": true + }, + "exclude": ["node_modules", "uni_modules", "unpackage", "**/*.js"], + "include": ["**/*.{ts,vue}"] +} diff --git a/uni.scss b/uni.scss new file mode 100644 index 0000000..519260d --- /dev/null +++ b/uni.scss @@ -0,0 +1,79 @@ +/** + * 这里是uni-app内置的常用样式变量 + * + * uni-app 官方扩展插件及插件市场(https://ext.dcloud.net.cn)上很多三方插件均使用了这些样式变量 + * 如果你是插件开发者,建议你使用scss预处理,并在插件代码中直接使用这些变量(无需 import 这个文件),方便用户通过搭积木的方式开发整体风格一致的App + * + */ + +/** + * 如果你是App开发者(插件使用者),你可以通过修改这些变量来定制自己的插件主题,实现自定义主题功能 + * + * 如果你的项目同样使用了scss预处理,你也可以直接在你的 scss 代码中使用如下变量,同时无需 import 这个文件 + */ + +/* 颜色变量 */ + +/* 行为相关颜色 */ +$uni-color-primary: #007aff; +$uni-color-success: #4cd964; +$uni-color-warning: #f0ad4e; +$uni-color-error: #dd524d; + +/* 文字基本颜色 */ +$uni-text-color: #333; //基本色 +$uni-text-color-inverse: #fff; //反色 +$uni-text-color-grey: #999; //辅助灰色,如加载更多的提示信息 +$uni-text-color-placeholder: #808080; +$uni-text-color-disable: #c0c0c0; + +/* 背景颜色 */ +$uni-bg-color: #ffffff; +$uni-bg-color-grey: #f8f8f8; +$uni-bg-color-hover: #f1f1f1; //点击状态颜色 +$uni-bg-color-mask: rgba(0, 0, 0, 0.4); //遮罩颜色 + +/* 边框颜色 */ +$uni-border-color: #c8c7cc; + +/* 尺寸变量 */ + +/* 文字尺寸 */ +$uni-font-size-sm: 12px; +$uni-font-size-base: 14px; +$uni-font-size-lg: 16px; + +/* 图片尺寸 */ +$uni-img-size-sm: 20px; +$uni-img-size-base: 26px; +$uni-img-size-lg: 40px; + +/* Border Radius */ +$uni-border-radius-sm: 2px; +$uni-border-radius-base: 3px; +$uni-border-radius-lg: 6px; +$uni-border-radius-circle: 50%; + +/* 水平间距 */ +$uni-spacing-row-sm: 5px; +$uni-spacing-row-base: 10px; +$uni-spacing-row-lg: 15px; + +/* 垂直间距 */ +$uni-spacing-col-sm: 4px; +$uni-spacing-col-base: 8px; +$uni-spacing-col-lg: 12px; + +/* 透明度 */ +$uni-opacity-disabled: 0.3; // 组件禁用态的透明度 + +/* 文章场景相关 */ +$uni-color-title: #2c405a; // 文章标题颜色 +$uni-font-size-title: 20px; +$uni-color-subtitle: #555555; // 二级标题颜色 +$uni-font-size-subtitle: 26px; +$uni-color-paragraph: #3f536e; // 文章段落颜色 +$uni-font-size-paragraph: 15px; + +/* uv-ui主题 */ +@import "@/uni_modules/uv-ui-tools/theme.scss"; diff --git a/uni_modules/uv-action-sheet/changelog.md b/uni_modules/uv-action-sheet/changelog.md new file mode 100644 index 0000000..ab3545e --- /dev/null +++ b/uni_modules/uv-action-sheet/changelog.md @@ -0,0 +1,7 @@ +## 1.0.2(2023-07-02) +uv-action-sheet 由于弹出层uv-popup的修改,打开和关闭方法更改,详情参考文档:https://www.uvui.cn/components/actionSheet.html +## 1.0.1(2023-05-16) +1. 优化组件依赖,修改后无需全局引入,组件导入即可使用 +2. 优化部分功能 +## 1.0.0(2023-05-10) +uv-action-sheet 底部操作菜单 diff --git a/uni_modules/uv-action-sheet/components/uv-action-sheet/props.js b/uni_modules/uv-action-sheet/components/uv-action-sheet/props.js new file mode 100644 index 0000000..8adffee --- /dev/null +++ b/uni_modules/uv-action-sheet/components/uv-action-sheet/props.js @@ -0,0 +1,50 @@ +export default { + props: { + // 标题,有值则显示,同时会显示关闭按钮 + title: { + type: String, + default: '' + }, + // 选项上方的描述信息 + description: { + type: String, + default: '' + }, + // 数据 + actions: { + type: Array, + default: () => [] + }, + // 取消按钮的文字,不为空时显示按钮 + cancelText: { + type: String, + default: '' + }, + // 点击某个菜单项时是否关闭弹窗 + closeOnClickAction: { + type: Boolean, + default: true + }, + // 处理底部安全区(默认true) + safeAreaInsetBottom: { + type: Boolean, + default: true + }, + // 小程序的打开方式 + openType: { + type: String, + default: '' + }, + // 点击遮罩是否允许关闭 (默认true) + closeOnClickOverlay: { + type: Boolean, + default: true + }, + // 圆角值 + round: { + type: [Boolean, String, Number], + default: 0 + }, + ...uni.$uv?.props?.actionSheet + } +} \ No newline at end of file diff --git a/uni_modules/uv-action-sheet/components/uv-action-sheet/uv-action-sheet.vue b/uni_modules/uv-action-sheet/components/uv-action-sheet/uv-action-sheet.vue new file mode 100644 index 0000000..edca089 --- /dev/null +++ b/uni_modules/uv-action-sheet/components/uv-action-sheet/uv-action-sheet.vue @@ -0,0 +1,280 @@ + + + + + + diff --git a/uni_modules/uv-action-sheet/package.json b/uni_modules/uv-action-sheet/package.json new file mode 100644 index 0000000..e7b6173 --- /dev/null +++ b/uni_modules/uv-action-sheet/package.json @@ -0,0 +1,92 @@ +{ + "id": "uv-action-sheet", + "displayName": "uv-action-sheet 底部操作菜单 全面兼容小程序、nvue、vue2、vue3等多端", + "version": "1.0.2", + "description": "该组件用于从底部弹出一个操作菜单,供用户选择并返回结果。本组件功能类似于uni的uni.showActionSheet API,配置更加灵活,所有平台都表现一致。", + "keywords": [ + "action-sheet", + "uvui", + "uv-ui", + "操作菜单", + "菜单选择" +], + "repository": "", + "engines": { + "HBuilderX": "^3.1.0" + }, + "dcloudext": { + "type": "component-vue", + "sale": { + "regular": { + "price": "0.00" + }, + "sourcecode": { + "price": "0.00" + } + }, + "contact": { + "qq": "" + }, + "declaration": { + "ads": "无", + "data": "插件不采集任何数据", + "permissions": "无" + }, + "npmurl": "" + }, + "uni_modules": { + "dependencies": [ + "uv-ui-tools", + "uv-popup", + "uv-icon", + "uv-line", + "uv-loading-icon", + "uv-gap" + ], + "encrypt": [], + "platforms": { + "cloud": { + "tcb": "y", + "aliyun": "y" + }, + "client": { + "Vue": { + "vue2": "y", + "vue3": "y" + }, + "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", + "钉钉": "u", + "快手": "u", + "飞书": "u", + "京东": "u" + }, + "快应用": { + "华为": "u", + "联盟": "u" + } + } + } + } +} \ No newline at end of file diff --git a/uni_modules/uv-action-sheet/readme.md b/uni_modules/uv-action-sheet/readme.md new file mode 100644 index 0000000..9ea5487 --- /dev/null +++ b/uni_modules/uv-action-sheet/readme.md @@ -0,0 +1,13 @@ +## ActionSheet 操作菜单 + +> **组件名:uv-action-sheet** + +本组件用于从底部弹出一个操作菜单,供用户选择并返回结果。 + +本组件功能类似于uni的uni.showActionSheet API,配置更加灵活,所有平台都表现一致。 + +### 查看文档 + +### [完整示例项目下载 | 关注更多组件](https://ext.dcloud.net.cn/plugin?name=uv-ui) + +#### 如使用过程中有任何问题,或者您对uv-ui有一些好的建议,欢迎加入 uv-ui 交流群:uv-ui、官方QQ群 diff --git a/uni_modules/uv-album/changelog.md b/uni_modules/uv-album/changelog.md new file mode 100644 index 0000000..42ab5e2 --- /dev/null +++ b/uni_modules/uv-album/changelog.md @@ -0,0 +1,10 @@ +## 1.0.4(2023-12-06) +1. 阻止事件冒泡处理 +## 1.0.3(2023-10-23) +1. 修复报错的BUG +## 1.0.2(2023-10-23) +1. 修复设置singleSize、multipleSize、space等值带单位,存在不显示的BUG +## 1.0.1(2023-09-13) +1. 添加依赖 +## 1.0.0(2023-08-30) +1. 新增uv-album相册组件 diff --git a/uni_modules/uv-album/components/uv-album/uv-album.vue b/uni_modules/uv-album/components/uv-album/uv-album.vue new file mode 100644 index 0000000..835d792 --- /dev/null +++ b/uni_modules/uv-album/components/uv-album/uv-album.vue @@ -0,0 +1,312 @@ + + + + \ No newline at end of file diff --git a/uni_modules/uv-album/package.json b/uni_modules/uv-album/package.json new file mode 100644 index 0000000..700602f --- /dev/null +++ b/uni_modules/uv-album/package.json @@ -0,0 +1,88 @@ +{ + "id": "uv-album", + "displayName": "uv-album 相册 全面兼容vue3+2、app、h5、小程序等多端", + "version": "1.0.4", + "description": "本组件提供一个类似相册的功能,让开发者开发起来更加得心应手,功能齐全,灵活配置可以,开箱即用。减少重复的模板代码", + "keywords": [ + "album", + "uv-ui", + "uvui", + "相册", + "图片" +], + "repository": "", + "engines": { + "HBuilderX": "^3.1.0" + }, + "dcloudext": { + "type": "component-vue", + "sale": { + "regular": { + "price": "0.00" + }, + "sourcecode": { + "price": "0.00" + } + }, + "contact": { + "qq": "" + }, + "declaration": { + "ads": "无", + "data": "插件不采集任何数据", + "permissions": "无" + }, + "npmurl": "" + }, + "uni_modules": { + "dependencies": [ + "uv-ui-tools", + "uv-text" + ], + "encrypt": [], + "platforms": { + "cloud": { + "tcb": "y", + "aliyun": "y" + }, + "client": { + "Vue": { + "vue2": "y", + "vue3": "y" + }, + "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", + "钉钉": "u", + "快手": "u", + "飞书": "u", + "京东": "u" + }, + "快应用": { + "华为": "u", + "联盟": "u" + } + } + } + } +} \ No newline at end of file diff --git a/uni_modules/uv-album/readme.md b/uni_modules/uv-album/readme.md new file mode 100644 index 0000000..edd2f0b --- /dev/null +++ b/uni_modules/uv-album/readme.md @@ -0,0 +1,21 @@ +# Album 相册 + +> **组件名:uv-album** + +本组件提供一个类似相册的功能,让开发者开发起来更加得心应手。 + +功能齐全,灵活配置可以,开箱即用。减少重复的模板代码。 + +# 查看文档 + +## [下载完整示例项目](https://ext.dcloud.net.cn/plugin?name=uv-ui) (请不要 下载插件ZIP) + +### [更多插件,请关注uv-ui组件库](https://ext.dcloud.net.cn/plugin?name=uv-ui) + + + +![image](https://mp-a667b617-c5f1-4a2d-9a54-683a67cff588.cdn.bspapp.com/uv-ui/banner.png) + + + +#### 如使用过程中有任何问题反馈,或者您对uv-ui有一些好的建议,欢迎加入uv-ui官方交流群:官方QQ群 \ No newline at end of file diff --git a/uni_modules/uv-alert/changelog.md b/uni_modules/uv-alert/changelog.md new file mode 100644 index 0000000..71cca03 --- /dev/null +++ b/uni_modules/uv-alert/changelog.md @@ -0,0 +1,7 @@ +## 1.0.2(2023-06-01) +1. 修复点击触发两次实践的BUG +## 1.0.1(2023-05-16) +1. 优化组件依赖,修改后无需全局引入,组件导入即可使用 +2. 优化部分功能 +## 1.0.0(2023-05-10) +uv-alert 警告提示组件 diff --git a/uni_modules/uv-alert/components/uv-alert/props.js b/uni_modules/uv-alert/components/uv-alert/props.js new file mode 100644 index 0000000..cc8edc1 --- /dev/null +++ b/uni_modules/uv-alert/components/uv-alert/props.js @@ -0,0 +1,45 @@ +export default { + props: { + // 显示文字 + title: { + type: String, + default: '' + }, + // 主题,success/warning/info/error + type: { + type: String, + default: 'warning' + }, + // 辅助性文字 + description: { + type: String, + default: '' + }, + // 是否可关闭 + closable: { + type: Boolean, + default: false + }, + // 是否显示图标 + showIcon: { + type: Boolean, + default: false + }, + // 浅或深色调,light-浅色,dark-深色 + effect: { + type: String, + default: 'light' + }, + // 文字是否居中 + center: { + type: Boolean, + default: false + }, + // 字体大小 + fontSize: { + type: [String, Number], + default: 14 + }, + ...uni.$uv?.props?.alert + } +} \ No newline at end of file diff --git a/uni_modules/uv-alert/components/uv-alert/uv-alert.vue b/uni_modules/uv-alert/components/uv-alert/uv-alert.vue new file mode 100644 index 0000000..ba3965e --- /dev/null +++ b/uni_modules/uv-alert/components/uv-alert/uv-alert.vue @@ -0,0 +1,246 @@ + + + + + diff --git a/uni_modules/uv-alert/package.json b/uni_modules/uv-alert/package.json new file mode 100644 index 0000000..34bec20 --- /dev/null +++ b/uni_modules/uv-alert/package.json @@ -0,0 +1,88 @@ +{ + "id": "uv-alert", + "displayName": "uv-alert 警告提示 全面兼容小程序、nvue、vue2、vue3等多端", + "version": "1.0.2", + "description": "uv-alert 警告提示,展现需要关注的信息。灵活配置,功能齐全,兼容全端", + "keywords": [ + "alert", + "uvui", + "uv-ui", + "警告提示" + ], + "repository": "", + "engines": { + "HBuilderX": "^3.1.0" + }, + "dcloudext": { + "type": "component-vue", + "sale": { + "regular": { + "price": "0.00" + }, + "sourcecode": { + "price": "0.00" + } + }, + "contact": { + "qq": "" + }, + "declaration": { + "ads": "无", + "data": "插件不采集任何数据", + "permissions": "无" + }, + "npmurl": "" + }, + "uni_modules": { + "dependencies": [ + "uv-ui-tools", + "uv-transition", + "uv-icon" + ], + "encrypt": [], + "platforms": { + "cloud": { + "tcb": "y", + "aliyun": "y" + }, + "client": { + "Vue": { + "vue2": "y", + "vue3": "y" + }, + "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", + "钉钉": "u", + "快手": "u", + "飞书": "u", + "京东": "u" + }, + "快应用": { + "华为": "u", + "联盟": "u" + } + } + } + } +} \ No newline at end of file diff --git a/uni_modules/uv-alert/readme.md b/uni_modules/uv-alert/readme.md new file mode 100644 index 0000000..63dda76 --- /dev/null +++ b/uni_modules/uv-alert/readme.md @@ -0,0 +1,15 @@ +## Alert 警告提示 + +> **组件名:uv-alert** + +警告提示,展现需要关注的信息。 + +当某个页面需要向用户显示警告的信息时。 + +非浮层的静态展现形式,始终展现,不会自动消失,用户可以点击关闭。 + +### 查看文档 + +### [完整示例项目下载 | 关注更多组件](https://ext.dcloud.net.cn/plugin?name=uv-ui) + +#### 如使用过程中有任何问题,或者您对uv-ui有一些好的建议,欢迎加入 uv-ui 交流群:uv-ui、官方QQ群 diff --git a/uni_modules/uv-avatar/changelog.md b/uni_modules/uv-avatar/changelog.md new file mode 100644 index 0000000..8631c86 --- /dev/null +++ b/uni_modules/uv-avatar/changelog.md @@ -0,0 +1,13 @@ +## 1.0.5(2023-12-06) +1. 优化 +## 1.0.4(2023-12-06) +1. 优化 +## 1.0.3(2023-12-06) +1. 阻止事件冒泡处理,单个头像模式 +## 1.0.2(2023-12-06) +1. 阻止事件冒泡处理 +## 1.0.1(2023-05-16) +1. 优化组件依赖,修改后无需全局引入,组件导入即可使用 +2. 优化部分功能 +## 1.0.0(2023-05-10) +uv-avatar 头像组件 diff --git a/uni_modules/uv-avatar/components/uv-avatar-group/props.js b/uni_modules/uv-avatar/components/uv-avatar-group/props.js new file mode 100644 index 0000000..a610ab4 --- /dev/null +++ b/uni_modules/uv-avatar/components/uv-avatar-group/props.js @@ -0,0 +1,53 @@ +export default { + props: { + // 头像图片组 + urls: { + type: Array, + default: () => [] + }, + // 最多展示的头像数量 + maxCount: { + type: [String, Number], + default: 5 + }, + // 头像形状 + shape: { + type: String, + default: 'circle' + }, + // 图片裁剪模式 + mode: { + type: String, + default: 'scaleToFill' + }, + // 超出maxCount时是否显示查看更多的提示 + showMore: { + type: Boolean, + default: true + }, + // 头像大小 + size: { + type: [String, Number], + default: 40 + }, + // 指定从数组的对象元素中读取哪个属性作为图片地址 + keyName: { + type: String, + default: '' + }, + // 头像之间的遮挡比例 + gap: { + type: [String, Number], + validator(value) { + return value >= 0 && value <= 1 + }, + default: 0.5 + }, + // 需额外显示的值 + extraValue: { + type: [Number, String], + default: 0 + }, + ...uni.$uv?.props?.avatarGroup + } +} \ No newline at end of file diff --git a/uni_modules/uv-avatar/components/uv-avatar-group/uv-avatar-group.vue b/uni_modules/uv-avatar/components/uv-avatar-group/uv-avatar-group.vue new file mode 100644 index 0000000..59481f6 --- /dev/null +++ b/uni_modules/uv-avatar/components/uv-avatar-group/uv-avatar-group.vue @@ -0,0 +1,106 @@ + + + + + diff --git a/uni_modules/uv-avatar/components/uv-avatar/props.js b/uni_modules/uv-avatar/components/uv-avatar/props.js new file mode 100644 index 0000000..6c8d725 --- /dev/null +++ b/uni_modules/uv-avatar/components/uv-avatar/props.js @@ -0,0 +1,80 @@ +import { range } from '@/uni_modules/uv-ui-tools/libs/function/test.js' +export default { + props: { + // 头像图片路径(不能为相对路径) + src: { + type: String, + default: '' + }, + // 头像形状,circle-圆形,square-方形 + shape: { + type: String, + default: 'circle' + }, + // 头像尺寸 + size: { + type: [String, Number], + default: 40 + }, + // 裁剪模式 + mode: { + type: String, + default: 'scaleToFill' + }, + // 显示的文字 + text: { + type: String, + default: '' + }, + // 背景色 + bgColor: { + type: String, + default: '#c0c4cc' + }, + // 文字颜色 + color: { + type: String, + default: '#fff' + }, + // 文字大小 + fontSize: { + type: [String, Number], + default: 18 + }, + // 显示的图标 + icon: { + type: String, + default: '' + }, + // 显示小程序头像,只对百度,微信,QQ小程序有效 + mpAvatar: { + type: Boolean, + default: false + }, + // 是否使用随机背景色 + randomBgColor: { + type: Boolean, + default: false + }, + // 加载失败的默认头像(组件有内置默认图片) + defaultUrl: { + type: String, + default: '' + }, + // 如果配置了randomBgColor为true,且配置了此值,则从默认的背景色数组中取出对应索引的颜色值,取值0-19之间 + colorIndex: { + type: [String, Number], + // 校验参数规则,索引在0-19之间 + validator(n) { + return range(n, [0, 19]) || n === '' + }, + default: '' + }, + // 组件标识符 + name: { + type: String, + default: '' + }, + ...uni.$uv?.props?.avatar + } +} \ No newline at end of file diff --git a/uni_modules/uv-avatar/components/uv-avatar/uv-avatar.vue b/uni_modules/uv-avatar/components/uv-avatar/uv-avatar.vue new file mode 100644 index 0000000..0959d6a --- /dev/null +++ b/uni_modules/uv-avatar/components/uv-avatar/uv-avatar.vue @@ -0,0 +1,175 @@ + + + + + diff --git a/uni_modules/uv-avatar/package.json b/uni_modules/uv-avatar/package.json new file mode 100644 index 0000000..e77ab68 --- /dev/null +++ b/uni_modules/uv-avatar/package.json @@ -0,0 +1,89 @@ +{ + "id": "uv-avatar", + "displayName": "uv-avatar 头像 全面兼容小程序、nvue、vue2、vue3等多端", + "version": "1.0.5", + "description": "uv-avatar 本组件一般用于展示头像的地方,如个人中心,或者评论列表页的用户头像展示等场所。", + "keywords": [ + "uv-avatar", + "uvui", + "uv-ui", + "avatar", + "头像" + ], + "repository": "", + "engines": { + "HBuilderX": "^3.1.0" + }, + "dcloudext": { + "type": "component-vue", + "sale": { + "regular": { + "price": "0.00" + }, + "sourcecode": { + "price": "0.00" + } + }, + "contact": { + "qq": "" + }, + "declaration": { + "ads": "无", + "data": "插件不采集任何数据", + "permissions": "无" + }, + "npmurl": "" + }, + "uni_modules": { + "dependencies": [ + "uv-ui-tools", + "uv-icon", + "uv-text" + ], + "encrypt": [], + "platforms": { + "cloud": { + "tcb": "y", + "aliyun": "y" + }, + "client": { + "Vue": { + "vue2": "y", + "vue3": "y" + }, + "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", + "钉钉": "u", + "快手": "u", + "飞书": "u", + "京东": "u" + }, + "快应用": { + "华为": "u", + "联盟": "u" + } + } + } + } +} \ No newline at end of file diff --git a/uni_modules/uv-avatar/readme.md b/uni_modules/uv-avatar/readme.md new file mode 100644 index 0000000..1f068eb --- /dev/null +++ b/uni_modules/uv-avatar/readme.md @@ -0,0 +1,11 @@ +## Avatar 头像 + +> **组件名:uv-avatar** + +本组件一般用于展示头像的地方,如个人中心,或者评论列表页的用户头像展示等场所。 + +### 查看文档 + +### [完整示例项目下载 | 关注更多组件](https://ext.dcloud.net.cn/plugin?name=uv-ui) + +#### 如使用过程中有任何问题,或者您对uv-ui有一些好的建议,欢迎加入 uv-ui 交流群:uv-ui、官方QQ群 diff --git a/uni_modules/uv-back-top/changelog.md b/uni_modules/uv-back-top/changelog.md new file mode 100644 index 0000000..9772262 --- /dev/null +++ b/uni_modules/uv-back-top/changelog.md @@ -0,0 +1,8 @@ +## 1.0.2(2023-07-03) +1. 优化插槽自定义内容部分 +2. 增加backToTop方法说明 +## 1.0.1(2023-05-16) +1. 优化组件依赖,修改后无需全局引入,组件导入即可使用 +2. 优化部分功能 +## 1.0.0(2023-05-10) +uv-back-top 返回顶部 diff --git a/uni_modules/uv-back-top/components/uv-back-top/props.js b/uni_modules/uv-back-top/components/uv-back-top/props.js new file mode 100644 index 0000000..74daff4 --- /dev/null +++ b/uni_modules/uv-back-top/components/uv-back-top/props.js @@ -0,0 +1,58 @@ +export default { + props: { + // 返回顶部的形状,circle-圆形,square-方形 + mode: { + type: String, + default: 'circle' + }, + // 自定义图标 + icon: { + type: String, + default: 'arrow-upward' + }, + // 提示文字 + text: { + type: String, + default: '' + }, + // 返回顶部滚动时间 + duration: { + type: [String, Number], + default: 100 + }, + // 滚动距离 + scrollTop: { + type: [String, Number], + default: 0 + }, + // 距离顶部多少距离显示,单位px + top: { + type: [String, Number], + default: 400 + }, + // 返回顶部按钮到底部的距离,单位px + bottom: { + type: [String, Number], + default: 100 + }, + // 返回顶部按钮到右边的距离,单位px + right: { + type: [String, Number], + default: 20 + }, + // 层级 + zIndex: { + type: [String, Number], + default: 9 + }, + // 图标的样式,对象形式 + iconStyle: { + type: Object, + default: () => ({ + color: '#909399', + fontSize: '19px' + }) + }, + ...uni.$uv?.props?.backtop + } +} \ No newline at end of file diff --git a/uni_modules/uv-back-top/components/uv-back-top/uv-back-top.vue b/uni_modules/uv-back-top/components/uv-back-top/uv-back-top.vue new file mode 100644 index 0000000..fad73d4 --- /dev/null +++ b/uni_modules/uv-back-top/components/uv-back-top/uv-back-top.vue @@ -0,0 +1,116 @@ + + + + + \ No newline at end of file diff --git a/uni_modules/uv-back-top/package.json b/uni_modules/uv-back-top/package.json new file mode 100644 index 0000000..a2035a5 --- /dev/null +++ b/uni_modules/uv-back-top/package.json @@ -0,0 +1,89 @@ +{ + "id": "uv-back-top", + "displayName": "uv-back-top 返回顶部 全面兼容小程序、nvue、vue2、vue3等多端", + "version": "1.0.2", + "description": "返回顶部 组件一个用于长页面,滑动一定距离后,出现返回顶部按钮,方便快速返回顶部的场景。", + "keywords": [ + "uv-back-top", + "uvui", + "uv-ui", + "avatar", + "返回顶部" + ], + "repository": "", + "engines": { + "HBuilderX": "^3.1.0" + }, + "dcloudext": { + "type": "component-vue", + "sale": { + "regular": { + "price": "0.00" + }, + "sourcecode": { + "price": "0.00" + } + }, + "contact": { + "qq": "" + }, + "declaration": { + "ads": "无", + "data": "插件不采集任何数据", + "permissions": "无" + }, + "npmurl": "" + }, + "uni_modules": { + "dependencies": [ + "uv-ui-tools", + "uv-icon", + "uv-transition" + ], + "encrypt": [], + "platforms": { + "cloud": { + "tcb": "y", + "aliyun": "y" + }, + "client": { + "Vue": { + "vue2": "y", + "vue3": "y" + }, + "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", + "钉钉": "u", + "快手": "u", + "飞书": "u", + "京东": "u" + }, + "快应用": { + "华为": "u", + "联盟": "u" + } + } + } + } +} \ No newline at end of file diff --git a/uni_modules/uv-back-top/readme.md b/uni_modules/uv-back-top/readme.md new file mode 100644 index 0000000..d6a2aec --- /dev/null +++ b/uni_modules/uv-back-top/readme.md @@ -0,0 +1,11 @@ +## BackTop 返回顶部 + +> **组件名:uv-back-top** + +该组件一个用于长页面,滑动一定距离后,出现返回顶部按钮,方便快速返回顶部的场景。 + +### 查看文档 + +### [完整示例项目下载 | 关注更多组件](https://ext.dcloud.net.cn/plugin?name=uv-ui) + +#### 如使用过程中有任何问题,或者您对uv-ui有一些好的建议,欢迎加入 uv-ui 交流群:uv-ui、官方QQ群 diff --git a/uni_modules/uv-badge/changelog.md b/uni_modules/uv-badge/changelog.md new file mode 100644 index 0000000..b0ba104 --- /dev/null +++ b/uni_modules/uv-badge/changelog.md @@ -0,0 +1,7 @@ +## 1.0.2(2023-06-04) +1. 修复type等属性为null的时候不显示徽标的BUG +## 1.0.1(2023-05-16) +1. 优化组件依赖,修改后无需全局引入,组件导入即可使用 +2. 优化部分功能 +## 1.0.0(2023-05-10) +uv-badge 徽标数,数字角标 diff --git a/uni_modules/uv-badge/components/uv-badge/props.js b/uni_modules/uv-badge/components/uv-badge/props.js new file mode 100644 index 0000000..c6369c3 --- /dev/null +++ b/uni_modules/uv-badge/components/uv-badge/props.js @@ -0,0 +1,73 @@ +export default { + props: { + // 是否显示圆点 + isDot: { + type: Boolean, + default: false + }, + // 显示的内容 + value: { + type: [Number, String], + default: '' + }, + // 是否显示 + show: { + type: Boolean, + default: true + }, + // 最大值,超过最大值会显示 '{max}+' + max: { + type: [Number, String], + default: 999 + }, + // 主题类型,error|warning|success|primary + type: { + type: [String,undefined,null], + default: 'error' + }, + // 当数值为 0 时,是否展示 Badge + showZero: { + type: Boolean, + default: false + }, + // 背景颜色,优先级比type高,如设置,type参数会失效 + bgColor: { + type: [String, null], + default: null + }, + // 字体颜色 + color: { + type: [String, null], + default: null + }, + // 徽标形状,circle-四角均为圆角,horn-左下角为直角 + shape: { + type: [String,undefined,null], + default: 'circle' + }, + // 设置数字的显示方式,overflow|ellipsis|limit + // overflow会根据max字段判断,超出显示`${max}+` + // ellipsis会根据max判断,超出显示`${max}...` + // limit会依据1000作为判断条件,超出1000,显示`${value/1000}K`,比如2.2k、3.34w,最多保留2位小数 + numberType: { + type: [String,undefined,null], + default: 'overflow' + }, + // 设置badge的位置偏移,格式为 [x, y],也即设置的为top和right的值,absolute为true时有效 + offset: { + type: Array, + default: () => [] + }, + // 是否反转背景和字体颜色 + inverted: { + type: Boolean, + default: false + }, + // 是否绝对定位 + absolute: { + type: Boolean, + default: false + }, + ...uni.$uv?.props?.badge + } +} \ No newline at end of file diff --git a/uni_modules/uv-badge/components/uv-badge/uv-badge.vue b/uni_modules/uv-badge/components/uv-badge/uv-badge.vue new file mode 100644 index 0000000..f7d3911 --- /dev/null +++ b/uni_modules/uv-badge/components/uv-badge/uv-badge.vue @@ -0,0 +1,176 @@ + + + + + diff --git a/uni_modules/uv-badge/package.json b/uni_modules/uv-badge/package.json new file mode 100644 index 0000000..5a81386 --- /dev/null +++ b/uni_modules/uv-badge/package.json @@ -0,0 +1,87 @@ +{ + "id": "uv-badge", + "displayName": "uv-badge 徽标数,数字角标 全面兼容小程序、nvue、vue2、vue3等多端", + "version": "1.0.2", + "description": "徽标数一般用于图标右上角显示未读的消息数量,提示用户点击,有圆点和圆包含文字两种形式。", + "keywords": [ + "uv-badge", + "uvui", + "uv-ui", + "徽标数", + "数字角标" + ], + "repository": "", + "engines": { + "HBuilderX": "^3.1.0" + }, + "dcloudext": { + "type": "component-vue", + "sale": { + "regular": { + "price": "0.00" + }, + "sourcecode": { + "price": "0.00" + } + }, + "contact": { + "qq": "" + }, + "declaration": { + "ads": "无", + "data": "插件不采集任何数据", + "permissions": "无" + }, + "npmurl": "" + }, + "uni_modules": { + "dependencies": [ + "uv-ui-tools" + ], + "encrypt": [], + "platforms": { + "cloud": { + "tcb": "y", + "aliyun": "y" + }, + "client": { + "Vue": { + "vue2": "y", + "vue3": "y" + }, + "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", + "钉钉": "u", + "快手": "u", + "飞书": "u", + "京东": "u" + }, + "快应用": { + "华为": "u", + "联盟": "u" + } + } + } + } +} \ No newline at end of file diff --git a/uni_modules/uv-badge/readme.md b/uni_modules/uv-badge/readme.md new file mode 100644 index 0000000..cf597eb --- /dev/null +++ b/uni_modules/uv-badge/readme.md @@ -0,0 +1,11 @@ +## Badge 徽标数 + +> **组件名:uv-badge** + +该组件一般用于图标右上角显示未读的消息数量,提示用户点击,有圆点和圆包含文字两种形式。 + +### 查看文档 + +### [完整示例项目下载 | 关注更多组件](https://ext.dcloud.net.cn/plugin?name=uv-ui) + +#### 如使用过程中有任何问题,或者您对uv-ui有一些好的建议,欢迎加入 uv-ui 交流群:uv-ui、官方QQ群 diff --git a/uni_modules/uv-button/changelog.md b/uni_modules/uv-button/changelog.md new file mode 100644 index 0000000..11e954e --- /dev/null +++ b/uni_modules/uv-button/changelog.md @@ -0,0 +1,33 @@ +## 1.0.15(2023-12-20) +1. 优化 +## 1.0.14(2023-12-06) +1. 优化 +## 1.0.13(2023-12-06) +1. 阻止事件冒泡处理 +## 1.0.12(2023-10-19) +1. 增加后置插槽 +## 1.0.11(2023-09-21) +1. 修复通过customStyle修改按钮宽度,组件中最外层节点不改变的问题 +## 1.0.10(2023-09-15) +1. 按钮支持open-type="agreePrivacyAuthorization" +## 1.0.9(2023-09-11) +1. 增加参数iconSize,用于控制图标的大小 +## 1.0.8(2023-09-10) +1. 修复多个按钮在一行宽度不正常的BUG +## 1.0.7(2023-09-07) +1. 修复warning颜色对应错误的BUG +## 1.0.6(2023-07-25) +1. 增加customTextStyle属性,方便自定义文字样式 +## 1.0.5(2023-07-20) +1. 解决微信小程序动态设置hover-class点击态不消失的BUG +## 1.0.4(2023-06-29) +1. 修改上次更新出现nvue报错异常 +## 1.0.3(2023-06-28) + 修复:设置open-type="chooseAvatar"等值不生效的BUG +## 1.0.2(2023-06-01) +1. 修复按钮点击触发两次的BUG +## 1.0.1(2023-05-16) +1. 优化组件依赖,修改后无需全局引入,组件导入即可使用 +2. 优化部分功能 +## 1.0.0(2023-05-10) +uv-button 按钮 diff --git a/uni_modules/uv-button/components/uv-button/nvue.scss b/uni_modules/uv-button/components/uv-button/nvue.scss new file mode 100644 index 0000000..be6c16e --- /dev/null +++ b/uni_modules/uv-button/components/uv-button/nvue.scss @@ -0,0 +1,46 @@ +$uv-button-active-opacity:0.75 !default; +$uv-button-loading-text-margin-left:4px !default; +$uv-button-text-color: #FFFFFF !default; +$uv-button-text-plain-error-color:$uv-error !default; +$uv-button-text-plain-warning-color:$uv-warning !default; +$uv-button-text-plain-success-color:$uv-success !default; +$uv-button-text-plain-info-color:$uv-info !default; +$uv-button-text-plain-primary-color:$uv-primary !default; +.uv-button { + &--active { + opacity: $uv-button-active-opacity; + } + + &--active--plain { + background-color: rgb(217, 217, 217); + } + + &__loading-text { + margin-left:$uv-button-loading-text-margin-left; + } + + &__text, + &__loading-text { + color:$uv-button-text-color; + } + + &__text--plain--error { + color:$uv-button-text-plain-error-color; + } + + &__text--plain--warning { + color:$uv-button-text-plain-warning-color; + } + + &__text--plain--success{ + color:$uv-button-text-plain-success-color; + } + + &__text--plain--info { + color:$uv-button-text-plain-info-color; + } + + &__text--plain--primary { + color:$uv-button-text-plain-primary-color; + } +} \ No newline at end of file diff --git a/uni_modules/uv-button/components/uv-button/props.js b/uni_modules/uv-button/components/uv-button/props.js new file mode 100644 index 0000000..6275ad5 --- /dev/null +++ b/uni_modules/uv-button/components/uv-button/props.js @@ -0,0 +1,163 @@ +export default { + props: { + // 是否细边框 + hairline: { + type: Boolean, + default: true + }, + // 按钮的预置样式,info,primary,error,warning,success + type: { + type: String, + default: 'info' + }, + // 按钮尺寸,large,normal,small,mini + size: { + type: String, + default: 'normal' + }, + // 按钮形状,circle(两边为半圆),square(带圆角) + shape: { + type: String, + default: 'square' + }, + // 按钮是否镂空 + plain: { + type: Boolean, + default: false + }, + // 是否禁止状态 + disabled: { + type: Boolean, + default: false + }, + // 是否加载中 + loading: { + type: Boolean, + default: false + }, + // 加载中提示文字 + loadingText: { + type: [String, Number], + default: '' + }, + // 加载状态图标类型 + loadingMode: { + type: String, + default: 'spinner' + }, + // 加载图标大小 + loadingSize: { + type: [String, Number], + default: 14 + }, + // 开放能力,具体请看uniapp稳定关于button组件部分说明 + // https://uniapp.dcloud.io/component/button + openType: { + type: String, + default: '' + }, + // 用于
组件,点击分别会触发 组件的 submit/reset 事件 + // 取值为submit(提交表单),reset(重置表单) + formType: { + type: String, + default: '' + }, + // 打开 APP 时,向 APP 传递的参数,open-type=launchApp时有效 + // 只微信小程序、QQ小程序有效 + appParameter: { + type: String, + default: '' + }, + // 指定是否阻止本节点的祖先节点出现点击态,微信小程序有效 + hoverStopPropagation: { + type: Boolean, + default: true + }, + // 指定返回用户信息的语言,zh_CN 简体中文,zh_TW 繁体中文,en 英文。只微信小程序有效 + lang: { + type: String, + default: 'en' + }, + // 会话来源,open-type="contact"时有效。只微信小程序有效 + sessionFrom: { + type: String, + default: '' + }, + // 会话内消息卡片标题,open-type="contact"时有效 + // 默认当前标题,只微信小程序有效 + sendMessageTitle: { + type: String, + default: '' + }, + // 会话内消息卡片点击跳转小程序路径,open-type="contact"时有效 + // 默认当前分享路径,只微信小程序有效 + sendMessagePath: { + type: String, + default: '' + }, + // 会话内消息卡片图片,open-type="contact"时有效 + // 默认当前页面截图,只微信小程序有效 + sendMessageImg: { + type: String, + default: '' + }, + // 是否显示会话内消息卡片,设置此参数为 true,用户进入客服会话会在右下角显示"可能要发送的小程序"提示, + // 用户点击后可以快速发送小程序消息,open-type="contact"时有效 + showMessageCard: { + type: Boolean, + default: true + }, + // 额外传参参数,用于小程序的data-xxx属性,通过target.dataset.name获取 + dataName: { + type: String, + default: '' + }, + // 节流,一定时间内只能触发一次 + throttleTime: { + type: [String, Number], + default: 0 + }, + // 按住后多久出现点击态,单位毫秒 + hoverStartTime: { + type: [String, Number], + default: 0 + }, + // 手指松开后点击态保留时间,单位毫秒 + hoverStayTime: { + type: [String, Number], + default: 200 + }, + // 按钮文字,之所以通过props传入,是因为slot传入的话 + // nvue中无法控制文字的样式 + text: { + type: [String, Number], + default: '' + }, + // 按钮图标 + icon: { + type: String, + default: '' + }, + // 按钮图标大小 + iconSize: { + type: [String, Number], + default: '' + }, + // 按钮图标颜色 + iconColor: { + type: String, + default: '#000000' + }, + // 按钮颜色,支持传入linear-gradient渐变色 + color: { + type: String, + default: '' + }, + // 自定义按钮文本样式 + customTextStyle: { + type: [Object,String], + default: '' + }, + ...uni.$uv?.props?.button + } +} diff --git a/uni_modules/uv-button/components/uv-button/uv-button.vue b/uni_modules/uv-button/components/uv-button/uv-button.vue new file mode 100644 index 0000000..3a2470a --- /dev/null +++ b/uni_modules/uv-button/components/uv-button/uv-button.vue @@ -0,0 +1,528 @@ + + + + + diff --git a/uni_modules/uv-button/components/uv-button/vue.scss b/uni_modules/uv-button/components/uv-button/vue.scss new file mode 100644 index 0000000..7a089be --- /dev/null +++ b/uni_modules/uv-button/components/uv-button/vue.scss @@ -0,0 +1,93 @@ +@import '@/uni_modules/uv-ui-tools/libs/css/color.scss'; +// nvue下hover-class无效 +$uv-button-before-top:50% !default; +$uv-button-before-left:50% !default; +$uv-button-before-width:100% !default; +$uv-button-before-height:100% !default; +$uv-button-before-transform:translate(-50%, -50%) !default; +$uv-button-before-opacity:0 !default; +$uv-button-before-background-color:#000 !default; +$uv-button-before-border-color:#000 !default; +$uv-button-active-before-opacity:.15 !default; +$uv-button-icon-margin-left:4px !default; +$uv-button-plain-uv-button-info-color:$uv-info; +$uv-button-plain-uv-button-success-color:$uv-success; +$uv-button-plain-uv-button-error-color:$uv-error; +$uv-button-plain-uv-button-warning-color:$uv-warning; + +.uv-button-wrapper { + position: relative; + &--dis { + position: absolute; + left: 0; + top: 0; + right: 0; + bottom: 0; + z-index: 9; + } +} + +.uv-button { + width: 100%; + + &__text { + white-space: nowrap; + line-height: 1; + } + + &:before { + position: absolute; + top:$uv-button-before-top; + left:$uv-button-before-left; + width:$uv-button-before-width; + height:$uv-button-before-height; + border: inherit; + border-radius: inherit; + transform:$uv-button-before-transform; + opacity:$uv-button-before-opacity; + content: " "; + background-color:$uv-button-before-background-color; + border-color:$uv-button-before-border-color; + } + + &--active { + &:before { + opacity: .15 + } + } + + &__icon+&__text:not(:empty), + &__loading-text { + margin-left:$uv-button-icon-margin-left; + } + + &--plain { + &.uv-button--primary { + color: $uv-primary; + } + } + + &--plain { + &.uv-button--info { + color:$uv-button-plain-uv-button-info-color; + } + } + + &--plain { + &.uv-button--success { + color:$uv-button-plain-uv-button-success-color; + } + } + + &--plain { + &.uv-button--error { + color:$uv-button-plain-uv-button-error-color; + } + } + + &--plain { + &.uv-button--warning { + color:$uv-button-plain-uv-button-warning-color; + } + } +} diff --git a/uni_modules/uv-button/package.json b/uni_modules/uv-button/package.json new file mode 100644 index 0000000..c2a4a17 --- /dev/null +++ b/uni_modules/uv-button/package.json @@ -0,0 +1,89 @@ +{ + "id": "uv-button", + "displayName": "uv-button 按钮 全面兼容vue3+2、app、h5、小程序等多端", + "version": "1.0.15", + "description": "按钮组件内部实现以uni-app的button组件为基础,进行二次封装,灵活配置,功能齐全,兼容全端。", + "keywords": [ + "uv-button", + "uvui", + "uv-ui", + "button", + "按钮" + ], + "repository": "", + "engines": { + "HBuilderX": "^3.1.0" + }, + "dcloudext": { + "type": "component-vue", + "sale": { + "regular": { + "price": "0.00" + }, + "sourcecode": { + "price": "0.00" + } + }, + "contact": { + "qq": "" + }, + "declaration": { + "ads": "无", + "data": "插件不采集任何数据", + "permissions": "无" + }, + "npmurl": "" + }, + "uni_modules": { + "dependencies": [ + "uv-ui-tools", + "uv-loading-icon", + "uv-icon" + ], + "encrypt": [], + "platforms": { + "cloud": { + "tcb": "y", + "aliyun": "y" + }, + "client": { + "Vue": { + "vue2": "y", + "vue3": "y" + }, + "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", + "钉钉": "u", + "快手": "u", + "飞书": "u", + "京东": "u" + }, + "快应用": { + "华为": "u", + "联盟": "u" + } + } + } + } +} \ No newline at end of file diff --git a/uni_modules/uv-button/readme.md b/uni_modules/uv-button/readme.md new file mode 100644 index 0000000..124a7f4 --- /dev/null +++ b/uni_modules/uv-button/readme.md @@ -0,0 +1,19 @@ +## Button 按钮 + +> **组件名:uv-button** + +该组件内部实现以`uni-app`的`button`组件为基础,进行二次封装,灵活配置,功能齐全,兼容全端。灵活配置,内置状态设置,开箱即用。 + +# 查看文档 + +## [下载完整示例项目](https://ext.dcloud.net.cn/plugin?name=uv-ui) (请不要 下载插件ZIP) + +### [更多插件,请关注uv-ui组件库](https://ext.dcloud.net.cn/plugin?name=uv-ui) + + + +![image](https://mp-a667b617-c5f1-4a2d-9a54-683a67cff588.cdn.bspapp.com/uv-ui/banner.png) + + + +#### 如使用过程中有任何问题反馈,或者您对uv-ui有一些好的建议,欢迎加入uv-ui官方交流群:官方QQ群 \ No newline at end of file diff --git a/uni_modules/uv-calendar/changelog.md b/uni_modules/uv-calendar/changelog.md new file mode 100644 index 0000000..581562a --- /dev/null +++ b/uni_modules/uv-calendar/changelog.md @@ -0,0 +1,16 @@ +## 1.0.6(2023-11-03) +1. **该版本不再维护**,推荐使用新版本[https://ext.dcloud.net.cn/plugin?name=uv-calendars](https://ext.dcloud.net.cn/plugin?name=uv-calendars) +## 1.0.5(2023-07-02) +uv-calendar 由于弹出层uv-popup的修改,打开和关闭方法更改,详情参考文档:https://www.uvui.cn/components/calendar.html +## 1.0.4(2023-06-15) +1. formatter格式化中增加topInfo参数 +## 1.0.3(2023-06-08) +1. 增加点击日期change回调 +2. 优化 +## 1.0.2(2023-06-05) +1. 修改多个时间选择的时候存在反选的BUG +## 1.0.1(2023-05-16) +1. 优化组件依赖,修改后无需全局引入,组件导入即可使用 +2. 优化部分功能 +## 1.0.0(2023-05-10) +uv-calendar 日历 diff --git a/uni_modules/uv-calendar/components/uv-calendar/calendar.js b/uni_modules/uv-calendar/components/uv-calendar/calendar.js new file mode 100644 index 0000000..e006dea --- /dev/null +++ b/uni_modules/uv-calendar/components/uv-calendar/calendar.js @@ -0,0 +1,546 @@ +/** +* @1900-2100区间内的公历、农历互转 +* @charset UTF-8 +* @github https://github.com/jjonline/calendar.js +* @Author Jea杨(JJonline@JJonline.Cn) +* @Time 2014-7-21 +* @Time 2016-8-13 Fixed 2033hex、Attribution Annals +* @Time 2016-9-25 Fixed lunar LeapMonth Param Bug +* @Time 2017-7-24 Fixed use getTerm Func Param Error.use solar year,NOT lunar year +* @Version 1.0.3 +* @公历转农历:calendar.solar2lunar(1987,11,01); //[you can ignore params of prefix 0] +* @农历转公历:calendar.lunar2solar(1987,09,10); //[you can ignore params of prefix 0] +*/ +/* eslint-disable */ +var calendar = { + + /** + * 农历1900-2100的润大小信息表 + * @Array Of Property + * @return Hex + */ + lunarInfo: [0x04bd8, 0x04ae0, 0x0a570, 0x054d5, 0x0d260, 0x0d950, 0x16554, 0x056a0, 0x09ad0, 0x055d2, // 1900-1909 + 0x04ae0, 0x0a5b6, 0x0a4d0, 0x0d250, 0x1d255, 0x0b540, 0x0d6a0, 0x0ada2, 0x095b0, 0x14977, // 1910-1919 + 0x04970, 0x0a4b0, 0x0b4b5, 0x06a50, 0x06d40, 0x1ab54, 0x02b60, 0x09570, 0x052f2, 0x04970, // 1920-1929 + 0x06566, 0x0d4a0, 0x0ea50, 0x06e95, 0x05ad0, 0x02b60, 0x186e3, 0x092e0, 0x1c8d7, 0x0c950, // 1930-1939 + 0x0d4a0, 0x1d8a6, 0x0b550, 0x056a0, 0x1a5b4, 0x025d0, 0x092d0, 0x0d2b2, 0x0a950, 0x0b557, // 1940-1949 + 0x06ca0, 0x0b550, 0x15355, 0x04da0, 0x0a5b0, 0x14573, 0x052b0, 0x0a9a8, 0x0e950, 0x06aa0, // 1950-1959 + 0x0aea6, 0x0ab50, 0x04b60, 0x0aae4, 0x0a570, 0x05260, 0x0f263, 0x0d950, 0x05b57, 0x056a0, // 1960-1969 + 0x096d0, 0x04dd5, 0x04ad0, 0x0a4d0, 0x0d4d4, 0x0d250, 0x0d558, 0x0b540, 0x0b6a0, 0x195a6, // 1970-1979 + 0x095b0, 0x049b0, 0x0a974, 0x0a4b0, 0x0b27a, 0x06a50, 0x06d40, 0x0af46, 0x0ab60, 0x09570, // 1980-1989 + 0x04af5, 0x04970, 0x064b0, 0x074a3, 0x0ea50, 0x06b58, 0x05ac0, 0x0ab60, 0x096d5, 0x092e0, // 1990-1999 + 0x0c960, 0x0d954, 0x0d4a0, 0x0da50, 0x07552, 0x056a0, 0x0abb7, 0x025d0, 0x092d0, 0x0cab5, // 2000-2009 + 0x0a950, 0x0b4a0, 0x0baa4, 0x0ad50, 0x055d9, 0x04ba0, 0x0a5b0, 0x15176, 0x052b0, 0x0a930, // 2010-2019 + 0x07954, 0x06aa0, 0x0ad50, 0x05b52, 0x04b60, 0x0a6e6, 0x0a4e0, 0x0d260, 0x0ea65, 0x0d530, // 2020-2029 + 0x05aa0, 0x076a3, 0x096d0, 0x04afb, 0x04ad0, 0x0a4d0, 0x1d0b6, 0x0d250, 0x0d520, 0x0dd45, // 2030-2039 + 0x0b5a0, 0x056d0, 0x055b2, 0x049b0, 0x0a577, 0x0a4b0, 0x0aa50, 0x1b255, 0x06d20, 0x0ada0, // 2040-2049 + /** Add By JJonline@JJonline.Cn**/ + 0x14b63, 0x09370, 0x049f8, 0x04970, 0x064b0, 0x168a6, 0x0ea50, 0x06b20, 0x1a6c4, 0x0aae0, // 2050-2059 + 0x0a2e0, 0x0d2e3, 0x0c960, 0x0d557, 0x0d4a0, 0x0da50, 0x05d55, 0x056a0, 0x0a6d0, 0x055d4, // 2060-2069 + 0x052d0, 0x0a9b8, 0x0a950, 0x0b4a0, 0x0b6a6, 0x0ad50, 0x055a0, 0x0aba4, 0x0a5b0, 0x052b0, // 2070-2079 + 0x0b273, 0x06930, 0x07337, 0x06aa0, 0x0ad50, 0x14b55, 0x04b60, 0x0a570, 0x054e4, 0x0d160, // 2080-2089 + 0x0e968, 0x0d520, 0x0daa0, 0x16aa6, 0x056d0, 0x04ae0, 0x0a9d4, 0x0a2d0, 0x0d150, 0x0f252, // 2090-2099 + 0x0d520], // 2100 + + /** + * 公历每个月份的天数普通表 + * @Array Of Property + * @return Number + */ + solarMonth: [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31], + + /** + * 天干地支之天干速查表 + * @Array Of Property trans["甲","乙","丙","丁","戊","己","庚","辛","壬","癸"] + * @return Cn string + */ + Gan: ['\u7532', '\u4e59', '\u4e19', '\u4e01', '\u620a', '\u5df1', '\u5e9a', '\u8f9b', '\u58ec', '\u7678'], + + /** + * 天干地支之地支速查表 + * @Array Of Property + * @trans["子","丑","寅","卯","辰","巳","午","未","申","酉","戌","亥"] + * @return Cn string + */ + Zhi: ['\u5b50', '\u4e11', '\u5bc5', '\u536f', '\u8fb0', '\u5df3', '\u5348', '\u672a', '\u7533', '\u9149', '\u620c', '\u4ea5'], + + /** + * 天干地支之地支速查表<=>生肖 + * @Array Of Property + * @trans["鼠","牛","虎","兔","龙","蛇","马","羊","猴","鸡","狗","猪"] + * @return Cn string + */ + Animals: ['\u9f20', '\u725b', '\u864e', '\u5154', '\u9f99', '\u86c7', '\u9a6c', '\u7f8a', '\u7334', '\u9e21', '\u72d7', '\u732a'], + + /** + * 24节气速查表 + * @Array Of Property + * @trans["小寒","大寒","立春","雨水","惊蛰","春分","清明","谷雨","立夏","小满","芒种","夏至","小暑","大暑","立秋","处暑","白露","秋分","寒露","霜降","立冬","小雪","大雪","冬至"] + * @return Cn string + */ + solarTerm: ['\u5c0f\u5bd2', '\u5927\u5bd2', '\u7acb\u6625', '\u96e8\u6c34', '\u60ca\u86f0', '\u6625\u5206', '\u6e05\u660e', '\u8c37\u96e8', '\u7acb\u590f', '\u5c0f\u6ee1', '\u8292\u79cd', '\u590f\u81f3', '\u5c0f\u6691', '\u5927\u6691', '\u7acb\u79cb', '\u5904\u6691', '\u767d\u9732', '\u79cb\u5206', '\u5bd2\u9732', '\u971c\u964d', '\u7acb\u51ac', '\u5c0f\u96ea', '\u5927\u96ea', '\u51ac\u81f3'], + + /** + * 1900-2100各年的24节气日期速查表 + * @Array Of Property + * @return 0x string For splice + */ + sTermInfo: ['9778397bd097c36b0b6fc9274c91aa', '97b6b97bd19801ec9210c965cc920e', '97bcf97c3598082c95f8c965cc920f', + '97bd0b06bdb0722c965ce1cfcc920f', 'b027097bd097c36b0b6fc9274c91aa', '97b6b97bd19801ec9210c965cc920e', + '97bcf97c359801ec95f8c965cc920f', '97bd0b06bdb0722c965ce1cfcc920f', 'b027097bd097c36b0b6fc9274c91aa', + '97b6b97bd19801ec9210c965cc920e', '97bcf97c359801ec95f8c965cc920f', '97bd0b06bdb0722c965ce1cfcc920f', + 'b027097bd097c36b0b6fc9274c91aa', '9778397bd19801ec9210c965cc920e', '97b6b97bd19801ec95f8c965cc920f', + '97bd09801d98082c95f8e1cfcc920f', '97bd097bd097c36b0b6fc9210c8dc2', '9778397bd197c36c9210c9274c91aa', + '97b6b97bd19801ec95f8c965cc920e', '97bd09801d98082c95f8e1cfcc920f', '97bd097bd097c36b0b6fc9210c8dc2', + '9778397bd097c36c9210c9274c91aa', '97b6b97bd19801ec95f8c965cc920e', '97bcf97c3598082c95f8e1cfcc920f', + '97bd097bd097c36b0b6fc9210c8dc2', '9778397bd097c36c9210c9274c91aa', '97b6b97bd19801ec9210c965cc920e', + '97bcf97c3598082c95f8c965cc920f', '97bd097bd097c35b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa', + '97b6b97bd19801ec9210c965cc920e', '97bcf97c3598082c95f8c965cc920f', '97bd097bd097c35b0b6fc920fb0722', + '9778397bd097c36b0b6fc9274c91aa', '97b6b97bd19801ec9210c965cc920e', '97bcf97c359801ec95f8c965cc920f', + '97bd097bd097c35b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa', '97b6b97bd19801ec9210c965cc920e', + '97bcf97c359801ec95f8c965cc920f', '97bd097bd097c35b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa', + '97b6b97bd19801ec9210c965cc920e', '97bcf97c359801ec95f8c965cc920f', '97bd097bd07f595b0b6fc920fb0722', + '9778397bd097c36b0b6fc9210c8dc2', '9778397bd19801ec9210c9274c920e', '97b6b97bd19801ec95f8c965cc920f', + '97bd07f5307f595b0b0bc920fb0722', '7f0e397bd097c36b0b6fc9210c8dc2', '9778397bd097c36c9210c9274c920e', + '97b6b97bd19801ec95f8c965cc920f', '97bd07f5307f595b0b0bc920fb0722', '7f0e397bd097c36b0b6fc9210c8dc2', + '9778397bd097c36c9210c9274c91aa', '97b6b97bd19801ec9210c965cc920e', '97bd07f1487f595b0b0bc920fb0722', + '7f0e397bd097c36b0b6fc9210c8dc2', '9778397bd097c36b0b6fc9274c91aa', '97b6b97bd19801ec9210c965cc920e', + '97bcf7f1487f595b0b0bb0b6fb0722', '7f0e397bd097c35b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa', + '97b6b97bd19801ec9210c965cc920e', '97bcf7f1487f595b0b0bb0b6fb0722', '7f0e397bd097c35b0b6fc920fb0722', + '9778397bd097c36b0b6fc9274c91aa', '97b6b97bd19801ec9210c965cc920e', '97bcf7f1487f531b0b0bb0b6fb0722', + '7f0e397bd097c35b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa', '97b6b97bd19801ec9210c965cc920e', + '97bcf7f1487f531b0b0bb0b6fb0722', '7f0e397bd07f595b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa', + '97b6b97bd19801ec9210c9274c920e', '97bcf7f0e47f531b0b0bb0b6fb0722', '7f0e397bd07f595b0b0bc920fb0722', + '9778397bd097c36b0b6fc9210c91aa', '97b6b97bd197c36c9210c9274c920e', '97bcf7f0e47f531b0b0bb0b6fb0722', + '7f0e397bd07f595b0b0bc920fb0722', '9778397bd097c36b0b6fc9210c8dc2', '9778397bd097c36c9210c9274c920e', + '97b6b7f0e47f531b0723b0b6fb0722', '7f0e37f5307f595b0b0bc920fb0722', '7f0e397bd097c36b0b6fc9210c8dc2', + '9778397bd097c36b0b70c9274c91aa', '97b6b7f0e47f531b0723b0b6fb0721', '7f0e37f1487f595b0b0bb0b6fb0722', + '7f0e397bd097c35b0b6fc9210c8dc2', '9778397bd097c36b0b6fc9274c91aa', '97b6b7f0e47f531b0723b0b6fb0721', + '7f0e27f1487f595b0b0bb0b6fb0722', '7f0e397bd097c35b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa', + '97b6b7f0e47f531b0723b0b6fb0721', '7f0e27f1487f531b0b0bb0b6fb0722', '7f0e397bd097c35b0b6fc920fb0722', + '9778397bd097c36b0b6fc9274c91aa', '97b6b7f0e47f531b0723b0b6fb0721', '7f0e27f1487f531b0b0bb0b6fb0722', + '7f0e397bd097c35b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa', '97b6b7f0e47f531b0723b0b6fb0721', + '7f0e27f1487f531b0b0bb0b6fb0722', '7f0e397bd07f595b0b0bc920fb0722', '9778397bd097c36b0b6fc9274c91aa', + '97b6b7f0e47f531b0723b0787b0721', '7f0e27f0e47f531b0b0bb0b6fb0722', '7f0e397bd07f595b0b0bc920fb0722', + '9778397bd097c36b0b6fc9210c91aa', '97b6b7f0e47f149b0723b0787b0721', '7f0e27f0e47f531b0723b0b6fb0722', + '7f0e397bd07f595b0b0bc920fb0722', '9778397bd097c36b0b6fc9210c8dc2', '977837f0e37f149b0723b0787b0721', + '7f07e7f0e47f531b0723b0b6fb0722', '7f0e37f5307f595b0b0bc920fb0722', '7f0e397bd097c35b0b6fc9210c8dc2', + '977837f0e37f14998082b0787b0721', '7f07e7f0e47f531b0723b0b6fb0721', '7f0e37f1487f595b0b0bb0b6fb0722', + '7f0e397bd097c35b0b6fc9210c8dc2', '977837f0e37f14998082b0787b06bd', '7f07e7f0e47f531b0723b0b6fb0721', + '7f0e27f1487f531b0b0bb0b6fb0722', '7f0e397bd097c35b0b6fc920fb0722', '977837f0e37f14998082b0787b06bd', + '7f07e7f0e47f531b0723b0b6fb0721', '7f0e27f1487f531b0b0bb0b6fb0722', '7f0e397bd097c35b0b6fc920fb0722', + '977837f0e37f14998082b0787b06bd', '7f07e7f0e47f531b0723b0b6fb0721', '7f0e27f1487f531b0b0bb0b6fb0722', + '7f0e397bd07f595b0b0bc920fb0722', '977837f0e37f14998082b0787b06bd', '7f07e7f0e47f531b0723b0b6fb0721', + '7f0e27f1487f531b0b0bb0b6fb0722', '7f0e397bd07f595b0b0bc920fb0722', '977837f0e37f14998082b0787b06bd', + '7f07e7f0e47f149b0723b0787b0721', '7f0e27f0e47f531b0b0bb0b6fb0722', '7f0e397bd07f595b0b0bc920fb0722', + '977837f0e37f14998082b0723b06bd', '7f07e7f0e37f149b0723b0787b0721', '7f0e27f0e47f531b0723b0b6fb0722', + '7f0e397bd07f595b0b0bc920fb0722', '977837f0e37f14898082b0723b02d5', '7ec967f0e37f14998082b0787b0721', + '7f07e7f0e47f531b0723b0b6fb0722', '7f0e37f1487f595b0b0bb0b6fb0722', '7f0e37f0e37f14898082b0723b02d5', + '7ec967f0e37f14998082b0787b0721', '7f07e7f0e47f531b0723b0b6fb0722', '7f0e37f1487f531b0b0bb0b6fb0722', + '7f0e37f0e37f14898082b0723b02d5', '7ec967f0e37f14998082b0787b06bd', '7f07e7f0e47f531b0723b0b6fb0721', + '7f0e37f1487f531b0b0bb0b6fb0722', '7f0e37f0e37f14898082b072297c35', '7ec967f0e37f14998082b0787b06bd', + '7f07e7f0e47f531b0723b0b6fb0721', '7f0e27f1487f531b0b0bb0b6fb0722', '7f0e37f0e37f14898082b072297c35', + '7ec967f0e37f14998082b0787b06bd', '7f07e7f0e47f531b0723b0b6fb0721', '7f0e27f1487f531b0b0bb0b6fb0722', + '7f0e37f0e366aa89801eb072297c35', '7ec967f0e37f14998082b0787b06bd', '7f07e7f0e47f149b0723b0787b0721', + '7f0e27f1487f531b0b0bb0b6fb0722', '7f0e37f0e366aa89801eb072297c35', '7ec967f0e37f14998082b0723b06bd', + '7f07e7f0e47f149b0723b0787b0721', '7f0e27f0e47f531b0723b0b6fb0722', '7f0e37f0e366aa89801eb072297c35', + '7ec967f0e37f14998082b0723b06bd', '7f07e7f0e37f14998083b0787b0721', '7f0e27f0e47f531b0723b0b6fb0722', + '7f0e37f0e366aa89801eb072297c35', '7ec967f0e37f14898082b0723b02d5', '7f07e7f0e37f14998082b0787b0721', + '7f07e7f0e47f531b0723b0b6fb0722', '7f0e36665b66aa89801e9808297c35', '665f67f0e37f14898082b0723b02d5', + '7ec967f0e37f14998082b0787b0721', '7f07e7f0e47f531b0723b0b6fb0722', '7f0e36665b66a449801e9808297c35', + '665f67f0e37f14898082b0723b02d5', '7ec967f0e37f14998082b0787b06bd', '7f07e7f0e47f531b0723b0b6fb0721', + '7f0e36665b66a449801e9808297c35', '665f67f0e37f14898082b072297c35', '7ec967f0e37f14998082b0787b06bd', + '7f07e7f0e47f531b0723b0b6fb0721', '7f0e26665b66a449801e9808297c35', '665f67f0e37f1489801eb072297c35', + '7ec967f0e37f14998082b0787b06bd', '7f07e7f0e47f531b0723b0b6fb0721', '7f0e27f1487f531b0b0bb0b6fb0722'], + + /** + * 数字转中文速查表 + * @Array Of Property + * @trans ['日','一','二','三','四','五','六','七','八','九','十'] + * @return Cn string + */ + nStr1: ['\u65e5', '\u4e00', '\u4e8c', '\u4e09', '\u56db', '\u4e94', '\u516d', '\u4e03', '\u516b', '\u4e5d', '\u5341'], + + /** + * 日期转农历称呼速查表 + * @Array Of Property + * @trans ['初','十','廿','卅'] + * @return Cn string + */ + nStr2: ['\u521d', '\u5341', '\u5eff', '\u5345'], + + /** + * 月份转农历称呼速查表 + * @Array Of Property + * @trans ['正','一','二','三','四','五','六','七','八','九','十','冬','腊'] + * @return Cn string + */ + nStr3: ['\u6b63', '\u4e8c', '\u4e09', '\u56db', '\u4e94', '\u516d', '\u4e03', '\u516b', '\u4e5d', '\u5341', '\u51ac', '\u814a'], + + /** + * 返回农历y年一整年的总天数 + * @param lunar Year + * @return Number + * @eg:var count = calendar.lYearDays(1987) ;//count=387 + */ + lYearDays: function (y) { + var i; var sum = 348 + for (i = 0x8000; i > 0x8; i >>= 1) { sum += (this.lunarInfo[y - 1900] & i) ? 1 : 0 } + return (sum + this.leapDays(y)) + }, + + /** + * 返回农历y年闰月是哪个月;若y年没有闰月 则返回0 + * @param lunar Year + * @return Number (0-12) + * @eg:var leapMonth = calendar.leapMonth(1987) ;//leapMonth=6 + */ + leapMonth: function (y) { // 闰字编码 \u95f0 + return (this.lunarInfo[y - 1900] & 0xf) + }, + + /** + * 返回农历y年闰月的天数 若该年没有闰月则返回0 + * @param lunar Year + * @return Number (0、29、30) + * @eg:var leapMonthDay = calendar.leapDays(1987) ;//leapMonthDay=29 + */ + leapDays: function (y) { + if (this.leapMonth(y)) { + return ((this.lunarInfo[y - 1900] & 0x10000) ? 30 : 29) + } + return (0) + }, + + /** + * 返回农历y年m月(非闰月)的总天数,计算m为闰月时的天数请使用leapDays方法 + * @param lunar Year + * @return Number (-1、29、30) + * @eg:var MonthDay = calendar.monthDays(1987,9) ;//MonthDay=29 + */ + monthDays: function (y, m) { + if (m > 12 || m < 1) { return -1 }// 月份参数从1至12,参数错误返回-1 + return ((this.lunarInfo[y - 1900] & (0x10000 >> m)) ? 30 : 29) + }, + + /** + * 返回公历(!)y年m月的天数 + * @param solar Year + * @return Number (-1、28、29、30、31) + * @eg:var solarMonthDay = calendar.leapDays(1987) ;//solarMonthDay=30 + */ + solarDays: function (y, m) { + if (m > 12 || m < 1) { return -1 } // 若参数错误 返回-1 + var ms = m - 1 + if (ms == 1) { // 2月份的闰平规律测算后确认返回28或29 + return (((y % 4 == 0) && (y % 100 != 0) || (y % 400 == 0)) ? 29 : 28) + } else { + return (this.solarMonth[ms]) + } + }, + + /** + * 农历年份转换为干支纪年 + * @param lYear 农历年的年份数 + * @return Cn string + */ + toGanZhiYear: function (lYear) { + var ganKey = (lYear - 3) % 10 + var zhiKey = (lYear - 3) % 12 + if (ganKey == 0) ganKey = 10// 如果余数为0则为最后一个天干 + if (zhiKey == 0) zhiKey = 12// 如果余数为0则为最后一个地支 + return this.Gan[ganKey - 1] + this.Zhi[zhiKey - 1] + }, + + /** + * 公历月、日判断所属星座 + * @param cMonth [description] + * @param cDay [description] + * @return Cn string + */ + toAstro: function (cMonth, cDay) { + var s = '\u9b54\u7faf\u6c34\u74f6\u53cc\u9c7c\u767d\u7f8a\u91d1\u725b\u53cc\u5b50\u5de8\u87f9\u72ee\u5b50\u5904\u5973\u5929\u79e4\u5929\u874e\u5c04\u624b\u9b54\u7faf' + var arr = [20, 19, 21, 21, 21, 22, 23, 23, 23, 23, 22, 22] + return s.substr(cMonth * 2 - (cDay < arr[cMonth - 1] ? 2 : 0), 2) + '\u5ea7'// 座 + }, + + /** + * 传入offset偏移量返回干支 + * @param offset 相对甲子的偏移量 + * @return Cn string + */ + toGanZhi: function (offset) { + return this.Gan[offset % 10] + this.Zhi[offset % 12] + }, + + /** + * 传入公历(!)y年获得该年第n个节气的公历日期 + * @param y公历年(1900-2100);n二十四节气中的第几个节气(1~24);从n=1(小寒)算起 + * @return day Number + * @eg:var _24 = calendar.getTerm(1987,3) ;//_24=4;意即1987年2月4日立春 + */ + getTerm: function (y, n) { + if (y < 1900 || y > 2100) { return -1 } + if (n < 1 || n > 24) { return -1 } + var _table = this.sTermInfo[y - 1900] + var _info = [ + parseInt('0x' + _table.substr(0, 5)).toString(), + parseInt('0x' + _table.substr(5, 5)).toString(), + parseInt('0x' + _table.substr(10, 5)).toString(), + parseInt('0x' + _table.substr(15, 5)).toString(), + parseInt('0x' + _table.substr(20, 5)).toString(), + parseInt('0x' + _table.substr(25, 5)).toString() + ] + var _calday = [ + _info[0].substr(0, 1), + _info[0].substr(1, 2), + _info[0].substr(3, 1), + _info[0].substr(4, 2), + + _info[1].substr(0, 1), + _info[1].substr(1, 2), + _info[1].substr(3, 1), + _info[1].substr(4, 2), + + _info[2].substr(0, 1), + _info[2].substr(1, 2), + _info[2].substr(3, 1), + _info[2].substr(4, 2), + + _info[3].substr(0, 1), + _info[3].substr(1, 2), + _info[3].substr(3, 1), + _info[3].substr(4, 2), + + _info[4].substr(0, 1), + _info[4].substr(1, 2), + _info[4].substr(3, 1), + _info[4].substr(4, 2), + + _info[5].substr(0, 1), + _info[5].substr(1, 2), + _info[5].substr(3, 1), + _info[5].substr(4, 2) + ] + return parseInt(_calday[n - 1]) + }, + + /** + * 传入农历数字月份返回汉语通俗表示法 + * @param lunar month + * @return Cn string + * @eg:var cnMonth = calendar.toChinaMonth(12) ;//cnMonth='腊月' + */ + toChinaMonth: function (m) { // 月 => \u6708 + if (m > 12 || m < 1) { return -1 } // 若参数错误 返回-1 + var s = this.nStr3[m - 1] + s += '\u6708'// 加上月字 + return s + }, + + /** + * 传入农历日期数字返回汉字表示法 + * @param lunar day + * @return Cn string + * @eg:var cnDay = calendar.toChinaDay(21) ;//cnMonth='廿一' + */ + toChinaDay: function (d) { // 日 => \u65e5 + var s + switch (d) { + case 10: + s = '\u521d\u5341'; break + case 20: + s = '\u4e8c\u5341'; break + break + case 30: + s = '\u4e09\u5341'; break + break + default: + s = this.nStr2[Math.floor(d / 10)] + s += this.nStr1[d % 10] + } + return (s) + }, + + /** + * 年份转生肖[!仅能大致转换] => 精确划分生肖分界线是“立春” + * @param y year + * @return Cn string + * @eg:var animal = calendar.getAnimal(1987) ;//animal='兔' + */ + getAnimal: function (y) { + return this.Animals[(y - 4) % 12] + }, + + /** + * 传入阳历年月日获得详细的公历、农历object信息 <=>JSON + * @param y solar year + * @param m solar month + * @param d solar day + * @return JSON object + * @eg:console.log(calendar.solar2lunar(1987,11,01)); + */ + solar2lunar: function (y, m, d) { // 参数区间1900.1.31~2100.12.31 + // 年份限定、上限 + if (y < 1900 || y > 2100) { + return -1// undefined转换为数字变为NaN + } + // 公历传参最下限 + if (y == 1900 && m == 1 && d < 31) { + return -1 + } + // 未传参 获得当天 + if (!y) { + var objDate = new Date() + } else { + var objDate = new Date(y, parseInt(m) - 1, d) + } + var i; var leap = 0; var temp = 0 + // 修正ymd参数 + var y = objDate.getFullYear() + var m = objDate.getMonth() + 1 + var d = objDate.getDate() + var offset = (Date.UTC(objDate.getFullYear(), objDate.getMonth(), objDate.getDate()) - Date.UTC(1900, 0, 31)) / 86400000 + for (i = 1900; i < 2101 && offset > 0; i++) { + temp = this.lYearDays(i) + offset -= temp + } + if (offset < 0) { + offset += temp; i-- + } + + // 是否今天 + var isTodayObj = new Date() + var isToday = false + if (isTodayObj.getFullYear() == y && isTodayObj.getMonth() + 1 == m && isTodayObj.getDate() == d) { + isToday = true + } + // 星期几 + var nWeek = objDate.getDay() + var cWeek = this.nStr1[nWeek] + // 数字表示周几顺应天朝周一开始的惯例 + if (nWeek == 0) { + nWeek = 7 + } + // 农历年 + var year = i + var leap = this.leapMonth(i) // 闰哪个月 + var isLeap = false + + // 效验闰月 + for (i = 1; i < 13 && offset > 0; i++) { + // 闰月 + if (leap > 0 && i == (leap + 1) && isLeap == false) { + --i + isLeap = true; temp = this.leapDays(year) // 计算农历闰月天数 + } else { + temp = this.monthDays(year, i)// 计算农历普通月天数 + } + // 解除闰月 + if (isLeap == true && i == (leap + 1)) { isLeap = false } + offset -= temp + } + // 闰月导致数组下标重叠取反 + if (offset == 0 && leap > 0 && i == leap + 1) { + if (isLeap) { + isLeap = false + } else { + isLeap = true; --i + } + } + if (offset < 0) { + offset += temp; --i + } + // 农历月 + var month = i + // 农历日 + var day = offset + 1 + // 天干地支处理 + var sm = m - 1 + var gzY = this.toGanZhiYear(year) + + // 当月的两个节气 + // bugfix-2017-7-24 11:03:38 use lunar Year Param `y` Not `year` + var firstNode = this.getTerm(y, (m * 2 - 1))// 返回当月「节」为几日开始 + var secondNode = this.getTerm(y, (m * 2))// 返回当月「节」为几日开始 + + // 依据12节气修正干支月 + var gzM = this.toGanZhi((y - 1900) * 12 + m + 11) + if (d >= firstNode) { + gzM = this.toGanZhi((y - 1900) * 12 + m + 12) + } + + // 传入的日期的节气与否 + var isTerm = false + var Term = null + if (firstNode == d) { + isTerm = true + Term = this.solarTerm[m * 2 - 2] + } + if (secondNode == d) { + isTerm = true + Term = this.solarTerm[m * 2 - 1] + } + // 日柱 当月一日与 1900/1/1 相差天数 + var dayCyclical = Date.UTC(y, sm, 1, 0, 0, 0, 0) / 86400000 + 25567 + 10 + var gzD = this.toGanZhi(dayCyclical + d - 1) + // 该日期所属的星座 + var astro = this.toAstro(m, d) + + return { 'lYear': year, 'lMonth': month, 'lDay': day, 'Animal': this.getAnimal(year), 'IMonthCn': (isLeap ? '\u95f0' : '') + this.toChinaMonth(month), 'IDayCn': this.toChinaDay(day), 'cYear': y, 'cMonth': m, 'cDay': d, 'gzYear': gzY, 'gzMonth': gzM, 'gzDay': gzD, 'isToday': isToday, 'isLeap': isLeap, 'nWeek': nWeek, 'ncWeek': '\u661f\u671f' + cWeek, 'isTerm': isTerm, 'Term': Term, 'astro': astro } + }, + + /** + * 传入农历年月日以及传入的月份是否闰月获得详细的公历、农历object信息 <=>JSON + * @param y lunar year + * @param m lunar month + * @param d lunar day + * @param isLeapMonth lunar month is leap or not.[如果是农历闰月第四个参数赋值true即可] + * @return JSON object + * @eg:console.log(calendar.lunar2solar(1987,9,10)); + */ + lunar2solar: function (y, m, d, isLeapMonth) { // 参数区间1900.1.31~2100.12.1 + var isLeapMonth = !!isLeapMonth + var leapOffset = 0 + var leapMonth = this.leapMonth(y) + var leapDay = this.leapDays(y) + if (isLeapMonth && (leapMonth != m)) { return -1 }// 传参要求计算该闰月公历 但该年得出的闰月与传参的月份并不同 + if (y == 2100 && m == 12 && d > 1 || y == 1900 && m == 1 && d < 31) { return -1 }// 超出了最大极限值 + var day = this.monthDays(y, m) + var _day = day + // bugFix 2016-9-25 + // if month is leap, _day use leapDays method + if (isLeapMonth) { + _day = this.leapDays(y, m) + } + if (y < 1900 || y > 2100 || d > _day) { return -1 }// 参数合法性效验 + + // 计算农历的时间差 + var offset = 0 + for (var i = 1900; i < y; i++) { + offset += this.lYearDays(i) + } + var leap = 0; var isAdd = false + for (var i = 1; i < m; i++) { + leap = this.leapMonth(y) + if (!isAdd) { // 处理闰月 + if (leap <= i && leap > 0) { + offset += this.leapDays(y); isAdd = true + } + } + offset += this.monthDays(y, i) + } + // 转换闰月农历 需补充该年闰月的前一个月的时差 + if (isLeapMonth) { offset += day } + // 1900年农历正月一日的公历时间为1900年1月30日0时0分0秒(该时间也是本农历的最开始起始点) + var stmap = Date.UTC(1900, 1, 30, 0, 0, 0) + var calObj = new Date((offset + d - 31) * 86400000 + stmap) + var cY = calObj.getUTCFullYear() + var cM = calObj.getUTCMonth() + 1 + var cD = calObj.getUTCDate() + + return this.solar2lunar(cY, cM, cD) + } +} + +export default calendar diff --git a/uni_modules/uv-calendar/components/uv-calendar/header.vue b/uni_modules/uv-calendar/components/uv-calendar/header.vue new file mode 100644 index 0000000..d7daa7b --- /dev/null +++ b/uni_modules/uv-calendar/components/uv-calendar/header.vue @@ -0,0 +1,104 @@ + + + + + diff --git a/uni_modules/uv-calendar/components/uv-calendar/month.vue b/uni_modules/uv-calendar/components/uv-calendar/month.vue new file mode 100644 index 0000000..1a649bc --- /dev/null +++ b/uni_modules/uv-calendar/components/uv-calendar/month.vue @@ -0,0 +1,616 @@ + + + + + diff --git a/uni_modules/uv-calendar/components/uv-calendar/props.js b/uni_modules/uv-calendar/components/uv-calendar/props.js new file mode 100644 index 0000000..c359293 --- /dev/null +++ b/uni_modules/uv-calendar/components/uv-calendar/props.js @@ -0,0 +1,145 @@ +export default { + props: { + // 日历顶部标题 + title: { + type: String, + default: '日期选择' + }, + // 是否显示标题 + showTitle: { + type: Boolean, + default: true + }, + // 是否显示副标题 + showSubtitle: { + type: Boolean, + default: true + }, + // 日期类型选择,single-选择单个日期,multiple-可以选择多个日期,range-选择日期范围 + mode: { + type: String, + default: 'single' + }, + // mode=range时,第一个日期底部的提示文字 + startText: { + type: String, + default: '开始' + }, + // mode=range时,最后一个日期底部的提示文字 + endText: { + type: String, + default: '结束' + }, + // 自定义列表 + customList: { + type: Array, + default: () => [] + }, + // 主题色,对底部按钮和选中日期有效 + color: { + type: String, + default: '#3c9cff' + }, + // 最小的可选日期 + minDate: { + type: [String, Number], + default: 0 + }, + // 最大可选日期 + maxDate: { + type: [String, Number], + default: 0 + }, + // 默认选中的日期,mode为multiple或range是必须为数组格式 + defaultDate: { + type: [Array, String, Date, null], + default: null + }, + // mode=multiple时,最多可选多少个日期 + maxCount: { + type: [String, Number], + default: Number.MAX_SAFE_INTEGER + }, + // 日期行高 + rowHeight: { + type: [String, Number], + default: 56 + }, + // 日期格式化函数 + formatter: { + type: [Function, null], + default: null + }, + // 是否显示农历 + showLunar: { + type: Boolean, + default: false + }, + // 是否显示月份背景色 + showMark: { + type: Boolean, + default: true + }, + // 确定按钮的文字 + confirmText: { + type: String, + default: '确定' + }, + // 确认按钮处于禁用状态时的文字 + confirmDisabledText: { + type: String, + default: '确定' + }, + // 是否允许点击遮罩关闭日历 + closeOnClickOverlay: { + type: Boolean, + default: false + }, + // 是否允许点击确认按钮关闭日历 + closeOnClickConfirm: { + type: Boolean, + default: true + }, + // 是否为只读状态,只读状态下禁止选择日期 + readonly: { + type: Boolean, + default: false + }, + // 是否展示确认按钮 + showConfirm: { + type: Boolean, + default: true + }, + // 日期区间最多可选天数,默认无限制,mode = range时有效 Infinity + maxRange: { + type: [Number, String], + default: Number.MAX_SAFE_INTEGER + }, + // 范围选择超过最多可选天数时的提示文案,mode = range时有效 + rangePrompt: { + type: String, + default: '' + }, + // 范围选择超过最多可选天数时,是否展示提示文案,mode = range时有效 + showRangePrompt: { + type: Boolean, + default: true + }, + // 是否允许日期范围的起止时间为同一天,mode = range时有效 + allowSameDay: { + type: Boolean, + default: false + }, + // 圆角值 + round: { + type: [Boolean, String, Number], + default: 0 + }, + // 最多展示月份数量 + monthNum: { + type: [Number, String], + default: 3 + }, + ...uni.$uv?.props?.calendar + } +} \ No newline at end of file diff --git a/uni_modules/uv-calendar/components/uv-calendar/uv-calendar.vue b/uni_modules/uv-calendar/components/uv-calendar/uv-calendar.vue new file mode 100644 index 0000000..626e833 --- /dev/null +++ b/uni_modules/uv-calendar/components/uv-calendar/uv-calendar.vue @@ -0,0 +1,390 @@ + + + + + diff --git a/uni_modules/uv-calendar/package.json b/uni_modules/uv-calendar/package.json new file mode 100644 index 0000000..03d8812 --- /dev/null +++ b/uni_modules/uv-calendar/package.json @@ -0,0 +1,89 @@ +{ + "id": "uv-calendar", + "displayName": "uv-calendar 日历 全面兼容vue3+2、app、h5、小程序等多端", + "version": "1.0.6", + "description": "日历组件用于单个选择日期,范围选择日期等,日历被包裹在底部弹起的容器中,灵活配置,功能齐全,兼容全端。强烈推荐使用最新版日历组件,在下方跳入。", + "keywords": [ + "uv-calendar", + "uvui", + "uv-ui", + "calendar", + "日历" + ], + "repository": "", + "engines": { + "HBuilderX": "^3.1.0" + }, + "dcloudext": { + "type": "component-vue", + "sale": { + "regular": { + "price": "0.00" + }, + "sourcecode": { + "price": "0.00" + } + }, + "contact": { + "qq": "" + }, + "declaration": { + "ads": "无", + "data": "插件不采集任何数据", + "permissions": "无" + }, + "npmurl": "" + }, + "uni_modules": { + "dependencies": [ + "uv-ui-tools", + "uv-button", + "uv-popup" + ], + "encrypt": [], + "platforms": { + "cloud": { + "tcb": "y", + "aliyun": "y" + }, + "client": { + "Vue": { + "vue2": "y", + "vue3": "y" + }, + "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", + "钉钉": "u", + "快手": "u", + "飞书": "u", + "京东": "u" + }, + "快应用": { + "华为": "u", + "联盟": "u" + } + } + } + } +} \ No newline at end of file diff --git a/uni_modules/uv-calendar/readme.md b/uni_modules/uv-calendar/readme.md new file mode 100644 index 0000000..3c2de54 --- /dev/null +++ b/uni_modules/uv-calendar/readme.md @@ -0,0 +1,21 @@ +## Calendar 日历 + +> **组件名:uv-calendar** + +此组件用于单个选择日期,范围选择日期等,日历被包裹在底部弹起的容器中。灵活配置,功能齐全,兼容全端。 + +## 温馨提示:该组件不再更新,强烈推荐使用最新版日历组件:[https://www.uvui.cn/components/calendars.html](https://www.uvui.cn/components/calendars.html)。基于 `uv-ui` 插件市场首款多功能日历组件,不仅可以查看、选择日期,还可以选择任意范围内的日期、打点操作、自定义主题颜色、自定义文案、农历显示等。追求的就是完美。 + +# 查看文档 + +## [下载完整示例项目](https://ext.dcloud.net.cn/plugin?name=uv-ui) (请不要 下载插件ZIP) + +### [更多插件,请关注uv-ui组件库](https://ext.dcloud.net.cn/plugin?name=uv-ui) + + + +![image](https://mp-a667b617-c5f1-4a2d-9a54-683a67cff588.cdn.bspapp.com/uv-ui/banner.png) + + + +#### 如使用过程中有任何问题反馈,或者您对uv-ui有一些好的建议,欢迎加入uv-ui官方交流群:官方QQ群 \ No newline at end of file diff --git a/uni_modules/uv-calendars/changelog.md b/uni_modules/uv-calendars/changelog.md new file mode 100644 index 0000000..b3b2e38 --- /dev/null +++ b/uni_modules/uv-calendars/changelog.md @@ -0,0 +1,40 @@ +## 1.0.15(2023-11-08) +1. 增加readonly属性,是否为只读状态,只读状态下禁止选择日期 +## 1.0.14(2023-10-12) +1. 修复selected没有设置了info或者info设置为空字符串后,文本则无法恢复BUG +## 1.0.13(2023-09-19) +1. 修复range模式下,selected设置了info后选中后,导致文本不恢复的问题 +2. 修复multiple模式下,selected自定义信息的颜色没变,依然是白色 +## 1.0.12(2023-09-14) +1. 优化 +## 1.0.11(2023-09-14) +1. 增加allowSameDay参数,是否允许日期范围的起止时间为同一天,mode = range时有效 +2. 修复在vue2+小程序渲染时闪烁的问题 +## 1.0.10(2023-09-07) +1. 修复国际化失效的BUG +## 1.0.9(2023-09-01) +1. 修复在pages.json中设置easycom会报错的BUG +## 1.0.8(2023-08-29) +1. 修复mainjs中设置setConfig修改属性不生效的问题,出自评论区:https://ext.dcloud.net.cn/plugin?id=12287 +## 1.0.7(2023-08-26) +1. 去除range参数,由mode="range"替换 +2. 新增mode参数,不传 / multiple / range,分别为单日期, 多个日期,选择日期范围 +3. 与uv-calendar选择日期的功能保持一致 +## 1.0.6(2023-08-25) +1. 修复点击返回今天按钮时,monthSwitch方法回调参数返回月份不是当天对应月份:https://github.com/climblee/uv-ui/issues/7 +## 1.0.5(2023-08-13) +1. 修复选择月份弹窗层级的问题 +## 1.0.4(2023-08-06) +1. 优化 +## 1.0.3(2023-08-06) +1. 修复高度不对的BUG +2. 修复文案在小屏幕的BUG +## 1.0.2(2023-08-05) +1. 增加startText参数 +2. 增加endText参数 +3. 增加selected中的参数 +4. 优化日历范围选择 +## 1.0.1(2023-08-04) +1. 修复 自定义主题时 颜色错误的BUG +## 1.0.0(2023-08-03) +1. 新增 uv-calendars 新版日历发布 diff --git a/uni_modules/uv-calendars/components/uv-calendars/calendar-body.vue b/uni_modules/uv-calendars/components/uv-calendars/calendar-body.vue new file mode 100644 index 0000000..b675fbd --- /dev/null +++ b/uni_modules/uv-calendars/components/uv-calendars/calendar-body.vue @@ -0,0 +1,376 @@ + + + + + \ No newline at end of file diff --git a/uni_modules/uv-calendars/components/uv-calendars/calendar-item.vue b/uni_modules/uv-calendars/components/uv-calendars/calendar-item.vue new file mode 100644 index 0000000..862d068 --- /dev/null +++ b/uni_modules/uv-calendars/components/uv-calendars/calendar-item.vue @@ -0,0 +1,248 @@ + + + \ No newline at end of file diff --git a/uni_modules/uv-calendars/components/uv-calendars/calendar.js b/uni_modules/uv-calendars/components/uv-calendars/calendar.js new file mode 100644 index 0000000..b8d7d6f --- /dev/null +++ b/uni_modules/uv-calendars/components/uv-calendars/calendar.js @@ -0,0 +1,546 @@ +/** +* @1900-2100区间内的公历、农历互转 +* @charset UTF-8 +* @github https://github.com/jjonline/calendar.js +* @Author Jea杨(JJonline@JJonline.Cn) +* @Time 2014-7-21 +* @Time 2016-8-13 Fixed 2033hex、Attribution Annals +* @Time 2016-9-25 Fixed lunar LeapMonth Param Bug +* @Time 2017-7-24 Fixed use getTerm Func Param Error.use solar year,NOT lunar year +* @Version 1.0.3 +* @公历转农历:calendar.solar2lunar(1987,11,01); //[you can ignore params of prefix 0] +* @农历转公历:calendar.lunar2solar(1987,09,10); //[you can ignore params of prefix 0] +*/ +/* eslint-disable */ +var calendar = { + + /** + * 农历1900-2100的润大小信息表 + * @Array Of Property + * @return Hex + */ + lunarInfo: [0x04bd8, 0x04ae0, 0x0a570, 0x054d5, 0x0d260, 0x0d950, 0x16554, 0x056a0, 0x09ad0, 0x055d2, // 1900-1909 + 0x04ae0, 0x0a5b6, 0x0a4d0, 0x0d250, 0x1d255, 0x0b540, 0x0d6a0, 0x0ada2, 0x095b0, 0x14977, // 1910-1919 + 0x04970, 0x0a4b0, 0x0b4b5, 0x06a50, 0x06d40, 0x1ab54, 0x02b60, 0x09570, 0x052f2, 0x04970, // 1920-1929 + 0x06566, 0x0d4a0, 0x0ea50, 0x06e95, 0x05ad0, 0x02b60, 0x186e3, 0x092e0, 0x1c8d7, 0x0c950, // 1930-1939 + 0x0d4a0, 0x1d8a6, 0x0b550, 0x056a0, 0x1a5b4, 0x025d0, 0x092d0, 0x0d2b2, 0x0a950, 0x0b557, // 1940-1949 + 0x06ca0, 0x0b550, 0x15355, 0x04da0, 0x0a5b0, 0x14573, 0x052b0, 0x0a9a8, 0x0e950, 0x06aa0, // 1950-1959 + 0x0aea6, 0x0ab50, 0x04b60, 0x0aae4, 0x0a570, 0x05260, 0x0f263, 0x0d950, 0x05b57, 0x056a0, // 1960-1969 + 0x096d0, 0x04dd5, 0x04ad0, 0x0a4d0, 0x0d4d4, 0x0d250, 0x0d558, 0x0b540, 0x0b6a0, 0x195a6, // 1970-1979 + 0x095b0, 0x049b0, 0x0a974, 0x0a4b0, 0x0b27a, 0x06a50, 0x06d40, 0x0af46, 0x0ab60, 0x09570, // 1980-1989 + 0x04af5, 0x04970, 0x064b0, 0x074a3, 0x0ea50, 0x06b58, 0x05ac0, 0x0ab60, 0x096d5, 0x092e0, // 1990-1999 + 0x0c960, 0x0d954, 0x0d4a0, 0x0da50, 0x07552, 0x056a0, 0x0abb7, 0x025d0, 0x092d0, 0x0cab5, // 2000-2009 + 0x0a950, 0x0b4a0, 0x0baa4, 0x0ad50, 0x055d9, 0x04ba0, 0x0a5b0, 0x15176, 0x052b0, 0x0a930, // 2010-2019 + 0x07954, 0x06aa0, 0x0ad50, 0x05b52, 0x04b60, 0x0a6e6, 0x0a4e0, 0x0d260, 0x0ea65, 0x0d530, // 2020-2029 + 0x05aa0, 0x076a3, 0x096d0, 0x04afb, 0x04ad0, 0x0a4d0, 0x1d0b6, 0x0d250, 0x0d520, 0x0dd45, // 2030-2039 + 0x0b5a0, 0x056d0, 0x055b2, 0x049b0, 0x0a577, 0x0a4b0, 0x0aa50, 0x1b255, 0x06d20, 0x0ada0, // 2040-2049 + /** Add By JJonline@JJonline.Cn**/ + 0x14b63, 0x09370, 0x049f8, 0x04970, 0x064b0, 0x168a6, 0x0ea50, 0x06b20, 0x1a6c4, 0x0aae0, // 2050-2059 + 0x0a2e0, 0x0d2e3, 0x0c960, 0x0d557, 0x0d4a0, 0x0da50, 0x05d55, 0x056a0, 0x0a6d0, 0x055d4, // 2060-2069 + 0x052d0, 0x0a9b8, 0x0a950, 0x0b4a0, 0x0b6a6, 0x0ad50, 0x055a0, 0x0aba4, 0x0a5b0, 0x052b0, // 2070-2079 + 0x0b273, 0x06930, 0x07337, 0x06aa0, 0x0ad50, 0x14b55, 0x04b60, 0x0a570, 0x054e4, 0x0d160, // 2080-2089 + 0x0e968, 0x0d520, 0x0daa0, 0x16aa6, 0x056d0, 0x04ae0, 0x0a9d4, 0x0a2d0, 0x0d150, 0x0f252, // 2090-2099 + 0x0d520], // 2100 + + /** + * 公历每个月份的天数普通表 + * @Array Of Property + * @return Number + */ + solarMonth: [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31], + + /** + * 天干地支之天干速查表 + * @Array Of Property trans["甲","乙","丙","丁","戊","己","庚","辛","壬","癸"] + * @return Cn string + */ + Gan: ['\u7532', '\u4e59', '\u4e19', '\u4e01', '\u620a', '\u5df1', '\u5e9a', '\u8f9b', '\u58ec', '\u7678'], + + /** + * 天干地支之地支速查表 + * @Array Of Property + * @trans["子","丑","寅","卯","辰","巳","午","未","申","酉","戌","亥"] + * @return Cn string + */ + Zhi: ['\u5b50', '\u4e11', '\u5bc5', '\u536f', '\u8fb0', '\u5df3', '\u5348', '\u672a', '\u7533', '\u9149', '\u620c', '\u4ea5'], + + /** + * 天干地支之地支速查表<=>生肖 + * @Array Of Property + * @trans["鼠","牛","虎","兔","龙","蛇","马","羊","猴","鸡","狗","猪"] + * @return Cn string + */ + Animals: ['\u9f20', '\u725b', '\u864e', '\u5154', '\u9f99', '\u86c7', '\u9a6c', '\u7f8a', '\u7334', '\u9e21', '\u72d7', '\u732a'], + + /** + * 24节气速查表 + * @Array Of Property + * @trans["小寒","大寒","立春","雨水","惊蛰","春分","清明","谷雨","立夏","小满","芒种","夏至","小暑","大暑","立秋","处暑","白露","秋分","寒露","霜降","立冬","小雪","大雪","冬至"] + * @return Cn string + */ + solarTerm: ['\u5c0f\u5bd2', '\u5927\u5bd2', '\u7acb\u6625', '\u96e8\u6c34', '\u60ca\u86f0', '\u6625\u5206', '\u6e05\u660e', '\u8c37\u96e8', '\u7acb\u590f', '\u5c0f\u6ee1', '\u8292\u79cd', '\u590f\u81f3', '\u5c0f\u6691', '\u5927\u6691', '\u7acb\u79cb', '\u5904\u6691', '\u767d\u9732', '\u79cb\u5206', '\u5bd2\u9732', '\u971c\u964d', '\u7acb\u51ac', '\u5c0f\u96ea', '\u5927\u96ea', '\u51ac\u81f3'], + + /** + * 1900-2100各年的24节气日期速查表 + * @Array Of Property + * @return 0x string For splice + */ + sTermInfo: ['9778397bd097c36b0b6fc9274c91aa', '97b6b97bd19801ec9210c965cc920e', '97bcf97c3598082c95f8c965cc920f', + '97bd0b06bdb0722c965ce1cfcc920f', 'b027097bd097c36b0b6fc9274c91aa', '97b6b97bd19801ec9210c965cc920e', + '97bcf97c359801ec95f8c965cc920f', '97bd0b06bdb0722c965ce1cfcc920f', 'b027097bd097c36b0b6fc9274c91aa', + '97b6b97bd19801ec9210c965cc920e', '97bcf97c359801ec95f8c965cc920f', '97bd0b06bdb0722c965ce1cfcc920f', + 'b027097bd097c36b0b6fc9274c91aa', '9778397bd19801ec9210c965cc920e', '97b6b97bd19801ec95f8c965cc920f', + '97bd09801d98082c95f8e1cfcc920f', '97bd097bd097c36b0b6fc9210c8dc2', '9778397bd197c36c9210c9274c91aa', + '97b6b97bd19801ec95f8c965cc920e', '97bd09801d98082c95f8e1cfcc920f', '97bd097bd097c36b0b6fc9210c8dc2', + '9778397bd097c36c9210c9274c91aa', '97b6b97bd19801ec95f8c965cc920e', '97bcf97c3598082c95f8e1cfcc920f', + '97bd097bd097c36b0b6fc9210c8dc2', '9778397bd097c36c9210c9274c91aa', '97b6b97bd19801ec9210c965cc920e', + '97bcf97c3598082c95f8c965cc920f', '97bd097bd097c35b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa', + '97b6b97bd19801ec9210c965cc920e', '97bcf97c3598082c95f8c965cc920f', '97bd097bd097c35b0b6fc920fb0722', + '9778397bd097c36b0b6fc9274c91aa', '97b6b97bd19801ec9210c965cc920e', '97bcf97c359801ec95f8c965cc920f', + '97bd097bd097c35b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa', '97b6b97bd19801ec9210c965cc920e', + '97bcf97c359801ec95f8c965cc920f', '97bd097bd097c35b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa', + '97b6b97bd19801ec9210c965cc920e', '97bcf97c359801ec95f8c965cc920f', '97bd097bd07f595b0b6fc920fb0722', + '9778397bd097c36b0b6fc9210c8dc2', '9778397bd19801ec9210c9274c920e', '97b6b97bd19801ec95f8c965cc920f', + '97bd07f5307f595b0b0bc920fb0722', '7f0e397bd097c36b0b6fc9210c8dc2', '9778397bd097c36c9210c9274c920e', + '97b6b97bd19801ec95f8c965cc920f', '97bd07f5307f595b0b0bc920fb0722', '7f0e397bd097c36b0b6fc9210c8dc2', + '9778397bd097c36c9210c9274c91aa', '97b6b97bd19801ec9210c965cc920e', '97bd07f1487f595b0b0bc920fb0722', + '7f0e397bd097c36b0b6fc9210c8dc2', '9778397bd097c36b0b6fc9274c91aa', '97b6b97bd19801ec9210c965cc920e', + '97bcf7f1487f595b0b0bb0b6fb0722', '7f0e397bd097c35b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa', + '97b6b97bd19801ec9210c965cc920e', '97bcf7f1487f595b0b0bb0b6fb0722', '7f0e397bd097c35b0b6fc920fb0722', + '9778397bd097c36b0b6fc9274c91aa', '97b6b97bd19801ec9210c965cc920e', '97bcf7f1487f531b0b0bb0b6fb0722', + '7f0e397bd097c35b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa', '97b6b97bd19801ec9210c965cc920e', + '97bcf7f1487f531b0b0bb0b6fb0722', '7f0e397bd07f595b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa', + '97b6b97bd19801ec9210c9274c920e', '97bcf7f0e47f531b0b0bb0b6fb0722', '7f0e397bd07f595b0b0bc920fb0722', + '9778397bd097c36b0b6fc9210c91aa', '97b6b97bd197c36c9210c9274c920e', '97bcf7f0e47f531b0b0bb0b6fb0722', + '7f0e397bd07f595b0b0bc920fb0722', '9778397bd097c36b0b6fc9210c8dc2', '9778397bd097c36c9210c9274c920e', + '97b6b7f0e47f531b0723b0b6fb0722', '7f0e37f5307f595b0b0bc920fb0722', '7f0e397bd097c36b0b6fc9210c8dc2', + '9778397bd097c36b0b70c9274c91aa', '97b6b7f0e47f531b0723b0b6fb0721', '7f0e37f1487f595b0b0bb0b6fb0722', + '7f0e397bd097c35b0b6fc9210c8dc2', '9778397bd097c36b0b6fc9274c91aa', '97b6b7f0e47f531b0723b0b6fb0721', + '7f0e27f1487f595b0b0bb0b6fb0722', '7f0e397bd097c35b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa', + '97b6b7f0e47f531b0723b0b6fb0721', '7f0e27f1487f531b0b0bb0b6fb0722', '7f0e397bd097c35b0b6fc920fb0722', + '9778397bd097c36b0b6fc9274c91aa', '97b6b7f0e47f531b0723b0b6fb0721', '7f0e27f1487f531b0b0bb0b6fb0722', + '7f0e397bd097c35b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa', '97b6b7f0e47f531b0723b0b6fb0721', + '7f0e27f1487f531b0b0bb0b6fb0722', '7f0e397bd07f595b0b0bc920fb0722', '9778397bd097c36b0b6fc9274c91aa', + '97b6b7f0e47f531b0723b0787b0721', '7f0e27f0e47f531b0b0bb0b6fb0722', '7f0e397bd07f595b0b0bc920fb0722', + '9778397bd097c36b0b6fc9210c91aa', '97b6b7f0e47f149b0723b0787b0721', '7f0e27f0e47f531b0723b0b6fb0722', + '7f0e397bd07f595b0b0bc920fb0722', '9778397bd097c36b0b6fc9210c8dc2', '977837f0e37f149b0723b0787b0721', + '7f07e7f0e47f531b0723b0b6fb0722', '7f0e37f5307f595b0b0bc920fb0722', '7f0e397bd097c35b0b6fc9210c8dc2', + '977837f0e37f14998082b0787b0721', '7f07e7f0e47f531b0723b0b6fb0721', '7f0e37f1487f595b0b0bb0b6fb0722', + '7f0e397bd097c35b0b6fc9210c8dc2', '977837f0e37f14998082b0787b06bd', '7f07e7f0e47f531b0723b0b6fb0721', + '7f0e27f1487f531b0b0bb0b6fb0722', '7f0e397bd097c35b0b6fc920fb0722', '977837f0e37f14998082b0787b06bd', + '7f07e7f0e47f531b0723b0b6fb0721', '7f0e27f1487f531b0b0bb0b6fb0722', '7f0e397bd097c35b0b6fc920fb0722', + '977837f0e37f14998082b0787b06bd', '7f07e7f0e47f531b0723b0b6fb0721', '7f0e27f1487f531b0b0bb0b6fb0722', + '7f0e397bd07f595b0b0bc920fb0722', '977837f0e37f14998082b0787b06bd', '7f07e7f0e47f531b0723b0b6fb0721', + '7f0e27f1487f531b0b0bb0b6fb0722', '7f0e397bd07f595b0b0bc920fb0722', '977837f0e37f14998082b0787b06bd', + '7f07e7f0e47f149b0723b0787b0721', '7f0e27f0e47f531b0b0bb0b6fb0722', '7f0e397bd07f595b0b0bc920fb0722', + '977837f0e37f14998082b0723b06bd', '7f07e7f0e37f149b0723b0787b0721', '7f0e27f0e47f531b0723b0b6fb0722', + '7f0e397bd07f595b0b0bc920fb0722', '977837f0e37f14898082b0723b02d5', '7ec967f0e37f14998082b0787b0721', + '7f07e7f0e47f531b0723b0b6fb0722', '7f0e37f1487f595b0b0bb0b6fb0722', '7f0e37f0e37f14898082b0723b02d5', + '7ec967f0e37f14998082b0787b0721', '7f07e7f0e47f531b0723b0b6fb0722', '7f0e37f1487f531b0b0bb0b6fb0722', + '7f0e37f0e37f14898082b0723b02d5', '7ec967f0e37f14998082b0787b06bd', '7f07e7f0e47f531b0723b0b6fb0721', + '7f0e37f1487f531b0b0bb0b6fb0722', '7f0e37f0e37f14898082b072297c35', '7ec967f0e37f14998082b0787b06bd', + '7f07e7f0e47f531b0723b0b6fb0721', '7f0e27f1487f531b0b0bb0b6fb0722', '7f0e37f0e37f14898082b072297c35', + '7ec967f0e37f14998082b0787b06bd', '7f07e7f0e47f531b0723b0b6fb0721', '7f0e27f1487f531b0b0bb0b6fb0722', + '7f0e37f0e366aa89801eb072297c35', '7ec967f0e37f14998082b0787b06bd', '7f07e7f0e47f149b0723b0787b0721', + '7f0e27f1487f531b0b0bb0b6fb0722', '7f0e37f0e366aa89801eb072297c35', '7ec967f0e37f14998082b0723b06bd', + '7f07e7f0e47f149b0723b0787b0721', '7f0e27f0e47f531b0723b0b6fb0722', '7f0e37f0e366aa89801eb072297c35', + '7ec967f0e37f14998082b0723b06bd', '7f07e7f0e37f14998083b0787b0721', '7f0e27f0e47f531b0723b0b6fb0722', + '7f0e37f0e366aa89801eb072297c35', '7ec967f0e37f14898082b0723b02d5', '7f07e7f0e37f14998082b0787b0721', + '7f07e7f0e47f531b0723b0b6fb0722', '7f0e36665b66aa89801e9808297c35', '665f67f0e37f14898082b0723b02d5', + '7ec967f0e37f14998082b0787b0721', '7f07e7f0e47f531b0723b0b6fb0722', '7f0e36665b66a449801e9808297c35', + '665f67f0e37f14898082b0723b02d5', '7ec967f0e37f14998082b0787b06bd', '7f07e7f0e47f531b0723b0b6fb0721', + '7f0e36665b66a449801e9808297c35', '665f67f0e37f14898082b072297c35', '7ec967f0e37f14998082b0787b06bd', + '7f07e7f0e47f531b0723b0b6fb0721', '7f0e26665b66a449801e9808297c35', '665f67f0e37f1489801eb072297c35', + '7ec967f0e37f14998082b0787b06bd', '7f07e7f0e47f531b0723b0b6fb0721', '7f0e27f1487f531b0b0bb0b6fb0722'], + + /** + * 数字转中文速查表 + * @Array Of Property + * @trans ['日','一','二','三','四','五','六','七','八','九','十'] + * @return Cn string + */ + nStr1: ['\u65e5', '\u4e00', '\u4e8c', '\u4e09', '\u56db', '\u4e94', '\u516d', '\u4e03', '\u516b', '\u4e5d', '\u5341'], + + /** + * 日期转农历称呼速查表 + * @Array Of Property + * @trans ['初','十','廿','卅'] + * @return Cn string + */ + nStr2: ['\u521d', '\u5341', '\u5eff', '\u5345'], + + /** + * 月份转农历称呼速查表 + * @Array Of Property + * @trans ['正','一','二','三','四','五','六','七','八','九','十','冬','腊'] + * @return Cn string + */ + nStr3: ['\u6b63', '\u4e8c', '\u4e09', '\u56db', '\u4e94', '\u516d', '\u4e03', '\u516b', '\u4e5d', '\u5341', '\u51ac', '\u814a'], + + /** + * 返回农历y年一整年的总天数 + * @param lunar Year + * @return Number + * @eg:var count = calendar.lYearDays(1987) ;//count=387 + */ + lYearDays: function (y) { + var i; var sum = 348 + for (i = 0x8000; i > 0x8; i >>= 1) { sum += (this.lunarInfo[y - 1900] & i) ? 1 : 0 } + return (sum + this.leapDays(y)) + }, + + /** + * 返回农历y年闰月是哪个月;若y年没有闰月 则返回0 + * @param lunar Year + * @return Number (0-12) + * @eg:var leapMonth = calendar.leapMonth(1987) ;//leapMonth=6 + */ + leapMonth: function (y) { // 闰字编码 \u95f0 + return (this.lunarInfo[y - 1900] & 0xf) + }, + + /** + * 返回农历y年闰月的天数 若该年没有闰月则返回0 + * @param lunar Year + * @return Number (0、29、30) + * @eg:var leapMonthDay = calendar.leapDays(1987) ;//leapMonthDay=29 + */ + leapDays: function (y) { + if (this.leapMonth(y)) { + return ((this.lunarInfo[y - 1900] & 0x10000) ? 30 : 29) + } + return (0) + }, + + /** + * 返回农历y年m月(非闰月)的总天数,计算m为闰月时的天数请使用leapDays方法 + * @param lunar Year + * @return Number (-1、29、30) + * @eg:var MonthDay = calendar.monthDays(1987,9) ;//MonthDay=29 + */ + monthDays: function (y, m) { + if (m > 12 || m < 1) { return -1 }// 月份参数从1至12,参数错误返回-1 + return ((this.lunarInfo[y - 1900] & (0x10000 >> m)) ? 30 : 29) + }, + + /** + * 返回公历(!)y年m月的天数 + * @param solar Year + * @return Number (-1、28、29、30、31) + * @eg:var solarMonthDay = calendar.leapDays(1987) ;//solarMonthDay=30 + */ + solarDays: function (y, m) { + if (m > 12 || m < 1) { return -1 } // 若参数错误 返回-1 + var ms = m - 1 + if (ms == 1) { // 2月份的闰平规律测算后确认返回28或29 + return (((y % 4 == 0) && (y % 100 != 0) || (y % 400 == 0)) ? 29 : 28) + } else { + return (this.solarMonth[ms]) + } + }, + + /** + * 农历年份转换为干支纪年 + * @param lYear 农历年的年份数 + * @return Cn string + */ + toGanZhiYear: function (lYear) { + var ganKey = (lYear - 3) % 10 + var zhiKey = (lYear - 3) % 12 + if (ganKey == 0) ganKey = 10// 如果余数为0则为最后一个天干 + if (zhiKey == 0) zhiKey = 12// 如果余数为0则为最后一个地支 + return this.Gan[ganKey - 1] + this.Zhi[zhiKey - 1] + }, + + /** + * 公历月、日判断所属星座 + * @param cMonth [description] + * @param cDay [description] + * @return Cn string + */ + toAstro: function (cMonth, cDay) { + var s = '\u9b54\u7faf\u6c34\u74f6\u53cc\u9c7c\u767d\u7f8a\u91d1\u725b\u53cc\u5b50\u5de8\u87f9\u72ee\u5b50\u5904\u5973\u5929\u79e4\u5929\u874e\u5c04\u624b\u9b54\u7faf' + var arr = [20, 19, 21, 21, 21, 22, 23, 23, 23, 23, 22, 22] + return s.substr(cMonth * 2 - (cDay < arr[cMonth - 1] ? 2 : 0), 2) + '\u5ea7'// 座 + }, + + /** + * 传入offset偏移量返回干支 + * @param offset 相对甲子的偏移量 + * @return Cn string + */ + toGanZhi: function (offset) { + return this.Gan[offset % 10] + this.Zhi[offset % 12] + }, + + /** + * 传入公历(!)y年获得该年第n个节气的公历日期 + * @param y公历年(1900-2100);n二十四节气中的第几个节气(1~24);从n=1(小寒)算起 + * @return day Number + * @eg:var _24 = calendar.getTerm(1987,3) ;//_24=4;意即1987年2月4日立春 + */ + getTerm: function (y, n) { + if (y < 1900 || y > 2100) { return -1 } + if (n < 1 || n > 24) { return -1 } + var _table = this.sTermInfo[y - 1900] + var _info = [ + parseInt('0x' + _table.substr(0, 5)).toString(), + parseInt('0x' + _table.substr(5, 5)).toString(), + parseInt('0x' + _table.substr(10, 5)).toString(), + parseInt('0x' + _table.substr(15, 5)).toString(), + parseInt('0x' + _table.substr(20, 5)).toString(), + parseInt('0x' + _table.substr(25, 5)).toString() + ] + var _calday = [ + _info[0].substr(0, 1), + _info[0].substr(1, 2), + _info[0].substr(3, 1), + _info[0].substr(4, 2), + + _info[1].substr(0, 1), + _info[1].substr(1, 2), + _info[1].substr(3, 1), + _info[1].substr(4, 2), + + _info[2].substr(0, 1), + _info[2].substr(1, 2), + _info[2].substr(3, 1), + _info[2].substr(4, 2), + + _info[3].substr(0, 1), + _info[3].substr(1, 2), + _info[3].substr(3, 1), + _info[3].substr(4, 2), + + _info[4].substr(0, 1), + _info[4].substr(1, 2), + _info[4].substr(3, 1), + _info[4].substr(4, 2), + + _info[5].substr(0, 1), + _info[5].substr(1, 2), + _info[5].substr(3, 1), + _info[5].substr(4, 2) + ] + return parseInt(_calday[n - 1]) + }, + + /** + * 传入农历数字月份返回汉语通俗表示法 + * @param lunar month + * @return Cn string + * @eg:var cnMonth = calendar.toChinaMonth(12) ;//cnMonth='腊月' + */ + toChinaMonth: function (m) { // 月 => \u6708 + if (m > 12 || m < 1) { return -1 } // 若参数错误 返回-1 + var s = this.nStr3[m - 1] + s += '\u6708'// 加上月字 + return s + }, + + /** + * 传入农历日期数字返回汉字表示法 + * @param lunar day + * @return Cn string + * @eg:var cnDay = calendar.toChinaDay(21) ;//cnMonth='廿一' + */ + toChinaDay: function (d) { // 日 => \u65e5 + var s + switch (d) { + case 10: + s = '\u521d\u5341'; break + case 20: + s = '\u4e8c\u5341'; break + break + case 30: + s = '\u4e09\u5341'; break + break + default : + s = this.nStr2[Math.floor(d / 10)] + s += this.nStr1[d % 10] + } + return (s) + }, + + /** + * 年份转生肖[!仅能大致转换] => 精确划分生肖分界线是“立春” + * @param y year + * @return Cn string + * @eg:var animal = calendar.getAnimal(1987) ;//animal='兔' + */ + getAnimal: function (y) { + return this.Animals[(y - 4) % 12] + }, + + /** + * 传入阳历年月日获得详细的公历、农历object信息 <=>JSON + * @param y solar year + * @param m solar month + * @param d solar day + * @return JSON object + * @eg:console.log(calendar.solar2lunar(1987,11,01)); + */ + solar2lunar: function (y, m, d) { // 参数区间1900.1.31~2100.12.31 + // 年份限定、上限 + if (y < 1900 || y > 2100) { + return -1// undefined转换为数字变为NaN + } + // 公历传参最下限 + if (y == 1900 && m == 1 && d < 31) { + return -1 + } + // 未传参 获得当天 + if (!y) { + var objDate = new Date() + } else { + var objDate = new Date(y, parseInt(m) - 1, d) + } + var i; var leap = 0; var temp = 0 + // 修正ymd参数 + var y = objDate.getFullYear() + var m = objDate.getMonth() + 1 + var d = objDate.getDate() + var offset = (Date.UTC(objDate.getFullYear(), objDate.getMonth(), objDate.getDate()) - Date.UTC(1900, 0, 31)) / 86400000 + for (i = 1900; i < 2101 && offset > 0; i++) { + temp = this.lYearDays(i) + offset -= temp + } + if (offset < 0) { + offset += temp; i-- + } + + // 是否今天 + var isTodayObj = new Date() + var isToday = false + if (isTodayObj.getFullYear() == y && isTodayObj.getMonth() + 1 == m && isTodayObj.getDate() == d) { + isToday = true + } + // 星期几 + var nWeek = objDate.getDay() + var cWeek = this.nStr1[nWeek] + // 数字表示周几顺应天朝周一开始的惯例 + if (nWeek == 0) { + nWeek = 7 + } + // 农历年 + var year = i + var leap = this.leapMonth(i) // 闰哪个月 + var isLeap = false + + // 效验闰月 + for (i = 1; i < 13 && offset > 0; i++) { + // 闰月 + if (leap > 0 && i == (leap + 1) && isLeap == false) { + --i + isLeap = true; temp = this.leapDays(year) // 计算农历闰月天数 + } else { + temp = this.monthDays(year, i)// 计算农历普通月天数 + } + // 解除闰月 + if (isLeap == true && i == (leap + 1)) { isLeap = false } + offset -= temp + } + // 闰月导致数组下标重叠取反 + if (offset == 0 && leap > 0 && i == leap + 1) { + if (isLeap) { + isLeap = false + } else { + isLeap = true; --i + } + } + if (offset < 0) { + offset += temp; --i + } + // 农历月 + var month = i + // 农历日 + var day = offset + 1 + // 天干地支处理 + var sm = m - 1 + var gzY = this.toGanZhiYear(year) + + // 当月的两个节气 + // bugfix-2017-7-24 11:03:38 use lunar Year Param `y` Not `year` + var firstNode = this.getTerm(y, (m * 2 - 1))// 返回当月「节」为几日开始 + var secondNode = this.getTerm(y, (m * 2))// 返回当月「节」为几日开始 + + // 依据12节气修正干支月 + var gzM = this.toGanZhi((y - 1900) * 12 + m + 11) + if (d >= firstNode) { + gzM = this.toGanZhi((y - 1900) * 12 + m + 12) + } + + // 传入的日期的节气与否 + var isTerm = false + var Term = null + if (firstNode == d) { + isTerm = true + Term = this.solarTerm[m * 2 - 2] + } + if (secondNode == d) { + isTerm = true + Term = this.solarTerm[m * 2 - 1] + } + // 日柱 当月一日与 1900/1/1 相差天数 + var dayCyclical = Date.UTC(y, sm, 1, 0, 0, 0, 0) / 86400000 + 25567 + 10 + var gzD = this.toGanZhi(dayCyclical + d - 1) + // 该日期所属的星座 + var astro = this.toAstro(m, d) + + return { 'lYear': year, 'lMonth': month, 'lDay': day, 'Animal': this.getAnimal(year), 'IMonthCn': (isLeap ? '\u95f0' : '') + this.toChinaMonth(month), 'IDayCn': this.toChinaDay(day), 'cYear': y, 'cMonth': m, 'cDay': d, 'gzYear': gzY, 'gzMonth': gzM, 'gzDay': gzD, 'isToday': isToday, 'isLeap': isLeap, 'nWeek': nWeek, 'ncWeek': '\u661f\u671f' + cWeek, 'isTerm': isTerm, 'Term': Term, 'astro': astro } + }, + + /** + * 传入农历年月日以及传入的月份是否闰月获得详细的公历、农历object信息 <=>JSON + * @param y lunar year + * @param m lunar month + * @param d lunar day + * @param isLeapMonth lunar month is leap or not.[如果是农历闰月第四个参数赋值true即可] + * @return JSON object + * @eg:console.log(calendar.lunar2solar(1987,9,10)); + */ + lunar2solar: function (y, m, d, isLeapMonth) { // 参数区间1900.1.31~2100.12.1 + var isLeapMonth = !!isLeapMonth + var leapOffset = 0 + var leapMonth = this.leapMonth(y) + var leapDay = this.leapDays(y) + if (isLeapMonth && (leapMonth != m)) { return -1 }// 传参要求计算该闰月公历 但该年得出的闰月与传参的月份并不同 + if (y == 2100 && m == 12 && d > 1 || y == 1900 && m == 1 && d < 31) { return -1 }// 超出了最大极限值 + var day = this.monthDays(y, m) + var _day = day + // bugFix 2016-9-25 + // if month is leap, _day use leapDays method + if (isLeapMonth) { + _day = this.leapDays(y, m) + } + if (y < 1900 || y > 2100 || d > _day) { return -1 }// 参数合法性效验 + + // 计算农历的时间差 + var offset = 0 + for (var i = 1900; i < y; i++) { + offset += this.lYearDays(i) + } + var leap = 0; var isAdd = false + for (var i = 1; i < m; i++) { + leap = this.leapMonth(y) + if (!isAdd) { // 处理闰月 + if (leap <= i && leap > 0) { + offset += this.leapDays(y); isAdd = true + } + } + offset += this.monthDays(y, i) + } + // 转换闰月农历 需补充该年闰月的前一个月的时差 + if (isLeapMonth) { offset += day } + // 1900年农历正月一日的公历时间为1900年1月30日0时0分0秒(该时间也是本农历的最开始起始点) + var stmap = Date.UTC(1900, 1, 30, 0, 0, 0) + var calObj = new Date((offset + d - 31) * 86400000 + stmap) + var cY = calObj.getUTCFullYear() + var cM = calObj.getUTCMonth() + 1 + var cD = calObj.getUTCDate() + + return this.solar2lunar(cY, cM, cD) + } +} + +export default calendar diff --git a/uni_modules/uv-calendars/components/uv-calendars/i18n/en.json b/uni_modules/uv-calendars/components/uv-calendars/i18n/en.json new file mode 100644 index 0000000..c83e8b2 --- /dev/null +++ b/uni_modules/uv-calendars/components/uv-calendars/i18n/en.json @@ -0,0 +1,12 @@ +{ + "uv-calender.ok": "ok", + "uv-calender.cancel": "cancel", + "uv-calender.today": "today", + "uv-calender.MON": "MON", + "uv-calender.TUE": "TUE", + "uv-calender.WED": "WED", + "uv-calender.THU": "THU", + "uv-calender.FRI": "FRI", + "uv-calender.SAT": "SAT", + "uv-calender.SUN": "SUN" +} diff --git a/uni_modules/uv-calendars/components/uv-calendars/i18n/index.js b/uni_modules/uv-calendars/components/uv-calendars/i18n/index.js new file mode 100644 index 0000000..de7509c --- /dev/null +++ b/uni_modules/uv-calendars/components/uv-calendars/i18n/index.js @@ -0,0 +1,8 @@ +import en from './en.json' +import zhHans from './zh-Hans.json' +import zhHant from './zh-Hant.json' +export default { + en, + 'zh-Hans': zhHans, + 'zh-Hant': zhHant +} diff --git a/uni_modules/uv-calendars/components/uv-calendars/i18n/zh-Hans.json b/uni_modules/uv-calendars/components/uv-calendars/i18n/zh-Hans.json new file mode 100644 index 0000000..03c5486 --- /dev/null +++ b/uni_modules/uv-calendars/components/uv-calendars/i18n/zh-Hans.json @@ -0,0 +1,12 @@ +{ + "uv-calender.ok": "确定", + "uv-calender.cancel": "取消", + "uv-calender.today": "今日", + "uv-calender.SUN": "日", + "uv-calender.MON": "一", + "uv-calender.TUE": "二", + "uv-calender.WED": "三", + "uv-calender.THU": "四", + "uv-calender.FRI": "五", + "uv-calender.SAT": "六" +} diff --git a/uni_modules/uv-calendars/components/uv-calendars/i18n/zh-Hant.json b/uni_modules/uv-calendars/components/uv-calendars/i18n/zh-Hant.json new file mode 100644 index 0000000..95cf29e --- /dev/null +++ b/uni_modules/uv-calendars/components/uv-calendars/i18n/zh-Hant.json @@ -0,0 +1,12 @@ +{ + "uv-calender.ok": "確定", + "uv-calender.cancel": "取消", + "uv-calender.today": "今日", + "uv-calender.SUN": "日", + "uv-calender.MON": "一", + "uv-calender.TUE": "二", + "uv-calender.WED": "三", + "uv-calender.THU": "四", + "uv-calender.FRI": "五", + "uv-calender.SAT": "六" +} diff --git a/uni_modules/uv-calendars/components/uv-calendars/util.js b/uni_modules/uv-calendars/components/uv-calendars/util.js new file mode 100644 index 0000000..ae1c6d6 --- /dev/null +++ b/uni_modules/uv-calendars/components/uv-calendars/util.js @@ -0,0 +1,435 @@ +import CALENDAR from './calendar.js' +class Calendar { + constructor({ + date, + selected, + startDate, + endDate, + range, + multiple, + allowSameDay + } = {}) { + // 当前日期 + this.date = this.getDate(new Date()) // 当前初入日期 + // 打点信息 + this.selected = selected || []; + // 范围开始 + this.startDate = startDate + // 范围结束 + this.endDate = endDate + this.range = range + this.multiple = multiple + this.allowSameDay = allowSameDay + // 多选状态 + this.cleanRangeStatus() + // 范围状态 + this.cleanMultipleStatus() + // 每周日期 + this.weeks = {} + // this._getWeek(this.date.fullDate) + } + /** + * 设置日期 + * @param {Object} date + */ + setDate(date, status) { + if (this.range && status == 'init') { + this.cleanRangeStatus(); + if (Array.isArray(date)) { + this.rangeStatus.before = date[0]; + this.rangeStatus.after = date.length > 1 ? date[date.length - 1] : ''; + if (this.rangeStatus.after && this.dateCompare(this.rangeStatus.before, this.rangeStatus.after)) { + this.rangeStatus.data = this.geDateAll(this.rangeStatus.before, this.rangeStatus.after) + } + this.selectDate = this.getDate(date[0]) + this._getWeek(this.selectDate.fullDate) + } else { + this.selectDate = this.getDate(date) + this.rangeStatus.before = this.selectDate.fullDate; + this._getWeek(this.selectDate.fullDate) + } + } else if (this.multiple && status == 'init') { + this.cleanMultipleStatus(); + if (Array.isArray(date)) { + this.multipleStatus.data = date; + this.selectDate = this.getDate(date[0]) + this._getWeek(this.selectDate.fullDate) + } else { + this.selectDate = this.getDate(date) + this.multipleStatus.data = [this.selectDate.fullDate]; + this._getWeek(this.selectDate.fullDate) + } + } else { + if (Array.isArray(date)) { + this.selectDate = this.getDate(date[0]) + this._getWeek(this.selectDate.fullDate) + } else { + this.selectDate = this.getDate(date) + this._getWeek(this.selectDate.fullDate) + } + } + } + /** + * 清理多选状态 + */ + cleanRangeStatus() { + this.rangeStatus = { + before: '', + after: '', + data: [] + } + } + /** + * 清理多选状态 + */ + cleanMultipleStatus() { + this.multipleStatus = { + data: [] + } + } + /** + * 重置开始日期 + */ + resetSatrtDate(startDate) { + // 范围开始 + this.startDate = startDate + } + /** + * 重置结束日期 + */ + resetEndDate(endDate) { + // 范围结束 + this.endDate = endDate + } + /** + * 获取任意时间 + */ + getDate(date, AddDayCount = 0, str = 'day') { + if (!date) { + date = new Date() + } + if (typeof date !== 'object') { + date = date.replace(/-/g, '/') + } + const dd = new Date(date) + switch (str) { + case 'day': + dd.setDate(dd.getDate() + AddDayCount) // 获取AddDayCount天后的日期 + break + case 'month': + if (dd.getDate() === 31 && AddDayCount > 0) { + dd.setDate(dd.getDate() + AddDayCount) + } else { + const preMonth = dd.getMonth() + dd.setMonth(preMonth + AddDayCount) // 获取AddDayCount天后的日期 + const nextMonth = dd.getMonth() + // 处理 pre 切换月份目标月份为2月没有当前日(30 31) 切换错误问题 + if (AddDayCount < 0 && preMonth !== 0 && nextMonth - preMonth > AddDayCount) { + dd.setMonth(nextMonth + (nextMonth - preMonth + AddDayCount)) + } + // 处理 next 切换月份目标月份为2月没有当前日(30 31) 切换错误问题 + if (AddDayCount > 0 && nextMonth - preMonth > AddDayCount) { + dd.setMonth(nextMonth - (nextMonth - preMonth - AddDayCount)) + } + } + break + case 'year': + dd.setFullYear(dd.getFullYear() + AddDayCount) // 获取AddDayCount天后的日期 + break + } + const y = dd.getFullYear() + const m = dd.getMonth() + 1 < 10 ? '0' + (dd.getMonth() + 1) : dd.getMonth() + 1 // 获取当前月份的日期,不足10补0 + const d = dd.getDate() < 10 ? '0' + dd.getDate() : dd.getDate() // 获取当前几号,不足10补0 + return { + fullDate: y + '-' + m + '-' + d, + year: y, + month: m, + date: d, + day: dd.getDay() + } + } + /** + * 获取上月剩余天数 + */ + _getLastMonthDays(firstDay, full) { + let dateArr = [] + for (let i = firstDay; i > 0; i--) { + const beforeDate = new Date(full.year, full.month - 1, -i + 1).getDate() + dateArr.push({ + date: beforeDate, + month: full.month - 1, + lunar: this.getlunar(full.year, full.month - 1, beforeDate), + disable: true + }) + } + return dateArr + } + /** + * 获取本月天数 + */ + _currentMonthDys(dateData, full) { + let dateArr = [] + let fullDate = this.date.fullDate + for (let i = 1; i <= dateData; i++) { + let nowDate = full.year + '-' + (full.month < 10 ? full.month : full.month) + '-' + (i < 10 ? '0' + i : i) + // 是否今天 + let isDay = fullDate === nowDate + // 获取打点信息 + let info = this.selected && this.selected.find((item) => { + if (this.dateEqual(nowDate, item.date)) { + return item + } + }) + // 日期禁用 + let disableBefore = true + let disableAfter = true + if (this.startDate) { + // let dateCompBefore = this.dateCompare(this.startDate, fullDate) + // disableBefore = this.dateCompare(dateCompBefore ? this.startDate : fullDate, nowDate) + disableBefore = this.dateCompare(this.startDate, nowDate) + } + if (this.endDate) { + // let dateCompAfter = this.dateCompare(fullDate, this.endDate) + // disableAfter = this.dateCompare(nowDate, dateCompAfter ? this.endDate : fullDate) + disableAfter = this.dateCompare(nowDate, this.endDate) + } + let ranges = this.rangeStatus.data + let checked = false + let rangesStatus = -1 + if (this.range) { + if (ranges) { + rangesStatus = ranges.findIndex((item) => { + return this.dateEqual(item, nowDate) + }) + } + if (rangesStatus !== -1) { + checked = true + } + } + let multiples = this.multipleStatus.data + let checked_multiple = false + let multiplesStatus = -1 + if (this.multiple) { + if (multiples) { + multiplesStatus = multiples.findIndex((item) => { + return this.dateEqual(item, nowDate) + }) + } + if (multiplesStatus !== -1) { + checked_multiple = true + } + } + let data = { + fullDate: nowDate, + year: full.year, + date: i, + range: this.range ? checked : false, + multiple: this.multiple ? checked_multiple : false, + beforeRange: this.dateEqual(this.rangeStatus.before, nowDate), + afterRange: this.dateEqual(this.rangeStatus.after, nowDate), + dateEqual: this.range && checked && this.dateEqual(this.rangeStatus.before, this.rangeStatus.after), + month: full.month, + lunar: this.getlunar(full.year, full.month, i), + disable: !(disableBefore && disableAfter), + isDay + } + if (info) { + data.extraInfo = info + } + dateArr.push(data) + } + return dateArr + } + /** + * 获取下月天数 + */ + _getNextMonthDays(surplus, full) { + let dateArr = [] + for (let i = 1; i < surplus + 1; i++) { + dateArr.push({ + date: i, + month: Number(full.month) + 1, + lunar: this.getlunar(full.year, Number(full.month) + 1, i), + disable: true + }) + } + return dateArr + } + /** + * 获取当前日期详情 + * @param {Object} date + */ + getInfo(date) { + if (!date) { + date = new Date() + } else if (Array.isArray(date)) { + date = date[0] + } + const dateInfo = this.canlender.find(item => item.fullDate === this.getDate(date).fullDate) + return dateInfo + } + /** + * 比较时间大小 + */ + dateCompare(startDate, endDate) { + // 计算截止时间 + startDate = new Date(startDate.replace('-', '/').replace('-', '/')) + // 计算详细项的截止时间 + endDate = new Date(endDate.replace('-', '/').replace('-', '/')) + if (startDate <= endDate) { + return true + } else { + return false + } + } + /** + * 比较时间是否相等 + */ + dateEqual(before, after) { + // 计算截止时间 + before = new Date(before.replace('-', '/').replace('-', '/')) + // 计算详细项的截止时间 + after = new Date(after.replace('-', '/').replace('-', '/')) + if (before.getTime() - after.getTime() === 0) { + return true + } else { + return false + } + } + /** + * 比较after时间是否大于before时间 + */ + dateAfterLgBefore(before, after) { + // 计算截止时间 + before = new Date(before.replace('-', '/').replace('-', '/')) + // 计算详细项的截止时间 + after = new Date(after.replace('-', '/').replace('-', '/')) + if (after.getTime() - before.getTime() > 0) { + return true + } else { + return false + } + } + /** + * 获取日期范围内所有日期 + * @param {Object} begin + * @param {Object} end + */ + geDateAll(begin, end) { + var arr = [] + var ab = begin.split('-') + var ae = end.split('-') + var db = new Date() + db.setFullYear(ab[0], ab[1] - 1, ab[2]) + var de = new Date() + de.setFullYear(ae[0], ae[1] - 1, ae[2]) + var unixDb = db.getTime() - 24 * 60 * 60 * 1000 + var unixDe = de.getTime() - 24 * 60 * 60 * 1000 + for (var k = unixDb; k <= unixDe;) { + k = k + 24 * 60 * 60 * 1000 + arr.push(this.getDate(new Date(parseInt(k))).fullDate) + } + return arr + } + /** + * 计算阴历日期显示 + */ + getlunar(year, month, date) { + return CALENDAR.solar2lunar(year, month, date) + } + /** + * 设置打点 + */ + setSelectInfo(data, value) { + this.selected = value + this._getWeek(data) + } + /** + * 获取多选状态 + */ + setMultiple(fullDate) { + if (!this.multiple) return + let multiples = this.multipleStatus.data; + const findIndex = multiples.findIndex(item => this.dateEqual(fullDate, item)); + if (findIndex < 0) { + this.multipleStatus.data = this.multipleStatus.data.concat([fullDate]); + } else { + this.multipleStatus.data.splice(findIndex, 1); + } + this._getWeek(fullDate) + } + /** + * 获取范围状态 + */ + setRange(fullDate) { + let { + before, + after + } = this.rangeStatus + if (!this.range) return + if (before && after) { + this.cleanRangeStatus(); + this.rangeStatus.before = fullDate + } else { + if (!before) { + this.rangeStatus.before = fullDate + } else { + if (this.allowSameDay && this.dateEqual(before, fullDate)) { + this.rangeStatus.after = fullDate + } else if (!this.dateAfterLgBefore(this.rangeStatus.before, fullDate)) { + this.cleanRangeStatus(); + this.rangeStatus.before = fullDate + this._getWeek(fullDate) + return; + } + this.rangeStatus.after = fullDate + if (this.dateCompare(this.rangeStatus.before, this.rangeStatus.after)) { + this.rangeStatus.data = this.geDateAll(this.rangeStatus.before, this.rangeStatus.after); + } else { + this.rangeStatus.data = this.geDateAll(this.rangeStatus.after, this.rangeStatus.before); + } + } + } + this._getWeek(fullDate) + } + /** + * 获取每周数据 + * @param {Object} dateData + */ + _getWeek(dateData) { + const { + year, + month + } = this.getDate(dateData) + let firstDay = new Date(year, month - 1, 1).getDay() + let currentDay = new Date(year, month, 0).getDate() + let dates = { + lastMonthDays: this._getLastMonthDays(firstDay, this.getDate(dateData)), // 上个月末尾几天 + currentMonthDys: this._currentMonthDys(currentDay, this.getDate(dateData)), // 本月天数 + nextMonthDays: [], // 下个月开始几天 + weeks: [] + } + let canlender = [] + const surplus = 42 - (dates.lastMonthDays.length + dates.currentMonthDys.length) + dates.nextMonthDays = this._getNextMonthDays(surplus, this.getDate(dateData)) + canlender = canlender.concat(dates.lastMonthDays, dates.currentMonthDys, dates.nextMonthDays) + let weeks = {} + // 拼接数组 上个月开始几天 + 本月天数+ 下个月开始几天 + for (let i = 0; i < canlender.length; i++) { + if (i % 7 === 0) { + weeks[parseInt(i / 7)] = new Array(7) + } + weeks[parseInt(i / 7)][i % 7] = canlender[i] + } + this.canlender = canlender + this.weeks = weeks + } + //静态方法 + // static init(date) { + // if (!this.instance) { + // this.instance = new Calendar(date); + // } + // return this.instance; + // } +} +export default Calendar \ No newline at end of file diff --git a/uni_modules/uv-calendars/components/uv-calendars/uv-calendars.vue b/uni_modules/uv-calendars/components/uv-calendars/uv-calendars.vue new file mode 100644 index 0000000..8d5b377 --- /dev/null +++ b/uni_modules/uv-calendars/components/uv-calendars/uv-calendars.vue @@ -0,0 +1,452 @@ + + + \ No newline at end of file diff --git a/uni_modules/uv-calendars/package.json b/uni_modules/uv-calendars/package.json new file mode 100644 index 0000000..7153510 --- /dev/null +++ b/uni_modules/uv-calendars/package.json @@ -0,0 +1,89 @@ +{ + "id": "uv-calendars", + "displayName": "uv-calendars 最新日历 全面兼容vue3+2、app、h5、小程序等多端", + "version": "1.0.15", + "description": "新版本uv-calendars,不仅拥有老版本的所有功能,还增加了更加适用的插入页面等强大功能,且更加简洁。查看日期、选择单个或多个或任意范围日期,打点操作,自定义文案,自定义主题等强大功能。", + "keywords": [ + "uv-ui", + "uvui", + "日历", + "打卡", + "日历选择" +], + "repository": "", + "engines": { + "HBuilderX": "^3.1.0" + }, + "dcloudext": { + "type": "component-vue", + "sale": { + "regular": { + "price": "0.00" + }, + "sourcecode": { + "price": "0.00" + } + }, + "contact": { + "qq": "" + }, + "declaration":{ + "ads": "无", + "data": "插件不采集任何数据", + "permissions": "无" + }, + "npmurl": "" + }, + "uni_modules": { + "dependencies": [ + "uv-ui-tools", + "uv-popup", + "uv-toolbar" + ], + "encrypt": [], + "platforms": { + "cloud": { + "tcb": "y", + "aliyun": "y" + }, + "client": { + "Vue": { + "vue2": "y", + "vue3": "y" + }, + "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", + "钉钉": "u", + "快手": "u", + "飞书": "u", + "京东": "u" + }, + "快应用": { + "华为": "u", + "联盟": "u" + } + } + } + } +} \ No newline at end of file diff --git a/uni_modules/uv-calendars/readme.md b/uni_modules/uv-calendars/readme.md new file mode 100644 index 0000000..d986eb9 --- /dev/null +++ b/uni_modules/uv-calendars/readme.md @@ -0,0 +1,23 @@ +## Calendars 全新日历 + +> **组件名:uv-calendars** + +为了解决老版本`uv-calendar`性能问题,特别是对日期选择范围有很大限制,体验不友好等缺点。于是有了新版日历组件。 + +新版本`uv-calendars`,不仅拥有老版本的所有功能,还增加了更加适用的插入页面等强大功能,且更加简洁。查看日期、选择单个或多个或任意范围日期,打点操作,自定义文案,自定义主题等强大功能。 + +常用场景:酒店日期预订、火车机票选择购买日期、上下班打卡等。 + +# 查看文档 + +## [下载完整示例项目](https://ext.dcloud.net.cn/plugin?name=uv-ui) (请不要 下载插件ZIP) + +### [更多插件,请关注uv-ui组件库](https://ext.dcloud.net.cn/plugin?name=uv-ui) + + + +![image](https://mp-a667b617-c5f1-4a2d-9a54-683a67cff588.cdn.bspapp.com/uv-ui/banner.png) + + + +#### 如使用过程中有任何问题反馈,或者您对uv-ui有一些好的建议,欢迎加入uv-ui官方交流群:官方QQ群 \ No newline at end of file diff --git a/uni_modules/uv-cell/changelog.md b/uni_modules/uv-cell/changelog.md new file mode 100644 index 0000000..c342b0c --- /dev/null +++ b/uni_modules/uv-cell/changelog.md @@ -0,0 +1,13 @@ +## 1.0.5(2023-12-06) +1. 修复uv-cell right-icon插槽编译到APP端不显示的BUG,问题来源:https://gitee.com/climblee/uv-ui/issues/I8LXZI +## 1.0.4(2023-09-19) +1. 增加cellStyle参数,方便自定义单元格的样式 +## 1.0.3(2023-07-03) +去除插槽判断,避免某些平台不显示的BUG +## 1.0.2(2023-06-21) +1. 优化 +## 1.0.1(2023-05-16) +1. 优化组件依赖,修改后无需全局引入,组件导入即可使用 +2. 优化部分功能 +## 1.0.0(2023-05-10) +uv-cell 单元格 diff --git a/uni_modules/uv-cell/components/uv-cell-group/props.js b/uni_modules/uv-cell/components/uv-cell-group/props.js new file mode 100644 index 0000000..57deb4c --- /dev/null +++ b/uni_modules/uv-cell/components/uv-cell-group/props.js @@ -0,0 +1,15 @@ +export default { + props: { + // 分组标题 + title: { + type: String, + default: '' + }, + // 是否显示外边框 + border: { + type: Boolean, + default: true + }, + ...uni.$uv?.props?.cellGroup + } +} \ No newline at end of file diff --git a/uni_modules/uv-cell/components/uv-cell-group/uv-cell-group.vue b/uni_modules/uv-cell/components/uv-cell-group/uv-cell-group.vue new file mode 100644 index 0000000..0f17865 --- /dev/null +++ b/uni_modules/uv-cell/components/uv-cell-group/uv-cell-group.vue @@ -0,0 +1,63 @@ + + + + + + diff --git a/uni_modules/uv-cell/components/uv-cell/props.js b/uni_modules/uv-cell/components/uv-cell/props.js new file mode 100644 index 0000000..6579636 --- /dev/null +++ b/uni_modules/uv-cell/components/uv-cell/props.js @@ -0,0 +1,116 @@ +export default { + props: { + // 标题 + title: { + type: [String, Number], + default: '' + }, + // 标题下方的描述信息 + label: { + type: [String, Number], + default: '' + }, + // 右侧的内容 + value: { + type: [String, Number], + default: '' + }, + // 左侧图标名称,或者图片链接(本地文件建议使用绝对地址) + icon: { + type: String, + default: '' + }, + // 是否禁用cell + disabled: { + type: Boolean, + default: false + }, + // 是否显示下边框 + border: { + type: Boolean, + default: true + }, + // 内容是否垂直居中(主要是针对右侧的value部分) + center: { + type: Boolean, + default: true + }, + // 点击后跳转的URL地址 + url: { + type: String, + default: '' + }, + // 链接跳转的方式,内部使用的是uvui封装的route方法,可能会进行拦截操作 + linkType: { + type: String, + default: 'navigateTo' + }, + // 是否开启点击反馈(表现为点击时加上灰色背景) + clickable: { + type: Boolean, + default: false + }, + // 是否展示右侧箭头并开启点击反馈 + isLink: { + type: Boolean, + default: false + }, + // 是否显示表单状态下的必填星号(此组件可能会内嵌入input组件) + required: { + type: Boolean, + default: false + }, + // 右侧的图标箭头 + rightIcon: { + type: String, + default: 'arrow-right' + }, + // 右侧箭头的方向,可选值为:left,up,down + arrowDirection: { + type: String, + default: '' + }, + // 左侧图标样式 + iconStyle: { + type: [Object, String], + default: () => { + return {} + } + }, + // 右侧箭头图标的样式 + rightIconStyle: { + type: [Object, String], + default: () => { + return {} + } + }, + // 标题的样式 + titleStyle: { + type: [Object, String], + default: () => { + return {} + } + }, + // 单位元的大小,可选值为large + size: { + type: String, + default: '' + }, + // 点击cell是否阻止事件传播 + stop: { + type: Boolean, + default: true + }, + // 标识符,cell被点击时返回 + name: { + type: [Number, String], + default: '' + }, + // 单元格自定义样式 + cellStyle: { + type: [Object, String], + default: () => {} + }, + ...uni.$uv?.props?.cell + } +} \ No newline at end of file diff --git a/uni_modules/uv-cell/components/uv-cell/uv-cell.vue b/uni_modules/uv-cell/components/uv-cell/uv-cell.vue new file mode 100644 index 0000000..bdd268e --- /dev/null +++ b/uni_modules/uv-cell/components/uv-cell/uv-cell.vue @@ -0,0 +1,209 @@ + + + + + \ No newline at end of file diff --git a/uni_modules/uv-cell/package.json b/uni_modules/uv-cell/package.json new file mode 100644 index 0000000..8ff5cf6 --- /dev/null +++ b/uni_modules/uv-cell/package.json @@ -0,0 +1,89 @@ +{ + "id": "uv-cell", + "displayName": "uv-cell 单元格 全面兼容小程序、nvue、vue2、vue3等多端", + "version": "1.0.5", + "description": "cell单元格一般用于一组列表的情况,比如个人中心页,设置页等。", + "keywords": [ + "uv-cell", + "uvui", + "uv-ui", + "单元格", + "设置页" +], + "repository": "", + "engines": { + "HBuilderX": "^3.1.0" + }, + "dcloudext": { + "type": "component-vue", + "sale": { + "regular": { + "price": "0.00" + }, + "sourcecode": { + "price": "0.00" + } + }, + "contact": { + "qq": "" + }, + "declaration": { + "ads": "无", + "data": "插件不采集任何数据", + "permissions": "无" + }, + "npmurl": "" + }, + "uni_modules": { + "dependencies": [ + "uv-ui-tools", + "uv-icon", + "uv-line" + ], + "encrypt": [], + "platforms": { + "cloud": { + "tcb": "y", + "aliyun": "y" + }, + "client": { + "Vue": { + "vue2": "y", + "vue3": "y" + }, + "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", + "钉钉": "u", + "快手": "u", + "飞书": "u", + "京东": "u" + }, + "快应用": { + "华为": "u", + "联盟": "u" + } + } + } + } +} \ No newline at end of file diff --git a/uni_modules/uv-cell/readme.md b/uni_modules/uv-cell/readme.md new file mode 100644 index 0000000..3ea9937 --- /dev/null +++ b/uni_modules/uv-cell/readme.md @@ -0,0 +1,11 @@ +## Cell 单元格 + +> **组件名:uv-cell** + +cell单元格一般用于一组列表的情况,比如个人中心页,设置页等。 + +### 查看文档 + +### [完整示例项目下载 | 关注更多组件](https://ext.dcloud.net.cn/plugin?name=uv-ui) + +#### 如使用过程中有任何问题,或者您对uv-ui有一些好的建议,欢迎加入 uv-ui 交流群:uv-ui、官方QQ群 diff --git a/uni_modules/uv-checkbox/changelog.md b/uni_modules/uv-checkbox/changelog.md new file mode 100644 index 0000000..2a142ce --- /dev/null +++ b/uni_modules/uv-checkbox/changelog.md @@ -0,0 +1,34 @@ +## 1.0.14(2023-11-04) +1. 修复label文字较多不分行的问题 +## 1.0.13(2023-10-11) +1. 优化同类问题:https://gitee.com/climblee/uv-ui/issues/I872VD +## 1.0.12(2023-09-22) +1. 修复change回调中v-model值不更新的BUG +## 1.0.11(2023-09-01) +1. 修复点击空隙处无效的问题 +2. label支持插槽下可点击 +## 1.0.10(2023-08-27) +1. 修复label设置布尔值不生效的BUG +## 1.0.9(2023-08-16) +1. 解决数据多不换行的BUG +## 1.0.8(2023-07-13) +1. 修复 uv-checkbox设置value属性不生效的BUG +## 1.0.7(2023-07-05) +修复vue3模式下,动态修改v-model绑定的值无效的BUG +## 1.0.6(2023-06-29) +1. 增加label插槽,与radio保持一致 +2. 优化文档 +## 1.0.5(2023-06-12) +1. 修复1.0.4改出的问题 +## 1.0.4(2023-06-08) +1. 复选框修复全局设置不生效的BUG +## 1.0.3(2023-06-06) +1. uv-checkbox-group 兼容自定义样式customStyle,方便通过样式调整整体位置等; +2. .uv-checkbox-group--row增加flex-wrap: wrap;允许换行 +## 1.0.2(2023-05-30) +1. 修复error报错的BUG +## 1.0.1(2023-05-16) +1. 优化组件依赖,修改后无需全局引入,组件导入即可使用 +2. 优化部分功能 +## 1.0.0(2023-05-10) +uv-checkbox 复选框 diff --git a/uni_modules/uv-checkbox/components/uv-checkbox-group/props.js b/uni_modules/uv-checkbox/components/uv-checkbox-group/props.js new file mode 100644 index 0000000..47bf005 --- /dev/null +++ b/uni_modules/uv-checkbox/components/uv-checkbox-group/props.js @@ -0,0 +1,84 @@ +export default { + props: { + // 绑定的值 + value: { + type: Array, + default: () => [] + }, + modelValue: { + type: Array, + default: () => [] + }, + // 标识符 + name: { + type: String, + default: '' + }, + // 形状,circle-圆形,square-方形 + shape: { + type: String, + default: 'square' + }, + // 是否禁用全部checkbox + disabled: { + type: Boolean, + default: false + }, + // 选中状态下的颜色,如设置此值,将会覆盖parent的activeColor值 + activeColor: { + type: String, + default: '#2979ff' + }, + // 未选中的颜色 + inactiveColor: { + type: String, + default: '#c8c9cc' + }, + // 整个组件的尺寸,默认px + size: { + type: [String, Number], + default: 18 + }, + // 布局方式,row-横向,column-纵向 + placement: { + type: String, + default: 'row' + }, + // label的字体大小,px单位 + labelSize: { + type: [String, Number], + default: 14 + }, + // label的字体颜色 + labelColor: { + type: [String], + default: '#303133' + }, + // 是否禁止点击文本操作 + labelDisabled: { + type: Boolean, + default: false + }, + // 图标颜色 + iconColor: { + type: String, + default: '#fff' + }, + // 图标的大小,单位px + iconSize: { + type: [String, Number], + default: 12 + }, + // 勾选图标的对齐方式,left-左边,right-右边 + iconPlacement: { + type: String, + default: 'left' + }, + // 竖向配列时,是否显示下划线 + borderBottom: { + type: Boolean, + default: false + }, + ...uni.$uv?.props?.checkboxGroup + } +} \ No newline at end of file diff --git a/uni_modules/uv-checkbox/components/uv-checkbox-group/uv-checkbox-group.vue b/uni_modules/uv-checkbox/components/uv-checkbox-group/uv-checkbox-group.vue new file mode 100644 index 0000000..d5ea81f --- /dev/null +++ b/uni_modules/uv-checkbox/components/uv-checkbox-group/uv-checkbox-group.vue @@ -0,0 +1,119 @@ + + + + + diff --git a/uni_modules/uv-checkbox/components/uv-checkbox/props.js b/uni_modules/uv-checkbox/components/uv-checkbox/props.js new file mode 100644 index 0000000..58ec890 --- /dev/null +++ b/uni_modules/uv-checkbox/components/uv-checkbox/props.js @@ -0,0 +1,70 @@ +export default { + props: { + // checkbox的名称 + name: { + type: [String, Number, Boolean], + default: '' + }, + // 形状,square为方形,circle为圆型 + shape: { + type: String, + default: '' + }, + // 整体的大小 + size: { + type: [String, Number], + default: '' + }, + // 是否默认选中 + checked: { + type: Boolean, + default: false + }, + // 是否禁用 + disabled: { + type: [String, Boolean], + default: '' + }, + // 选中状态下的颜色,如设置此值,将会覆盖parent的activeColor值 + activeColor: { + type: String, + default: '' + }, + // 未选中的颜色 + inactiveColor: { + type: String, + default: '' + }, + // 图标的大小,单位px + iconSize: { + type: [String, Number], + default: '' + }, + // 图标颜色 + iconColor: { + type: String, + default: '' + }, + // label提示文字,因为nvue下,直接slot进来的文字,由于特殊的结构,无法修改样式 + label: { + type: [String, Number, Boolean], + default: '' + }, + // label的字体大小,px单位 + labelSize: { + type: [String, Number], + default: '' + }, + // label的颜色 + labelColor: { + type: String, + default: '' + }, + // 是否禁止点击提示语选中复选框 + labelDisabled: { + type: [String, Boolean], + default: '' + }, + ...uni.$uv?.props?.checkbox + } +} \ No newline at end of file diff --git a/uni_modules/uv-checkbox/components/uv-checkbox/uv-checkbox.vue b/uni_modules/uv-checkbox/components/uv-checkbox/uv-checkbox.vue new file mode 100644 index 0000000..dfd1912 --- /dev/null +++ b/uni_modules/uv-checkbox/components/uv-checkbox/uv-checkbox.vue @@ -0,0 +1,370 @@ + + + + + diff --git a/uni_modules/uv-checkbox/package.json b/uni_modules/uv-checkbox/package.json new file mode 100644 index 0000000..44944d9 --- /dev/null +++ b/uni_modules/uv-checkbox/package.json @@ -0,0 +1,88 @@ +{ + "id": "uv-checkbox", + "displayName": "uv-checkbox 复选框 全面兼容vue3+2、app、h5、小程序等多端", + "version": "1.0.14", + "description": "复选框组件一般用于需要多个选择的场景,该组件功能完整,使用方便。", + "keywords": [ + "uv-checkbox", + "uvui", + "uv-ui", + "checkbox", + "复选框" +], + "repository": "", + "engines": { + "HBuilderX": "^3.1.0" + }, + "dcloudext": { + "type": "component-vue", + "sale": { + "regular": { + "price": "0.00" + }, + "sourcecode": { + "price": "0.00" + } + }, + "contact": { + "qq": "" + }, + "declaration": { + "ads": "无", + "data": "插件不采集任何数据", + "permissions": "无" + }, + "npmurl": "" + }, + "uni_modules": { + "dependencies": [ + "uv-ui-tools", + "uv-icon" + ], + "encrypt": [], + "platforms": { + "cloud": { + "tcb": "y", + "aliyun": "y" + }, + "client": { + "Vue": { + "vue2": "y", + "vue3": "y" + }, + "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", + "钉钉": "u", + "快手": "u", + "飞书": "u", + "京东": "u" + }, + "快应用": { + "华为": "u", + "联盟": "u" + } + } + } + } +} \ No newline at end of file diff --git a/uni_modules/uv-checkbox/readme.md b/uni_modules/uv-checkbox/readme.md new file mode 100644 index 0000000..43b6f2e --- /dev/null +++ b/uni_modules/uv-checkbox/readme.md @@ -0,0 +1,19 @@ +## Checkbox 复选框 + +> **组件名:uv-checkbox** + +复选框组件一般用于需要多个选择的场景,该组件功能完整,使用方便。可配合 `uv-form` 组件进行表单验证等场景使用。 + +# 查看文档 + +## [下载完整示例项目](https://ext.dcloud.net.cn/plugin?name=uv-ui) (请不要 下载插件ZIP) + +### [更多插件,请关注uv-ui组件库](https://ext.dcloud.net.cn/plugin?name=uv-ui) + + + +![image](https://mp-a667b617-c5f1-4a2d-9a54-683a67cff588.cdn.bspapp.com/uv-ui/banner.png) + + + +#### 如使用过程中有任何问题反馈,或者您对uv-ui有一些好的建议,欢迎加入uv-ui官方交流群:官方QQ群 \ No newline at end of file diff --git a/uni_modules/uv-code-input/changelog.md b/uni_modules/uv-code-input/changelog.md new file mode 100644 index 0000000..1fefc03 --- /dev/null +++ b/uni_modules/uv-code-input/changelog.md @@ -0,0 +1,13 @@ +## 1.0.5(2023-08-05) +在vue2模式下,v-model设置为0时不生效的BUG +## 1.0.4(2023-07-13) +1. 修复value/v-model更改不生效的BUG +## 1.0.3(2023-06-28) +修复:使用:disabledKeyboard="true"属性,事件全部失效的BUG +## 1.0.2(2023-06-23) +优化下边框 +## 1.0.1(2023-05-16) +1. 优化组件依赖,修改后无需全局引入,组件导入即可使用 +2. 优化部分功能 +## 1.0.0(2023-05-10) +uv-code-input 验证码输入 diff --git a/uni_modules/uv-code-input/components/uv-code-input/props.js b/uni_modules/uv-code-input/components/uv-code-input/props.js new file mode 100644 index 0000000..4a5e460 --- /dev/null +++ b/uni_modules/uv-code-input/components/uv-code-input/props.js @@ -0,0 +1,83 @@ +export default { + props: { + value: { + type: [String, Number], + default: '' + }, + modelValue: { + type: [String, Number], + default: '' + }, + // 键盘弹起时,是否自动上推页面 + adjustPosition: { + type: Boolean, + default: true + }, + // 最大输入长度 + maxlength: { + type: [String, Number], + default: 6 + }, + // 是否用圆点填充 + dot: { + type: Boolean, + default: false + }, + // 显示模式,box-盒子模式,line-底部横线模式 + mode: { + type: String, + default: 'box' + }, + // 是否细边框 + hairline: { + type: Boolean, + default: false + }, + // 字符间的距离 + space: { + type: [String, Number], + default: 10 + }, + // 是否自动获取焦点 + focus: { + type: Boolean, + default: false + }, + // 字体是否加粗 + bold: { + type: Boolean, + default: false + }, + // 字体颜色 + color: { + type: String, + default: '#606266' + }, + // 字体大小 + fontSize: { + type: [String, Number], + default: 18 + }, + // 输入框的大小,宽等于高 + size: { + type: [String, Number], + default: 35 + }, + // 是否隐藏原生键盘,如果想用自定义键盘的话,需设置此参数为true + disabledKeyboard: { + type: Boolean, + default: false + }, + // 边框和线条颜色 + borderColor: { + type: String, + default: '#c9cacc' + }, + // 是否禁止输入"."符号 + disabledDot: { + type: Boolean, + default: true + }, + ...uni.$uv?.props?.codeInput + } +} \ No newline at end of file diff --git a/uni_modules/uv-code-input/components/uv-code-input/uv-code-input.vue b/uni_modules/uv-code-input/components/uv-code-input/uv-code-input.vue new file mode 100644 index 0000000..14ad8a2 --- /dev/null +++ b/uni_modules/uv-code-input/components/uv-code-input/uv-code-input.vue @@ -0,0 +1,272 @@ + + + + \ No newline at end of file diff --git a/uni_modules/uv-code-input/package.json b/uni_modules/uv-code-input/package.json new file mode 100644 index 0000000..ab8762c --- /dev/null +++ b/uni_modules/uv-code-input/package.json @@ -0,0 +1,87 @@ +{ + "id": "uv-code-input", + "displayName": "uv-code-input 验证码输入 全面兼容vue3+2、app、h5、小程序等多端", + "version": "1.0.5", + "description": "验证码输入组件一般用于验证用户短信验证码的场景,输入框或横线多种模式可选。", + "keywords": [ + "uv-code-input", + "uvui", + "uv-ui", + "code", + "验证码输入" +], + "repository": "", + "engines": { + "HBuilderX": "^3.1.0" + }, + "dcloudext": { + "type": "component-vue", + "sale": { + "regular": { + "price": "0.00" + }, + "sourcecode": { + "price": "0.00" + } + }, + "contact": { + "qq": "" + }, + "declaration": { + "ads": "无", + "data": "插件不采集任何数据", + "permissions": "无" + }, + "npmurl": "" + }, + "uni_modules": { + "dependencies": [ + "uv-ui-tools" + ], + "encrypt": [], + "platforms": { + "cloud": { + "tcb": "y", + "aliyun": "y" + }, + "client": { + "Vue": { + "vue2": "y", + "vue3": "y" + }, + "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", + "钉钉": "u", + "快手": "u", + "飞书": "u", + "京东": "u" + }, + "快应用": { + "华为": "u", + "联盟": "u" + } + } + } + } +} \ No newline at end of file diff --git a/uni_modules/uv-code-input/readme.md b/uni_modules/uv-code-input/readme.md new file mode 100644 index 0000000..aa5b0a1 --- /dev/null +++ b/uni_modules/uv-code-input/readme.md @@ -0,0 +1,19 @@ +## CodeInput 验证码输入框 + +> **组件名:uv-code-input** + +该组件一般用于验证用户短信验证码的场景,输入框或横线多种模式可选。 + +# 查看文档 + +## [下载完整示例项目](https://ext.dcloud.net.cn/plugin?name=uv-ui) (请不要 下载插件ZIP) + +### [更多插件,请关注uv-ui组件库](https://ext.dcloud.net.cn/plugin?name=uv-ui) + + + +![image](https://mp-a667b617-c5f1-4a2d-9a54-683a67cff588.cdn.bspapp.com/uv-ui/banner.png) + + + +#### 如使用过程中有任何问题反馈,或者您对uv-ui有一些好的建议,欢迎加入uv-ui官方交流群:官方QQ群 \ No newline at end of file diff --git a/uni_modules/uv-code/changelog.md b/uni_modules/uv-code/changelog.md new file mode 100644 index 0000000..7054a25 --- /dev/null +++ b/uni_modules/uv-code/changelog.md @@ -0,0 +1,9 @@ +## 1.0.3(2023-10-13) +1. 优化 +## 1.0.2(2023-10-13) +1. unmounted兼容vue3 +## 1.0.1(2023-05-16) +1. 优化组件依赖,修改后无需全局引入,组件导入即可使用 +2. 优化部分功能 +## 1.0.0(2023-05-10) +uv-code 验证码倒计时 diff --git a/uni_modules/uv-code/components/uv-code/props.js b/uni_modules/uv-code/components/uv-code/props.js new file mode 100644 index 0000000..afc9d3c --- /dev/null +++ b/uni_modules/uv-code/components/uv-code/props.js @@ -0,0 +1,35 @@ +export default { + props: { + // 倒计时总秒数 + seconds: { + type: [String, Number], + default: 60 + }, + // 尚未开始时提示 + startText: { + type: String, + default: '获取验证码' + }, + // 正在倒计时中的提示 + changeText: { + type: String, + default: 'X秒重新获取' + }, + // 倒计时结束时的提示 + endText: { + type: String, + default: '重新获取' + }, + // 是否在H5刷新或各端返回再进入时继续倒计时 + keepRunning: { + type: Boolean, + default: false + }, + // 为了区分多个页面,或者一个页面多个倒计时组件本地存储的继续倒计时变了 + uniqueKey: { + type: String, + default: '' + }, + ...uni.$uv?.props?.code + } +} \ No newline at end of file diff --git a/uni_modules/uv-code/components/uv-code/uv-code.vue b/uni_modules/uv-code/components/uv-code/uv-code.vue new file mode 100644 index 0000000..de02c83 --- /dev/null +++ b/uni_modules/uv-code/components/uv-code/uv-code.vue @@ -0,0 +1,136 @@ + + \ No newline at end of file diff --git a/uni_modules/uv-code/package.json b/uni_modules/uv-code/package.json new file mode 100644 index 0000000..d4392c0 --- /dev/null +++ b/uni_modules/uv-code/package.json @@ -0,0 +1,87 @@ +{ + "id": "uv-code", + "displayName": "uv-code 验证码倒计时 全面兼容小程序、nvue、vue2、vue3等多端", + "version": "1.0.3", + "description": "考虑到用户实际发送验证码的场景,可能是一个按钮,也可能是一段文字,提示语各有不同,所以本组件不提供界面显示,只提供倒计时文本,由用户将文本嵌入到具体的场景。", + "keywords": [ + "uv-code", + "uvui", + "uv-ui", + "code", + "验证码倒计时" +], + "repository": "", + "engines": { + "HBuilderX": "^3.1.0" + }, + "dcloudext": { + "type": "component-vue", + "sale": { + "regular": { + "price": "0.00" + }, + "sourcecode": { + "price": "0.00" + } + }, + "contact": { + "qq": "" + }, + "declaration": { + "ads": "无", + "data": "插件不采集任何数据", + "permissions": "无" + }, + "npmurl": "" + }, + "uni_modules": { + "dependencies": [ + "uv-ui-tools" + ], + "encrypt": [], + "platforms": { + "cloud": { + "tcb": "y", + "aliyun": "y" + }, + "client": { + "Vue": { + "vue2": "y", + "vue3": "y" + }, + "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", + "钉钉": "u", + "快手": "u", + "飞书": "u", + "京东": "u" + }, + "快应用": { + "华为": "u", + "联盟": "u" + } + } + } + } +} \ No newline at end of file diff --git a/uni_modules/uv-code/readme.md b/uni_modules/uv-code/readme.md new file mode 100644 index 0000000..cf2eb51 --- /dev/null +++ b/uni_modules/uv-code/readme.md @@ -0,0 +1,11 @@ +## Code 验证码输入框 + +> **组件名:uv-code** + +考虑到用户实际发送验证码的场景,可能是一个按钮,也可能是一段文字,提示语各有不同,所以本组件不提供界面显示,只提供倒计时文本,由用户将文本嵌入到具体的场景。 + +### 查看文档 + +### [完整示例项目下载 | 关注更多组件](https://ext.dcloud.net.cn/plugin?name=uv-ui) + +#### 如使用过程中有任何问题,或者您对uv-ui有一些好的建议,欢迎加入 uv-ui 交流群:uv-ui、官方QQ群 diff --git a/uni_modules/uv-collapse/changelog.md b/uni_modules/uv-collapse/changelog.md new file mode 100644 index 0000000..0219560 --- /dev/null +++ b/uni_modules/uv-collapse/changelog.md @@ -0,0 +1,5 @@ +## 1.0.1(2023-05-16) +1. 优化组件依赖,修改后无需全局引入,组件导入即可使用 +2. 优化部分功能 +## 1.0.0(2023-05-10) +uv-collapse 折叠面板 diff --git a/uni_modules/uv-collapse/components/uv-collapse-item/props.js b/uni_modules/uv-collapse/components/uv-collapse-item/props.js new file mode 100644 index 0000000..18983c1 --- /dev/null +++ b/uni_modules/uv-collapse/components/uv-collapse-item/props.js @@ -0,0 +1,60 @@ +export default { + props: { + // 标题 + title: { + type: String, + default: '' + }, + // 标题右侧内容 + value: { + type: String, + default: '' + }, + // 标题下方的描述信息 + label: { + type: String, + default: '' + }, + // 是否禁用折叠面板 + disabled: { + type: Boolean, + default: false + }, + // 是否展示右侧箭头并开启点击反馈 + isLink: { + type: Boolean, + default: true + }, + // 是否开启点击反馈 + clickable: { + type: Boolean, + default: true + }, + // 是否显示内边框 + border: { + type: Boolean, + default: true + }, + // 标题的对齐方式 + align: { + type: String, + default: 'left' + }, + // 唯一标识符 + name: { + type: [String, Number], + default: '' + }, + // 标题左侧图片,可为绝对路径的图片或内置图标 + icon: { + type: String, + default: '' + }, + // 面板展开收起的过渡时间,单位ms + duration: { + type: Number, + default: 300 + }, + ...uni.$uv?.props?.collapseItem + } +} \ No newline at end of file diff --git a/uni_modules/uv-collapse/components/uv-collapse-item/uv-collapse-item.vue b/uni_modules/uv-collapse/components/uv-collapse-item/uv-collapse-item.vue new file mode 100644 index 0000000..840f28d --- /dev/null +++ b/uni_modules/uv-collapse/components/uv-collapse-item/uv-collapse-item.vue @@ -0,0 +1,229 @@ + + + + + diff --git a/uni_modules/uv-collapse/components/uv-collapse/props.js b/uni_modules/uv-collapse/components/uv-collapse/props.js new file mode 100644 index 0000000..70fa04c --- /dev/null +++ b/uni_modules/uv-collapse/components/uv-collapse/props.js @@ -0,0 +1,20 @@ +export default { + props: { + // 当前展开面板的name,非手风琴模式:[],手风琴模式:string | number + value: { + type: [String, Number, Array, null], + default: null + }, + // 是否手风琴模式 + accordion: { + type: Boolean, + default: false + }, + // 是否显示外边框 + border: { + type: Boolean, + default: true + }, + ...uni.$uv?.props?.collapse + } +} \ No newline at end of file diff --git a/uni_modules/uv-collapse/components/uv-collapse/uv-collapse.vue b/uni_modules/uv-collapse/components/uv-collapse/uv-collapse.vue new file mode 100644 index 0000000..5e5c96d --- /dev/null +++ b/uni_modules/uv-collapse/components/uv-collapse/uv-collapse.vue @@ -0,0 +1,86 @@ + + + diff --git a/uni_modules/uv-collapse/package.json b/uni_modules/uv-collapse/package.json new file mode 100644 index 0000000..cf9565f --- /dev/null +++ b/uni_modules/uv-collapse/package.json @@ -0,0 +1,89 @@ +{ + "id": "uv-collapse", + "displayName": "uv-collapse 折叠面板 全面兼容小程序、nvue、vue2、vue3等多端", + "version": "1.0.1", + "description": "折叠面板组件,通过折叠面板收纳内容区域,点击可展开收起,多功能参数可配置。", + "keywords": [ + "uv-collapse", + "uvui", + "uv-ui", + "collapse", + "折叠面板" +], + "repository": "", + "engines": { + "HBuilderX": "^3.1.0" + }, + "dcloudext": { + "type": "component-vue", + "sale": { + "regular": { + "price": "0.00" + }, + "sourcecode": { + "price": "0.00" + } + }, + "contact": { + "qq": "" + }, + "declaration": { + "ads": "无", + "data": "插件不采集任何数据", + "permissions": "无" + }, + "npmurl": "" + }, + "uni_modules": { + "dependencies": [ + "uv-ui-tools", + "uv-line", + "uv-cell" + ], + "encrypt": [], + "platforms": { + "cloud": { + "tcb": "y", + "aliyun": "y" + }, + "client": { + "Vue": { + "vue2": "y", + "vue3": "y" + }, + "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", + "钉钉": "u", + "快手": "u", + "飞书": "u", + "京东": "u" + }, + "快应用": { + "华为": "u", + "联盟": "u" + } + } + } + } +} \ No newline at end of file diff --git a/uni_modules/uv-collapse/readme.md b/uni_modules/uv-collapse/readme.md new file mode 100644 index 0000000..cb340ba --- /dev/null +++ b/uni_modules/uv-collapse/readme.md @@ -0,0 +1,11 @@ +## Collapse 折叠面板 + +> **组件名:uv-collapse** + +通过折叠面板收纳内容区域,点击可展开收起,多功能参数可配置。 + +### 查看文档 + +### [完整示例项目下载 | 关注更多组件](https://ext.dcloud.net.cn/plugin?name=uv-ui) + +#### 如使用过程中有任何问题,或者您对uv-ui有一些好的建议,欢迎加入 uv-ui 交流群:uv-ui、官方QQ群 diff --git a/uni_modules/uv-count-down/changelog.md b/uni_modules/uv-count-down/changelog.md new file mode 100644 index 0000000..44392c2 --- /dev/null +++ b/uni_modules/uv-count-down/changelog.md @@ -0,0 +1,9 @@ +## 1.0.3(2023-10-13) +1. unmounted兼容vue3 +## 1.0.2(2023-06-20) +1. 增加外部样式customStyle参数 +## 1.0.1(2023-05-16) +1. 优化组件依赖,修改后无需全局引入,组件导入即可使用 +2. 优化部分功能 +## 1.0.0(2023-05-10) +uv-count-down 倒计时 diff --git a/uni_modules/uv-count-down/components/uv-count-down/props.js b/uni_modules/uv-count-down/components/uv-count-down/props.js new file mode 100644 index 0000000..c5b5461 --- /dev/null +++ b/uni_modules/uv-count-down/components/uv-count-down/props.js @@ -0,0 +1,25 @@ +export default { + props: { + // 倒计时时长,单位ms + time: { + type: [String, Number], + default: 0 + }, + // 时间格式,DD-日,HH-时,mm-分,ss-秒,SSS-毫秒 + format: { + type: String, + default: 'HH:mm:ss' + }, + // 是否自动开始倒计时 + autoStart: { + type: Boolean, + default: true + }, + // 是否展示毫秒倒计时 + millisecond: { + type: Boolean, + default: false + }, + ...uni.$uv?.props?.countDown + } +} \ No newline at end of file diff --git a/uni_modules/uv-count-down/components/uv-count-down/utils.js b/uni_modules/uv-count-down/components/uv-count-down/utils.js new file mode 100644 index 0000000..8c75005 --- /dev/null +++ b/uni_modules/uv-count-down/components/uv-count-down/utils.js @@ -0,0 +1,62 @@ +// 补0,如1 -> 01 +function padZero(num, targetLength = 2) { + let str = `${num}` + while (str.length < targetLength) { + str = `0${str}` + } + return str +} +const SECOND = 1000 +const MINUTE = 60 * SECOND +const HOUR = 60 * MINUTE +const DAY = 24 * HOUR +export function parseTimeData(time) { + const days = Math.floor(time / DAY) + const hours = Math.floor((time % DAY) / HOUR) + const minutes = Math.floor((time % HOUR) / MINUTE) + const seconds = Math.floor((time % MINUTE) / SECOND) + const milliseconds = Math.floor(time % SECOND) + return { + days, + hours, + minutes, + seconds, + milliseconds + } +} +export function parseFormat(format, timeData) { + let { + days, + hours, + minutes, + seconds, + milliseconds + } = timeData + // 如果格式化字符串中不存在DD(天),则将天的时间转为小时中去 + if (format.indexOf('DD') === -1) { + hours += days * 24 + } else { + // 对天补0 + format = format.replace('DD', padZero(days)) + } + // 其他同理于DD的格式化处理方式 + if (format.indexOf('HH') === -1) { + minutes += hours * 60 + } else { + format = format.replace('HH', padZero(hours)) + } + if (format.indexOf('mm') === -1) { + seconds += minutes * 60 + } else { + format = format.replace('mm', padZero(minutes)) + } + if (format.indexOf('ss') === -1) { + milliseconds += seconds * 1000 + } else { + format = format.replace('ss', padZero(seconds)) + } + return format.replace('SSS', padZero(milliseconds, 3)) +} +export function isSameSecond(time1, time2) { + return Math.floor(time1 / 1000) === Math.floor(time2 / 1000) +} diff --git a/uni_modules/uv-count-down/components/uv-count-down/uv-count-down.vue b/uni_modules/uv-count-down/components/uv-count-down/uv-count-down.vue new file mode 100644 index 0000000..a758d31 --- /dev/null +++ b/uni_modules/uv-count-down/components/uv-count-down/uv-count-down.vue @@ -0,0 +1,169 @@ + + + \ No newline at end of file diff --git a/uni_modules/uv-count-down/package.json b/uni_modules/uv-count-down/package.json new file mode 100644 index 0000000..da501f1 --- /dev/null +++ b/uni_modules/uv-count-down/package.json @@ -0,0 +1,87 @@ +{ + "id": "uv-count-down", + "displayName": "uv-count-down 倒计时 全面兼容小程序、nvue、vue2、vue3等多端", + "version": "1.0.3", + "description": "该倒计时组件一般使用于某个活动的截止时间上,通过数字的变化,给用户明确的时间感受,提示用户进行某一个行为操作。", + "keywords": [ + "uv-count-down", + "uvui", + "uv-ui", + "countDown", + "倒计时" +], + "repository": "", + "engines": { + "HBuilderX": "^3.1.0" + }, + "dcloudext": { + "type": "component-vue", + "sale": { + "regular": { + "price": "0.00" + }, + "sourcecode": { + "price": "0.00" + } + }, + "contact": { + "qq": "" + }, + "declaration": { + "ads": "无", + "data": "插件不采集任何数据", + "permissions": "无" + }, + "npmurl": "" + }, + "uni_modules": { + "dependencies": [ + "uv-ui-tools" + ], + "encrypt": [], + "platforms": { + "cloud": { + "tcb": "y", + "aliyun": "y" + }, + "client": { + "Vue": { + "vue2": "y", + "vue3": "y" + }, + "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", + "钉钉": "u", + "快手": "u", + "飞书": "u", + "京东": "u" + }, + "快应用": { + "华为": "u", + "联盟": "u" + } + } + } + } +} \ No newline at end of file diff --git a/uni_modules/uv-count-down/readme.md b/uni_modules/uv-count-down/readme.md new file mode 100644 index 0000000..0f326a8 --- /dev/null +++ b/uni_modules/uv-count-down/readme.md @@ -0,0 +1,11 @@ +## CountDown 倒计时 + +> **组件名:uv-count-down** + +该组件一般使用于某个活动的截止时间上,通过数字的变化,给用户明确的时间感受,提示用户进行某一个行为操作。 + +### 查看文档 + +### [完整示例项目下载 | 关注更多组件](https://ext.dcloud.net.cn/plugin?name=uv-ui) + +#### 如使用过程中有任何问题,或者您对uv-ui有一些好的建议,欢迎加入 uv-ui 交流群:uv-ui、官方QQ群 diff --git a/uni_modules/uv-count-to/changelog.md b/uni_modules/uv-count-to/changelog.md new file mode 100644 index 0000000..cf323f9 --- /dev/null +++ b/uni_modules/uv-count-to/changelog.md @@ -0,0 +1,13 @@ +## 1.0.4(2023-06-20) +1. 优化 +## 1.0.3(2023-06-20) +1. 修复继续滚动的函数 +2. 修复其他 +## 1.0.2(2023-06-20) +1. 适配px和rpx的单位 +2. 适配customStyle参数 +## 1.0.1(2023-05-16) +1. 优化组件依赖,修改后无需全局引入,组件导入即可使用 +2. 优化部分功能 +## 1.0.0(2023-05-10) +uv-count-to 数字滚动 diff --git a/uni_modules/uv-count-to/components/uv-count-to/props.js b/uni_modules/uv-count-to/components/uv-count-to/props.js new file mode 100644 index 0000000..498371a --- /dev/null +++ b/uni_modules/uv-count-to/components/uv-count-to/props.js @@ -0,0 +1,60 @@ +export default { + props: { + // 开始的数值,默认从0增长到某一个数 + startVal: { + type: [String, Number], + default: 0 + }, + // 要滚动的目标数值,必须 + endVal: { + type: [String, Number], + default: 0 + }, + // 滚动到目标数值的动画持续时间,单位为毫秒(ms) + duration: { + type: [String, Number], + default: 2000 + }, + // 设置数值后是否自动开始滚动 + autoplay: { + type: Boolean, + default: true + }, + // 要显示的小数位数 + decimals: { + type: [String, Number], + default: 0 + }, + // 是否在即将到达目标数值的时候,使用缓慢滚动的效果 + useEasing: { + type: Boolean, + default: true + }, + // 十进制分割 + decimal: { + type: [String, Number], + default: '.' + }, + // 字体颜色 + color: { + type: String, + default: '#606266' + }, + // 字体大小 + fontSize: { + type: [String, Number], + default: 22 + }, + // 是否加粗字体 + bold: { + type: Boolean, + default: false + }, + // 千位分隔符,类似金额的分割(¥23,321.05中的",") + separator: { + type: String, + default: '' + }, + ...uni.$uv?.props?.countTo + } +} \ No newline at end of file diff --git a/uni_modules/uv-count-to/components/uv-count-to/uv-count-to.vue b/uni_modules/uv-count-to/components/uv-count-to/uv-count-to.vue new file mode 100644 index 0000000..5f34167 --- /dev/null +++ b/uni_modules/uv-count-to/components/uv-count-to/uv-count-to.vue @@ -0,0 +1,187 @@ + + + + + diff --git a/uni_modules/uv-count-to/package.json b/uni_modules/uv-count-to/package.json new file mode 100644 index 0000000..1ed07dc --- /dev/null +++ b/uni_modules/uv-count-to/package.json @@ -0,0 +1,87 @@ +{ + "id": "uv-count-to", + "displayName": "uv-count-to 数字滚动 全面兼容小程序、nvue、vue2、vue3等多端", + "version": "1.0.4", + "description": "该数字滚动组件一般用于需要滚动数字到某一个值的场景,目标要求是一个递增的值,一种数字上升的视觉冲击效果。", + "keywords": [ + "countTo", + "uvui", + "uv-ui", + "数字滚动", + "数字变化" +], + "repository": "", + "engines": { + "HBuilderX": "^3.1.0" + }, + "dcloudext": { + "type": "component-vue", + "sale": { + "regular": { + "price": "0.00" + }, + "sourcecode": { + "price": "0.00" + } + }, + "contact": { + "qq": "" + }, + "declaration": { + "ads": "无", + "data": "插件不采集任何数据", + "permissions": "无" + }, + "npmurl": "" + }, + "uni_modules": { + "dependencies": [ + "uv-ui-tools" + ], + "encrypt": [], + "platforms": { + "cloud": { + "tcb": "y", + "aliyun": "y" + }, + "client": { + "Vue": { + "vue2": "y", + "vue3": "y" + }, + "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", + "钉钉": "u", + "快手": "u", + "飞书": "u", + "京东": "u" + }, + "快应用": { + "华为": "u", + "联盟": "u" + } + } + } + } +} \ No newline at end of file diff --git a/uni_modules/uv-count-to/readme.md b/uni_modules/uv-count-to/readme.md new file mode 100644 index 0000000..5d5f996 --- /dev/null +++ b/uni_modules/uv-count-to/readme.md @@ -0,0 +1,11 @@ +## CountTo 数字滚动 + +> **组件名:uv-count-to** + +该组件一般用于需要滚动数字到某一个值的场景,目标要求是一个递增的值。 + +### 查看文档 + +### [完整示例项目下载 | 关注更多组件](https://ext.dcloud.net.cn/plugin?name=uv-ui) + +#### 如使用过程中有任何问题,或者您对uv-ui有一些好的建议,欢迎加入 uv-ui 交流群:uv-ui、官方QQ群 diff --git a/uni_modules/uv-datetime-picker/changelog.md b/uni_modules/uv-datetime-picker/changelog.md new file mode 100644 index 0000000..44784c6 --- /dev/null +++ b/uni_modules/uv-datetime-picker/changelog.md @@ -0,0 +1,28 @@ +## 1.0.12(2023-11-27) +1. 增加round圆角属性 +## 1.0.11(2023-10-11) +1. 修复设置minDate出现选择错乱的BUG +## 1.0.10(2023-09-01) +1. 增加clearDate参数,是否清除上次选择,默认false +## 1.0.9(2023-08-31) +1. 增加mode="year",方便只选择年 +## 1.0.8(2023-07-17) +1. 优化文档 +2. 优化其他 +## 1.0.7(2023-07-13) +1. 修复 uv-datetime-picker 设置value属性不生效的BUG +## 1.0.6(2023-07-05) +修复vue3模式下,动态修改v-model绑定的值无效的BUG +## 1.0.5(2023-07-02) +uv-datetime-picker 由于弹出层uv-popup的修改,打开和关闭方法更改,详情参考文档:https://www.uvui.cn/components/datetimePicker.html +## 1.0.4(2023-06-29) +1. 修复抖音小程序报错的BUG +## 1.0.3(2023-06-07) +1. 取消defaultIndex参数,传该值没实际意义,后续更新文档 +## 1.0.2(2023-06-02) +1. 修复v-model重新赋值不更新的BUG +## 1.0.1(2023-05-16) +1. 优化组件依赖,修改后无需全局引入,组件导入即可使用 +2. 优化部分功能 +## 1.0.0(2023-05-10) +uv-datetime-picker 时间选择器 diff --git a/uni_modules/uv-datetime-picker/components/uv-datetime-picker/props.js b/uni_modules/uv-datetime-picker/components/uv-datetime-picker/props.js new file mode 100644 index 0000000..6031d84 --- /dev/null +++ b/uni_modules/uv-datetime-picker/components/uv-datetime-picker/props.js @@ -0,0 +1,130 @@ +export default { + props: { + value: { + type: [String, Number], + default: '' + }, + modelValue: { + type: [String, Number], + default: '' + }, + // 是否打开组件 + show: { + type: Boolean, + default: false + }, + // 是否展示顶部的操作栏 + showToolbar: { + type: Boolean, + default: true + }, + // 顶部标题 + title: { + type: String, + default: '' + }, + // 展示格式,mode=date为日期选择,mode=time为时间选择,mode=year-month为年月选择,mode=datetime为日期时间选择 + mode: { + type: String, + default: 'datetime' + }, + // 可选的最大时间 + maxDate: { + type: Number, + // 最大默认值为后10年 + default: new Date(new Date().getFullYear() + 10, 0, 1).getTime() + }, + // 可选的最小时间 + minDate: { + type: Number, + // 最小默认值为前10年 + default: new Date(new Date().getFullYear() - 10, 0, 1).getTime() + }, + // 可选的最小小时,仅mode=time有效 + minHour: { + type: Number, + default: 0 + }, + // 可选的最大小时,仅mode=time有效 + maxHour: { + type: Number, + default: 23 + }, + // 可选的最小分钟,仅mode=time有效 + minMinute: { + type: Number, + default: 0 + }, + // 可选的最大分钟,仅mode=time有效 + maxMinute: { + type: Number, + default: 59 + }, + // 选项过滤函数 + filter: { + type: [Function, null], + default: null + }, + // 选项格式化函数 + formatter: { + type: [Function, null], + default: null + }, + // 是否显示加载中状态 + loading: { + type: Boolean, + default: false + }, + // 各列中,单个选项的高度 + itemHeight: { + type: [String, Number], + default: 44 + }, + // 取消按钮的文字 + cancelText: { + type: String, + default: '取消' + }, + // 确认按钮的文字 + confirmText: { + type: String, + default: '确认' + }, + // 取消按钮的颜色 + cancelColor: { + type: String, + default: '#909193' + }, + // 确认按钮的颜色 + confirmColor: { + type: String, + default: '#3c9cff' + }, + // 每列中可见选项的数量 + visibleItemCount: { + type: [String, Number], + default: 5 + }, + // 是否允许点击遮罩关闭选择器 + closeOnClickOverlay: { + type: Boolean, + default: true + }, + // 是否允许点击确认关闭选择器 + closeOnClickConfirm: { + type: Boolean, + default: true + }, + // 是否清空上次选择内容 + clearDate: { + type: Boolean, + default: false + }, + // 圆角 + round: { + type: [String, Number], + default: 0 + }, + ...uni.$uv?.props?.datetimePicker + } +} \ No newline at end of file diff --git a/uni_modules/uv-datetime-picker/components/uv-datetime-picker/uv-datetime-picker.vue b/uni_modules/uv-datetime-picker/components/uv-datetime-picker/uv-datetime-picker.vue new file mode 100644 index 0000000..45600dd --- /dev/null +++ b/uni_modules/uv-datetime-picker/components/uv-datetime-picker/uv-datetime-picker.vue @@ -0,0 +1,355 @@ + + \ No newline at end of file diff --git a/uni_modules/uv-datetime-picker/package.json b/uni_modules/uv-datetime-picker/package.json new file mode 100644 index 0000000..adbba14 --- /dev/null +++ b/uni_modules/uv-datetime-picker/package.json @@ -0,0 +1,88 @@ +{ + "id": "uv-datetime-picker", + "displayName": "uv-datetime-picker 时间选择器 全面兼容vue3+2、app、h5、小程序等多端", + "version": "1.0.12", + "description": "时间选择器组件用于时间日期,主要用于年月日时分的选择,具体选择的精确度由参数控制。", + "keywords": [ + "datetime-picker", + "uvui", + "uv-ui", + "datetime", + "时间选择" +], + "repository": "", + "engines": { + "HBuilderX": "^3.1.0" + }, + "dcloudext": { + "type": "component-vue", + "sale": { + "regular": { + "price": "0.00" + }, + "sourcecode": { + "price": "0.00" + } + }, + "contact": { + "qq": "" + }, + "declaration": { + "ads": "无", + "data": "插件不采集任何数据", + "permissions": "无" + }, + "npmurl": "" + }, + "uni_modules": { + "dependencies": [ + "uv-ui-tools", + "uv-picker" + ], + "encrypt": [], + "platforms": { + "cloud": { + "tcb": "y", + "aliyun": "y" + }, + "client": { + "Vue": { + "vue2": "y", + "vue3": "y" + }, + "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", + "钉钉": "u", + "快手": "u", + "飞书": "u", + "京东": "u" + }, + "快应用": { + "华为": "u", + "联盟": "u" + } + } + } + } +} \ No newline at end of file diff --git a/uni_modules/uv-datetime-picker/readme.md b/uni_modules/uv-datetime-picker/readme.md new file mode 100644 index 0000000..0db9d9c --- /dev/null +++ b/uni_modules/uv-datetime-picker/readme.md @@ -0,0 +1,19 @@ +## DatetimePicker 时间选择器 + +> **组件名:uv-datetime-picker** + +此选择器用于时间日期,主要用于年月日时分的选择,具体选择的精确度由参数控制。 + +# 查看文档 + +## [下载完整示例项目](https://ext.dcloud.net.cn/plugin?name=uv-ui) (请不要 下载插件ZIP) + +### [更多插件,请关注uv-ui组件库](https://ext.dcloud.net.cn/plugin?name=uv-ui) + + + +![image](https://mp-a667b617-c5f1-4a2d-9a54-683a67cff588.cdn.bspapp.com/uv-ui/banner.png) + + + +#### 如使用过程中有任何问题反馈,或者您对uv-ui有一些好的建议,欢迎加入uv-ui官方交流群:官方QQ群 \ No newline at end of file diff --git a/uni_modules/uv-divider/changelog.md b/uni_modules/uv-divider/changelog.md new file mode 100644 index 0000000..9ff8c52 --- /dev/null +++ b/uni_modules/uv-divider/changelog.md @@ -0,0 +1,11 @@ +## 1.0.4(2023-12-06) +1. 优化 +## 1.0.3(2023-12-06) +1. 阻止事件冒泡问题 +## 1.0.2(2023-06-01) +1. 修复点击触发两次事件的BUG +## 1.0.1(2023-05-16) +1. 优化组件依赖,修改后无需全局引入,组件导入即可使用 +2. 优化部分功能 +## 1.0.0(2023-05-10) +uv-divider 分割线 diff --git a/uni_modules/uv-divider/components/uv-divider/props.js b/uni_modules/uv-divider/components/uv-divider/props.js new file mode 100644 index 0000000..7b97c2c --- /dev/null +++ b/uni_modules/uv-divider/components/uv-divider/props.js @@ -0,0 +1,45 @@ +export default { + props: { + // 是否虚线 + dashed: { + type: Boolean, + default: false + }, + // 是否细线 + hairline: { + type: Boolean, + default: true + }, + // 是否以点替代文字,优先于text字段起作用 + dot: { + type: Boolean, + default: false + }, + // 内容文本的位置,left-左边,center-中间,right-右边 + textPosition: { + type: String, + default: 'center' + }, + // 文本内容 + text: { + type: [String, Number], + default: '' + }, + // 文本大小 + textSize: { + type: [String, Number], + default: 14 + }, + // 文本颜色 + textColor: { + type: String, + default: '#909399' + }, + // 线条颜色 + lineColor: { + type: String, + default: '#dcdfe6' + }, + ...uni.$uv?.props?.divider + } +} \ No newline at end of file diff --git a/uni_modules/uv-divider/components/uv-divider/uv-divider.vue b/uni_modules/uv-divider/components/uv-divider/uv-divider.vue new file mode 100644 index 0000000..ba0dfa7 --- /dev/null +++ b/uni_modules/uv-divider/components/uv-divider/uv-divider.vue @@ -0,0 +1,113 @@ + + + \ No newline at end of file diff --git a/uni_modules/uv-divider/package.json b/uni_modules/uv-divider/package.json new file mode 100644 index 0000000..a54b458 --- /dev/null +++ b/uni_modules/uv-divider/package.json @@ -0,0 +1,88 @@ +{ + "id": "uv-divider", + "displayName": "uv-divider 分割线 全面兼容小程序、nvue、vue2、vue3等多端", + "version": "1.0.4", + "description": "区隔内容的分割线,一般用于页面底部没有更多的提示。", + "keywords": [ + "divider", + "uvui", + "uv-ui", + "分割线", + "没有更多" +], + "repository": "", + "engines": { + "HBuilderX": "^3.1.0" + }, + "dcloudext": { + "type": "component-vue", + "sale": { + "regular": { + "price": "0.00" + }, + "sourcecode": { + "price": "0.00" + } + }, + "contact": { + "qq": "" + }, + "declaration": { + "ads": "无", + "data": "插件不采集任何数据", + "permissions": "无" + }, + "npmurl": "" + }, + "uni_modules": { + "dependencies": [ + "uv-ui-tools", + "uv-line" + ], + "encrypt": [], + "platforms": { + "cloud": { + "tcb": "y", + "aliyun": "y" + }, + "client": { + "Vue": { + "vue2": "y", + "vue3": "y" + }, + "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", + "钉钉": "u", + "快手": "u", + "飞书": "u", + "京东": "u" + }, + "快应用": { + "华为": "u", + "联盟": "u" + } + } + } + } +} \ No newline at end of file diff --git a/uni_modules/uv-divider/readme.md b/uni_modules/uv-divider/readme.md new file mode 100644 index 0000000..2384cba --- /dev/null +++ b/uni_modules/uv-divider/readme.md @@ -0,0 +1,11 @@ +## Divider 分割线 + +> **组件名:uv-divider** + +区隔内容的分割线,一般用于页面底部"没有更多"的提示。 + +### 查看文档 + +### [完整示例项目下载 | 关注更多组件](https://ext.dcloud.net.cn/plugin?name=uv-ui) + +#### 如使用过程中有任何问题,或者您对uv-ui有一些好的建议,欢迎加入 uv-ui 交流群:uv-ui、官方QQ群 diff --git a/uni_modules/uv-drop-down/changelog.md b/uni_modules/uv-drop-down/changelog.md new file mode 100644 index 0000000..637c605 --- /dev/null +++ b/uni_modules/uv-drop-down/changelog.md @@ -0,0 +1,13 @@ +## 1.0.5(2024-01-02) +1. 修复parentData不变的BUG +## 1.0.4(2023-09-28) +1. 增加uv-sticky依赖 +## 1.0.3(2023-08-29) +1. 修复自定义内容,点击自定义内容时会自动关闭弹窗的问题 +## 1.0.2(2023-08-22) +1. 优化 +## 1.0.1(2023-08-22) +1. 增加@change回调,返回弹窗关闭状态 +2. 增加init方法,方便位置改变进行调整 +## 1.0.0(2023-07-30) +新增uv-drop-down 下拉筛选组件 diff --git a/uni_modules/uv-drop-down/components/uv-drop-down-item/uv-drop-down-item.vue b/uni_modules/uv-drop-down/components/uv-drop-down-item/uv-drop-down-item.vue new file mode 100644 index 0000000..9438a57 --- /dev/null +++ b/uni_modules/uv-drop-down/components/uv-drop-down-item/uv-drop-down-item.vue @@ -0,0 +1,169 @@ + + + \ No newline at end of file diff --git a/uni_modules/uv-drop-down/components/uv-drop-down-popup/uv-drop-down-popup.vue b/uni_modules/uv-drop-down/components/uv-drop-down-popup/uv-drop-down-popup.vue new file mode 100644 index 0000000..6a1efc8 --- /dev/null +++ b/uni_modules/uv-drop-down/components/uv-drop-down-popup/uv-drop-down-popup.vue @@ -0,0 +1,242 @@ + + + \ No newline at end of file diff --git a/uni_modules/uv-drop-down/components/uv-drop-down/uv-drop-down.vue b/uni_modules/uv-drop-down/components/uv-drop-down/uv-drop-down.vue new file mode 100644 index 0000000..9978b40 --- /dev/null +++ b/uni_modules/uv-drop-down/components/uv-drop-down/uv-drop-down.vue @@ -0,0 +1,135 @@ + + + \ No newline at end of file diff --git a/uni_modules/uv-drop-down/package.json b/uni_modules/uv-drop-down/package.json new file mode 100644 index 0000000..f4ad683 --- /dev/null +++ b/uni_modules/uv-drop-down/package.json @@ -0,0 +1,91 @@ +{ + "id": "uv-drop-down", + "displayName": "uv-drop-down 下拉筛选 全面兼容vue3+2、app、h5、小程序等多端", + "version": "1.0.5", + "description": "该组件主要提供筛选下拉筛选框,内置基础筛选功能,可以根据自己的需求自定义筛选项", + "keywords": [ + "uv-drop-down", + "uvui", + "uv-ui", + "下拉筛选", + "筛选" + ], + "repository": "", + "engines": { + "HBuilderX": "^3.1.0" + }, + "dcloudext": { + "type": "component-vue", + "sale": { + "regular": { + "price": "0.00" + }, + "sourcecode": { + "price": "0.00" + } + }, + "contact": { + "qq": "" + }, + "declaration": { + "ads": "无", + "data": "插件不采集任何数据", + "permissions": "无" + }, + "npmurl": "" + }, + "uni_modules": { + "dependencies": [ + "uv-ui-tools", + "uv-icon", + "uv-text", + "uv-transition", + "uv-sticky" + ], + "encrypt": [], + "platforms": { + "cloud": { + "tcb": "y", + "aliyun": "y" + }, + "client": { + "Vue": { + "vue2": "y", + "vue3": "y" + }, + "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", + "钉钉": "u", + "快手": "u", + "飞书": "u", + "京东": "u" + }, + "快应用": { + "华为": "u", + "联盟": "u" + } + } + } + } +} \ No newline at end of file diff --git a/uni_modules/uv-drop-down/readme.md b/uni_modules/uv-drop-down/readme.md new file mode 100644 index 0000000..31cbd24 --- /dev/null +++ b/uni_modules/uv-drop-down/readme.md @@ -0,0 +1,23 @@ +## DropDown 下拉筛选 + +> **组件名:uv-drop-down** + +该组件主要提供筛选下拉筛选框,内置基础筛选功能,可以根据自己的需求自定义筛选项。 + +为了兼容app-nvue,需要内置三个组件进行配合使用,uv-drop-down属于菜单项(其实还包括子组件uv-drop-down-item),uv-drop-down-popup属于筛选框。 + +只需要做简单的约定式配置,即可使用该功能,兼容性良好,已经在多端进行了多次测试。 + +# 查看文档 + +## [下载完整示例项目](https://ext.dcloud.net.cn/plugin?name=uv-ui) (请不要 下载插件ZIP) + +### [更多插件,请关注uv-ui组件库](https://ext.dcloud.net.cn/plugin?name=uv-ui) + + + +![image](https://mp-a667b617-c5f1-4a2d-9a54-683a67cff588.cdn.bspapp.com/uv-ui/banner.png) + + + +#### 如使用过程中有任何问题反馈,或者您对uv-ui有一些好的建议,欢迎加入uv-ui官方交流群:官方QQ群 \ No newline at end of file diff --git a/uni_modules/uv-empty/changelog.md b/uni_modules/uv-empty/changelog.md new file mode 100644 index 0000000..a1cc2ad --- /dev/null +++ b/uni_modules/uv-empty/changelog.md @@ -0,0 +1,13 @@ +## 1.0.5(2023-12-20) +1. 优化 +## 1.0.4(2023-08-04) +1. icon支持base64图片 +## 1.0.3(2023-07-17) +1. 修复 uv-empty 恢复设置mode属性的内置图标 +## 1.0.2(2023-07-03) +去除插槽判断,避免某些平台不显示的BUG +## 1.0.1(2023-05-16) +1. 优化组件依赖,修改后无需全局引入,组件导入即可使用 +2. 优化部分功能 +## 1.0.0(2023-05-10) +uv-empty 内容为空 diff --git a/uni_modules/uv-empty/components/uv-empty/props.js b/uni_modules/uv-empty/components/uv-empty/props.js new file mode 100644 index 0000000..26c282d --- /dev/null +++ b/uni_modules/uv-empty/components/uv-empty/props.js @@ -0,0 +1,60 @@ +export default { + props: { + // 内置图标名称,或图片路径,建议绝对路径 + icon: { + type: String, + default: '' + }, + // 提示文字 + text: { + type: String, + default: '' + }, + // 文字颜色 + textColor: { + type: String, + default: '#c0c4cc' + }, + // 文字大小 + textSize: { + type: [String, Number], + default: 14 + }, + // 图标的颜色 + iconColor: { + type: String, + default: '#c0c4cc' + }, + // 图标的大小 + iconSize: { + type: [String, Number], + default: 90 + }, + // 选择预置的图标类型 + mode: { + type: String, + default: 'data' + }, + // 图标宽度,单位px + width: { + type: [String, Number], + default: 160 + }, + // 图标高度,单位px + height: { + type: [String, Number], + default: 160 + }, + // 是否显示组件 + show: { + type: Boolean, + default: true + }, + // 组件距离上一个元素之间的距离,默认px单位 + marginTop: { + type: [String, Number], + default: 0 + }, + ...uni.$uv?.props?.empty + } +} \ No newline at end of file diff --git a/uni_modules/uv-empty/components/uv-empty/uv-empty.vue b/uni_modules/uv-empty/components/uv-empty/uv-empty.vue new file mode 100644 index 0000000..22a9264 --- /dev/null +++ b/uni_modules/uv-empty/components/uv-empty/uv-empty.vue @@ -0,0 +1,126 @@ + + + \ No newline at end of file diff --git a/uni_modules/uv-empty/package.json b/uni_modules/uv-empty/package.json new file mode 100644 index 0000000..e10f451 --- /dev/null +++ b/uni_modules/uv-empty/package.json @@ -0,0 +1,88 @@ +{ + "id": "uv-empty", + "displayName": "uv-empty 内容为空 全面兼容vue3+2、app、h5、小程序等多端", + "version": "1.0.5", + "description": "该组件用于需要加载内容,但是加载的第一页数据就为空,提示一个 没有内容 的场景, 我们精心挑选了十几个场景的图标,方便您使用。", + "keywords": [ + "empty", + "uvui", + "uv-ui", + "空数据", + "暂无数据" +], + "repository": "", + "engines": { + "HBuilderX": "^3.1.0" + }, + "dcloudext": { + "type": "component-vue", + "sale": { + "regular": { + "price": "0.00" + }, + "sourcecode": { + "price": "0.00" + } + }, + "contact": { + "qq": "" + }, + "declaration": { + "ads": "无", + "data": "插件不采集任何数据", + "permissions": "无" + }, + "npmurl": "" + }, + "uni_modules": { + "dependencies": [ + "uv-ui-tools", + "uv-icon" + ], + "encrypt": [], + "platforms": { + "cloud": { + "tcb": "y", + "aliyun": "y" + }, + "client": { + "Vue": { + "vue2": "y", + "vue3": "y" + }, + "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", + "钉钉": "u", + "快手": "u", + "飞书": "u", + "京东": "u" + }, + "快应用": { + "华为": "u", + "联盟": "u" + } + } + } + } +} \ No newline at end of file diff --git a/uni_modules/uv-empty/readme.md b/uni_modules/uv-empty/readme.md new file mode 100644 index 0000000..ecef14d --- /dev/null +++ b/uni_modules/uv-empty/readme.md @@ -0,0 +1,19 @@ +## Empty 内容为空 + +> **组件名:uv-empty** + +该组件用于需要加载内容,但是加载的第一页数据就为空,提示一个"没有内容"的场景, 我们精心挑选了十几个场景的图标,方便您使用。 + +# 查看文档 + +## [下载完整示例项目](https://ext.dcloud.net.cn/plugin?name=uv-ui) (请不要 下载插件ZIP) + +### [更多插件,请关注uv-ui组件库](https://ext.dcloud.net.cn/plugin?name=uv-ui) + + + +![image](https://mp-a667b617-c5f1-4a2d-9a54-683a67cff588.cdn.bspapp.com/uv-ui/banner.png) + + + +#### 如使用过程中有任何问题反馈,或者您对uv-ui有一些好的建议,欢迎加入uv-ui官方交流群:官方QQ群 \ No newline at end of file diff --git a/uni_modules/uv-form/changelog.md b/uni_modules/uv-form/changelog.md new file mode 100644 index 0000000..b229bca --- /dev/null +++ b/uni_modules/uv-form/changelog.md @@ -0,0 +1,23 @@ +## 1.0.9(2023-08-14) +1. 修复设置labelWidth属性时,节点渲染有闪动的BUG +## 1.0.8(2023-08-13) +1. 修复未设置rules的情况下报错的BUG +2. 优化错误提示 +## 1.0.7(2023-08-10) +1. 修复在vue3+setup语法糖中错误文字动画错乱 +## 1.0.6(2023-07-17) +1. 优化文档 +2. 优化其他 +## 1.0.5(2023-07-03) +去除插槽判断,避免某些平台不显示的BUG +## 1.0.4(2023-07-02) +uv-form 由于弹出层uv-transition的修改,组件内部做了相应的修改,参数不变。 +## 1.0.3(2023-06-18) +1. 修改某些情况下的BUG +## 1.0.2(2023-06-15) +1. 修复支付宝报错的BUG +## 1.0.1(2023-05-16) +1. 优化组件依赖,修改后无需全局引入,组件导入即可使用 +2. 优化部分功能 +## 1.0.0(2023-05-10) +uv-form 表单 diff --git a/uni_modules/uv-form/components/uv-form-item/props.js b/uni_modules/uv-form/components/uv-form-item/props.js new file mode 100644 index 0000000..00a26bc --- /dev/null +++ b/uni_modules/uv-form/components/uv-form-item/props.js @@ -0,0 +1,49 @@ +export default { + props: { + // input的label提示语 + label: { + type: String, + default: '' + }, + // 绑定的值 + prop: { + type: String, + default: '' + }, + // 是否显示表单域的下划线边框 + borderBottom: { + type: [Boolean], + default: false + }, + // label的位置,left-左边,top-上边 + labelPosition: { + type: String, + default: '' + }, + // label的宽度,单位px + labelWidth: { + type: [String, Number], + default: '' + }, + // 右侧图标 + rightIcon: { + type: String, + default: '' + }, + // 左侧图标 + leftIcon: { + type: String, + default: '' + }, + // 是否显示左边的必填星号,只作显示用,具体校验必填的逻辑,请在rules中配置 + required: { + type: Boolean, + default: false + }, + leftIconStyle: { + type: [String, Object], + default: '' + }, + ...uni.$uv?.props?.formItem + } +} \ No newline at end of file diff --git a/uni_modules/uv-form/components/uv-form-item/uv-form-item.vue b/uni_modules/uv-form/components/uv-form-item/uv-form-item.vue new file mode 100644 index 0000000..25d93ea --- /dev/null +++ b/uni_modules/uv-form/components/uv-form-item/uv-form-item.vue @@ -0,0 +1,226 @@ + + + + \ No newline at end of file diff --git a/uni_modules/uv-form/components/uv-form/props.js b/uni_modules/uv-form/components/uv-form/props.js new file mode 100644 index 0000000..6cffb95 --- /dev/null +++ b/uni_modules/uv-form/components/uv-form/props.js @@ -0,0 +1,46 @@ +export default { + props: { + // 当前form的需要验证字段的集合 + model: { + type: Object, + default: () => ({}) + }, + // 验证规则 + rules: { + type: [Object, Function, Array], + default: () => ({}) + }, + // 有错误时的提示方式,message-提示信息,toast-进行toast提示 + // border-bottom-下边框呈现红色,none-无提示 + errorType: { + type: String, + default: 'message' + }, + // 是否显示表单域的下划线边框 + borderBottom: { + type: Boolean, + default: true + }, + // label的位置,left-左边,top-上边 + labelPosition: { + type: String, + default: 'left' + }, + // label的宽度,单位px + labelWidth: { + type: [String, Number], + default: 45 + }, + // lable字体的对齐方式 + labelAlign: { + type: String, + default: 'left' + }, + // lable的样式,对象形式 + labelStyle: { + type: Object, + default: () => ({}) + }, + ...uni.$uv?.props?.form + } +} \ No newline at end of file diff --git a/uni_modules/uv-form/components/uv-form/uv-form.vue b/uni_modules/uv-form/components/uv-form/uv-form.vue new file mode 100644 index 0000000..bc0876f --- /dev/null +++ b/uni_modules/uv-form/components/uv-form/uv-form.vue @@ -0,0 +1,209 @@ + + + \ No newline at end of file diff --git a/uni_modules/uv-form/components/uv-form/valid.js b/uni_modules/uv-form/components/uv-form/valid.js new file mode 100644 index 0000000..9e114df --- /dev/null +++ b/uni_modules/uv-form/components/uv-form/valid.js @@ -0,0 +1,1343 @@ +function _extends() { + _extends = Object.assign || function (target) { + for (let i = 1; i < arguments.length; i++) { + const source = arguments[i] + + for (const key in source) { + if (Object.prototype.hasOwnProperty.call(source, key)) { + target[key] = source[key] + } + } + } + + return target + } + + return _extends.apply(this, arguments) +} + +/* eslint no-console:0 */ +const formatRegExp = /%[sdj%]/g +let warning = function warning() {} // don't print warning message when in production env or node runtime + +if (typeof process !== 'undefined' && process.env && process.env.NODE_ENV !== 'production' && typeof window + !== 'undefined' && typeof document !== 'undefined') { + warning = function warning(type, errors) { + if (typeof console !== 'undefined' && console.warn) { + if (errors.every((e) => typeof e === 'string')) { + console.warn(type, errors) + } + } + } +} + +function convertFieldsError(errors) { + if (!errors || !errors.length) return null + const fields = {} + errors.forEach((error) => { + const { field } = error + fields[field] = fields[field] || [] + fields[field].push(error) + }) + return fields +} + +function format() { + for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { + args[_key] = arguments[_key] + } + + let i = 1 + const f = args[0] + const len = args.length + + if (typeof f === 'function') { + return f.apply(null, args.slice(1)) + } + + if (typeof f === 'string') { + let str = String(f).replace(formatRegExp, (x) => { + if (x === '%%') { + return '%' + } + + if (i >= len) { + return x + } + + switch (x) { + case '%s': + return String(args[i++]) + + case '%d': + return Number(args[i++]) + + case '%j': + try { + return JSON.stringify(args[i++]) + } catch (_) { + return '[Circular]' + } + + break + + default: + return x + } + }) + + for (let arg = args[i]; i < len; arg = args[++i]) { + str += ` ${arg}` + } + + return str + } + + return f +} + +function isNativeStringType(type) { + return type === 'string' || type === 'url' || type === 'hex' || type === 'email' || type === 'pattern' +} + +function isEmptyValue(value, type) { + if (value === undefined || value === null) { + return true + } + + if (type === 'array' && Array.isArray(value) && !value.length) { + return true + } + + if (isNativeStringType(type) && typeof value === 'string' && !value) { + return true + } + + return false +} + +function asyncParallelArray(arr, func, callback) { + const results = [] + let total = 0 + const arrLength = arr.length + + function count(errors) { + results.push.apply(results, errors) + total++ + + if (total === arrLength) { + callback(results) + } + } + + arr.forEach((a) => { + func(a, count) + }) +} + +function asyncSerialArray(arr, func, callback) { + let index = 0 + const arrLength = arr.length + + function next(errors) { + if (errors && errors.length) { + callback(errors) + return + } + + const original = index + index += 1 + + if (original < arrLength) { + func(arr[original], next) + } else { + callback([]) + } + } + + next([]) +} + +function flattenObjArr(objArr) { + const ret = [] + Object.keys(objArr).forEach((k) => { + ret.push.apply(ret, objArr[k]) + }) + return ret +} + +function asyncMap(objArr, option, func, callback) { + if (option.first) { + const _pending = new Promise((resolve, reject) => { + const next = function next(errors) { + callback(errors) + return errors.length ? reject({ + errors, + fields: convertFieldsError(errors) + }) : resolve() + } + + const flattenArr = flattenObjArr(objArr) + asyncSerialArray(flattenArr, func, next) + }) + + _pending.catch((e) => e) + + return _pending + } + + let firstFields = option.firstFields || [] + + if (firstFields === true) { + firstFields = Object.keys(objArr) + } + + const objArrKeys = Object.keys(objArr) + const objArrLength = objArrKeys.length + let total = 0 + const results = [] + const pending = new Promise((resolve, reject) => { + const next = function next(errors) { + results.push.apply(results, errors) + total++ + + if (total === objArrLength) { + callback(results) + return results.length ? reject({ + errors: results, + fields: convertFieldsError(results) + }) : resolve() + } + } + + if (!objArrKeys.length) { + callback(results) + resolve() + } + + objArrKeys.forEach((key) => { + const arr = objArr[key] + + if (firstFields.indexOf(key) !== -1) { + asyncSerialArray(arr, func, next) + } else { + asyncParallelArray(arr, func, next) + } + }) + }) + pending.catch((e) => e) + return pending +} + +function complementError(rule) { + return function (oe) { + if (oe && oe.message) { + oe.field = oe.field || rule.fullField + return oe + } + + return { + message: typeof oe === 'function' ? oe() : oe, + field: oe.field || rule.fullField + } + } +} + +function deepMerge(target, source) { + if (source) { + for (const s in source) { + if (source.hasOwnProperty(s)) { + const value = source[s] + + if (typeof value === 'object' && typeof target[s] === 'object') { + target[s] = { ...target[s], ...value } + } else { + target[s] = value + } + } + } + } + + return target +} + +/** + * Rule for validating required fields. + * + * @param rule The validation rule. + * @param value The value of the field on the source object. + * @param source The source object being validated. + * @param errors An array of errors that this rule may add + * validation errors to. + * @param options The validation options. + * @param options.messages The validation messages. + */ + +function required(rule, value, source, errors, options, type) { + if (rule.required && (!source.hasOwnProperty(rule.field) || isEmptyValue(value, type || rule.type))) { + errors.push(format(options.messages.required, rule.fullField)) + } +} + +/** + * Rule for validating whitespace. + * + * @param rule The validation rule. + * @param value The value of the field on the source object. + * @param source The source object being validated. + * @param errors An array of errors that this rule may add + * validation errors to. + * @param options The validation options. + * @param options.messages The validation messages. + */ + +function whitespace(rule, value, source, errors, options) { + if (/^\s+$/.test(value) || value === '') { + errors.push(format(options.messages.whitespace, rule.fullField)) + } +} + +/* eslint max-len:0 */ + +const pattern = { + // http://emailregex.com/ + email: /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/, + url: new RegExp( + '^(?!mailto:)(?:(?:http|https|ftp)://|//)(?:\\S+(?::\\S*)?@)?(?:(?:(?:[1-9]\\d?|1\\d\\d|2[01]\\d|22[0-3])(?:\\.(?:1?\\d{1,2}|2[0-4]\\d|25[0-5])){2}(?:\\.(?:[0-9]\\d?|1\\d\\d|2[0-4]\\d|25[0-4]))|(?:(?:[a-z\\u00a1-\\uffff0-9]+-*)*[a-z\\u00a1-\\uffff0-9]+)(?:\\.(?:[a-z\\u00a1-\\uffff0-9]+-*)*[a-z\\u00a1-\\uffff0-9]+)*(?:\\.(?:[a-z\\u00a1-\\uffff]{2,})))|localhost)(?::\\d{2,5})?(?:(/|\\?|#)[^\\s]*)?$', + 'i' + ), + hex: /^#?([a-f0-9]{6}|[a-f0-9]{3})$/i +} +var types = { + integer: function integer(value) { + return /^(-)?\d+$/.test(value); + }, + float: function float(value) { + return /^(-)?\d+(\.\d+)?$/.test(value); + }, + array: function array(value) { + return Array.isArray(value) + }, + regexp: function regexp(value) { + if (value instanceof RegExp) { + return true + } + + try { + return !!new RegExp(value) + } catch (e) { + return false + } + }, + date: function date(value) { + return typeof value.getTime === 'function' && typeof value.getMonth === 'function' && typeof value.getYear + === 'function' + }, + number: function number(value) { + if (isNaN(value)) { + return false + } + + // 修改源码,将字符串数值先转为数值 + return typeof +value === 'number' + }, + object: function object(value) { + return typeof value === 'object' && !types.array(value) + }, + method: function method(value) { + return typeof value === 'function' + }, + email: function email(value) { + return typeof value === 'string' && !!value.match(pattern.email) && value.length < 255 + }, + url: function url(value) { + return typeof value === 'string' && !!value.match(pattern.url) + }, + hex: function hex(value) { + return typeof value === 'string' && !!value.match(pattern.hex) + } +} +/** + * Rule for validating the type of a value. + * + * @param rule The validation rule. + * @param value The value of the field on the source object. + * @param source The source object being validated. + * @param errors An array of errors that this rule may add + * validation errors to. + * @param options The validation options. + * @param options.messages The validation messages. + */ + +function type(rule, value, source, errors, options) { + if (rule.required && value === undefined) { + required(rule, value, source, errors, options) + return + } + + const custom = ['integer', 'float', 'array', 'regexp', 'object', 'method', 'email', 'number', 'date', 'url', 'hex'] + const ruleType = rule.type + + if (custom.indexOf(ruleType) > -1) { + if (!types[ruleType](value)) { + errors.push(format(options.messages.types[ruleType], rule.fullField, rule.type)) + } // straight typeof check + } else if (ruleType && typeof value !== rule.type) { + errors.push(format(options.messages.types[ruleType], rule.fullField, rule.type)) + } +} + +/** + * Rule for validating minimum and maximum allowed values. + * + * @param rule The validation rule. + * @param value The value of the field on the source object. + * @param source The source object being validated. + * @param errors An array of errors that this rule may add + * validation errors to. + * @param options The validation options. + * @param options.messages The validation messages. + */ + +function range(rule, value, source, errors, options) { + const len = typeof rule.len === 'number' + const min = typeof rule.min === 'number' + const max = typeof rule.max === 'number' // 正则匹配码点范围从U+010000一直到U+10FFFF的文字(补充平面Supplementary Plane) + + const spRegexp = /[\uD800-\uDBFF][\uDC00-\uDFFF]/g + let val = value + let key = null + const num = typeof value === 'number' + const str = typeof value === 'string' + const arr = Array.isArray(value) + + if (num) { + key = 'number' + } else if (str) { + key = 'string' + } else if (arr) { + key = 'array' + } // if the value is not of a supported type for range validation + // the validation rule rule should use the + // type property to also test for a particular type + + if (!key) { + return false + } + + if (arr) { + val = value.length + } + + if (str) { + // 处理码点大于U+010000的文字length属性不准确的bug,如"𠮷𠮷𠮷".lenght !== 3 + val = value.replace(spRegexp, '_').length + } + + if (len) { + if (val !== rule.len) { + errors.push(format(options.messages[key].len, rule.fullField, rule.len)) + } + } else if (min && !max && val < rule.min) { + errors.push(format(options.messages[key].min, rule.fullField, rule.min)) + } else if (max && !min && val > rule.max) { + errors.push(format(options.messages[key].max, rule.fullField, rule.max)) + } else if (min && max && (val < rule.min || val > rule.max)) { + errors.push(format(options.messages[key].range, rule.fullField, rule.min, rule.max)) + } +} + +const ENUM = 'enum' +/** + * Rule for validating a value exists in an enumerable list. + * + * @param rule The validation rule. + * @param value The value of the field on the source object. + * @param source The source object being validated. + * @param errors An array of errors that this rule may add + * validation errors to. + * @param options The validation options. + * @param options.messages The validation messages. + */ + +function enumerable(rule, value, source, errors, options) { + rule[ENUM] = Array.isArray(rule[ENUM]) ? rule[ENUM] : [] + + if (rule[ENUM].indexOf(value) === -1) { + errors.push(format(options.messages[ENUM], rule.fullField, rule[ENUM].join(', '))) + } +} + +/** + * Rule for validating a regular expression pattern. + * + * @param rule The validation rule. + * @param value The value of the field on the source object. + * @param source The source object being validated. + * @param errors An array of errors that this rule may add + * validation errors to. + * @param options The validation options. + * @param options.messages The validation messages. + */ + +function pattern$1(rule, value, source, errors, options) { + if (rule.pattern) { + if (rule.pattern instanceof RegExp) { + // if a RegExp instance is passed, reset `lastIndex` in case its `global` + // flag is accidentally set to `true`, which in a validation scenario + // is not necessary and the result might be misleading + rule.pattern.lastIndex = 0 + + if (!rule.pattern.test(value)) { + errors.push(format(options.messages.pattern.mismatch, rule.fullField, value, rule.pattern)) + } + } else if (typeof rule.pattern === 'string') { + const _pattern = new RegExp(rule.pattern) + + if (!_pattern.test(value)) { + errors.push(format(options.messages.pattern.mismatch, rule.fullField, value, rule.pattern)) + } + } + } +} + +const rules = { + required, + whitespace, + type, + range, + enum: enumerable, + pattern: pattern$1 +} + +/** + * Performs validation for string types. + * + * @param rule The validation rule. + * @param value The value of the field on the source object. + * @param callback The callback function. + * @param source The source object being validated. + * @param options The validation options. + * @param options.messages The validation messages. + */ + +function string(rule, value, callback, source, options) { + const errors = [] + const validate = rule.required || !rule.required && source.hasOwnProperty(rule.field) + + if (validate) { + if (isEmptyValue(value, 'string') && !rule.required) { + return callback() + } + + rules.required(rule, value, source, errors, options, 'string') + + if (!isEmptyValue(value, 'string')) { + rules.type(rule, value, source, errors, options) + rules.range(rule, value, source, errors, options) + rules.pattern(rule, value, source, errors, options) + + if (rule.whitespace === true) { + rules.whitespace(rule, value, source, errors, options) + } + } + } + + callback(errors) +} + +/** + * Validates a function. + * + * @param rule The validation rule. + * @param value The value of the field on the source object. + * @param callback The callback function. + * @param source The source object being validated. + * @param options The validation options. + * @param options.messages The validation messages. + */ + +function method(rule, value, callback, source, options) { + const errors = [] + const validate = rule.required || !rule.required && source.hasOwnProperty(rule.field) + + if (validate) { + if (isEmptyValue(value) && !rule.required) { + return callback() + } + + rules.required(rule, value, source, errors, options) + + if (value !== undefined) { + rules.type(rule, value, source, errors, options) + } + } + + callback(errors) +} + +/** + * Validates a number. + * + * @param rule The validation rule. + * @param value The value of the field on the source object. + * @param callback The callback function. + * @param source The source object being validated. + * @param options The validation options. + * @param options.messages The validation messages. + */ + +function number(rule, value, callback, source, options) { + const errors = [] + const validate = rule.required || !rule.required && source.hasOwnProperty(rule.field) + + if (validate) { + if (value === '') { + value = undefined + } + + if (isEmptyValue(value) && !rule.required) { + return callback() + } + + rules.required(rule, value, source, errors, options) + + if (value !== undefined) { + rules.type(rule, value, source, errors, options) + rules.range(rule, value, source, errors, options) + } + } + + callback(errors) +} + +/** + * Validates a boolean. + * + * @param rule The validation rule. + * @param value The value of the field on the source object. + * @param callback The callback function. + * @param source The source object being validated. + * @param options The validation options. + * @param options.messages The validation messages. + */ + +function _boolean(rule, value, callback, source, options) { + const errors = [] + const validate = rule.required || !rule.required && source.hasOwnProperty(rule.field) + + if (validate) { + if (isEmptyValue(value) && !rule.required) { + return callback() + } + + rules.required(rule, value, source, errors, options) + + if (value !== undefined) { + rules.type(rule, value, source, errors, options) + } + } + + callback(errors) +} + +/** + * Validates the regular expression type. + * + * @param rule The validation rule. + * @param value The value of the field on the source object. + * @param callback The callback function. + * @param source The source object being validated. + * @param options The validation options. + * @param options.messages The validation messages. + */ + +function regexp(rule, value, callback, source, options) { + const errors = [] + const validate = rule.required || !rule.required && source.hasOwnProperty(rule.field) + + if (validate) { + if (isEmptyValue(value) && !rule.required) { + return callback() + } + + rules.required(rule, value, source, errors, options) + + if (!isEmptyValue(value)) { + rules.type(rule, value, source, errors, options) + } + } + + callback(errors) +} + +/** + * Validates a number is an integer. + * + * @param rule The validation rule. + * @param value The value of the field on the source object. + * @param callback The callback function. + * @param source The source object being validated. + * @param options The validation options. + * @param options.messages The validation messages. + */ + +function integer(rule, value, callback, source, options) { + const errors = [] + const validate = rule.required || !rule.required && source.hasOwnProperty(rule.field) + + if (validate) { + if (isEmptyValue(value) && !rule.required) { + return callback() + } + + rules.required(rule, value, source, errors, options) + + if (value !== undefined) { + rules.type(rule, value, source, errors, options) + rules.range(rule, value, source, errors, options) + } + } + + callback(errors) +} + +/** + * Validates a number is a floating point number. + * + * @param rule The validation rule. + * @param value The value of the field on the source object. + * @param callback The callback function. + * @param source The source object being validated. + * @param options The validation options. + * @param options.messages The validation messages. + */ + +function floatFn(rule, value, callback, source, options) { + const errors = [] + const validate = rule.required || !rule.required && source.hasOwnProperty(rule.field) + + if (validate) { + if (isEmptyValue(value) && !rule.required) { + return callback() + } + + rules.required(rule, value, source, errors, options) + + if (value !== undefined) { + rules.type(rule, value, source, errors, options) + rules.range(rule, value, source, errors, options) + } + } + + callback(errors) +} + +/** + * Validates an array. + * + * @param rule The validation rule. + * @param value The value of the field on the source object. + * @param callback The callback function. + * @param source The source object being validated. + * @param options The validation options. + * @param options.messages The validation messages. + */ + +function array(rule, value, callback, source, options) { + const errors = [] + const validate = rule.required || !rule.required && source.hasOwnProperty(rule.field) + + if (validate) { + if (isEmptyValue(value, 'array') && !rule.required) { + return callback() + } + + rules.required(rule, value, source, errors, options, 'array') + + if (!isEmptyValue(value, 'array')) { + rules.type(rule, value, source, errors, options) + rules.range(rule, value, source, errors, options) + } + } + + callback(errors) +} + +/** + * Validates an object. + * + * @param rule The validation rule. + * @param value The value of the field on the source object. + * @param callback The callback function. + * @param source The source object being validated. + * @param options The validation options. + * @param options.messages The validation messages. + */ + +function object(rule, value, callback, source, options) { + const errors = [] + const validate = rule.required || !rule.required && source.hasOwnProperty(rule.field) + + if (validate) { + if (isEmptyValue(value) && !rule.required) { + return callback() + } + + rules.required(rule, value, source, errors, options) + + if (value !== undefined) { + rules.type(rule, value, source, errors, options) + } + } + + callback(errors) +} + +const ENUM$1 = 'enum' +/** + * Validates an enumerable list. + * + * @param rule The validation rule. + * @param value The value of the field on the source object. + * @param callback The callback function. + * @param source The source object being validated. + * @param options The validation options. + * @param options.messages The validation messages. + */ + +function enumerable$1(rule, value, callback, source, options) { + const errors = [] + const validate = rule.required || !rule.required && source.hasOwnProperty(rule.field) + + if (validate) { + if (isEmptyValue(value) && !rule.required) { + return callback() + } + + rules.required(rule, value, source, errors, options) + + if (value !== undefined) { + rules[ENUM$1](rule, value, source, errors, options) + } + } + + callback(errors) +} + +/** + * Validates a regular expression pattern. + * + * Performs validation when a rule only contains + * a pattern property but is not declared as a string type. + * + * @param rule The validation rule. + * @param value The value of the field on the source object. + * @param callback The callback function. + * @param source The source object being validated. + * @param options The validation options. + * @param options.messages The validation messages. + */ + +function pattern$2(rule, value, callback, source, options) { + const errors = [] + const validate = rule.required || !rule.required && source.hasOwnProperty(rule.field) + + if (validate) { + if (isEmptyValue(value, 'string') && !rule.required) { + return callback() + } + + rules.required(rule, value, source, errors, options) + + if (!isEmptyValue(value, 'string')) { + rules.pattern(rule, value, source, errors, options) + } + } + + callback(errors) +} + +function date(rule, value, callback, source, options) { + const errors = [] + const validate = rule.required || !rule.required && source.hasOwnProperty(rule.field) + + if (validate) { + if (isEmptyValue(value) && !rule.required) { + return callback() + } + + rules.required(rule, value, source, errors, options) + + if (!isEmptyValue(value)) { + let dateObject + + if (typeof value === 'number') { + dateObject = new Date(value) + } else { + dateObject = value + } + + rules.type(rule, dateObject, source, errors, options) + + if (dateObject) { + rules.range(rule, dateObject.getTime(), source, errors, options) + } + } + } + + callback(errors) +} + +function required$1(rule, value, callback, source, options) { + const errors = [] + const type = Array.isArray(value) ? 'array' : typeof value + rules.required(rule, value, source, errors, options, type) + callback(errors) +} + +function type$1(rule, value, callback, source, options) { + const ruleType = rule.type + const errors = [] + const validate = rule.required || !rule.required && source.hasOwnProperty(rule.field) + + if (validate) { + if (isEmptyValue(value, ruleType) && !rule.required) { + return callback() + } + + rules.required(rule, value, source, errors, options, ruleType) + + if (!isEmptyValue(value, ruleType)) { + rules.type(rule, value, source, errors, options) + } + } + + callback(errors) +} + +/** + * Performs validation for any type. + * + * @param rule The validation rule. + * @param value The value of the field on the source object. + * @param callback The callback function. + * @param source The source object being validated. + * @param options The validation options. + * @param options.messages The validation messages. + */ + +function any(rule, value, callback, source, options) { + const errors = [] + const validate = rule.required || !rule.required && source.hasOwnProperty(rule.field) + + if (validate) { + if (isEmptyValue(value) && !rule.required) { + return callback() + } + + rules.required(rule, value, source, errors, options) + } + + callback(errors) +} + +const validators = { + string, + method, + number, + boolean: _boolean, + regexp, + integer, + float: floatFn, + array, + object, + enum: enumerable$1, + pattern: pattern$2, + date, + url: type$1, + hex: type$1, + email: type$1, + required: required$1, + any +} + +function newMessages() { + return { + default: 'Validation error on field %s', + required: '%s is required', + enum: '%s must be one of %s', + whitespace: '%s cannot be empty', + date: { + format: '%s date %s is invalid for format %s', + parse: '%s date could not be parsed, %s is invalid ', + invalid: '%s date %s is invalid' + }, + types: { + string: '%s is not a %s', + method: '%s is not a %s (function)', + array: '%s is not an %s', + object: '%s is not an %s', + number: '%s is not a %s', + date: '%s is not a %s', + boolean: '%s is not a %s', + integer: '%s is not an %s', + float: '%s is not a %s', + regexp: '%s is not a valid %s', + email: '%s is not a valid %s', + url: '%s is not a valid %s', + hex: '%s is not a valid %s' + }, + string: { + len: '%s must be exactly %s characters', + min: '%s must be at least %s characters', + max: '%s cannot be longer than %s characters', + range: '%s must be between %s and %s characters' + }, + number: { + len: '%s must equal %s', + min: '%s cannot be less than %s', + max: '%s cannot be greater than %s', + range: '%s must be between %s and %s' + }, + array: { + len: '%s must be exactly %s in length', + min: '%s cannot be less than %s in length', + max: '%s cannot be greater than %s in length', + range: '%s must be between %s and %s in length' + }, + pattern: { + mismatch: '%s value %s does not match pattern %s' + }, + clone: function clone() { + const cloned = JSON.parse(JSON.stringify(this)) + cloned.clone = this.clone + return cloned + } + } +} +const messages = newMessages() + +/** + * Encapsulates a validation schema. + * + * @param descriptor An object declaring validation rules + * for this schema. + */ + +function Schema(descriptor) { + this.rules = null + this._messages = messages + this.define(descriptor) +} + +Schema.prototype = { + messages: function messages(_messages) { + if (_messages) { + this._messages = deepMerge(newMessages(), _messages) + } + + return this._messages + }, + define: function define(rules) { + if (!rules) { + throw new Error('Cannot configure a schema with no rules') + } + + if (typeof rules !== 'object' || Array.isArray(rules)) { + throw new Error('Rules must be an object') + } + + this.rules = {} + let z + let item + + for (z in rules) { + if (rules.hasOwnProperty(z)) { + item = rules[z] + this.rules[z] = Array.isArray(item) ? item : [item] + } + } + }, + validate: function validate(source_, o, oc) { + const _this = this + + if (o === void 0) { + o = {} + } + + if (oc === void 0) { + oc = function oc() {} + } + + let source = source_ + let options = o + let callback = oc + + if (typeof options === 'function') { + callback = options + options = {} + } + + if (!this.rules || Object.keys(this.rules).length === 0) { + if (callback) { + callback() + } + + return Promise.resolve() + } + + function complete(results) { + let i + let errors = [] + let fields = {} + + function add(e) { + if (Array.isArray(e)) { + let _errors + + errors = (_errors = errors).concat.apply(_errors, e) + } else { + errors.push(e) + } + } + + for (i = 0; i < results.length; i++) { + add(results[i]) + } + + if (!errors.length) { + errors = null + fields = null + } else { + fields = convertFieldsError(errors) + } + + callback(errors, fields) + } + + if (options.messages) { + let messages$1 = this.messages() + + if (messages$1 === messages) { + messages$1 = newMessages() + } + + deepMerge(messages$1, options.messages) + options.messages = messages$1 + } else { + options.messages = this.messages() + } + + let arr + let value + const series = {} + const keys = options.keys || Object.keys(this.rules) + keys.forEach((z) => { + arr = _this.rules[z] + value = source[z] + arr.forEach((r) => { + let rule = r + + if (typeof rule.transform === 'function') { + if (source === source_) { + source = { ...source } + } + + value = source[z] = rule.transform(value) + } + + if (typeof rule === 'function') { + rule = { + validator: rule + } + } else { + rule = { ...rule } + } + + rule.validator = _this.getValidationMethod(rule) + rule.field = z + rule.fullField = rule.fullField || z + rule.type = _this.getType(rule) + + if (!rule.validator) { + return + } + + series[z] = series[z] || [] + series[z].push({ + rule, + value, + source, + field: z + }) + }) + }) + const errorFields = {} + return asyncMap(series, options, (data, doIt) => { + const { rule } = data + let deep = (rule.type === 'object' || rule.type === 'array') && (typeof rule.fields === 'object' || typeof rule.defaultField + === 'object') + deep = deep && (rule.required || !rule.required && data.value) + rule.field = data.field + + function addFullfield(key, schema) { + return { ...schema, fullField: `${rule.fullField}.${key}` } + } + + function cb(e) { + if (e === void 0) { + e = [] + } + + let errors = e + + if (!Array.isArray(errors)) { + errors = [errors] + } + + if (!options.suppressWarning && errors.length) { + Schema.warning('async-validator:', errors) + } + + if (errors.length && rule.message) { + errors = [].concat(rule.message) + } + + errors = errors.map(complementError(rule)) + + if (options.first && errors.length) { + errorFields[rule.field] = 1 + return doIt(errors) + } + + if (!deep) { + doIt(errors) + } else { + // if rule is required but the target object + // does not exist fail at the rule level and don't + // go deeper + if (rule.required && !data.value) { + if (rule.message) { + errors = [].concat(rule.message).map(complementError(rule)) + } else if (options.error) { + errors = [options.error(rule, format(options.messages.required, rule.field))] + } else { + errors = [] + } + + return doIt(errors) + } + + let fieldsSchema = {} + + if (rule.defaultField) { + for (const k in data.value) { + if (data.value.hasOwnProperty(k)) { + fieldsSchema[k] = rule.defaultField + } + } + } + + fieldsSchema = { ...fieldsSchema, ...data.rule.fields } + + for (const f in fieldsSchema) { + if (fieldsSchema.hasOwnProperty(f)) { + const fieldSchema = Array.isArray(fieldsSchema[f]) ? fieldsSchema[f] : [fieldsSchema[f]] + fieldsSchema[f] = fieldSchema.map(addFullfield.bind(null, f)) + } + } + + const schema = new Schema(fieldsSchema) + schema.messages(options.messages) + + if (data.rule.options) { + data.rule.options.messages = options.messages + data.rule.options.error = options.error + } + + schema.validate(data.value, data.rule.options || options, (errs) => { + const finalErrors = [] + + if (errors && errors.length) { + finalErrors.push.apply(finalErrors, errors) + } + + if (errs && errs.length) { + finalErrors.push.apply(finalErrors, errs) + } + + doIt(finalErrors.length ? finalErrors : null) + }) + } + } + + let res + + if (rule.asyncValidator) { + res = rule.asyncValidator(rule, data.value, cb, data.source, options) + } else if (rule.validator) { + res = rule.validator(rule, data.value, cb, data.source, options) + + if (res === true) { + cb() + } else if (res === false) { + cb(rule.message || `${rule.field} fails`) + } else if (res instanceof Array) { + cb(res) + } else if (res instanceof Error) { + cb(res.message) + } + } + + if (res && res.then) { + res.then(() => cb(), (e) => cb(e)) + } + }, (results) => { + complete(results) + }) + }, + getType: function getType(rule) { + if (rule.type === undefined && rule.pattern instanceof RegExp) { + rule.type = 'pattern' + } + + if (typeof rule.validator !== 'function' && rule.type && !validators.hasOwnProperty(rule.type)) { + throw new Error(format('Unknown rule type %s', rule.type)) + } + + return rule.type || 'string' + }, + getValidationMethod: function getValidationMethod(rule) { + if (typeof rule.validator === 'function') { + return rule.validator + } + + const keys = Object.keys(rule) + const messageIndex = keys.indexOf('message') + + if (messageIndex !== -1) { + keys.splice(messageIndex, 1) + } + + if (keys.length === 1 && keys[0] === 'required') { + return validators.required + } + + return validators[this.getType(rule)] || false + } +} + +Schema.register = function register(type, validator) { + if (typeof validator !== 'function') { + throw new Error('Cannot register a validator by type, validator is not a function') + } + + validators[type] = validator +} + +Schema.warning = warning +Schema.messages = messages + +export default Schema +// # sourceMappingURL=index.js.map diff --git a/uni_modules/uv-form/package.json b/uni_modules/uv-form/package.json new file mode 100644 index 0000000..5e612c2 --- /dev/null +++ b/uni_modules/uv-form/package.json @@ -0,0 +1,93 @@ +{ + "id": "uv-form", + "displayName": "uv-form 表单 全面兼容vue3+2、app、h5、小程序等多端", + "version": "1.0.9", + "description": "此组件一般用于表单场景,可以配置Input输入框,Textarea文本域,Checkbox复选框,Radio单选框,开关选择器等,进行表单验证等。", + "keywords": [ + "form", + "uvui", + "uv-ui", + "表单", + "表单验证" +], + "repository": "", + "engines": { + "HBuilderX": "^3.1.0" + }, + "dcloudext": { + "type": "component-vue", + "sale": { + "regular": { + "price": "0.00" + }, + "sourcecode": { + "price": "0.00" + } + }, + "contact": { + "qq": "" + }, + "declaration": { + "ads": "无", + "data": "插件不采集任何数据", + "permissions": "无" + }, + "npmurl": "" + }, + "uni_modules": { + "dependencies": [ + "uv-ui-tools", + "uv-icon", + "uv-line", + "uv-transition", + "uv-action-sheet", + "uv-input", + "uv-button" + ], + "encrypt": [], + "platforms": { + "cloud": { + "tcb": "y", + "aliyun": "y" + }, + "client": { + "Vue": { + "vue2": "y", + "vue3": "y" + }, + "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", + "钉钉": "u", + "快手": "u", + "飞书": "u", + "京东": "u" + }, + "快应用": { + "华为": "u", + "联盟": "u" + } + } + } + } +} \ No newline at end of file diff --git a/uni_modules/uv-form/readme.md b/uni_modules/uv-form/readme.md new file mode 100644 index 0000000..0458a6a --- /dev/null +++ b/uni_modules/uv-form/readme.md @@ -0,0 +1,19 @@ +## Form 表单 + +> **组件名:uv-form** + +此组件一般用于表单场景,可以配置`Input`输入框,`Textarea`文本域,`Checkbox`复选框,`Radio`单选框,开关选择器等,进行表单验证等。 + +# 查看文档 + +## [下载完整示例项目](https://ext.dcloud.net.cn/plugin?name=uv-ui) (请不要 下载插件ZIP) + +### [更多插件,请关注uv-ui组件库](https://ext.dcloud.net.cn/plugin?name=uv-ui) + + + +![image](https://mp-a667b617-c5f1-4a2d-9a54-683a67cff588.cdn.bspapp.com/uv-ui/banner.png) + + + +#### 如使用过程中有任何问题反馈,或者您对uv-ui有一些好的建议,欢迎加入uv-ui官方交流群:官方QQ群 \ No newline at end of file diff --git a/uni_modules/uv-gap/changelog.md b/uni_modules/uv-gap/changelog.md new file mode 100644 index 0000000..7d603b4 --- /dev/null +++ b/uni_modules/uv-gap/changelog.md @@ -0,0 +1,5 @@ +## 1.0.1(2023-05-16) +1. 优化组件依赖,修改后无需全局引入,组件导入即可使用 +2. 优化部分功能 +## 1.0.0(2023-05-10) +1. 新增间隔槽组件 diff --git a/uni_modules/uv-gap/components/uv-gap/props.js b/uni_modules/uv-gap/components/uv-gap/props.js new file mode 100644 index 0000000..0ad787c --- /dev/null +++ b/uni_modules/uv-gap/components/uv-gap/props.js @@ -0,0 +1,25 @@ +export default { + props: { + // 背景颜色(默认transparent) + bgColor: { + type: String, + default: 'transparent' + }, + // 分割槽高度,单位px(默认20) + height: { + type: [String, Number], + default: 20 + }, + // 与上一个组件的距离 + marginTop: { + type: [String, Number], + default: 0 + }, + // 与下一个组件的距离 + marginBottom: { + type: [String, Number], + default: 0 + }, + ...uni.$uv?.props?.gap + } +} \ No newline at end of file diff --git a/uni_modules/uv-gap/components/uv-gap/uv-gap.vue b/uni_modules/uv-gap/components/uv-gap/uv-gap.vue new file mode 100644 index 0000000..55720a1 --- /dev/null +++ b/uni_modules/uv-gap/components/uv-gap/uv-gap.vue @@ -0,0 +1,36 @@ + + + diff --git a/uni_modules/uv-gap/package.json b/uni_modules/uv-gap/package.json new file mode 100644 index 0000000..3a17ec3 --- /dev/null +++ b/uni_modules/uv-gap/package.json @@ -0,0 +1,87 @@ +{ + "id": "uv-gap", + "displayName": "uv-gap 间隔槽 全面兼容小程序、nvue、vue2、vue3等多端", + "version": "1.0.1", + "description": "该组件一般用于内容块之间的用一个灰色块隔开的场景,方便用户风格统一,减少工作量。", + "keywords": [ + "gap", + "uvui", + "uv-ui", + "间隔槽", + "内容块" +], + "repository": "", + "engines": { + "HBuilderX": "^3.1.0" + }, + "dcloudext": { + "type": "component-vue", + "sale": { + "regular": { + "price": "0.00" + }, + "sourcecode": { + "price": "0.00" + } + }, + "contact": { + "qq": "" + }, + "declaration": { + "ads": "无", + "data": "插件不采集任何数据", + "permissions": "无" + }, + "npmurl": "" + }, + "uni_modules": { + "dependencies": [ + "uv-ui-tools" + ], + "encrypt": [], + "platforms": { + "cloud": { + "tcb": "y", + "aliyun": "y" + }, + "client": { + "Vue": { + "vue2": "y", + "vue3": "y" + }, + "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", + "钉钉": "u", + "快手": "u", + "飞书": "u", + "京东": "u" + }, + "快应用": { + "华为": "u", + "联盟": "u" + } + } + } + } +} \ No newline at end of file diff --git a/uni_modules/uv-gap/readme.md b/uni_modules/uv-gap/readme.md new file mode 100644 index 0000000..dedd565 --- /dev/null +++ b/uni_modules/uv-gap/readme.md @@ -0,0 +1,12 @@ +## Gap 间隔槽 + +> **组件名:uv-gap** + +该组件一般用于内容块之间的用一个灰色块隔开的场景,方便用户风格统一,减少工作量。 + +### 查看文档 + +### [完整示例项目下载 | 关注更多组件](https://ext.dcloud.net.cn/plugin?name=uv-ui) + +#### 如使用过程中有任何问题,或者您对uv-ui有一些好的建议,欢迎加入 uv-ui 交流群:uv-ui、官方QQ群 + diff --git a/uni_modules/uv-grid/changelog.md b/uni_modules/uv-grid/changelog.md new file mode 100644 index 0000000..8c61261 --- /dev/null +++ b/uni_modules/uv-grid/changelog.md @@ -0,0 +1,21 @@ +## 1.0.9(2023-12-06) +1. 优化 +## 1.0.8(2023-12-06) +1. 阻止事件冒泡问题 +## 1.0.7(2023-10-13) +1. unmounted兼容vue3 +## 1.0.6(2023-08-14) +1. 修复初始的时候闪动的BUG +## 1.0.5(2023-06-22) +1. 优化修改 +## 1.0.4(2023-06-21) +1. 修复BUG +## 1.0.3(2023-06-01) +1. 修复点击触发两次事件的BUG +## 1.0.2(2023-05-23) +1. 优化 +## 1.0.1(2023-05-16) +1. 优化组件依赖,修改后无需全局引入,组件导入即可使用 +2. 优化部分功能 +## 1.0.0(2023-05-10) +uv-grid 宫格布局 diff --git a/uni_modules/uv-grid/components/uv-grid-item/props.js b/uni_modules/uv-grid/components/uv-grid-item/props.js new file mode 100644 index 0000000..6b86298 --- /dev/null +++ b/uni_modules/uv-grid/components/uv-grid-item/props.js @@ -0,0 +1,15 @@ +export default { + props: { + // 宫格的name + name: { + type: [String, Number, null], + default: null + }, + // 背景颜色 + bgColor: { + type: String, + default: 'transparent' + }, + ...uni.$uv?.props?.gridItem + } +} \ No newline at end of file diff --git a/uni_modules/uv-grid/components/uv-grid-item/uv-grid-item.vue b/uni_modules/uv-grid/components/uv-grid-item/uv-grid-item.vue new file mode 100644 index 0000000..9412852 --- /dev/null +++ b/uni_modules/uv-grid/components/uv-grid-item/uv-grid-item.vue @@ -0,0 +1,226 @@ + + + + + diff --git a/uni_modules/uv-grid/components/uv-grid/props.js b/uni_modules/uv-grid/components/uv-grid/props.js new file mode 100644 index 0000000..d5f8474 --- /dev/null +++ b/uni_modules/uv-grid/components/uv-grid/props.js @@ -0,0 +1,20 @@ +export default { + props: { + // 分成几列 + col: { + type: [String, Number], + default: 3 + }, + // 是否显示边框 + border: { + type: Boolean, + default: false + }, + // 宫格对齐方式,表现为数量少的时候,靠左,居中,还是靠右 + align: { + type: String, + default: 'left' + }, + ...uni.$uv?.props?.grid + } +} \ No newline at end of file diff --git a/uni_modules/uv-grid/components/uv-grid/uv-grid.vue b/uni_modules/uv-grid/components/uv-grid/uv-grid.vue new file mode 100644 index 0000000..0314b18 --- /dev/null +++ b/uni_modules/uv-grid/components/uv-grid/uv-grid.vue @@ -0,0 +1,100 @@ + + + + + diff --git a/uni_modules/uv-grid/package.json b/uni_modules/uv-grid/package.json new file mode 100644 index 0000000..0c93379 --- /dev/null +++ b/uni_modules/uv-grid/package.json @@ -0,0 +1,88 @@ +{ + "id": "uv-grid", + "displayName": "uv-grid 宫格布局 全面兼容vue3+2、app、h5、小程序等多端", + "version": "1.0.9", + "description": "uv-grid 宫格组件一般用于同时展示多个同类项目的场景,可以给宫格的项目设置徽标组件(badge),或者图标等,也可以扩展为左右滑动的轮播形式。", + "keywords": [ + "uv-grid", + "uvui", + "uv-ui", + "宫格布局", + "grid" +], + "repository": "", + "engines": { + "HBuilderX": "^3.1.0" + }, + "dcloudext": { + "type": "component-vue", + "sale": { + "regular": { + "price": "0.00" + }, + "sourcecode": { + "price": "0.00" + } + }, + "contact": { + "qq": "" + }, + "declaration": { + "ads": "无", + "data": "插件不采集任何数据", + "permissions": "无" + }, + "npmurl": "" + }, + "uni_modules": { + "dependencies": [ + "uv-ui-tools", + "uv-icon" + ], + "encrypt": [], + "platforms": { + "cloud": { + "tcb": "y", + "aliyun": "y" + }, + "client": { + "Vue": { + "vue2": "y", + "vue3": "y" + }, + "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", + "钉钉": "u", + "快手": "u", + "飞书": "u", + "京东": "u" + }, + "快应用": { + "华为": "u", + "联盟": "u" + } + } + } + } +} \ No newline at end of file diff --git a/uni_modules/uv-grid/readme.md b/uni_modules/uv-grid/readme.md new file mode 100644 index 0000000..cd13cef --- /dev/null +++ b/uni_modules/uv-grid/readme.md @@ -0,0 +1,17 @@ +## Grid 宫格布局 + +> **组件名:uv-grid** + +宫格组件一般用于同时展示多个同类项目的场景,可以给宫格的项目设置徽标组件(badge),或者图标等,也可以扩展为左右滑动的轮播形式。 + +# 查看文档 + +### [更多插件,请关注uv-ui组件库](https://ext.dcloud.net.cn/plugin?name=uv-ui) + + + +![image](https://mp-a667b617-c5f1-4a2d-9a54-683a67cff588.cdn.bspapp.com/uv-ui/banner.png) + + + +#### 如使用过程中有任何问题反馈,或者您对uv-ui有一些好的建议,欢迎加入uv-ui官方交流群:官方QQ群 \ No newline at end of file diff --git a/uni_modules/uv-icon/changelog.md b/uni_modules/uv-icon/changelog.md new file mode 100644 index 0000000..c610827 --- /dev/null +++ b/uni_modules/uv-icon/changelog.md @@ -0,0 +1,31 @@ +## 1.0.13(2023-12-06) +1. 优化 +## 1.0.12(2023-12-06) +1. 阻止事件冒泡处理 +## 1.0.11(2023-10-29) +1. imgMode默认值改成aspectFit +## 1.0.10(2023-08-13) +1. 优化nvue,方便自定义图标 +## 1.0.9(2023-07-28) +1. 修改几个对应错误图标的BUG +## 1.0.8(2023-07-24) +1. 优化 支持base64图片 +## 1.0.7(2023-07-17) +1. 修复 uv-icon 恢复uv-empty相关的图标 +## 1.0.6(2023-07-13) +1. 修复icon设置name属性对应图标错误的BUG +## 1.0.5(2023-07-04) +1. 更新图标,删除一些不常用的图标 +2. 删除base64,修改成ttf文件引入读取图标 +3. 自定义图标文档说明:https://www.uvui.cn/guide/customIcon.html +## 1.0.4(2023-07-03) +1. 修复主题颜色在APP不生效的BUG +## 1.0.3(2023-05-24) +1. 将线上ttf字体包替换成base64,避免加载时或者网络差时候显示白色方块 +## 1.0.2(2023-05-16) +1. 优化组件依赖,修改后无需全局引入,组件导入即可使用 +2. 优化部分功能 +## 1.0.1(2023-05-10) +1. 修复小程序中异常显示 +## 1.0.0(2023-05-04) +新发版 diff --git a/uni_modules/uv-icon/components/uv-icon/icons.js b/uni_modules/uv-icon/components/uv-icon/icons.js new file mode 100644 index 0000000..8469a2d --- /dev/null +++ b/uni_modules/uv-icon/components/uv-icon/icons.js @@ -0,0 +1,160 @@ +export default { + 'uvicon-level': 'e68f', + 'uvicon-checkbox-mark': 'e659', + 'uvicon-folder': 'e694', + 'uvicon-movie': 'e67c', + 'uvicon-star-fill': 'e61e', + 'uvicon-star': 'e618', + 'uvicon-phone-fill': 'e6ac', + 'uvicon-phone': 'e6ba', + 'uvicon-apple-fill': 'e635', + 'uvicon-backspace': 'e64d', + 'uvicon-attach': 'e640', + 'uvicon-empty-data': 'e671', + 'uvicon-empty-address': 'e68a', + 'uvicon-empty-favor': 'e662', + 'uvicon-empty-car': 'e657', + 'uvicon-empty-order': 'e66b', + 'uvicon-empty-list': 'e672', + 'uvicon-empty-search': 'e677', + 'uvicon-empty-permission': 'e67d', + 'uvicon-empty-news': 'e67e', + 'uvicon-empty-history': 'e685', + 'uvicon-empty-coupon': 'e69b', + 'uvicon-empty-page': 'e60e', + 'uvicon-empty-wifi-off': 'e6cc', + 'uvicon-reload': 'e627', + 'uvicon-order': 'e695', + 'uvicon-server-man': 'e601', + 'uvicon-search': 'e632', + 'uvicon-more-dot-fill': 'e66f', + 'uvicon-scan': 'e631', + 'uvicon-map': 'e665', + 'uvicon-map-fill': 'e6a8', + 'uvicon-tags': 'e621', + 'uvicon-tags-fill': 'e613', + 'uvicon-eye': 'e664', + 'uvicon-eye-fill': 'e697', + 'uvicon-eye-off': 'e69c', + 'uvicon-eye-off-outline': 'e688', + 'uvicon-mic': 'e66d', + 'uvicon-mic-off': 'e691', + 'uvicon-calendar': 'e65c', + 'uvicon-trash': 'e623', + 'uvicon-trash-fill': 'e6ce', + 'uvicon-play-left': 'e6bf', + 'uvicon-play-right': 'e6b3', + 'uvicon-minus': 'e614', + 'uvicon-plus': 'e625', + 'uvicon-info-circle': 'e69f', + 'uvicon-info-circle-fill': 'e6a7', + 'uvicon-question-circle': 'e622', + 'uvicon-question-circle-fill': 'e6bc', + 'uvicon-close': 'e65a', + 'uvicon-checkmark': 'e64a', + 'uvicon-checkmark-circle': 'e643', + 'uvicon-checkmark-circle-fill': 'e668', + 'uvicon-setting': 'e602', + 'uvicon-setting-fill': 'e6d0', + 'uvicon-heart': 'e6a2', + 'uvicon-heart-fill': 'e68b', + 'uvicon-camera': 'e642', + 'uvicon-camera-fill': 'e650', + 'uvicon-more-circle': 'e69e', + 'uvicon-more-circle-fill': 'e684', + 'uvicon-chat': 'e656', + 'uvicon-chat-fill': 'e63f', + 'uvicon-bag': 'e647', + 'uvicon-error-circle': 'e66e', + 'uvicon-error-circle-fill': 'e655', + 'uvicon-close-circle': 'e64e', + 'uvicon-close-circle-fill': 'e666', + 'uvicon-share': 'e629', + 'uvicon-share-fill': 'e6bb', + 'uvicon-share-square': 'e6c4', + 'uvicon-shopping-cart': 'e6cb', + 'uvicon-shopping-cart-fill': 'e630', + 'uvicon-bell': 'e651', + 'uvicon-bell-fill': 'e604', + 'uvicon-list': 'e690', + 'uvicon-list-dot': 'e6a9', + 'uvicon-zhifubao-circle-fill': 'e617', + 'uvicon-weixin-circle-fill': 'e6cd', + 'uvicon-weixin-fill': 'e620', + 'uvicon-qq-fill': 'e608', + 'uvicon-qq-circle-fill': 'e6b9', + 'uvicon-moments-circel-fill': 'e6c2', + 'uvicon-moments': 'e6a0', + 'uvicon-car': 'e64f', + 'uvicon-car-fill': 'e648', + 'uvicon-warning-fill': 'e6c7', + 'uvicon-warning': 'e6c1', + 'uvicon-clock-fill': 'e64b', + 'uvicon-clock': 'e66c', + 'uvicon-edit-pen': 'e65d', + 'uvicon-edit-pen-fill': 'e679', + 'uvicon-email': 'e673', + 'uvicon-email-fill': 'e683', + 'uvicon-minus-circle': 'e6a5', + 'uvicon-plus-circle': 'e603', + 'uvicon-plus-circle-fill': 'e611', + 'uvicon-file-text': 'e687', + 'uvicon-file-text-fill': 'e67f', + 'uvicon-pushpin': 'e6d1', + 'uvicon-pushpin-fill': 'e6b6', + 'uvicon-grid': 'e68c', + 'uvicon-grid-fill': 'e698', + 'uvicon-play-circle': 'e6af', + 'uvicon-play-circle-fill': 'e62a', + 'uvicon-pause-circle-fill': 'e60c', + 'uvicon-pause': 'e61c', + 'uvicon-pause-circle': 'e696', + 'uvicon-gift-fill': 'e6b0', + 'uvicon-gift': 'e680', + 'uvicon-kefu-ermai': 'e660', + 'uvicon-server-fill': 'e610', + 'uvicon-coupon-fill': 'e64c', + 'uvicon-coupon': 'e65f', + 'uvicon-integral': 'e693', + 'uvicon-integral-fill': 'e6b1', + 'uvicon-home-fill': 'e68e', + 'uvicon-home': 'e67b', + 'uvicon-account': 'e63a', + 'uvicon-account-fill': 'e653', + 'uvicon-thumb-down-fill': 'e628', + 'uvicon-thumb-down': 'e60a', + 'uvicon-thumb-up': 'e612', + 'uvicon-thumb-up-fill': 'e62c', + 'uvicon-lock-fill': 'e6a6', + 'uvicon-lock-open': 'e68d', + 'uvicon-lock-opened-fill': 'e6a1', + 'uvicon-lock': 'e69d', + 'uvicon-red-packet': 'e6c3', + 'uvicon-photo-fill': 'e6b4', + 'uvicon-photo': 'e60d', + 'uvicon-volume-off-fill': 'e6c8', + 'uvicon-volume-off': 'e6bd', + 'uvicon-volume-fill': 'e624', + 'uvicon-volume': 'e605', + 'uvicon-download': 'e670', + 'uvicon-arrow-up-fill': 'e636', + 'uvicon-arrow-down-fill': 'e638', + 'uvicon-play-left-fill': 'e6ae', + 'uvicon-play-right-fill': 'e6ad', + 'uvicon-arrow-downward': 'e634', + 'uvicon-arrow-leftward': 'e63b', + 'uvicon-arrow-rightward': 'e644', + 'uvicon-arrow-upward': 'e641', + 'uvicon-arrow-down': 'e63e', + 'uvicon-arrow-right': 'e63c', + 'uvicon-arrow-left': 'e646', + 'uvicon-arrow-up': 'e633', + 'uvicon-skip-back-left': 'e6c5', + 'uvicon-skip-forward-right': 'e61f', + 'uvicon-arrow-left-double': 'e637', + 'uvicon-man': 'e675', + 'uvicon-woman': 'e626', + 'uvicon-en': 'e6b8', + 'uvicon-twitte': 'e607', + 'uvicon-twitter-circle-fill': 'e6cf' +} \ No newline at end of file diff --git a/uni_modules/uv-icon/components/uv-icon/props.js b/uni_modules/uv-icon/components/uv-icon/props.js new file mode 100644 index 0000000..7668cf9 --- /dev/null +++ b/uni_modules/uv-icon/components/uv-icon/props.js @@ -0,0 +1,90 @@ +export default { + props: { + // 图标类名 + name: { + type: String, + default: '' + }, + // 图标颜色,可接受主题色 + color: { + type: String, + default: '#606266' + }, + // 字体大小,单位px + size: { + type: [String, Number], + default: '16px' + }, + // 是否显示粗体 + bold: { + type: Boolean, + default: false + }, + // 点击图标的时候传递事件出去的index(用于区分点击了哪一个) + index: { + type: [String, Number], + default: null + }, + // 触摸图标时的类名 + hoverClass: { + type: String, + default: '' + }, + // 自定义扩展前缀,方便用户扩展自己的图标库 + customPrefix: { + type: String, + default: 'uvicon' + }, + // 图标右边或者下面的文字 + label: { + type: [String, Number], + default: '' + }, + // label的位置,只能右边或者下边 + labelPos: { + type: String, + default: 'right' + }, + // label的大小 + labelSize: { + type: [String, Number], + default: '15px' + }, + // label的颜色 + labelColor: { + type: String, + default: '#606266' + }, + // label与图标的距离 + space: { + type: [String, Number], + default: '3px' + }, + // 图片的mode + imgMode: { + type: String, + default: 'aspectFit' + }, + // 用于显示图片小图标时,图片的宽度 + width: { + type: [String, Number], + default: '' + }, + // 用于显示图片小图标时,图片的高度 + height: { + type: [String, Number], + default: '' + }, + // 用于解决某些情况下,让图标垂直居中的用途 + top: { + type: [String, Number], + default: 0 + }, + // 是否阻止事件传播 + stop: { + type: Boolean, + default: false + }, + ...uni.$uv?.props?.icon + } +} \ No newline at end of file diff --git a/uni_modules/uv-icon/components/uv-icon/uv-icon.vue b/uni_modules/uv-icon/components/uv-icon/uv-icon.vue new file mode 100644 index 0000000..d61c9e5 --- /dev/null +++ b/uni_modules/uv-icon/components/uv-icon/uv-icon.vue @@ -0,0 +1,226 @@ + + + + + \ No newline at end of file diff --git a/uni_modules/uv-icon/components/uv-icon/uvicons.ttf b/uni_modules/uv-icon/components/uv-icon/uvicons.ttf new file mode 100644 index 0000000000000000000000000000000000000000..9aedef864f7e685fbe1dac7e0f36fda281d35a7c GIT binary patch literal 39632 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 literal 0 HcmV?d00001 diff --git a/uni_modules/uv-icon/package.json b/uni_modules/uv-icon/package.json new file mode 100644 index 0000000..0a838d5 --- /dev/null +++ b/uni_modules/uv-icon/package.json @@ -0,0 +1,83 @@ +{ + "id": "uv-icon", + "displayName": "uv-icon 图标 全面兼容vue3+2、app、h5、小程序等多端", + "version": "1.0.13", + "description": "基于字体的图标集,包含了大多数常见场景的图标,支持自定义,支持自定义图片图标等。可自定义颜色、大小。", + "keywords": [ + "uv-ui,uvui,uv-icon,icon,图标,字体图标" +], + "repository": "", + "engines": { + "HBuilderX": "^3.1.0" + }, + "dcloudext": { + "type": "component-vue", + "sale": { + "regular": { + "price": "0.00" + }, + "sourcecode": { + "price": "0.00" + } + }, + "contact": { + "qq": "" + }, + "declaration": { + "ads": "无", + "data": "插件不采集任何数据", + "permissions": "无" + }, + "npmurl": "" + }, + "uni_modules": { + "dependencies": [ + "uv-ui-tools" + ], + "encrypt": [], + "platforms": { + "cloud": { + "tcb": "y", + "aliyun": "y" + }, + "client": { + "Vue": { + "vue2": "y", + "vue3": "y" + }, + "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", + "钉钉": "u", + "快手": "u", + "飞书": "u", + "京东": "u" + }, + "快应用": { + "华为": "u", + "联盟": "u" + } + } + } + } +} \ No newline at end of file diff --git a/uni_modules/uv-icon/readme.md b/uni_modules/uv-icon/readme.md new file mode 100644 index 0000000..d526e1a --- /dev/null +++ b/uni_modules/uv-icon/readme.md @@ -0,0 +1,15 @@ +## uv-icon 图标库 + +> **组件名:uv-icon** + +基于字体的图标集,包含了大多数常见场景的图标,支持自定义,支持自定义图片图标等。 + +# 查看文档 + +## [下载完整示例项目](https://ext.dcloud.net.cn/plugin?name=uv-ui) + +### [更多插件,请关注uv-ui组件库](https://ext.dcloud.net.cn/plugin?name=uv-ui) + +![image](https://mp-a667b617-c5f1-4a2d-9a54-683a67cff588.cdn.bspapp.com/uv-ui/banner.png) + +#### 如使用过程中有任何问题反馈,或者您对uv-ui有一些好的建议,欢迎加入uv-ui官方交流群:官方QQ群 diff --git a/uni_modules/uv-image/changelog.md b/uni_modules/uv-image/changelog.md new file mode 100644 index 0000000..e5a633d --- /dev/null +++ b/uni_modules/uv-image/changelog.md @@ -0,0 +1,36 @@ +## 1.0.16(2023-12-21) +1. 修复设置show-menu-by-longpress不生效的BUG +## 1.0.15(2023-12-06) +1. 优化 +## 1.0.14(2023-12-06) +1. 阻止事件冒泡问题 +## 1.0.13(2023-11-15) +1. 修复webp之前未使用的BUG +## 1.0.12(2023-10-11) +1. 修复懒加载报错:https://gitee.com/climblee/uv-ui/issues/I869JS +## 1.0.11(2023-08-31) +1. 修复设置widthFix时出现显示不全的BUG +2. 修复抖音等平台在width和height属性改变时出现不显示的BUG +## 1.0.10(2023-08-29) +1. 修复异步修改宽高不生效的问题,问题来源:https://gitee.com/climblee/uv-ui/issues/I7WUQ3 +## 1.0.9(2023-08-21) +1. 修复设置宽高为百分比不生效的BUG +## 1.0.8(2023-07-24) +1. 优化 nvue模式下增加cellChild参数,是否在list中cell节点下,nvue中cell下建议设置成true +## 1.0.7(2023-07-02) +修复VUE3模式下可能不显示的BUG +## 1.0.6(2023-07-02) +优化修改 +## 1.0.5(2023-06-28) +修复duration属性不生效的BUG +## 1.0.4(2023-05-27) +1. 修复可能报错的问题 +## 1.0.3(2023-05-24) +1. 去掉template中存在的this.导致头条小程序编译警告 +## 1.0.2(2023-05-23) +1. 优化 +## 1.0.1(2023-05-16) +1. 优化组件依赖,修改后无需全局引入,组件导入即可使用 +2. 优化部分功能 +## 1.0.0(2023-05-10) +uv-image 图片 diff --git a/uni_modules/uv-image/components/uv-image/props.js b/uni_modules/uv-image/components/uv-image/props.js new file mode 100644 index 0000000..6ef04a5 --- /dev/null +++ b/uni_modules/uv-image/components/uv-image/props.js @@ -0,0 +1,95 @@ +export default { + props: { + // 图片地址 + src: { + type: String, + default: '' + }, + // 裁剪模式 + mode: { + type: String, + default: 'aspectFill' + }, + // 宽度,单位任意 + width: { + type: [String, Number], + default: '300' + }, + // 高度,单位任意 + height: { + type: [String, Number], + default: '225' + }, + // 图片形状,circle-圆形,square-方形 + shape: { + type: String, + default: 'square' + }, + // 圆角,单位任意 + radius: { + type: [String, Number], + default: 0 + }, + // 是否懒加载,微信小程序、App、百度小程序、字节跳动小程序 + lazyLoad: { + type: Boolean, + default: true + }, + // 是否开启observer懒加载,nvue不生效 + observeLazyLoad: { + type: Boolean, + default: false + }, + // 开启长按图片显示识别微信小程序码菜单 + showMenuByLongpress: { + type: Boolean, + default: true + }, + // 加载中的图标,或者小图片 + loadingIcon: { + type: String, + default: 'photo' + }, + // 加载失败的图标,或者小图片 + errorIcon: { + type: String, + default: 'error-circle' + }, + // 是否显示加载中的图标或者自定义的slot + showLoading: { + type: Boolean, + default: true + }, + // 是否显示加载错误的图标或者自定义的slot + showError: { + type: Boolean, + default: true + }, + // 是否需要淡入效果 + fade: { + type: Boolean, + default: true + }, + // 只支持网络资源,只对微信小程序有效 + webp: { + type: Boolean, + default: false + }, + // 过渡时间,单位ms + duration: { + type: [String, Number], + default: 500 + }, + // 背景颜色,用于深色页面加载图片时,为了和背景色融合 + bgColor: { + type: String, + default: '#f3f4f6' + }, + // nvue模式下 是否直接显示,在uv-list等cell下面使用就需要设置 + cellChild: { + type: Boolean, + default: false + }, + ...uni.$uv?.props?.image + } +} \ No newline at end of file diff --git a/uni_modules/uv-image/components/uv-image/uv-image.vue b/uni_modules/uv-image/components/uv-image/uv-image.vue new file mode 100644 index 0000000..2ab4a78 --- /dev/null +++ b/uni_modules/uv-image/components/uv-image/uv-image.vue @@ -0,0 +1,287 @@ + + + + + diff --git a/uni_modules/uv-image/package.json b/uni_modules/uv-image/package.json new file mode 100644 index 0000000..796089e --- /dev/null +++ b/uni_modules/uv-image/package.json @@ -0,0 +1,89 @@ +{ + "id": "uv-image", + "displayName": "uv-image 图片 全面兼容vue3+2、app、h5、小程序等多端", + "version": "1.0.16", + "description": "uv-image 此组件为uni-app的image组件的加强版,在继承了原有功能外,增加observer懒加载功能,还支持淡入动画、加载中、加载失败提示、圆角值和形状等。", + "keywords": [ + "uv-image", + "uvui", + "uv-ui", + "image", + "图片" +], + "repository": "", + "engines": { + "HBuilderX": "^3.1.0" + }, + "dcloudext": { + "type": "component-vue", + "sale": { + "regular": { + "price": "0.00" + }, + "sourcecode": { + "price": "0.00" + } + }, + "contact": { + "qq": "" + }, + "declaration": { + "ads": "无", + "data": "插件不采集任何数据", + "permissions": "无" + }, + "npmurl": "" + }, + "uni_modules": { + "dependencies": [ + "uv-ui-tools", + "uv-transition", + "uv-icon" + ], + "encrypt": [], + "platforms": { + "cloud": { + "tcb": "y", + "aliyun": "y" + }, + "client": { + "Vue": { + "vue2": "y", + "vue3": "y" + }, + "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", + "钉钉": "u", + "快手": "u", + "飞书": "u", + "京东": "u" + }, + "快应用": { + "华为": "u", + "联盟": "u" + } + } + } + } +} \ No newline at end of file diff --git a/uni_modules/uv-image/readme.md b/uni_modules/uv-image/readme.md new file mode 100644 index 0000000..0ecc120 --- /dev/null +++ b/uni_modules/uv-image/readme.md @@ -0,0 +1,15 @@ +## Image 图片 + +> **组件名:uv-image** + +此组件为`uni-app`的`image`组件的加强版,在继承了原有功能外,增加`observer`懒加载功能,还支持淡入动画、加载中、加载失败提示、圆角值和形状等。 + +# 查看文档 + +## [下载完整示例项目](https://ext.dcloud.net.cn/plugin?name=uv-ui) + +### [更多插件,请关注uv-ui组件库](https://ext.dcloud.net.cn/plugin?name=uv-ui) + +![image](https://mp-a667b617-c5f1-4a2d-9a54-683a67cff588.cdn.bspapp.com/uv-ui/banner.png) + +#### 如使用过程中有任何问题反馈,或者您对uv-ui有一些好的建议,欢迎加入uv-ui官方交流群:官方QQ群 diff --git a/uni_modules/uv-index-list/changelog.md b/uni_modules/uv-index-list/changelog.md new file mode 100644 index 0000000..deda715 --- /dev/null +++ b/uni_modules/uv-index-list/changelog.md @@ -0,0 +1,18 @@ +## 1.0.7(2023-11-07) +1. 修复sticky属性不生效的BUG +## 1.0.6(2023-09-01) +1. 修复设置customNavHeight导致定位不准确的BUG +## 1.0.5(2023-08-23) +1. 修复ios端快速滑动+点击右侧导航会出现白屏的BUG +## 1.0.4(2023-07-25) +1. 修复全局设置成rpx存在的高度BUG +2. 修复其他BUG +## 1.0.3(2023-07-03) +去除插槽判断,避免某些平台不显示的BUG +## 1.0.2(2023-05-27) +1. select事件修复 +## 1.0.1(2023-05-16) +1. 优化组件依赖,修改后无需全局引入,组件导入即可使用 +2. 优化部分功能 +## 1.0.0(2023-05-10) +uv-index-list 索引列表 diff --git a/uni_modules/uv-index-list/components/uv-index-anchor/props.js b/uni_modules/uv-index-list/components/uv-index-anchor/props.js new file mode 100644 index 0000000..9ec949e --- /dev/null +++ b/uni_modules/uv-index-list/components/uv-index-anchor/props.js @@ -0,0 +1,30 @@ +export default { + props: { + // 列表锚点文本内容 + text: { + type: [String, Number], + default: '' + }, + // 列表锚点文字颜色 + color: { + type: String, + default: '#606266' + }, + // 列表锚点文字大小,单位默认px + size: { + type: [String, Number], + default: 14 + }, + // 列表锚点背景颜色 + bgColor: { + type: String, + default: '#dedede' + }, + // 列表锚点高度,单位默认px + height: { + type: [String, Number], + default: 32 + }, + ...uni.$uv?.props?.indexAnchor + } +} \ No newline at end of file diff --git a/uni_modules/uv-index-list/components/uv-index-anchor/uv-index-anchor.vue b/uni_modules/uv-index-list/components/uv-index-anchor/uv-index-anchor.vue new file mode 100644 index 0000000..e566aa7 --- /dev/null +++ b/uni_modules/uv-index-list/components/uv-index-anchor/uv-index-anchor.vue @@ -0,0 +1,98 @@ + + + + + diff --git a/uni_modules/uv-index-list/components/uv-index-item/uv-index-item.vue b/uni_modules/uv-index-list/components/uv-index-item/uv-index-item.vue new file mode 100644 index 0000000..f6e8901 --- /dev/null +++ b/uni_modules/uv-index-list/components/uv-index-item/uv-index-item.vue @@ -0,0 +1,87 @@ + + + + + diff --git a/uni_modules/uv-index-list/components/uv-index-list/props.js b/uni_modules/uv-index-list/components/uv-index-list/props.js new file mode 100644 index 0000000..0cf6356 --- /dev/null +++ b/uni_modules/uv-index-list/components/uv-index-list/props.js @@ -0,0 +1,30 @@ +export default { + props: { + // 右边锚点非激活的颜色 + inactiveColor: { + type: String, + default: '#606266' + }, + // 右边锚点激活的颜色 + activeColor: { + type: String, + default: '#5677fc' + }, + // 索引字符列表,数组形式 + indexList: { + type: Array, + default: () => [] + }, + // 是否开启锚点自动吸顶 + sticky: { + type: Boolean, + default: true + }, + // 自定义导航栏的高度 + customNavHeight: { + type: [String, Number], + default: 0 + }, + ...uni.$uv?.props?.indexList + } +} \ No newline at end of file diff --git a/uni_modules/uv-index-list/components/uv-index-list/uv-index-list.vue b/uni_modules/uv-index-list/components/uv-index-list/uv-index-list.vue new file mode 100644 index 0000000..e610323 --- /dev/null +++ b/uni_modules/uv-index-list/components/uv-index-list/uv-index-list.vue @@ -0,0 +1,461 @@ + + + + + diff --git a/uni_modules/uv-index-list/package.json b/uni_modules/uv-index-list/package.json new file mode 100644 index 0000000..133736b --- /dev/null +++ b/uni_modules/uv-index-list/package.json @@ -0,0 +1,88 @@ +{ + "id": "uv-index-list", + "displayName": "uv-index-list 索引列表 全面兼容vue3+2、app、h5、小程序等多端", + "version": "1.0.7", + "description": "该组件用于展示索引列表,右侧带索引的列表,方便快速定位到具体内容,通常用于城市/机场选择等场景。类似于微信通讯录页面", + "keywords": [ + "uv-index-list", + "uvui", + "uv-ui", + "index-list", + "索引列表" +], + "repository": "", + "engines": { + "HBuilderX": "^3.1.0" + }, + "dcloudext": { + "type": "component-vue", + "sale": { + "regular": { + "price": "0.00" + }, + "sourcecode": { + "price": "0.00" + } + }, + "contact": { + "qq": "" + }, + "declaration": { + "ads": "无", + "data": "插件不采集任何数据", + "permissions": "无" + }, + "npmurl": "" + }, + "uni_modules": { + "dependencies": [ + "uv-ui-tools", + "uv-transition" + ], + "encrypt": [], + "platforms": { + "cloud": { + "tcb": "y", + "aliyun": "y" + }, + "client": { + "Vue": { + "vue2": "y", + "vue3": "y" + }, + "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", + "钉钉": "u", + "快手": "u", + "飞书": "u", + "京东": "u" + }, + "快应用": { + "华为": "u", + "联盟": "u" + } + } + } + } +} \ No newline at end of file diff --git a/uni_modules/uv-index-list/readme.md b/uni_modules/uv-index-list/readme.md new file mode 100644 index 0000000..605741c --- /dev/null +++ b/uni_modules/uv-index-list/readme.md @@ -0,0 +1,19 @@ +## IndexList 索引列表 + +> **组件名:uv-index-list** + +用于展示索引列表,右侧带索引的列表,方便快速定位到具体内容,通常用于城市/机场选择等场景,类似于微信通讯录页面。 + +# 查看文档 + +## [下载完整示例项目](https://ext.dcloud.net.cn/plugin?name=uv-ui) (请不要 下载插件ZIP) + +### [更多插件,请关注uv-ui组件库](https://ext.dcloud.net.cn/plugin?name=uv-ui) + + + +![image](https://mp-a667b617-c5f1-4a2d-9a54-683a67cff588.cdn.bspapp.com/uv-ui/banner.png) + + + +#### 如使用过程中有任何问题反馈,或者您对uv-ui有一些好的建议,欢迎加入uv-ui官方交流群:官方QQ群 \ No newline at end of file diff --git a/uni_modules/uv-input/changelog.md b/uni_modules/uv-input/changelog.md new file mode 100644 index 0000000..2b354d0 --- /dev/null +++ b/uni_modules/uv-input/changelog.md @@ -0,0 +1,29 @@ +## 1.0.13(2023-12-06) +1. 优化 +## 1.0.12(2023-12-06) +1. 阻止事件冒泡问题 +## 1.0.11(2023-11-10) +1. 调整清除按钮样式的marginLeft,避免微信上多数情况触发不了的BUG +## 1.0.10(2023-10-07) +1. 修复搜狗输入法下存在不可清空的情况 +## 1.0.9(2023-09-14) +1. 修复H5等情况设置禁用或可读情况下,点击事件无效的问题 +## 1.0.8(2023-08-22) +1. 修复无法@keyboardheightchange无法获取键盘高度的BUG +## 1.0.7(2023-08-18) +1. 修复ios端不能输入的BUG +## 1.0.6(2023-08-05) +1. 修复在vue2模式下,v-model设置为0时不生效的BUG +## 1.0.5(2023-07-18) +1. 修复在微信小程序端清除内容存在不能清除的BUG +## 1.0.4(2023-07-13) +1. 修复value/v-model更改不生效的BUG +## 1.0.3(2023-07-03) +去除插槽判断,避免某些平台不显示的BUG +## 1.0.2(2023-05-16) +1. 优化组件依赖,修改后无需全局引入,组件导入即可使用 +2. 优化部分功能 +## 1.0.1(2023-05-12) +1. 修复vue3双向绑定的BUG +## 1.0.0(2023-05-10) +uv-input 输入框 diff --git a/uni_modules/uv-input/components/uv-input/props.js b/uni_modules/uv-input/components/uv-input/props.js new file mode 100644 index 0000000..e969493 --- /dev/null +++ b/uni_modules/uv-input/components/uv-input/props.js @@ -0,0 +1,175 @@ +export default { + props: { + value: { + type: [String, Number], + default: '' + }, + modelValue: { + type: [String, Number], + default: '' + }, + // 输入框类型 + // number-数字输入键盘,app-vue下可以输入浮点数,app-nvue和小程序平台下只能输入整数 + // idcard-身份证输入键盘,微信、支付宝、百度、QQ小程序 + // digit-带小数点的数字键盘,App的nvue页面、微信、支付宝、百度、头条、QQ小程序 + // text-文本输入键盘 + type: { + type: String, + default: 'text' + }, + // 是否禁用输入框 + disabled: { + type: Boolean, + default: false + }, + // 禁用状态时的背景色 + disabledColor: { + type: String, + default: '#f5f7fa' + }, + // 是否显示清除控件 + clearable: { + type: Boolean, + default: false + }, + // 是否密码类型 + password: { + type: Boolean, + default: false + }, + // 最大输入长度,设置为 -1 的时候不限制最大长度 + maxlength: { + type: [String, Number], + default: -1 + }, + // 输入框为空时的占位符 + placeholder: { + type: String, + default: null + }, + // 指定placeholder的样式类,注意页面或组件的style中写了scoped时,需要在类名前写/deep/ + placeholderClass: { + type: String, + default: 'input-placeholder' + }, + // 指定placeholder的样式 + placeholderStyle: { + type: [String, Object], + default: 'color: #c0c4cc' + }, + // 设置右下角按钮的文字,有效值:send|search|next|go|done,兼容性详见uni-app文档 + // https://uniapp.dcloud.io/component/input + // https://uniapp.dcloud.io/component/textarea + confirmType: { + type: String, + default: 'done' + }, + // 点击键盘右下角按钮时是否保持键盘不收起,H5无效 + confirmHold: { + type: Boolean, + default: false + }, + // focus时,点击页面的时候不收起键盘,微信小程序有效 + holdKeyboard: { + type: Boolean, + default: false + }, + // 自动获取焦点 + // 在 H5 平台能否聚焦以及软键盘是否跟随弹出,取决于当前浏览器本身的实现。nvue 页面不支持,需使用组件的 focus()、blur() 方法控制焦点 + focus: { + type: Boolean, + default: false + }, + // 键盘收起时,是否自动失去焦点,目前仅App3.0.0+有效 + autoBlur: { + type: Boolean, + default: false + }, + // 指定focus时光标的位置 + cursor: { + type: [String, Number], + default: -1 + }, + // 输入框聚焦时底部与键盘的距离 + cursorSpacing: { + type: [String, Number], + default: 30 + }, + // 光标起始位置,自动聚集时有效,需与selection-end搭配使用 + selectionStart: { + type: [String, Number], + default: -1 + }, + // 光标结束位置,自动聚集时有效,需与selection-start搭配使用 + selectionEnd: { + type: [String, Number], + default: -1 + }, + // 键盘弹起时,是否自动上推页面 + adjustPosition: { + type: Boolean, + default: true + }, + // 输入框内容对齐方式,可选值为:left|center|right + inputAlign: { + type: String, + default: 'left' + }, + // 输入框字体的大小 + fontSize: { + type: [String, Number], + default: '14px' + }, + // 输入框字体颜色 + color: { + type: String, + default: '#303133' + }, + // 输入框前置图标 + prefixIcon: { + type: String, + default: '' + }, + // 前置图标样式,对象或字符串 + prefixIconStyle: { + type: [String, Object], + default: '' + }, + // 输入框后置图标 + suffixIcon: { + type: String, + default: '' + }, + // 后置图标样式,对象或字符串 + suffixIconStyle: { + type: [String, Object], + default: '' + }, + // 边框类型,surround-四周边框,bottom-底部边框,none-无边框 + border: { + type: String, + default: 'surround' + }, + // 是否只读,与disabled不同之处在于disabled会置灰组件,而readonly则不会 + readonly: { + type: Boolean, + default: false + }, + // 输入框形状,circle-圆形,square-方形 + shape: { + type: String, + default: 'square' + }, + // 用于处理或者过滤输入框内容的方法 + formatter: { + type: [Function, null], + default: null + }, + // 是否忽略组件内对文本合成系统事件的处理 + ignoreCompositionEvent: { + type: Boolean, + default: true + }, + ...uni.$uv?.props?.input + } +} \ No newline at end of file diff --git a/uni_modules/uv-input/components/uv-input/uv-input.vue b/uni_modules/uv-input/components/uv-input/uv-input.vue new file mode 100644 index 0000000..20c1801 --- /dev/null +++ b/uni_modules/uv-input/components/uv-input/uv-input.vue @@ -0,0 +1,348 @@ + + + + + \ No newline at end of file diff --git a/uni_modules/uv-input/package.json b/uni_modules/uv-input/package.json new file mode 100644 index 0000000..6981fa9 --- /dev/null +++ b/uni_modules/uv-input/package.json @@ -0,0 +1,88 @@ +{ + "id": "uv-input", + "displayName": "uv-input 输入框 全面兼容vue3+2、app、h5、小程序等多端", + "version": "1.0.13", + "description": "uv-input 该组件为一个输入框,默认没有边框和样式,是专门为配合表单组件uv-form而设计的,利用它可以快速实现表单验证,输入内容,下拉选择等功能。", + "keywords": [ + "uv-input", + "uvui", + "uv-ui", + "input", + "输入框" +], + "repository": "", + "engines": { + "HBuilderX": "^3.1.0" + }, + "dcloudext": { + "type": "component-vue", + "sale": { + "regular": { + "price": "0.00" + }, + "sourcecode": { + "price": "0.00" + } + }, + "contact": { + "qq": "" + }, + "declaration": { + "ads": "无", + "data": "插件不采集任何数据", + "permissions": "无" + }, + "npmurl": "" + }, + "uni_modules": { + "dependencies": [ + "uv-ui-tools", + "uv-icon" + ], + "encrypt": [], + "platforms": { + "cloud": { + "tcb": "y", + "aliyun": "y" + }, + "client": { + "Vue": { + "vue2": "y", + "vue3": "y" + }, + "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", + "钉钉": "u", + "快手": "u", + "飞书": "u", + "京东": "u" + }, + "快应用": { + "华为": "u", + "联盟": "u" + } + } + } + } +} \ No newline at end of file diff --git a/uni_modules/uv-input/readme.md b/uni_modules/uv-input/readme.md new file mode 100644 index 0000000..00f47e4 --- /dev/null +++ b/uni_modules/uv-input/readme.md @@ -0,0 +1,19 @@ +## Input 输入框 + +> **组件名:uv-input** + +此组件为一个输入框,默认没有边框和样式,是专门为配合表单组件uv-form而设计的,利用它可以快速实现表单验证,输入内容,下拉选择等功能。 + +# 查看文档 + +## [下载完整示例项目](https://ext.dcloud.net.cn/plugin?name=uv-ui) (请不要 下载插件ZIP) + +### [更多插件,请关注uv-ui组件库](https://ext.dcloud.net.cn/plugin?name=uv-ui) + + + +![image](https://mp-a667b617-c5f1-4a2d-9a54-683a67cff588.cdn.bspapp.com/uv-ui/banner.png) + + + +#### 如使用过程中有任何问题反馈,或者您对uv-ui有一些好的建议,欢迎加入uv-ui官方交流群:官方QQ群 \ No newline at end of file diff --git a/uni_modules/uv-keyboard/changelog.md b/uni_modules/uv-keyboard/changelog.md new file mode 100644 index 0000000..1d1be01 --- /dev/null +++ b/uni_modules/uv-keyboard/changelog.md @@ -0,0 +1,17 @@ +## 1.0.5(2023-10-12) +1. 增加disKeys参数,mode = "car"下,被禁用的键,如:['I','O'] +2. 增加customabc参数,mode = "car"下,是否启用自定义中英文切换内容模式,为了兼容支付宝等小程序不兼容嵌套插槽,导致同时显示自定义内容和原始内容 +3. 增加ref方法changeCarMode,mode = "car"下, 调用此方法可以切换中英文模式 +4. 增加@changeCarInputMode,mode = "car"下,调用此方法可以进行切换中英文 +5. 增加插槽abc,mode = "car"下,自定义中英文切换内容,具体参考[车牌键盘自定义中英文切换及禁用键等设置](https://www.uvui.cn/components/keyboard.html#车牌键盘自定义中英文切换及禁用键等设置) +## 1.0.4(2023-09-04) +1. 优化,修改文件名称 +## 1.0.3(2023-09-04) +1. 修复键盘change回调事件产生冲突的BUG +## 1.0.2(2023-07-02) +uv-keyboard 由于弹出层uv-popup的修改,打开和关闭方法更改,详情参考文档:https://www.uvui.cn/components/keyboard.html +## 1.0.1(2023-05-16) +1. 优化组件依赖,修改后无需全局引入,组件导入即可使用 +2. 优化部分功能 +## 1.0.0(2023-05-10) +uv-keyboard 键盘 diff --git a/uni_modules/uv-keyboard/components/uv-keyboard-car/props.js b/uni_modules/uv-keyboard/components/uv-keyboard-car/props.js new file mode 100644 index 0000000..3dd93cc --- /dev/null +++ b/uni_modules/uv-keyboard/components/uv-keyboard-car/props.js @@ -0,0 +1,24 @@ +export default { + props: { + // 是否打乱键盘按键的顺序 + random: { + type: Boolean, + default: false + }, + // 输入一个中文后,是否自动切换到英文 + autoChange: { + type: Boolean, + default: false + }, + // 被禁用的键 + disKeys: { + type: Array, + default: ()=>[] + }, + // 是否自定义abc + customabc: { + type: Boolean, + default: false + } + } +} \ No newline at end of file diff --git a/uni_modules/uv-keyboard/components/uv-keyboard-car/uv-keyboard-car.vue b/uni_modules/uv-keyboard/components/uv-keyboard-car/uv-keyboard-car.vue new file mode 100644 index 0000000..e99e910 --- /dev/null +++ b/uni_modules/uv-keyboard/components/uv-keyboard-car/uv-keyboard-car.vue @@ -0,0 +1,347 @@ + + + + + diff --git a/uni_modules/uv-keyboard/components/uv-keyboard-number/props.js b/uni_modules/uv-keyboard/components/uv-keyboard-number/props.js new file mode 100644 index 0000000..60d63d4 --- /dev/null +++ b/uni_modules/uv-keyboard/components/uv-keyboard-number/props.js @@ -0,0 +1,19 @@ +export default { + props: { + // 键盘的类型,number-数字键盘,card-身份证键盘 + mode: { + type: String, + default: 'number' + }, + // 是否显示键盘的"."符号 + dotDisabled: { + type: Boolean, + default: false + }, + // 是否打乱键盘按键的顺序 + random: { + type: Boolean, + default: false + } + } +} \ No newline at end of file diff --git a/uni_modules/uv-keyboard/components/uv-keyboard-number/uv-keyboard-number.vue b/uni_modules/uv-keyboard/components/uv-keyboard-number/uv-keyboard-number.vue new file mode 100644 index 0000000..b7c0b8b --- /dev/null +++ b/uni_modules/uv-keyboard/components/uv-keyboard-number/uv-keyboard-number.vue @@ -0,0 +1,201 @@ + + + + + diff --git a/uni_modules/uv-keyboard/components/uv-keyboard/props.js b/uni_modules/uv-keyboard/components/uv-keyboard/props.js new file mode 100644 index 0000000..05dd76a --- /dev/null +++ b/uni_modules/uv-keyboard/components/uv-keyboard/props.js @@ -0,0 +1,95 @@ +export default { + props: { + // 键盘的类型,number-数字键盘,card-身份证键盘,car-车牌号键盘 + mode: { + type: String, + default: 'number' + }, + // 是否显示键盘的"."符号 + dotDisabled: { + type: Boolean, + default: false + }, + // 是否显示顶部工具条 + tooltip: { + type: Boolean, + default: true + }, + // 是否显示工具条中间的提示 + showTips: { + type: Boolean, + default: true + }, + // 工具条中间的提示文字 + tips: { + type: String, + default: '' + }, + // 是否显示工具条左边的"取消"按钮 + showCancel: { + type: Boolean, + default: true + }, + // 是否显示工具条右边的"完成"按钮 + showConfirm: { + type: Boolean, + default: true + }, + // 是否打乱键盘按键的顺序 + random: { + type: Boolean, + default: false + }, + // 是否开启底部安全区适配,开启的话,会在iPhoneX机型底部添加一定的内边距 + safeAreaInsetBottom: { + type: Boolean, + default: true + }, + // 是否允许通过点击遮罩关闭键盘 + closeOnClickOverlay: { + type: Boolean, + default: true + }, + // 是否允许点击确认按钮关闭组件 + closeOnClickConfirm: { + type: Boolean, + default: true + }, + // 是否显示遮罩,某些时候数字键盘时,用户希望看到自己的数值,所以可能不想要遮罩 + overlay: { + type: Boolean, + default: true + }, + // z-index值 + zIndex: { + type: [String, Number], + default: 10075 + }, + // 取消按钮的文字 + cancelText: { + type: String, + default: '取消' + }, + // 确认按钮的文字 + confirmText: { + type: String, + default: '确定' + }, + // 输入一个中文后,是否自动切换到英文 + autoChange: { + type: Boolean, + default: false + }, + // 被禁用的键 + disKeys: { + type: Array, + default: ()=>[] + }, + // 是否自定义abc + customabc: { + type: Boolean, + default: false + }, + ...uni.$uv?.props?.keyboard + } +} \ No newline at end of file diff --git a/uni_modules/uv-keyboard/components/uv-keyboard/uv-keyboard.vue b/uni_modules/uv-keyboard/components/uv-keyboard/uv-keyboard.vue new file mode 100644 index 0000000..60b15bf --- /dev/null +++ b/uni_modules/uv-keyboard/components/uv-keyboard/uv-keyboard.vue @@ -0,0 +1,180 @@ + + + + + diff --git a/uni_modules/uv-keyboard/package.json b/uni_modules/uv-keyboard/package.json new file mode 100644 index 0000000..69844c6 --- /dev/null +++ b/uni_modules/uv-keyboard/package.json @@ -0,0 +1,89 @@ +{ + "id": "uv-keyboard", + "displayName": "uv-keyboard 键盘 全面兼容vue3+2、app、h5、小程序等多端", + "version": "1.0.5", + "description": "uv-keyboard 该组件为自定义的键盘面板,内含了数字键盘,车牌号键,身份证号键盘3种模式,都有可以打乱按键顺序的选项。", + "keywords": [ + "uv-keyboard", + "uvui", + "uv-ui", + "keyboard", + "键盘" +], + "repository": "", + "engines": { + "HBuilderX": "^3.1.0" + }, + "dcloudext": { + "type": "component-vue", + "sale": { + "regular": { + "price": "0.00" + }, + "sourcecode": { + "price": "0.00" + } + }, + "contact": { + "qq": "" + }, + "declaration": { + "ads": "无", + "data": "插件不采集任何数据", + "permissions": "无" + }, + "npmurl": "" + }, + "uni_modules": { + "dependencies": [ + "uv-ui-tools", + "uv-popup", + "uv-icon" + ], + "encrypt": [], + "platforms": { + "cloud": { + "tcb": "y", + "aliyun": "y" + }, + "client": { + "Vue": { + "vue2": "y", + "vue3": "y" + }, + "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", + "钉钉": "u", + "快手": "u", + "飞书": "u", + "京东": "u" + }, + "快应用": { + "华为": "u", + "联盟": "u" + } + } + } + } +} \ No newline at end of file diff --git a/uni_modules/uv-keyboard/readme.md b/uni_modules/uv-keyboard/readme.md new file mode 100644 index 0000000..9cbef6c --- /dev/null +++ b/uni_modules/uv-keyboard/readme.md @@ -0,0 +1,19 @@ +## Keyboard 键盘 + +> **组件名:uv-keyboard** + +该组件为自定义的键盘面板,内含了数字键盘,车牌号键,身份证号键盘3种模式,都有可以打乱按键顺序的选项。 + +# 查看文档 + +## [下载完整示例项目](https://ext.dcloud.net.cn/plugin?name=uv-ui) (请不要 下载插件ZIP) + +### [更多插件,请关注uv-ui组件库](https://ext.dcloud.net.cn/plugin?name=uv-ui) + + + +![image](https://mp-a667b617-c5f1-4a2d-9a54-683a67cff588.cdn.bspapp.com/uv-ui/banner.png) + + + +#### 如使用过程中有任何问题反馈,或者您对uv-ui有一些好的建议,欢迎加入uv-ui官方交流群:官方QQ群 \ No newline at end of file diff --git a/uni_modules/uv-line-progress/changelog.md b/uni_modules/uv-line-progress/changelog.md new file mode 100644 index 0000000..975acce --- /dev/null +++ b/uni_modules/uv-line-progress/changelog.md @@ -0,0 +1,7 @@ +## 1.0.2(2023-06-20) +1. 适配height参数携带单位 +## 1.0.1(2023-05-16) +1. 优化组件依赖,修改后无需全局引入,组件导入即可使用 +2. 优化部分功能 +## 1.0.0(2023-05-10) +uv-line-progress 线形进度条 diff --git a/uni_modules/uv-line-progress/components/uv-line-progress/props.js b/uni_modules/uv-line-progress/components/uv-line-progress/props.js new file mode 100644 index 0000000..23138c7 --- /dev/null +++ b/uni_modules/uv-line-progress/components/uv-line-progress/props.js @@ -0,0 +1,29 @@ +export default { + props: { + // 激活部分的颜色 + activeColor: { + type: String, + default: '#19be6b' + }, + inactiveColor: { + type: String, + default: '#ececec' + }, + // 进度百分比,数值 + percentage: { + type: [String, Number], + default: 0 + }, + // 是否在进度条内部显示百分比的值 + showText: { + type: Boolean, + default: true + }, + // 进度条的高度,单位px + height: { + type: [String, Number], + default: 12 + }, + ...uni.$uv?.props?.lineProgress + } +} \ No newline at end of file diff --git a/uni_modules/uv-line-progress/components/uv-line-progress/uv-line-progress.vue b/uni_modules/uv-line-progress/components/uv-line-progress/uv-line-progress.vue new file mode 100644 index 0000000..229c2aa --- /dev/null +++ b/uni_modules/uv-line-progress/components/uv-line-progress/uv-line-progress.vue @@ -0,0 +1,146 @@ + + + + + diff --git a/uni_modules/uv-line-progress/package.json b/uni_modules/uv-line-progress/package.json new file mode 100644 index 0000000..01e550e --- /dev/null +++ b/uni_modules/uv-line-progress/package.json @@ -0,0 +1,87 @@ +{ + "id": "uv-line-progress", + "displayName": "uv-line-progress 线形进度条 全面兼容小程序、nvue、vue2、vue3等多端", + "version": "1.0.2", + "description": "uv-line-progress 该组件展示操作或任务的当前进度,比如上传文件,是一个线形的进度条。", + "keywords": [ + "uv-line-progress", + "uvui", + "uv-ui", + "progress", + "进度条" +], + "repository": "", + "engines": { + "HBuilderX": "^3.1.0" + }, + "dcloudext": { + "type": "component-vue", + "sale": { + "regular": { + "price": "0.00" + }, + "sourcecode": { + "price": "0.00" + } + }, + "contact": { + "qq": "" + }, + "declaration": { + "ads": "无", + "data": "插件不采集任何数据", + "permissions": "无" + }, + "npmurl": "" + }, + "uni_modules": { + "dependencies": [ + "uv-ui-tools" + ], + "encrypt": [], + "platforms": { + "cloud": { + "tcb": "y", + "aliyun": "y" + }, + "client": { + "Vue": { + "vue2": "y", + "vue3": "y" + }, + "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", + "钉钉": "u", + "快手": "u", + "飞书": "u", + "京东": "u" + }, + "快应用": { + "华为": "u", + "联盟": "u" + } + } + } + } +} \ No newline at end of file diff --git a/uni_modules/uv-line-progress/readme.md b/uni_modules/uv-line-progress/readme.md new file mode 100644 index 0000000..98e5d49 --- /dev/null +++ b/uni_modules/uv-line-progress/readme.md @@ -0,0 +1,11 @@ +## LineProgress 线形进度条 + +> **组件名:uv-line-progress** + +展示操作或任务的当前进度,比如上传文件,是一个线形的进度条。 + +### 查看文档 + +### [完整示例项目下载 | 关注更多组件](https://ext.dcloud.net.cn/plugin?name=uv-ui) + +#### 如使用过程中有任何问题,或者您对uv-ui有一些好的建议,欢迎加入 uv-ui 交流群:uv-ui、官方QQ群 diff --git a/uni_modules/uv-line/changelog.md b/uni_modules/uv-line/changelog.md new file mode 100644 index 0000000..5eb7ba8 --- /dev/null +++ b/uni_modules/uv-line/changelog.md @@ -0,0 +1,5 @@ +## 1.0.1(2023-05-16) +1. 优化组件依赖,修改后无需全局引入,组件导入即可使用 +2. 优化部分功能 +## 1.0.0(2023-05-10) +1. 新增线条组件 diff --git a/uni_modules/uv-line/components/uv-line/props.js b/uni_modules/uv-line/components/uv-line/props.js new file mode 100644 index 0000000..75b1007 --- /dev/null +++ b/uni_modules/uv-line/components/uv-line/props.js @@ -0,0 +1,34 @@ +export default { + props: { + color: { + type: String, + default: '#d6d7d9' + }, + // 长度,竖向时表现为高度,横向时表现为长度,可以为百分比,带px单位的值等 + length: { + type: [String, Number], + default: '100%' + }, + // 线条方向,col-竖向,row-横向 + direction: { + type: String, + default: 'row' + }, + // 是否显示细边框 + hairline: { + type: Boolean, + default: true + }, + // 线条与上下左右元素的间距,字符串形式,如"30px"、"20px 30px" + margin: { + type: [String, Number], + default: 0 + }, + // 是否虚线,true-虚线,false-实线 + dashed: { + type: Boolean, + default: false + }, + ...uni.$uv?.props?.line + } +} \ No newline at end of file diff --git a/uni_modules/uv-line/components/uv-line/uv-line.vue b/uni_modules/uv-line/components/uv-line/uv-line.vue new file mode 100644 index 0000000..866c507 --- /dev/null +++ b/uni_modules/uv-line/components/uv-line/uv-line.vue @@ -0,0 +1,60 @@ + + + + + diff --git a/uni_modules/uv-line/package.json b/uni_modules/uv-line/package.json new file mode 100644 index 0000000..036446a --- /dev/null +++ b/uni_modules/uv-line/package.json @@ -0,0 +1,87 @@ +{ + "id": "uv-line", + "displayName": "uv-line 线条 全面兼容小程序、nvue、vue2、vue3等多端", + "version": "1.0.1", + "description": "uv-line 此组件一般用于显示一根线条,用于分隔内容块,有横向和竖向两种模式,且能设置0.5px线条,使用也很简单。", + "keywords": [ + "uv-line", + "uvui", + "uv-ui", + "line", + "线条" +], + "repository": "", + "engines": { + "HBuilderX": "^3.1.0" + }, + "dcloudext": { + "type": "component-vue", + "sale": { + "regular": { + "price": "0.00" + }, + "sourcecode": { + "price": "0.00" + } + }, + "contact": { + "qq": "" + }, + "declaration": { + "ads": "无", + "data": "插件不采集任何数据", + "permissions": "无" + }, + "npmurl": "" + }, + "uni_modules": { + "dependencies": [ + "uv-ui-tools" + ], + "encrypt": [], + "platforms": { + "cloud": { + "tcb": "y", + "aliyun": "y" + }, + "client": { + "Vue": { + "vue2": "y", + "vue3": "y" + }, + "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", + "钉钉": "u", + "快手": "u", + "飞书": "u", + "京东": "u" + }, + "快应用": { + "华为": "u", + "联盟": "u" + } + } + } + } +} \ No newline at end of file diff --git a/uni_modules/uv-line/readme.md b/uni_modules/uv-line/readme.md new file mode 100644 index 0000000..e47533c --- /dev/null +++ b/uni_modules/uv-line/readme.md @@ -0,0 +1,11 @@ +## Line 线条 + +> **组件名:uv-line** + +此组件一般用于显示一根线条,用于分隔内容块,有横向和竖向两种模式,且能设置0.5px线条,使用也很简单。 + +### 查看文档 + +### [完整示例项目下载 | 关注更多组件](https://ext.dcloud.net.cn/plugin?name=uv-ui) + +#### 如使用过程中有任何问题,或者您对uv-ui有一些好的建议,欢迎加入 uv-ui 交流群:uv-ui、官方QQ群 diff --git a/uni_modules/uv-link/changelog.md b/uni_modules/uv-link/changelog.md new file mode 100644 index 0000000..ce52f84 --- /dev/null +++ b/uni_modules/uv-link/changelog.md @@ -0,0 +1,7 @@ +## 1.0.2(2023-08-13) +1. 修复报错的BUG +## 1.0.1(2023-05-16) +1. 优化组件依赖,修改后无需全局引入,组件导入即可使用 +2. 优化部分功能 +## 1.0.0(2023-05-10) +uv-link 超链接组件 diff --git a/uni_modules/uv-link/components/uv-link/props.js b/uni_modules/uv-link/components/uv-link/props.js new file mode 100644 index 0000000..b3f56a1 --- /dev/null +++ b/uni_modules/uv-link/components/uv-link/props.js @@ -0,0 +1,40 @@ +export default { + props: { + // 文字颜色 + color: { + type: String, + default: '' + }, + // 字体大小,单位px + fontSize: { + type: [String, Number], + default: 14 + }, + // 是否显示下划线 + underLine: { + type: Boolean, + default: false + }, + // 要跳转的链接 + href: { + type: String, + default: '' + }, + // 小程序中复制到粘贴板的提示语 + mpTips: { + type: String, + default: '链接已复制,请在浏览器打开' + }, + // 下划线颜色 + lineColor: { + type: String, + default: '' + }, + // 超链接的问题,不使用slot形式传入,是因为nvue下无法修改颜色 + text: { + type: String, + default: '' + }, + ...uni.$uv?.props?.link + } +} \ No newline at end of file diff --git a/uni_modules/uv-link/components/uv-link/uv-link.vue b/uni_modules/uv-link/components/uv-link/uv-link.vue new file mode 100644 index 0000000..4c9258e --- /dev/null +++ b/uni_modules/uv-link/components/uv-link/uv-link.vue @@ -0,0 +1,83 @@ + + + + + diff --git a/uni_modules/uv-link/package.json b/uni_modules/uv-link/package.json new file mode 100644 index 0000000..1b115f4 --- /dev/null +++ b/uni_modules/uv-link/package.json @@ -0,0 +1,87 @@ +{ + "id": "uv-link", + "displayName": "uv-link 超链接 全面兼容小程序、nvue、vue2、vue3等多端", + "version": "1.0.2", + "description": "uv-link 该组件为超链接组件", + "keywords": [ + "uv-link", + "uvui", + "uv-ui", + "link", + "超链接" +], + "repository": "", + "engines": { + "HBuilderX": "^3.1.0" + }, + "dcloudext": { + "type": "component-vue", + "sale": { + "regular": { + "price": "0.00" + }, + "sourcecode": { + "price": "0.00" + } + }, + "contact": { + "qq": "" + }, + "declaration": { + "ads": "无", + "data": "插件不采集任何数据", + "permissions": "无" + }, + "npmurl": "" + }, + "uni_modules": { + "dependencies": [ + "uv-ui-tools" + ], + "encrypt": [], + "platforms": { + "cloud": { + "tcb": "y", + "aliyun": "y" + }, + "client": { + "Vue": { + "vue2": "y", + "vue3": "y" + }, + "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", + "钉钉": "u", + "快手": "u", + "飞书": "u", + "京东": "u" + }, + "快应用": { + "华为": "u", + "联盟": "u" + } + } + } + } +} \ No newline at end of file diff --git a/uni_modules/uv-link/readme.md b/uni_modules/uv-link/readme.md new file mode 100644 index 0000000..6e8ce92 --- /dev/null +++ b/uni_modules/uv-link/readme.md @@ -0,0 +1,11 @@ +## Link 超链接 + +> **组件名:uv-link** + +该组件为超链接组件,在不同平台有不同表现形式。 + +### 查看文档 + +### [完整示例项目下载 | 关注更多组件](https://ext.dcloud.net.cn/plugin?name=uv-ui) + +#### 如使用过程中有任何问题,或者您对uv-ui有一些好的建议,欢迎加入 uv-ui 交流群:uv-ui、官方QQ群 diff --git a/uni_modules/uv-list/changelog.md b/uni_modules/uv-list/changelog.md new file mode 100644 index 0000000..6c130f0 --- /dev/null +++ b/uni_modules/uv-list/changelog.md @@ -0,0 +1,25 @@ +## 1.0.9(2023-11-10) +1. 修复设置ellipsis不生效的BUG +## 1.0.8(2023-09-20) +1. listItem优化可使用customStyle变量进行样式控制 +## 1.0.7(2023-08-29) +1. 修复边框的BUG +## 1.0.6(2023-08-16) +1. 修复switch开关返回undefined的问题 +2. 优化初始化可能导致的闪动 +## 1.0.5(2023-08-07) +1. 修复分包页面在ios端,nvue编译不能滚动的BUG +## 1.0.4(2023-08-04) +1. nvue修复 触底不触发事件的BUG +2. 更新文档说明事件触发 +## 1.0.3(2023-07-28) +1. 修改可能造成样式污染的BUG +## 1.0.2(2023-07-26) +1. 全面重构,用法与之前保持一致,参数全部变化 +2. 新增多个功能参数,方便一键构建列表 +3. List列表组件,包含基本列表样式、默认插槽机制、可扩展插槽机制、长列表性能优化、多端兼容。 +## 1.0.1(2023-05-16) +1. 优化组件依赖,修改后无需全局引入,组件导入即可使用 +2. 优化部分功能 +## 1.0.0(2023-05-10) +uv-list 列表 diff --git a/uni_modules/uv-list/components/uv-list-item/uv-list-item.vue b/uni_modules/uv-list/components/uv-list-item/uv-list-item.vue new file mode 100644 index 0000000..193b48d --- /dev/null +++ b/uni_modules/uv-list/components/uv-list-item/uv-list-item.vue @@ -0,0 +1,535 @@ + + + + + \ No newline at end of file diff --git a/uni_modules/uv-list/components/uv-list/uv-list.vue b/uni_modules/uv-list/components/uv-list/uv-list.vue new file mode 100644 index 0000000..3f3e5c2 --- /dev/null +++ b/uni_modules/uv-list/components/uv-list/uv-list.vue @@ -0,0 +1,147 @@ + + + + diff --git a/uni_modules/uv-list/package.json b/uni_modules/uv-list/package.json new file mode 100644 index 0000000..1b1156c --- /dev/null +++ b/uni_modules/uv-list/package.json @@ -0,0 +1,87 @@ +{ + "id": "uv-list", + "displayName": "uv-list 列表 全面兼容vue3+2、app、h5、小程序等多端", + "version": "1.0.9", + "description": "uv-list 多功能高性能列表组件", + "keywords": [ + "uv-list", + "uvui", + "uv-ui", + "list", + "列表" +], + "repository": "", + "engines": { + "HBuilderX": "^3.1.0" + }, + "dcloudext": { + "type": "component-vue", + "sale": { + "regular": { + "price": "0.00" + }, + "sourcecode": { + "price": "0.00" + } + }, + "contact": { + "qq": "" + }, + "declaration": { + "ads": "无", + "data": "插件不采集任何数据", + "permissions": "无" + }, + "npmurl": "" + }, + "uni_modules": { + "dependencies": [ + "uv-ui-tools" + ], + "encrypt": [], + "platforms": { + "cloud": { + "tcb": "y", + "aliyun": "y" + }, + "client": { + "Vue": { + "vue2": "y", + "vue3": "y" + }, + "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", + "钉钉": "u", + "快手": "u", + "飞书": "u", + "京东": "u" + }, + "快应用": { + "华为": "u", + "联盟": "u" + } + } + } + } +} \ No newline at end of file diff --git a/uni_modules/uv-list/readme.md b/uni_modules/uv-list/readme.md new file mode 100644 index 0000000..930cbd4 --- /dev/null +++ b/uni_modules/uv-list/readme.md @@ -0,0 +1,27 @@ +## List 列表 + +> **组件名:uv-list** + +List列表组件,包含基本列表样式、默认插槽机制、可扩展插槽机制、长列表性能优化、多端兼容。 + +在vue页面里,它默认使用页面级滚动,这样做的目的是性能更加友好。在app-nvue页面里,它默认使用原生list组件滚动,这样的长列表,在滚动出屏幕外后,系统会回收不可见区域的渲染内存资源,不会造成滚动越长手机越卡的问题。 + +uv-list组件是父容器,里面的核心是uv-list-item子组件,它代表列表中的一个可重复行,子组件可以无限循环。 + +uv-list-item有很多风格,uv-list-item组件通过内置的属性,满足一些常用的场景。当内置属性不满足需求时,可以通过扩展插槽来自定义列表内容,插槽包括:默认插槽(完全自定义内容)、具名插槽(header | body | footer),根据需求进行扩展。 + +内置属性可以覆盖的场景包括:导航列表、设置列表、小图标列表等,其他不能满足的场景使用插槽进行扩展。 + +# 查看文档 + +## [下载完整示例项目](https://ext.dcloud.net.cn/plugin?name=uv-ui) (请不要 下载插件ZIP) + +### [更多插件,请关注uv-ui组件库](https://ext.dcloud.net.cn/plugin?name=uv-ui) + + + +![image](https://mp-a667b617-c5f1-4a2d-9a54-683a67cff588.cdn.bspapp.com/uv-ui/banner.png) + + + +#### 如使用过程中有任何问题反馈,或者您对uv-ui有一些好的建议,欢迎加入uv-ui官方交流群:官方QQ群 \ No newline at end of file diff --git a/uni_modules/uv-load-more/changelog.md b/uni_modules/uv-load-more/changelog.md new file mode 100644 index 0000000..a2e0fed --- /dev/null +++ b/uni_modules/uv-load-more/changelog.md @@ -0,0 +1,7 @@ +## 1.0.2(2023-06-21) +1. 优化customStyle属性 +## 1.0.1(2023-05-16) +1. 优化组件依赖,修改后无需全局引入,组件导入即可使用 +2. 优化部分功能 +## 1.0.0(2023-05-10) +uv-load-more 加载更多 diff --git a/uni_modules/uv-load-more/components/uv-load-more/props.js b/uni_modules/uv-load-more/components/uv-load-more/props.js new file mode 100644 index 0000000..c6bc287 --- /dev/null +++ b/uni_modules/uv-load-more/components/uv-load-more/props.js @@ -0,0 +1,95 @@ +export default { + props: { + // 组件状态,loadmore-加载前的状态,loading-加载中的状态,nomore-没有更多的状态 + status: { + type: String, + default: 'loadmore' + }, + // 组件背景色 + bgColor: { + type: String, + default: 'transparent' + }, + // 是否显示加载中的图标 + icon: { + type: Boolean, + default: true + }, + // 字体大小 + fontSize: { + type: [String, Number], + default: 14 + }, + // 图标大小 + iconSize: { + type: [String, Number], + default: 16 + }, + // 字体颜色 + color: { + type: String, + default: '#606266' + }, + // 加载中状态的图标,spinner-花朵状图标,circle-圆圈状,semicircle-半圆 + loadingIcon: { + type: String, + default: 'spinner' + }, + // 加载前的提示语 + loadmoreText: { + type: String, + default: '加载更多' + }, + // 加载中提示语 + loadingText: { + type: String, + default: '正在加载...' + }, + // 没有更多的提示语 + nomoreText: { + type: String, + default: '没有更多了' + }, + // 在“没有更多”状态下,是否显示粗点 + isDot: { + type: Boolean, + default: false + }, + // 加载中图标的颜色 + iconColor: { + type: String, + default: '#b7b7b7' + }, + // 上边距 + marginTop: { + type: [String, Number], + default: 10 + }, + // 下边距 + marginBottom: { + type: [String, Number], + default: 10 + }, + // 高度,单位px + height: { + type: [String, Number], + default: 'auto' + }, + // 是否显示左边分割线 + line: { + type: Boolean, + default: false + }, + // 线条颜色 + lineColor: { + type: String, + default: '#E6E8EB' + }, + // 是否虚线,true-虚线,false-实线 + dashed: { + type: Boolean, + default: false + }, + ...uni.$uv?.props?.loadmore + } +} \ No newline at end of file diff --git a/uni_modules/uv-load-more/components/uv-load-more/uv-load-more.vue b/uni_modules/uv-load-more/components/uv-load-more/uv-load-more.vue new file mode 100644 index 0000000..2b5057c --- /dev/null +++ b/uni_modules/uv-load-more/components/uv-load-more/uv-load-more.vue @@ -0,0 +1,152 @@ + + + + + diff --git a/uni_modules/uv-load-more/package.json b/uni_modules/uv-load-more/package.json new file mode 100644 index 0000000..bc502e3 --- /dev/null +++ b/uni_modules/uv-load-more/package.json @@ -0,0 +1,89 @@ +{ + "id": "uv-load-more", + "displayName": "uv-load-more 加载更多 全面兼容小程序、nvue、vue2、vue3等多端", + "version": "1.0.2", + "description": "uv-load-more 此组件一般用于标识页面底部加载数据时的状态,共有三种状态:加载前、加载中、加载后。", + "keywords": [ + "uv-load-more", + "uvui", + "uv-ui", + "more", + "加载更多" +], + "repository": "", + "engines": { + "HBuilderX": "^3.1.0" + }, + "dcloudext": { + "type": "component-vue", + "sale": { + "regular": { + "price": "0.00" + }, + "sourcecode": { + "price": "0.00" + } + }, + "contact": { + "qq": "" + }, + "declaration": { + "ads": "无", + "data": "插件不采集任何数据", + "permissions": "无" + }, + "npmurl": "" + }, + "uni_modules": { + "dependencies": [ + "uv-ui-tools", + "uv-line", + "uv-loading-icon" + ], + "encrypt": [], + "platforms": { + "cloud": { + "tcb": "y", + "aliyun": "y" + }, + "client": { + "Vue": { + "vue2": "y", + "vue3": "y" + }, + "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", + "钉钉": "u", + "快手": "u", + "飞书": "u", + "京东": "u" + }, + "快应用": { + "华为": "u", + "联盟": "u" + } + } + } + } +} \ No newline at end of file diff --git a/uni_modules/uv-load-more/readme.md b/uni_modules/uv-load-more/readme.md new file mode 100644 index 0000000..2e9334e --- /dev/null +++ b/uni_modules/uv-load-more/readme.md @@ -0,0 +1,11 @@ +## LoadMore 加载更多 + +> **组件名:uv-load-more** + +此组件一般用于标识页面底部加载数据时的状态,共有三种状态:加载前、加载中、加载后。 + +### 查看文档 + +### [完整示例项目下载 | 关注更多组件](https://ext.dcloud.net.cn/plugin?name=uv-ui) + +#### 如使用过程中有任何问题,或者您对uv-ui有一些好的建议,欢迎加入 uv-ui 交流群:uv-ui、官方QQ群 diff --git a/uni_modules/uv-loading-icon/changelog.md b/uni_modules/uv-loading-icon/changelog.md new file mode 100644 index 0000000..f17e074 --- /dev/null +++ b/uni_modules/uv-loading-icon/changelog.md @@ -0,0 +1,9 @@ +## 1.0.3(2023-08-14) +1. 新增参数textStyle,自定义文本样式 +## 1.0.2(2023-06-27) +优化 +## 1.0.1(2023-05-16) +1. 优化组件依赖,修改后无需全局引入,组件导入即可使用 +2. 优化部分功能 +## 1.0.0(2023-05-10) +1. 新增uv-loading-icon组件 diff --git a/uni_modules/uv-loading-icon/components/uv-loading-icon/props.js b/uni_modules/uv-loading-icon/components/uv-loading-icon/props.js new file mode 100644 index 0000000..4ef0e94 --- /dev/null +++ b/uni_modules/uv-loading-icon/components/uv-loading-icon/props.js @@ -0,0 +1,67 @@ +export default { + props: { + // 是否显示组件 + show: { + type: Boolean, + default: true + }, + // 颜色 + color: { + type: String, + default: '#909193' + }, + // 提示文字颜色 + textColor: { + type: String, + default: '#909193' + }, + // 文字和图标是否垂直排列 + vertical: { + type: Boolean, + default: false + }, + // 模式选择,circle-圆形,spinner-花朵形,semicircle-半圆形 + mode: { + type: String, + default: 'spinner' + }, + // 图标大小,单位默认px + size: { + type: [String, Number], + default: 24 + }, + // 文字大小 + textSize: { + type: [String, Number], + default: 15 + }, + // 文字样式 + textStyle: { + type: Object, + default () { + return {} + } + }, + // 文字内容 + text: { + type: [String, Number], + default: '' + }, + // 动画模式 https://www.runoob.com/cssref/css3-pr-animation-timing-function.html + timingFunction: { + type: String, + default: 'linear' + }, + // 动画执行周期时间 + duration: { + type: [String, Number], + default: 1200 + }, + // mode=circle时的暗边颜色 + inactiveColor: { + type: String, + default: '' + }, + ...uni.$uv?.props?.loadingIcon + } +} \ No newline at end of file diff --git a/uni_modules/uv-loading-icon/components/uv-loading-icon/uv-loading-icon.vue b/uni_modules/uv-loading-icon/components/uv-loading-icon/uv-loading-icon.vue new file mode 100644 index 0000000..5650470 --- /dev/null +++ b/uni_modules/uv-loading-icon/components/uv-loading-icon/uv-loading-icon.vue @@ -0,0 +1,347 @@ + + + + + diff --git a/uni_modules/uv-loading-icon/package.json b/uni_modules/uv-loading-icon/package.json new file mode 100644 index 0000000..1485897 --- /dev/null +++ b/uni_modules/uv-loading-icon/package.json @@ -0,0 +1,87 @@ +{ + "id": "uv-loading-icon", + "displayName": "uv-loading-icon 加载动画 全面兼容vue3+2、app、h5、小程序等多端", + "version": "1.0.3", + "description": "此组件为一个小动画,目前用在uv-ui的uv-load-more加载更多等组件,还可以运用在项目中正在加载状态场景。", + "keywords": [ + "uv-loading-icon", + "uvui", + "uv-ui", + "loading", + "加载动画" +], + "repository": "", + "engines": { + "HBuilderX": "^3.1.0" + }, + "dcloudext": { + "type": "component-vue", + "sale": { + "regular": { + "price": "0.00" + }, + "sourcecode": { + "price": "0.00" + } + }, + "contact": { + "qq": "" + }, + "declaration": { + "ads": "无", + "data": "插件不采集任何数据", + "permissions": "无" + }, + "npmurl": "" + }, + "uni_modules": { + "dependencies": [ + "uv-ui-tools" + ], + "encrypt": [], + "platforms": { + "cloud": { + "tcb": "y", + "aliyun": "y" + }, + "client": { + "Vue": { + "vue2": "y", + "vue3": "y" + }, + "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", + "钉钉": "u", + "快手": "u", + "飞书": "u", + "京东": "u" + }, + "快应用": { + "华为": "u", + "联盟": "u" + } + } + } + } +} \ No newline at end of file diff --git a/uni_modules/uv-loading-icon/readme.md b/uni_modules/uv-loading-icon/readme.md new file mode 100644 index 0000000..7b0cf0f --- /dev/null +++ b/uni_modules/uv-loading-icon/readme.md @@ -0,0 +1,19 @@ +## LoadingIcon 加载动画 + +> **组件名:uv-loading-icon** + +此组件为一个小动画,目前用在 `uv-ui` 的 `uv-load-more` 加载更多等组件,还可以运用在项目中正在加载状态场景。 + +# 查看文档 + +## [下载完整示例项目](https://ext.dcloud.net.cn/plugin?name=uv-ui) (请不要 下载插件ZIP) + +### [更多插件,请关注uv-ui组件库](https://ext.dcloud.net.cn/plugin?name=uv-ui) + + + +![image](https://mp-a667b617-c5f1-4a2d-9a54-683a67cff588.cdn.bspapp.com/uv-ui/banner.png) + + + +#### 如使用过程中有任何问题反馈,或者您对uv-ui有一些好的建议,欢迎加入uv-ui官方交流群:官方QQ群 \ No newline at end of file diff --git a/uni_modules/uv-loading-page/changelog.md b/uni_modules/uv-loading-page/changelog.md new file mode 100644 index 0000000..4b7ef61 --- /dev/null +++ b/uni_modules/uv-loading-page/changelog.md @@ -0,0 +1,11 @@ +## 1.0.4(2024-01-20) +1. 修改上版本带出的问题 +## 1.0.3(2024-01-15) +1. 重构,避免初始加载的时候先显示页面的问题 +## 1.0.2(2023-07-02) +uv-loading-page 由于弹出层uv-transition的修改,组件内部做了相应的修改,参数不变。 +## 1.0.1(2023-05-16) +1. 优化组件依赖,修改后无需全局引入,组件导入即可使用 +2. 优化部分功能 +## 1.0.0(2023-05-10) +uv-loading-page 加载页 diff --git a/uni_modules/uv-loading-page/components/uv-loading-page/props.js b/uni_modules/uv-loading-page/components/uv-loading-page/props.js new file mode 100644 index 0000000..f1a8a06 --- /dev/null +++ b/uni_modules/uv-loading-page/components/uv-loading-page/props.js @@ -0,0 +1,55 @@ +export default { + props: { + // 提示内容 + loadingText: { + type: [String, Number], + default: '' + }, + // 文字上方用于替换loading动画的图片 + image: { + type: String, + default: '' + }, + // 加载动画的模式,circle-圆形,spinner-花朵形,semicircle-半圆形 + loadingMode: { + type: String, + default: 'circle' + }, + // 是否加载中 + loading: { + type: Boolean, + default: false + }, + // 背景色 + bgColor: { + type: String, + default: '#fff' + }, + // 文字颜色 + color: { + type: String, + default: '#C8C8C8' + }, + // 文字大小 + fontSize: { + type: [String, Number], + default: 16 + }, + // 图标大小 + iconSize: { + type: [String, Number], + default: 26 + }, + // 加载中图标的颜色,只能rgb或者十六进制颜色值 + loadingColor: { + type: String, + default: '#C8C8C8' + }, + // 过渡时间 + duration: { + type: [String, Number], + default: 300 + }, + ...uni.$uv?.props?.loadingPage + } +} \ No newline at end of file diff --git a/uni_modules/uv-loading-page/components/uv-loading-page/uv-loading-page.vue b/uni_modules/uv-loading-page/components/uv-loading-page/uv-loading-page.vue new file mode 100644 index 0000000..8fb26d1 --- /dev/null +++ b/uni_modules/uv-loading-page/components/uv-loading-page/uv-loading-page.vue @@ -0,0 +1,96 @@ + + + \ No newline at end of file diff --git a/uni_modules/uv-loading-page/package.json b/uni_modules/uv-loading-page/package.json new file mode 100644 index 0000000..cc9b171 --- /dev/null +++ b/uni_modules/uv-loading-page/package.json @@ -0,0 +1,89 @@ +{ + "id": "uv-loading-page", + "displayName": "uv-loading-page 加载页 全面兼容小程序、nvue、vue2、vue3等多端", + "version": "1.0.4", + "description": "uv-loading-page 该组件是一个页面级的加载效果,可以在页面初始化数据等场景使用,与骨架屏有相似之处。", + "keywords": [ + "uv-loading-page", + "uvui", + "uv-ui", + "page", + "loading" +], + "repository": "", + "engines": { + "HBuilderX": "^3.1.0" + }, + "dcloudext": { + "type": "component-vue", + "sale": { + "regular": { + "price": "0.00" + }, + "sourcecode": { + "price": "0.00" + } + }, + "contact": { + "qq": "" + }, + "declaration": { + "ads": "无", + "data": "插件不采集任何数据", + "permissions": "无" + }, + "npmurl": "" + }, + "uni_modules": { + "dependencies": [ + "uv-ui-tools", + "uv-transition", + "uv-loading-icon" + ], + "encrypt": [], + "platforms": { + "cloud": { + "tcb": "y", + "aliyun": "y" + }, + "client": { + "Vue": { + "vue2": "y", + "vue3": "y" + }, + "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", + "钉钉": "u", + "快手": "u", + "飞书": "u", + "京东": "u" + }, + "快应用": { + "华为": "u", + "联盟": "u" + } + } + } + } +} \ No newline at end of file diff --git a/uni_modules/uv-loading-page/readme.md b/uni_modules/uv-loading-page/readme.md new file mode 100644 index 0000000..3a5dd96 --- /dev/null +++ b/uni_modules/uv-loading-page/readme.md @@ -0,0 +1,11 @@ +## LoadingPage 加载页 + +> **组件名:uv-loading-page** + +该组件是一个页面级的加载效果,可以在页面初始化数据等场景使用,与骨架屏有相似之处。 + +### 查看文档 + +### [完整示例项目下载 | 关注更多组件](https://ext.dcloud.net.cn/plugin?name=uv-ui) + +#### 如使用过程中有任何问题,或者您对uv-ui有一些好的建议,欢迎加入 uv-ui 交流群:uv-ui、官方QQ群 diff --git a/uni_modules/uv-modal/changelog.md b/uni_modules/uv-modal/changelog.md new file mode 100644 index 0000000..d532286 --- /dev/null +++ b/uni_modules/uv-modal/changelog.md @@ -0,0 +1,28 @@ +## 1.0.11(2023-12-20) +1. 优化 +## 1.0.10(2023-12-19) +1. 修复confirm中快速使用closeLoading关闭加载状态失效的BUG +## 1.0.9(2023-11-28) +1. 修复上版本引出的确认和取消按钮均不显示,还有高度的BUG +## 1.0.8(2023-09-08) +1. 修复两个按钮之间竖线不显示的问题 +2. uv-ui项目自定义按钮示例修改 +## 1.0.7(2023-08-30) +1. 增加align参数,设置文本对齐方式,left center right +2. 增加textStyle参数,设置文本样式 +## 1.0.6(2023-08-23) +1. 修复异步loading时,确认回调还会一直触发 +## 1.0.5(2023-07-03) +去除插槽判断,避免某些平台不显示的BUG +## 1.0.4(2023-07-02) +uv-modal 由于弹出层uv-popup的修改,打开和关闭方法更改,详情参考文档:https://www.uvui.cn/components/modal.html +## 1.0.3(2023-06-29) +1. 增加closeLoading方法,方便异步加载手动取消 +2. 更新文档 +## 1.0.2(2023-06-11) +1. 新增zIndex参数 +## 1.0.1(2023-05-16) +1. 优化组件依赖,修改后无需全局引入,组件导入即可使用 +2. 优化部分功能 +## 1.0.0(2023-05-10) +uv-modal 模态框 diff --git a/uni_modules/uv-modal/components/uv-modal/props.js b/uni_modules/uv-modal/components/uv-modal/props.js new file mode 100644 index 0000000..6cb1f41 --- /dev/null +++ b/uni_modules/uv-modal/components/uv-modal/props.js @@ -0,0 +1,90 @@ +export default { + props: { + // 标题 + title: { + type: [String], + default: '' + }, + // 弹窗内容 + content: { + type: String, + default: '' + }, + // 确认文案 + confirmText: { + type: String, + default: '确认' + }, + // 取消文案 + cancelText: { + type: String, + default: '取消' + }, + // 是否显示确认按钮 + showConfirmButton: { + type: Boolean, + default: true + }, + // 是否显示取消按钮 + showCancelButton: { + type: Boolean, + default: false + }, + // 确认按钮颜色 + confirmColor: { + type: String, + default: '#2979ff' + }, + // 取消文字颜色 + cancelColor: { + type: String, + default: '#606266' + }, + // 对调确认和取消的位置 + buttonReverse: { + type: Boolean, + default: false + }, + // 是否开启缩放效果 + zoom: { + type: Boolean, + default: true + }, + // 层级 + zIndex: { + type: [String, Number], + default: 10075 + }, + // 是否异步关闭,只对确定按钮有效 + asyncClose: { + type: Boolean, + default: false + }, + // 是否允许点击遮罩关闭modal + closeOnClickOverlay: { + type: Boolean, + default: true + }, + // 给一个负的margin-top,往上偏移,避免和键盘重合的情况 + negativeTop: { + type: [String, Number], + default: 0 + }, + // modal宽度,不支持百分比,可以数值,px,rpx单位 + width: { + type: [String, Number], + default: '650rpx' + }, + // 文本对齐方式,默认left + align: { + type: String, + default: 'left' + }, + // 文本自定义样式 + textStyle: { + type: [Object, String], + default: '' + }, + ...uni.$uv?.props?.modal + } +} \ No newline at end of file diff --git a/uni_modules/uv-modal/components/uv-modal/uv-modal.vue b/uni_modules/uv-modal/components/uv-modal/uv-modal.vue new file mode 100644 index 0000000..4577b99 --- /dev/null +++ b/uni_modules/uv-modal/components/uv-modal/uv-modal.vue @@ -0,0 +1,245 @@ + + + + + diff --git a/uni_modules/uv-modal/package.json b/uni_modules/uv-modal/package.json new file mode 100644 index 0000000..2a815c0 --- /dev/null +++ b/uni_modules/uv-modal/package.json @@ -0,0 +1,90 @@ +{ + "id": "uv-modal", + "displayName": "uv-modal 模态框 全面兼容vue3+2、app、h5、小程序等多端", + "version": "1.0.11", + "description": "支持自定义内容,与uniapp提供的API uni.showModal类似,但是功能更强大,更加灵活", + "keywords": [ + "uv-modal", + "uvui", + "uv-ui", + "modal", + "模态框" +], + "repository": "", + "engines": { + "HBuilderX": "^3.1.0" + }, + "dcloudext": { + "type": "component-vue", + "sale": { + "regular": { + "price": "0.00" + }, + "sourcecode": { + "price": "0.00" + } + }, + "contact": { + "qq": "" + }, + "declaration": { + "ads": "无", + "data": "插件不采集任何数据", + "permissions": "无" + }, + "npmurl": "" + }, + "uni_modules": { + "dependencies": [ + "uv-ui-tools", + "uv-popup", + "uv-line", + "uv-loading-icon" + ], + "encrypt": [], + "platforms": { + "cloud": { + "tcb": "y", + "aliyun": "y" + }, + "client": { + "Vue": { + "vue2": "y", + "vue3": "y" + }, + "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", + "钉钉": "u", + "快手": "u", + "飞书": "u", + "京东": "u" + }, + "快应用": { + "华为": "u", + "联盟": "u" + } + } + } + } +} \ No newline at end of file diff --git a/uni_modules/uv-modal/readme.md b/uni_modules/uv-modal/readme.md new file mode 100644 index 0000000..e1aec02 --- /dev/null +++ b/uni_modules/uv-modal/readme.md @@ -0,0 +1,23 @@ +## Modal 模态框 + +> **组件名:uv-modal** + +弹出模态框,常用于消息提示、消息确认、在当前页面内完成特定的交互操作。 + +特性:支持自定义内容,与uniapp提供的API `uni.showModal` 类似,但是功能更强大,更加灵活。 + +运用场景:弹窗验证码输入等场景 + +# 查看文档 + +## [下载完整示例项目](https://ext.dcloud.net.cn/plugin?name=uv-ui) (请不要 下载插件ZIP) + +### [更多插件,请关注uv-ui组件库](https://ext.dcloud.net.cn/plugin?name=uv-ui) + + + +![image](https://mp-a667b617-c5f1-4a2d-9a54-683a67cff588.cdn.bspapp.com/uv-ui/banner.png) + + + +#### 如使用过程中有任何问题反馈,或者您对uv-ui有一些好的建议,欢迎加入uv-ui官方交流群:官方QQ群 \ No newline at end of file diff --git a/uni_modules/uv-navbar/changelog.md b/uni_modules/uv-navbar/changelog.md new file mode 100644 index 0000000..01cc4fd --- /dev/null +++ b/uni_modules/uv-navbar/changelog.md @@ -0,0 +1,17 @@ +## 1.0.7(2023-08-16) +1. 修复ios可能存在点击返回按钮点不到的情况 +## 1.0.6(2023-08-07) +1. 修复nvue在ios端可能存在背景图样式错乱的BUG +## 1.0.5(2023-08-04) +1. bgColor设置背景图片,增加imgMode属性 +## 1.0.4(2023-08-01) +1. bgColor属性支持背景图片,在线图片或base64图片都可以 +## 1.0.3(2023-07-03) +去除插槽判断,避免某些平台不显示的BUG +## 1.0.2(2023-06-05) +1. 兼容渐变背景色 +## 1.0.1(2023-05-16) +1. 优化组件依赖,修改后无需全局引入,组件导入即可使用 +2. 优化部分功能 +## 1.0.0(2023-05-10) +uv-navbar 自定义导航栏 diff --git a/uni_modules/uv-navbar/components/uv-navbar/props.js b/uni_modules/uv-navbar/components/uv-navbar/props.js new file mode 100644 index 0000000..47fe150 --- /dev/null +++ b/uni_modules/uv-navbar/components/uv-navbar/props.js @@ -0,0 +1,89 @@ +export default { + props: { + // 是否开启顶部安全区适配 + safeAreaInsetTop: { + type: Boolean, + default: true + }, + // 固定在顶部时,是否生成一个等高元素,以防止塌陷 + placeholder: { + type: Boolean, + default: false + }, + // 是否固定在顶部 + fixed: { + type: Boolean, + default: true + }, + // 是否显示下边框 + border: { + type: Boolean, + default: false + }, + // 左边的图标 + leftIcon: { + type: String, + default: 'arrow-left' + }, + // 左边的提示文字 + leftText: { + type: String, + default: '' + }, + // 左右的提示文字 + rightText: { + type: String, + default: '' + }, + // 右边的图标 + rightIcon: { + type: String, + default: '' + }, + // 标题 + title: { + type: [String, Number], + default: '' + }, + // 背景颜色 + bgColor: { + type: String, + default: '#ffffff' + }, + imgMode: { + type: String, + default: 'aspectFill' + }, + // 标题的宽度 + titleWidth: { + type: [String, Number], + default: '400rpx' + }, + // 导航栏高度 + height: { + type: [String, Number], + default: '44px' + }, + // 左侧返回图标的大小 + leftIconSize: { + type: [String, Number], + default: 20 + }, + // 左侧返回图标的颜色 + leftIconColor: { + type: String, + default: '#303133' + }, + // 点击左侧区域(返回图标),是否自动返回上一页 + autoBack: { + type: Boolean, + default: false + }, + // 标题的样式,对象或字符串 + titleStyle: { + type: [String, Object], + default: '' + }, + ...uni.$uv?.props?.navbar + } +} \ No newline at end of file diff --git a/uni_modules/uv-navbar/components/uv-navbar/uv-navbar.vue b/uni_modules/uv-navbar/components/uv-navbar/uv-navbar.vue new file mode 100644 index 0000000..a46ad7a --- /dev/null +++ b/uni_modules/uv-navbar/components/uv-navbar/uv-navbar.vue @@ -0,0 +1,245 @@ + + + + + diff --git a/uni_modules/uv-navbar/package.json b/uni_modules/uv-navbar/package.json new file mode 100644 index 0000000..8d429de --- /dev/null +++ b/uni_modules/uv-navbar/package.json @@ -0,0 +1,89 @@ +{ + "id": "uv-navbar", + "displayName": "uv-navbar 自定义导航栏 全面兼容vue3+2、app、h5、小程序等多端", + "version": "1.0.7", + "description": "uv-navbar 此组件一般用于在特殊情况下,需要自定义导航栏的时候用到,一般建议使用自带的原生导航栏。", + "keywords": [ + "uv-navbar", + "uvui", + "uv-ui", + "navbar", + "自定义导航栏" +], + "repository": "", + "engines": { + "HBuilderX": "^3.1.0" + }, + "dcloudext": { + "type": "component-vue", + "sale": { + "regular": { + "price": "0.00" + }, + "sourcecode": { + "price": "0.00" + } + }, + "contact": { + "qq": "" + }, + "declaration": { + "ads": "无", + "data": "插件不采集任何数据", + "permissions": "无" + }, + "npmurl": "" + }, + "uni_modules": { + "dependencies": [ + "uv-ui-tools", + "uv-icon", + "uv-status-bar" + ], + "encrypt": [], + "platforms": { + "cloud": { + "tcb": "y", + "aliyun": "y" + }, + "client": { + "Vue": { + "vue2": "y", + "vue3": "y" + }, + "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", + "钉钉": "u", + "快手": "u", + "飞书": "u", + "京东": "u" + }, + "快应用": { + "华为": "u", + "联盟": "u" + } + } + } + } +} \ No newline at end of file diff --git a/uni_modules/uv-navbar/readme.md b/uni_modules/uv-navbar/readme.md new file mode 100644 index 0000000..412ea7b --- /dev/null +++ b/uni_modules/uv-navbar/readme.md @@ -0,0 +1,19 @@ +## Navbar 自定义导航栏 + +> **组件名:uv-navbar** + +此组件一般用于在特殊情况下,需要自定义导航栏的时候用到,一般建议使用自带的原生导航栏,支持渐变色、透明色、图片背景。 + +# 查看文档 + +## [下载完整示例项目](https://ext.dcloud.net.cn/plugin?name=uv-ui) (请不要 下载插件ZIP) + +### [更多插件,请关注uv-ui组件库](https://ext.dcloud.net.cn/plugin?name=uv-ui) + + + +![image](https://mp-a667b617-c5f1-4a2d-9a54-683a67cff588.cdn.bspapp.com/uv-ui/banner.png) + + + +#### 如使用过程中有任何问题反馈,或者您对uv-ui有一些好的建议,欢迎加入uv-ui官方交流群:官方QQ群 \ No newline at end of file diff --git a/uni_modules/uv-no-network/changelog.md b/uni_modules/uv-no-network/changelog.md new file mode 100644 index 0000000..b6fc0ed --- /dev/null +++ b/uni_modules/uv-no-network/changelog.md @@ -0,0 +1,5 @@ +## 1.0.1(2023-05-16) +1. 优化组件依赖,修改后无需全局引入,组件导入即可使用 +2. 优化部分功能 +## 1.0.0(2023-05-10) +uv-no-network 无网络提示 diff --git a/uni_modules/uv-no-network/components/uv-no-network/props.js b/uni_modules/uv-no-network/components/uv-no-network/props.js new file mode 100644 index 0000000..595b1fc --- /dev/null +++ b/uni_modules/uv-no-network/components/uv-no-network/props.js @@ -0,0 +1,20 @@ +export default { + props: { + // 页面文字提示 + tips: { + type: String, + default: '哎呀,网络信号丢失' + }, + // 一个z-index值,用于设置没有网络这个组件的层次,因为页面可能会有其他定位的元素层级过高,导致此组件被覆盖 + zIndex: { + type: [String, Number], + default: '' + }, + // image 没有网络的图片提示 + image: { + type: String, + default: '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' + }, + ...uni.$uv?.props?.noNetwork + } +} \ No newline at end of file diff --git a/uni_modules/uv-no-network/components/uv-no-network/uv-no-network.vue b/uni_modules/uv-no-network/components/uv-no-network/uv-no-network.vue new file mode 100644 index 0000000..5f134fa --- /dev/null +++ b/uni_modules/uv-no-network/components/uv-no-network/uv-no-network.vue @@ -0,0 +1,222 @@ + + + + + diff --git a/uni_modules/uv-no-network/package.json b/uni_modules/uv-no-network/package.json new file mode 100644 index 0000000..cb48aa9 --- /dev/null +++ b/uni_modules/uv-no-network/package.json @@ -0,0 +1,90 @@ +{ + "id": "uv-no-network", + "displayName": "uv-no-network 无网络提示 全面兼容小程序、nvue、vue2、vue3等多端", + "version": "1.0.1", + "description": "uv-no-network 该组件在没有任何网络的情况下,显示在内容上方,无需任何配置,引入即可,内部自动处理所有功能和事件。", + "keywords": [ + "uv-no-network", + "uvui", + "uv-ui", + "network", + "无网络" +], + "repository": "", + "engines": { + "HBuilderX": "^3.1.0" + }, + "dcloudext": { + "type": "component-vue", + "sale": { + "regular": { + "price": "0.00" + }, + "sourcecode": { + "price": "0.00" + } + }, + "contact": { + "qq": "" + }, + "declaration": { + "ads": "无", + "data": "插件不采集任何数据", + "permissions": "无" + }, + "npmurl": "" + }, + "uni_modules": { + "dependencies": [ + "uv-ui-tools", + "uv-overlay", + "uv-icon", + "uv-button" + ], + "encrypt": [], + "platforms": { + "cloud": { + "tcb": "y", + "aliyun": "y" + }, + "client": { + "Vue": { + "vue2": "y", + "vue3": "y" + }, + "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", + "钉钉": "u", + "快手": "u", + "飞书": "u", + "京东": "u" + }, + "快应用": { + "华为": "u", + "联盟": "u" + } + } + } + } +} \ No newline at end of file diff --git a/uni_modules/uv-no-network/readme.md b/uni_modules/uv-no-network/readme.md new file mode 100644 index 0000000..0e4a1a2 --- /dev/null +++ b/uni_modules/uv-no-network/readme.md @@ -0,0 +1,11 @@ +## NoNetwork 无网络提示 + +> **组件名:uv-no-network** + +该组件在没有任何网络的情况下,显示在内容上方,无需任何配置,引入即可,内部自动处理所有功能和事件。 + +### 查看文档 + +### [完整示例项目下载 | 关注更多组件](https://ext.dcloud.net.cn/plugin?name=uv-ui) + +#### 如使用过程中有任何问题,或者您对uv-ui有一些好的建议,欢迎加入 uv-ui 交流群:uv-ui、官方QQ群 diff --git a/uni_modules/uv-notice-bar/changelog.md b/uni_modules/uv-notice-bar/changelog.md new file mode 100644 index 0000000..cdfec7d --- /dev/null +++ b/uni_modules/uv-notice-bar/changelog.md @@ -0,0 +1,19 @@ +## 1.0.7(2023-10-13) +1. unmounted兼容vue3 +## 1.0.6(2023-08-03) +1. 竖向滚动时候增加change回调 +## 1.0.5(2023-07-21) +1. 增加icon类型,支持设置false不显示图标 +2. 优化文档 +## 1.0.4(2023-07-03) +1. 增加disableScroll 属性,禁止自动滚动 +2. 优化文档 +## 1.0.3(2023-06-04) +1. 修复text传值为null报错的问题 +## 1.0.2(2023-05-30) +1. 修复error报错的BUG +## 1.0.1(2023-05-16) +1. 优化组件依赖,修改后无需全局引入,组件导入即可使用 +2. 优化部分功能 +## 1.0.0(2023-05-10) +uv-notice-bar 滚动通知 diff --git a/uni_modules/uv-notice-bar/components/uv-column-notice/props.js b/uni_modules/uv-notice-bar/components/uv-column-notice/props.js new file mode 100644 index 0000000..d93917c --- /dev/null +++ b/uni_modules/uv-notice-bar/components/uv-column-notice/props.js @@ -0,0 +1,61 @@ +export default { + props: { + // 显示的内容,字符串 + text: { + type: [Array], + default: '' + }, + // 是否显示左侧的音量图标 + icon: { + type: [String, Boolean, null], + default: 'volume' + }, + // 通告模式,link-显示右箭头,closable-显示右侧关闭图标 + mode: { + type: String, + default: '' + }, + // 文字颜色,各图标也会使用文字颜色 + color: { + type: String, + default: '#f9ae3d' + }, + // 背景颜色 + bgColor: { + type: String, + default: '#fdf6ec' + }, + // 字体大小,单位px + fontSize: { + type: [String, Number], + default: 14 + }, + // 水平滚动时的滚动速度,即每秒滚动多少px(px),这有利于控制文字无论多少时,都能有一个恒定的速度 + speed: { + type: [String, Number], + default: 80 + }, + // direction = row时,是否使用步进形式滚动 + step: { + type: Boolean, + default: false + }, + // 滚动一个周期的时间长,单位ms + duration: { + type: [String, Number], + default: 1500 + }, + // 是否禁止用手滑动切换,仅`direction="column"生效` + // 目前HX2.6.11,只支持App 2.5.5+、H5 2.5.5+、支付宝小程序、字节跳动小程序 + disableTouch: { + type: Boolean, + default: true + }, + // 是否禁止滚动,仅`direction="column"生效` + disableScroll: { + type: Boolean, + default: false + }, + ...uni.$uv?.props?.columnNotice + } +} \ No newline at end of file diff --git a/uni_modules/uv-notice-bar/components/uv-column-notice/uv-column-notice.vue b/uni_modules/uv-notice-bar/components/uv-column-notice/uv-column-notice.vue new file mode 100644 index 0000000..73c6bfc --- /dev/null +++ b/uni_modules/uv-notice-bar/components/uv-column-notice/uv-column-notice.vue @@ -0,0 +1,176 @@ + + + + + diff --git a/uni_modules/uv-notice-bar/components/uv-notice-bar/props.js b/uni_modules/uv-notice-bar/components/uv-notice-bar/props.js new file mode 100644 index 0000000..3fe0b44 --- /dev/null +++ b/uni_modules/uv-notice-bar/components/uv-notice-bar/props.js @@ -0,0 +1,76 @@ +export default { + props: { + // 显示的内容,数组 + text: { + type: [Array, String], + default: () => [] + }, + // 通告滚动模式,row-横向滚动,column-竖向滚动 + direction: { + type: String, + default: 'row' + }, + // direction = row时,是否使用步进形式滚动 + step: { + type: Boolean, + default: false + }, + // 是否显示左侧的音量图标 + icon: { + type: [String, Boolean, null], + default: 'volume' + }, + // 通告模式,link-显示右箭头,closable-显示右侧关闭图标 + mode: { + type: String, + default: '' + }, + // 文字颜色,各图标也会使用文字颜色 + color: { + type: String, + default: '#f9ae3d' + }, + // 背景颜色 + bgColor: { + type: String, + default: '#fdf6ec' + }, + // 水平滚动时的滚动速度,即每秒滚动多少px(px),这有利于控制文字无论多少时,都能有一个恒定的速度 + speed: { + type: [String, Number], + default: 80 + }, + // 字体大小 + fontSize: { + type: [String, Number], + default: 14 + }, + // 滚动一个周期的时间长,单位ms + duration: { + type: [String, Number], + default: 2000 + }, + // 跳转的页面路径 + url: { + type: String, + default: '' + }, + // 页面跳转的类型 + linkType: { + type: String, + default: 'navigateTo' + }, + // 是否禁止用手滑动切换 + // 目前HX2.6.11,只支持App 2.5.5+、H5 2.5.5+、支付宝小程序、字节跳动小程序 + disableTouch: { + type: Boolean, + default: true + }, + // 是否禁止滚动,仅`direction="column"生效` + disableScroll: { + type: Boolean, + default: false + }, + ...uni.$uv?.props?.noticeBar + } +} \ No newline at end of file diff --git a/uni_modules/uv-notice-bar/components/uv-notice-bar/uv-notice-bar.vue b/uni_modules/uv-notice-bar/components/uv-notice-bar/uv-notice-bar.vue new file mode 100644 index 0000000..14dd7c5 --- /dev/null +++ b/uni_modules/uv-notice-bar/components/uv-notice-bar/uv-notice-bar.vue @@ -0,0 +1,110 @@ + + + + diff --git a/uni_modules/uv-notice-bar/components/uv-row-notice/props.js b/uni_modules/uv-notice-bar/components/uv-row-notice/props.js new file mode 100644 index 0000000..cba1823 --- /dev/null +++ b/uni_modules/uv-notice-bar/components/uv-row-notice/props.js @@ -0,0 +1,40 @@ +export default { + props: { + // 显示的内容,字符串 + text: { + type: String, + default: '' + }, + // 是否显示左侧的音量图标 + icon: { + type: [String, Boolean, null], + default: 'volume' + }, + // 通告模式,link-显示右箭头,closable-显示右侧关闭图标 + mode: { + type: String, + default: '' + }, + // 文字颜色,各图标也会使用文字颜色 + color: { + type: String, + default: '#f9ae3d' + }, + // 背景颜色 + bgColor: { + type: String, + default: '#fdf6ec' + }, + // 字体大小,单位px + fontSize: { + type: [String, Number], + default: 14 + }, + // 水平滚动时的滚动速度,即每秒滚动多少px(rpx),这有利于控制文字无论多少时,都能有一个恒定的速度 + speed: { + type: [String, Number], + default: 80 + }, + ...uni.$uv?.props?.rowNotice + } +} \ No newline at end of file diff --git a/uni_modules/uv-notice-bar/components/uv-row-notice/uv-row-notice.vue b/uni_modules/uv-notice-bar/components/uv-row-notice/uv-row-notice.vue new file mode 100644 index 0000000..16117dd --- /dev/null +++ b/uni_modules/uv-notice-bar/components/uv-row-notice/uv-row-notice.vue @@ -0,0 +1,341 @@ + + + + diff --git a/uni_modules/uv-notice-bar/package.json b/uni_modules/uv-notice-bar/package.json new file mode 100644 index 0000000..f1bca29 --- /dev/null +++ b/uni_modules/uv-notice-bar/package.json @@ -0,0 +1,88 @@ +{ + "id": "uv-notice-bar", + "displayName": "uv-notice-bar 滚动通知 全面兼容vue3+2、app、h5、小程序等多端", + "version": "1.0.7", + "description": "uv-notice-bar 该组件用于滚动通告场景,有多种模式可供选择。", + "keywords": [ + "uv-notice-bar", + "uvui", + "uv-ui", + "notice", + "滚动公告" +], + "repository": "", + "engines": { + "HBuilderX": "^3.1.0" + }, + "dcloudext": { + "type": "component-vue", + "sale": { + "regular": { + "price": "0.00" + }, + "sourcecode": { + "price": "0.00" + } + }, + "contact": { + "qq": "" + }, + "declaration": { + "ads": "无", + "data": "插件不采集任何数据", + "permissions": "无" + }, + "npmurl": "" + }, + "uni_modules": { + "dependencies": [ + "uv-ui-tools", + "uv-icon" + ], + "encrypt": [], + "platforms": { + "cloud": { + "tcb": "y", + "aliyun": "y" + }, + "client": { + "Vue": { + "vue2": "y", + "vue3": "y" + }, + "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", + "钉钉": "u", + "快手": "u", + "飞书": "u", + "京东": "u" + }, + "快应用": { + "华为": "u", + "联盟": "u" + } + } + } + } +} \ No newline at end of file diff --git a/uni_modules/uv-notice-bar/readme.md b/uni_modules/uv-notice-bar/readme.md new file mode 100644 index 0000000..61eb131 --- /dev/null +++ b/uni_modules/uv-notice-bar/readme.md @@ -0,0 +1,19 @@ +## NoticeBar 滚动通知 + +> **组件名:uv-notice-bar** + +该组件用于滚动通告场景,有多种模式可供选择。灵活配置,开箱即用。 + +# 查看文档 + +## [下载完整示例项目](https://ext.dcloud.net.cn/plugin?name=uv-ui) (请不要 下载插件ZIP) + +### [更多插件,请关注uv-ui组件库](https://ext.dcloud.net.cn/plugin?name=uv-ui) + + + +![image](https://mp-a667b617-c5f1-4a2d-9a54-683a67cff588.cdn.bspapp.com/uv-ui/banner.png) + + + +#### 如使用过程中有任何问题反馈,或者您对uv-ui有一些好的建议,欢迎加入uv-ui官方交流群:官方QQ群 \ No newline at end of file diff --git a/uni_modules/uv-notify/changelog.md b/uni_modules/uv-notify/changelog.md new file mode 100644 index 0000000..5d818ba --- /dev/null +++ b/uni_modules/uv-notify/changelog.md @@ -0,0 +1,9 @@ +## 1.0.3(2023-10-13) +1. unmounted兼容vue3 +## 1.0.2(2023-07-02) +uv-notify 由于弹出层uv-popup的修改,打开和关闭方法更改,详情参考文档:https://www.uvui.cn/components/notify.html +## 1.0.1(2023-05-16) +1. 优化组件依赖,修改后无需全局引入,组件导入即可使用 +2. 优化部分功能 +## 1.0.0(2023-05-10) +uv-notify 消息提示 diff --git a/uni_modules/uv-notify/components/uv-notify/props.js b/uni_modules/uv-notify/components/uv-notify/props.js new file mode 100644 index 0000000..5728276 --- /dev/null +++ b/uni_modules/uv-notify/components/uv-notify/props.js @@ -0,0 +1,45 @@ +export default { + props: { + // 到顶部的距离 + top: { + type: [String, Number], + default: 0 + }, + // type主题,primary,success,warning,error + type: { + type: String, + default: 'primary' + }, + // 字体颜色 + color: { + type: String, + default: '#ffffff' + }, + // 背景颜色 + bgColor: { + type: String, + default: '' + }, + // 展示的文字内容 + message: { + type: String, + default: '' + }, + // 展示时长,为0时不消失,单位ms + duration: { + type: [String, Number], + default: 3000 + }, + // 字体大小 + fontSize: { + type: [String, Number], + default: 15 + }, + // 是否留出顶部安全距离(状态栏高度) + safeAreaInsetTop: { + type: Boolean, + default: false + }, + ...uni.$uv?.props?.notify + } +} \ No newline at end of file diff --git a/uni_modules/uv-notify/components/uv-notify/uv-notify.vue b/uni_modules/uv-notify/components/uv-notify/uv-notify.vue new file mode 100644 index 0000000..96c1566 --- /dev/null +++ b/uni_modules/uv-notify/components/uv-notify/uv-notify.vue @@ -0,0 +1,220 @@ + + + + + diff --git a/uni_modules/uv-notify/package.json b/uni_modules/uv-notify/package.json new file mode 100644 index 0000000..921949b --- /dev/null +++ b/uni_modules/uv-notify/package.json @@ -0,0 +1,90 @@ +{ + "id": "uv-notify", + "displayName": "uv-notify 消息提示 全面兼容小程序、nvue、vue2、vue3等多端", + "version": "1.0.3", + "description": "uv-notify 该组件一般用于页面顶部向下滑出一个提示,后自动收起的场景。", + "keywords": [ + "uv-notify", + "uvui", + "uv-ui", + "notify", + "消息提示" +], + "repository": "", + "engines": { + "HBuilderX": "^3.1.0" + }, + "dcloudext": { + "type": "component-vue", + "sale": { + "regular": { + "price": "0.00" + }, + "sourcecode": { + "price": "0.00" + } + }, + "contact": { + "qq": "" + }, + "declaration": { + "ads": "无", + "data": "插件不采集任何数据", + "permissions": "无" + }, + "npmurl": "" + }, + "uni_modules": { + "dependencies": [ + "uv-ui-tools", + "uv-status-bar", + "uv-overlay", + "uv-transition" + ], + "encrypt": [], + "platforms": { + "cloud": { + "tcb": "y", + "aliyun": "y" + }, + "client": { + "Vue": { + "vue2": "y", + "vue3": "y" + }, + "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", + "钉钉": "u", + "快手": "u", + "飞书": "u", + "京东": "u" + }, + "快应用": { + "华为": "u", + "联盟": "u" + } + } + } + } +} \ No newline at end of file diff --git a/uni_modules/uv-notify/readme.md b/uni_modules/uv-notify/readme.md new file mode 100644 index 0000000..482344a --- /dev/null +++ b/uni_modules/uv-notify/readme.md @@ -0,0 +1,11 @@ +## Notify 消息提示 + +> **组件名:uv-notify** + +该组件一般用于页面顶部向下滑出一个提示,后自动收起的场景。 + +### 查看文档 + +### [完整示例项目下载 | 关注更多组件](https://ext.dcloud.net.cn/plugin?name=uv-ui) + +#### 如使用过程中有任何问题,或者您对uv-ui有一些好的建议,欢迎加入 uv-ui 交流群:uv-ui、官方QQ群 diff --git a/uni_modules/uv-number-box/changelog.md b/uni_modules/uv-number-box/changelog.md new file mode 100644 index 0000000..3f07995 --- /dev/null +++ b/uni_modules/uv-number-box/changelog.md @@ -0,0 +1,7 @@ +## 1.0.2(2023-07-13) +1. 修复 uv-number-box设置value属性不生效的BUG +## 1.0.1(2023-05-16) +1. 优化组件依赖,修改后无需全局引入,组件导入即可使用 +2. 优化部分功能 +## 1.0.0(2023-05-10) +uv-number-box 步进器 diff --git a/uni_modules/uv-number-box/components/uv-number-box/props.js b/uni_modules/uv-number-box/components/uv-number-box/props.js new file mode 100644 index 0000000..64b633b --- /dev/null +++ b/uni_modules/uv-number-box/components/uv-number-box/props.js @@ -0,0 +1,113 @@ +export default { + props: { + value: { + type: [String, Number], + default: 0 + }, + modelValue: { + type: [String, Number], + default: 0 + }, + // 步进器标识符,在change回调返回 + name: { + type: [String, Number], + default: '' + }, + // 最小值 + min: { + type: [String, Number], + default: 1 + }, + // 最大值 + max: { + type: [String, Number], + default: Number.MAX_SAFE_INTEGER + }, + // 加减的步长,可为小数 + step: { + type: [String, Number], + default: 1 + }, + // 是否只允许输入整数 + integer: { + type: Boolean, + default: false + }, + // 是否禁用,包括输入框,加减按钮 + disabled: { + type: Boolean, + default: false + }, + // 是否禁用输入框 + disabledInput: { + type: Boolean, + default: false + }, + // 是否开启异步变更,开启后需要手动控制输入值 + asyncChange: { + type: Boolean, + default: false + }, + // 输入框宽度,单位为px + inputWidth: { + type: [String, Number], + default: 35 + }, + // 是否显示减少按钮 + showMinus: { + type: Boolean, + default: true + }, + // 是否显示增加按钮 + showPlus: { + type: Boolean, + default: true + }, + // 显示的小数位数 + decimalLength: { + type: [String, Number, null], + default: null + }, + // 是否开启长按加减手势 + longPress: { + type: Boolean, + default: true + }, + // 输入框文字和加减按钮图标的颜色 + color: { + type: String, + default: '#323233' + }, + // 按钮大小,宽高等于此值,单位px,输入框高度和此值保持一致 + buttonSize: { + type: [String, Number], + default: 30 + }, + // 输入框和按钮的背景颜色 + bgColor: { + type: String, + default: '#EBECEE' + }, + // 指定光标于键盘的距离,避免键盘遮挡输入框,单位px + cursorSpacing: { + type: [String, Number], + default: 100 + }, + // 是否禁用增加按钮 + disablePlus: { + type: Boolean, + default: false + }, + // 是否禁用减少按钮 + disableMinus: { + type: Boolean, + default: false + }, + // 加减按钮图标的样式 + iconStyle: { + type: [Object, String], + default: '' + }, + ...uni.$uv?.props?.numberBox + } +} \ No newline at end of file diff --git a/uni_modules/uv-number-box/components/uv-number-box/uv-number-box.vue b/uni_modules/uv-number-box/components/uv-number-box/uv-number-box.vue new file mode 100644 index 0000000..6937e89 --- /dev/null +++ b/uni_modules/uv-number-box/components/uv-number-box/uv-number-box.vue @@ -0,0 +1,395 @@ + + + + \ No newline at end of file diff --git a/uni_modules/uv-number-box/package.json b/uni_modules/uv-number-box/package.json new file mode 100644 index 0000000..771e6eb --- /dev/null +++ b/uni_modules/uv-number-box/package.json @@ -0,0 +1,88 @@ +{ + "id": "uv-number-box", + "displayName": "uv-number-box 步进器 全面兼容小程序、nvue、vue2、vue3等多端", + "version": "1.0.2", + "description": "uv-number-box 该组件一般用于商城购物选择物品数量的场景。", + "keywords": [ + "uv-number-box", + "uvui", + "uv-ui", + "number", + "步进器" +], + "repository": "", + "engines": { + "HBuilderX": "^3.1.0" + }, + "dcloudext": { + "type": "component-vue", + "sale": { + "regular": { + "price": "0.00" + }, + "sourcecode": { + "price": "0.00" + } + }, + "contact": { + "qq": "" + }, + "declaration": { + "ads": "无", + "data": "插件不采集任何数据", + "permissions": "无" + }, + "npmurl": "" + }, + "uni_modules": { + "dependencies": [ + "uv-ui-tools", + "uv-icon" + ], + "encrypt": [], + "platforms": { + "cloud": { + "tcb": "y", + "aliyun": "y" + }, + "client": { + "Vue": { + "vue2": "y", + "vue3": "y" + }, + "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", + "钉钉": "u", + "快手": "u", + "飞书": "u", + "京东": "u" + }, + "快应用": { + "华为": "u", + "联盟": "u" + } + } + } + } +} \ No newline at end of file diff --git a/uni_modules/uv-number-box/readme.md b/uni_modules/uv-number-box/readme.md new file mode 100644 index 0000000..6b83da9 --- /dev/null +++ b/uni_modules/uv-number-box/readme.md @@ -0,0 +1,11 @@ +## NumberBox 步进器 + +> **组件名:uv-number-box** + +该组件一般用于商城购物选择物品数量的场景。 + +### 查看文档 + +### [完整示例项目下载 | 关注更多组件](https://ext.dcloud.net.cn/plugin?name=uv-ui) + +#### 如使用过程中有任何问题,或者您对uv-ui有一些好的建议,欢迎加入 uv-ui 交流群:uv-ui、官方QQ群 diff --git a/uni_modules/uv-overlay/changelog.md b/uni_modules/uv-overlay/changelog.md new file mode 100644 index 0000000..ff14713 --- /dev/null +++ b/uni_modules/uv-overlay/changelog.md @@ -0,0 +1,9 @@ +## 1.0.3(2023-07-02) +uv-overlay 由于弹出层uv-transition的修改,组件内部做了相应的修改,参数不变。 +## 1.0.2(2023-06-29) +1. 优化,H5端禁止穿透滚动 +## 1.0.1(2023-05-16) +1. 优化组件依赖,修改后无需全局引入,组件导入即可使用 +2. 优化部分功能 +## 1.0.0(2023-05-10) +1. 新增uv-overlay组件 diff --git a/uni_modules/uv-overlay/components/uv-overlay/props.js b/uni_modules/uv-overlay/components/uv-overlay/props.js new file mode 100644 index 0000000..267c613 --- /dev/null +++ b/uni_modules/uv-overlay/components/uv-overlay/props.js @@ -0,0 +1,25 @@ +export default { + props: { + // 是否显示遮罩 + show: { + type: Boolean, + default: false + }, + // 层级z-index + zIndex: { + type: [String, Number], + default: 10070 + }, + // 遮罩的过渡时间,单位为ms + duration: { + type: [String, Number], + default: 300 + }, + // 不透明度值,当做rgba的第四个参数 + opacity: { + type: [String, Number], + default: 0.5 + }, + ...uni.$uv?.props?.overlay + } +} \ No newline at end of file diff --git a/uni_modules/uv-overlay/components/uv-overlay/uv-overlay.vue b/uni_modules/uv-overlay/components/uv-overlay/uv-overlay.vue new file mode 100644 index 0000000..53568c0 --- /dev/null +++ b/uni_modules/uv-overlay/components/uv-overlay/uv-overlay.vue @@ -0,0 +1,85 @@ + + + + diff --git a/uni_modules/uv-overlay/package.json b/uni_modules/uv-overlay/package.json new file mode 100644 index 0000000..a664f3a --- /dev/null +++ b/uni_modules/uv-overlay/package.json @@ -0,0 +1,88 @@ +{ + "id": "uv-overlay", + "displayName": "uv-overlay 遮罩层 全面兼容小程序、nvue、vue2、vue3等多端", + "version": "1.0.3", + "description": "uv-overlay 创建一个遮罩层,用于强调特定的页面元素,并阻止用户对遮罩下层的内容进行操作,一般用于弹窗场景,uv-popup、uv-toast、uv-tooltip等组件就是用了该组件。", + "keywords": [ + "uv-overlay", + "uvui", + "uv-ui", + "overlay", + "遮罩层" +], + "repository": "", + "engines": { + "HBuilderX": "^3.1.0" + }, + "dcloudext": { + "type": "component-vue", + "sale": { + "regular": { + "price": "0.00" + }, + "sourcecode": { + "price": "0.00" + } + }, + "contact": { + "qq": "" + }, + "declaration": { + "ads": "无", + "data": "插件不采集任何数据", + "permissions": "无" + }, + "npmurl": "" + }, + "uni_modules": { + "dependencies": [ + "uv-ui-tools", + "uv-transition" + ], + "encrypt": [], + "platforms": { + "cloud": { + "tcb": "y", + "aliyun": "y" + }, + "client": { + "Vue": { + "vue2": "y", + "vue3": "y" + }, + "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", + "钉钉": "u", + "快手": "u", + "飞书": "u", + "京东": "u" + }, + "快应用": { + "华为": "u", + "联盟": "u" + } + } + } + } +} \ No newline at end of file diff --git a/uni_modules/uv-overlay/readme.md b/uni_modules/uv-overlay/readme.md new file mode 100644 index 0000000..4e8af4b --- /dev/null +++ b/uni_modules/uv-overlay/readme.md @@ -0,0 +1,11 @@ +## Overlay 遮罩层 + +> **组件名:uv-overlay** + +创建一个遮罩层,用于强调特定的页面元素,并阻止用户对遮罩下层的内容进行操作,一般用于弹窗场景,uv-popup、uv-toast、uv-tooltip等组件就是用了该组件。 + +### 查看文档 + +### [完整示例项目下载 | 关注更多组件](https://ext.dcloud.net.cn/plugin?name=uv-ui) + +#### 如使用过程中有任何问题,或者您对uv-ui有一些好的建议,欢迎加入 uv-ui 交流群:uv-ui、官方QQ群 diff --git a/uni_modules/uv-parse/changelog.md b/uni_modules/uv-parse/changelog.md new file mode 100644 index 0000000..4575e07 --- /dev/null +++ b/uni_modules/uv-parse/changelog.md @@ -0,0 +1,13 @@ +## 1.0.4(2023-07-17) +1. 优化文档 +2. 优化其他 +## 1.0.3(2023-06-19) +1. 修复nvue模式下不显示的BUG +## 1.0.2(2023-06-02) +1. 修复可能存在的BUG +2. 优化 +## 1.0.1(2023-05-16) +1. 优化组件依赖,修改后无需全局引入,组件导入即可使用 +2. 优化部分功能 +## 1.0.0(2023-05-10) +uv-parse 富文本解析器 diff --git a/uni_modules/uv-parse/components/uv-parse/node/node.vue b/uni_modules/uv-parse/components/uv-parse/node/node.vue new file mode 100644 index 0000000..5857077 --- /dev/null +++ b/uni_modules/uv-parse/components/uv-parse/node/node.vue @@ -0,0 +1,576 @@ +