├── App.vue ├── README.md ├── api ├── activity.js ├── basic.js ├── distribution.js ├── login.js ├── merchant.js ├── pet.js ├── product.js ├── userInfo.js └── websocket.js ├── common ├── appRequestUrl.js ├── card │ ├── adopt.js │ ├── forum-no-poster.js │ ├── forum.js │ ├── owner.js │ └── pet.js ├── city.js ├── data.js ├── graceChecker.js ├── jweixin.js ├── moment.js ├── qqmap-wx-jssdk.min.js ├── router.js └── utils.js ├── components ├── cu-custom │ └── index.vue ├── home │ ├── rf-category-nav │ │ └── index.vue │ ├── rf-coupon │ │ └── index.vue │ ├── rf-home-header │ │ └── index.vue │ ├── rf-home-product-list │ │ └── index.vue │ ├── rf-mp-live │ │ └── index.vue │ ├── rf-rubik-cube │ │ └── index.vue │ ├── rf-swiper-category │ │ └── index.vue │ ├── rf-swiper-slide │ │ └── index.vue │ └── rf-swiper │ │ └── index.vue ├── mescroll-uni │ ├── components │ │ ├── mescroll-down.css │ │ ├── mescroll-down.vue │ │ ├── mescroll-empty.vue │ │ ├── mescroll-top.vue │ │ ├── mescroll-up.css │ │ └── mescroll-up.vue │ ├── mescroll-body.css │ ├── mescroll-body.vue │ ├── mescroll-mixins.js │ ├── mescroll-uni-option.js │ ├── mescroll-uni.css │ ├── mescroll-uni.js │ ├── mescroll-uni.vue │ ├── mixins │ │ ├── mescroll-comp.js │ │ ├── mescroll-more-item.js │ │ └── mescroll-more.js │ └── wxs │ │ ├── mixins.js │ │ ├── renderjs.js │ │ └── wxs.wxs ├── rf-attr-content │ └── index.vue ├── rf-avatar │ └── rf-avatar.vue ├── rf-back-home │ └── index.vue ├── rf-back-top │ └── index.vue ├── rf-badge │ └── rf-badge.vue ├── rf-calendar │ ├── calendar.js │ ├── rf-calendar-item.vue │ ├── rf-calendar.vue │ └── util.js ├── rf-count-down │ └── index.vue ├── rf-emoji │ └── rf-emoji.vue ├── rf-empty │ └── index.vue ├── rf-floor-index │ └── index.vue ├── rf-image │ └── rf-image.vue ├── rf-item-popup │ └── index.vue ├── rf-kefu │ └── index.vue ├── rf-list-cell │ └── index.vue ├── rf-live │ └── index.vue ├── rf-load-more │ └── rf-load-more.vue ├── rf-load-progress │ └── rf-load-progress.vue ├── rf-loading │ ├── index.vue │ └── loaders │ │ ├── bounce.vue │ │ ├── double-bounce.vue │ │ ├── double-cube.vue │ │ ├── double-dot.vue │ │ ├── loop.vue │ │ ├── rotate-plane.vue │ │ ├── scale-out.vue │ │ └── shrink-rect.vue ├── rf-nav-detail │ └── index.vue ├── rf-nav │ └── index.vue ├── rf-no-data │ └── index.vue ├── rf-number-box │ └── index.vue ├── rf-parser │ ├── index.vue │ └── libs │ │ ├── CssHandler.js │ │ ├── MpHtmlParser.js │ │ ├── config.js │ │ ├── handler.wxs │ │ └── trees.vue ├── rf-pick-regions │ └── index.vue ├── rf-picker │ └── index.vue ├── rf-popup-ad │ └── index.vue ├── rf-poster │ └── index.vue ├── rf-product-detail │ └── index.vue ├── rf-product-list │ └── index.vue ├── rf-protocol-popup │ └── index.vue ├── rf-qrcode │ └── index.vue ├── rf-rate │ └── rf-rate.vue ├── rf-recommend │ └── rf-recommend.vue ├── rf-search-bar │ └── index.vue ├── rf-search │ └── rf-search.vue ├── rf-share │ └── index.vue ├── rf-sign-calendar │ └── index.vue ├── rf-site-open │ └── index.vue ├── rf-swipe-dot │ └── index.vue ├── rf-swiper-slide │ └── index.vue ├── rf-table │ ├── index.vue │ └── regional.vue ├── rf-tag │ └── index.vue ├── rf-top-drawer │ └── index.vue ├── rf-top-dropdown │ └── index.vue ├── rf-version-upgrade │ └── index.vue ├── tm-upload │ ├── readme.md │ ├── tm-upload.vue │ └── tm-upload的副本.vue ├── uni-collapse-item │ └── uni-collapse-item.vue ├── uni-collapse │ └── uni-collapse.vue ├── uni-drawer │ ├── drawer.vue │ └── uni-drawer.vue ├── uni-swiper-dot │ └── uni-swiper-dot.vue └── uni-tag │ └── uni-tag.vue ├── config ├── assets.config.js ├── constData.config.js ├── formRule.config.js ├── index.config.js ├── routes.config.js ├── setting.config.js └── websocket.config.js ├── main.js ├── pages.json ├── pages ├── index │ ├── index.vue │ ├── notice │ │ ├── detail.vue │ │ └── notice.vue │ └── search │ │ └── search.vue ├── notify │ └── notify.vue ├── pet │ ├── 404.vue │ ├── apply-post.vue │ ├── apply-view.vue │ ├── ask.vue │ ├── city.vue │ ├── comment-post.vue │ ├── forum-comment-post.vue │ ├── forum-post.vue │ ├── forum-view.vue │ ├── forum.vue │ ├── list.vue │ ├── mescroll-item │ │ ├── my-apply-mescroll-item.vue │ │ ├── my-notify-mescroll-item.vue │ │ ├── my-pet-mescroll-item.vue │ │ ├── my-post-mescroll-item.vue │ │ ├── pet-index-mescroll-item.vue │ │ ├── pet-mescroll-item.vue │ │ └── post-mescroll-item.vue │ ├── my-apply.vue │ ├── my-notify.vue │ ├── my-pet.vue │ ├── my-post.vue │ ├── my.vue │ ├── order.vue │ ├── pet-post.vue │ ├── pet-view.vue │ ├── petInfo.vue │ ├── public.vue │ ├── service.vue │ └── web.vue ├── profile │ └── profile.vue ├── public │ ├── login.vue │ ├── logintype.vue │ ├── password.vue │ └── register.vue ├── set │ ├── about │ │ ├── about.vue │ │ └── detail.vue │ ├── authorization │ │ └── list.vue │ ├── feedback │ │ ├── detail.vue │ │ ├── feedback.vue │ │ └── list.vue │ ├── helper │ │ ├── detail.vue │ │ └── index.vue │ ├── invoice │ │ ├── invoice.vue │ │ ├── list.vue │ │ └── manage.vue │ └── set.vue └── user │ ├── account │ ├── account.vue │ ├── bill.vue │ ├── integral.vue │ ├── level.vue │ └── recharge.vue │ ├── address │ ├── address.vue │ └── manage.vue │ ├── collection │ └── collection.vue │ ├── coupon │ ├── coupon.vue │ ├── detail.vue │ └── list.vue │ ├── footprint │ └── footprint.vue │ ├── live.vue │ ├── money │ ├── pay.vue │ └── success.vue │ ├── userinfo │ └── userinfo.vue │ └── virtual │ ├── detail.vue │ └── index.vue ├── store └── index.js ├── uni.scss ├── utils ├── city.js ├── graceChecker.js ├── helper.js ├── payment.js ├── poster │ ├── QRCodeAlg.js │ ├── QS-SharePoster.js │ └── app.js ├── request │ ├── index.js │ └── request.js ├── router.js ├── share.js ├── uqrcode.js └── websocket.js └── uview-ui ├── LICENSE ├── README.md ├── components ├── u-action-sheet │ └── u-action-sheet.vue ├── u-alert-tips │ └── u-alert-tips.vue ├── u-avatar-cropper │ ├── u-avatar-cropper.vue │ └── weCropper.js ├── u-avatar │ └── u-avatar.vue ├── u-back-top │ └── u-back-top.vue ├── u-badge │ └── u-badge.vue ├── u-button │ └── u-button.vue ├── u-calendar │ └── u-calendar.vue ├── u-car-keyboard │ └── u-car-keyboard.vue ├── u-card │ └── u-card.vue ├── u-cell-group │ └── u-cell-group.vue ├── u-cell-item │ └── u-cell-item.vue ├── u-checkbox-group │ └── u-checkbox-group.vue ├── u-checkbox │ └── u-checkbox.vue ├── u-circle-progress │ ├── u-circle-progress.vue │ └── u-line-progress │ │ └── u-line-progress.vue ├── u-col │ └── u-col.vue ├── u-collapse-item │ └── u-collapse-item.vue ├── u-collapse │ └── u-collapse.vue ├── u-column-notice │ └── u-column-notice.vue ├── u-count-down │ └── u-count-down.vue ├── u-count-to │ └── u-count-to.vue ├── u-divider │ └── u-divider.vue ├── u-dropdown-item │ └── u-dropdown-item.vue ├── u-dropdown │ └── u-dropdown.vue ├── u-empty │ └── u-empty.vue ├── u-field │ └── u-field.vue ├── u-form-item │ └── u-form-item.vue ├── u-form │ └── u-form.vue ├── u-full-screen │ └── u-full-screen.vue ├── u-gap │ └── u-gap.vue ├── u-grid-item │ └── u-grid-item.vue ├── u-grid │ └── u-grid.vue ├── u-icon │ └── u-icon.vue ├── u-image │ └── u-image.vue ├── u-index-anchor │ └── u-index-anchor.vue ├── u-index-list │ └── u-index-list.vue ├── u-input │ └── u-input.vue ├── u-keyboard │ └── u-keyboard.vue ├── u-lazy-load │ └── u-lazy-load.vue ├── u-line-progress │ └── u-line-progress.vue ├── u-line │ └── u-line.vue ├── u-link │ └── u-link.vue ├── u-loading-page │ └── u-loading-page.vue ├── u-loading │ └── u-loading.vue ├── u-loadmore │ └── u-loadmore.vue ├── u-mask │ └── u-mask.vue ├── u-message-input │ └── u-message-input.vue ├── u-modal │ └── u-modal.vue ├── u-navbar │ └── u-navbar.vue ├── u-no-network │ └── u-no-network.vue ├── u-notice-bar │ └── u-notice-bar.vue ├── u-number-box │ └── u-number-box.vue ├── u-number-keyboard │ └── u-number-keyboard.vue ├── u-parse │ ├── libs │ │ ├── CssHandler.js │ │ ├── MpHtmlParser.js │ │ ├── config.js │ │ ├── handler.wxs │ │ └── trees.vue │ └── u-parse.vue ├── u-picker │ └── u-picker.vue ├── u-popup │ └── u-popup.vue ├── u-radio-group │ └── u-radio-group.vue ├── u-radio │ └── u-radio.vue ├── u-rate │ └── u-rate.vue ├── u-read-more │ └── u-read-more.vue ├── u-row-notice │ └── u-row-notice.vue ├── u-row │ └── u-row.vue ├── u-search │ └── u-search.vue ├── u-section │ └── u-section.vue ├── u-select │ └── u-select.vue ├── u-skeleton │ └── u-skeleton.vue ├── u-slider │ └── u-slider.vue ├── u-steps │ └── u-steps.vue ├── u-sticky │ └── u-sticky.vue ├── u-subsection │ └── u-subsection.vue ├── u-swipe-action │ └── u-swipe-action.vue ├── u-swiper │ └── u-swiper.vue ├── u-switch │ └── u-switch.vue ├── u-tabbar │ └── u-tabbar.vue ├── u-table │ └── u-table.vue ├── u-tabs-swiper │ └── u-tabs-swiper.vue ├── u-tabs │ └── u-tabs.vue ├── u-tag │ └── u-tag.vue ├── u-td │ └── u-td.vue ├── u-th │ └── u-th.vue ├── u-time-line-item │ └── u-time-line-item.vue ├── u-time-line │ └── u-time-line.vue ├── u-toast │ └── u-toast.vue ├── u-top-tips │ └── u-top-tips.vue ├── u-tr │ └── u-tr.vue ├── u-upload │ └── u-upload.vue ├── u-verification-code │ └── u-verification-code.vue └── u-waterfall │ └── u-waterfall.vue ├── iconfont.css ├── index.js ├── index.scss ├── libs ├── config │ ├── config.js │ └── zIndex.js ├── css │ ├── color.scss │ ├── common.scss │ ├── style.components.scss │ ├── style.h5.scss │ ├── style.mp.scss │ ├── style.nvue.scss │ └── style.vue.scss ├── function │ ├── $parent.js │ ├── addUnit.js │ ├── bem.js │ ├── color.js │ ├── colorGradient.js │ ├── debounce.js │ ├── deepClone.js │ ├── deepMerge.js │ ├── getParent.js │ ├── guid.js │ ├── md5.js │ ├── queryParams.js │ ├── random.js │ ├── randomArray.js │ ├── route.js │ ├── sys.js │ ├── test.js │ ├── throttle.js │ ├── timeFormat.js │ ├── timeFrom.js │ ├── toast.js │ ├── trim.js │ └── type2icon.js ├── mixin │ ├── mixin.js │ └── mpShare.js ├── request │ └── index.js ├── store │ └── index.js └── util │ ├── area.js │ ├── async-validator.js │ ├── city.js │ ├── emitter.js │ └── province.js ├── package.json └── theme.scss /README.md: -------------------------------------------------------------------------------- 1 | # UniChongWuServiceApplet 2 | 基于JAVA SpringBoot和UniAPP的宠物服务预约小程序 3 | 4 | 演示视频链接:https://www.bilibili.com/video/BV1BG411o7zo/ 5 | 6 | 详询 微信1:egvh56ufy7hh ,微信2:dabocode 。承接商业项目、课设、毕设和论文,包括但不限于Web、APP、小程序等,课设、毕设提供远程部署和不限次数代码解答! 7 | 8 | 实现的功能: 9 | 10 | 本系统的功能应该包括:用户登录和注册、首页展示、上门服务、宠物社区、后台管理(PC浏览器后台)等功能。 11 | 12 | 注册、登录:通过获取用户微信昵称,微信账号进行登录。系统允许匿名访问,匿名访问只能浏览界面,不能预约服务; 13 | 14 | 首页展示:首页主要有养宠宝典可进行信息浏览,收藏。宠物领养功能和宠物寄养功能,可进行详细咨询; 15 | 16 | 上门服务:为顾客的爱宠提供,提供上门喂养,遛宠服务,专业洗护,基础医疗咨询等4个模块的功能; 17 | 18 | 宠物社区:主要是可上传宠物照片,分享宠物趣事等; 19 | 20 | 后台管理:支持管理员对服务预约管理对订单进行添加,删除,修改。宠物社区管理对用户发布的趣事,对违规的信息进行删除。 21 | 22 | 用到的技术: 23 | 24 | 后端 java语言的SpringBoot框架、MySql数据库、Maven依赖管理等; 25 | 26 | 前端 Vue.js语法的UniApp框架。 27 | 28 | 另一个版本的宠物服务小程序传送门:https://github.com/KakarottoCui/UniChongWuFuwu 29 | -------------------------------------------------------------------------------- /api/activity.js: -------------------------------------------------------------------------------- 1 | //微信:egvh56ufy7hh ,QQ:821898835 2 | /** 3 | * @des 营销活动 4 | * 5 | * @author stavyan 6 | * @date 2020/12/15 11:16 上午 7 | * @copyright 2019 8 | */ 9 | // 大转盘 10 | // 大转盘活动列表 11 | const bigWheelActivityIndex = '/big-wheel/v1/activity/index'; 12 | // 大转盘详情 13 | const bigWheelActivityView = '/big-wheel/v1/activity/view'; 14 | // 大转盘抽奖 15 | const bigWheelRecordDraw = '/big-wheel/v1/record/draw'; 16 | // 大转盘抽奖记录 17 | const bigWheelRecordIndex = '/big-wheel/v1/record/index'; 18 | 19 | // 签到 20 | // 签到主页 21 | const tinySignIndex = '/tiny-sign/v1/index/index'; 22 | // 签到 23 | const tinySignCreate = '/tiny-sign/v1/record/create'; 24 | // 签到记录 25 | const tinySignRecordIndex = '/tiny-sign/v1/record/index'; 26 | // 今日排行榜 27 | const tinySignRankingIndex = '/tiny-sign/v1/ranking/index'; 28 | // 历史排行榜 29 | const tinySignRankingHistory = '/tiny-sign/v1/ranking/history'; 30 | 31 | export { 32 | bigWheelActivityIndex, 33 | bigWheelActivityView, 34 | bigWheelRecordDraw, 35 | bigWheelRecordIndex, 36 | tinySignIndex, 37 | tinySignCreate, 38 | tinySignRecordIndex, 39 | tinySignRankingIndex, 40 | tinySignRankingHistory 41 | }; 42 | -------------------------------------------------------------------------------- /api/basic.js: -------------------------------------------------------------------------------- 1 | /** 2 | *@des 公用基础 3 | *@author stav stavyan@qq.com 4 | *@blog https://stavtop.club 5 | *@date 2019/11/19 14:56:57 6 | *@param registerByPass 7 | */ 8 | 9 | // 获取省市区列表 10 | const provinceList = '/tiny-shop/v1/common/provinces/index'; 11 | // 收藏商品 12 | const collectCreate = '/tiny-shop/v1/common/collect/create'; 13 | // 删除收藏商品 14 | const collectDel = '/tiny-shop/v1/common/collect/delete'; 15 | 16 | // 分享/转发 17 | const transmitCreate = '/tiny-shop/v1/common/transmit/create'; 18 | 19 | // 广告 20 | const advList = '/tiny-shop/v1/common/adv/index'; 21 | const advView = '/tiny-shop/v1/common/adv/view'; 22 | 23 | // 配置 24 | const configList = '/tiny-shop/v1/common/config/index'; 25 | 26 | // 充值 27 | const payCreate = '/tiny-shop/v1/common/pay/create'; 28 | 29 | // 充值配置 30 | const wechatConfig = '/tiny-shop/v1/third-party/wechat-js-sdk'; 31 | 32 | // 公告 33 | // 公告列表 34 | const notifyAnnounceIndex = '/tiny-shop/v1/common/notify-announce/index'; 35 | // 公告详情 36 | const notifyAnnounceView = '/tiny-shop/v1/common/notify-announce/view'; 37 | 38 | // 版本检测 39 | const versionsIndex = '/app-versions/versions/index'; 40 | // 升级记录 41 | const versionsView = '/app-versions/versions/view'; 42 | 43 | // 版本检测 44 | const pickupPointIndex = '/tiny-shop/v1/common/pickup-point/index'; 45 | 46 | // 站点帮助-列表 47 | const helperIndex = '/tiny-shop/v1/common/helper/index'; 48 | // 站点帮助-详情 49 | const helperView = '/tiny-shop/v1/common/helper/view'; 50 | 51 | // 设备绑定(app推送) 52 | const bindingEquipment = '/tiny-shop/v1/member/auth/binding-equipment'; 53 | // 第三方绑定 54 | const authCreate = '/tiny-shop/v1/member/auth/create'; 55 | 56 | export { 57 | provinceList, 58 | collectCreate, 59 | collectDel, 60 | transmitCreate, 61 | advList, 62 | advView, 63 | payCreate, 64 | configList, 65 | wechatConfig, 66 | notifyAnnounceIndex, 67 | notifyAnnounceView, 68 | versionsIndex, 69 | versionsView, 70 | pickupPointIndex, 71 | helperIndex, 72 | helperView, 73 | bindingEquipment, 74 | authCreate 75 | }; 76 | -------------------------------------------------------------------------------- /api/distribution.js: -------------------------------------------------------------------------------- 1 | /** 2 | *@des 分销商相关接口 3 | *@author stav stavyan@qq.com 4 | *@blog https://stavtop.club 5 | *@date 2020/02/20 17:20:21 6 | */ 7 | 8 | // 个人信息 9 | const distributionMemberIndex = '/tiny-distribution/v1/member/index'; 10 | 11 | // 提现账号 12 | // 提现账号列表 13 | const bankAccountIndex = '/tiny-distribution/v1/bank-account/index'; 14 | // 删除提现账号 15 | const bankAccountDelete = '/tiny-distribution/v1/bank-account/delete'; 16 | // 更新提现账号 17 | const bankAccountUpdate = '/tiny-distribution/v1/bank-account/update'; 18 | // 新增提现账号 19 | const bankAccountCreate = '/tiny-distribution/v1/bank-account/create'; 20 | // 提现账号详情 21 | const bankAccountView = '/tiny-distribution/v1/bank-account/view'; 22 | // 提现配置 23 | const withdrawConfig = 24 | '/tiny-distribution/v1/promoter-commission-withdraw/config'; 25 | // 提现申请 26 | const withdrawCreate = 27 | '/tiny-distribution/v1/promoter-commission-withdraw/create'; 28 | // 提现申请列表 29 | const withdrawList = '/tiny-distribution/v1/promoter-commission-withdraw/index'; 30 | 31 | // 分销商 32 | // 申请进度 33 | const promoterApplySchedule = '/tiny-distribution/v1/promoter-apply/schedule'; 34 | // 申请记录 35 | const promoterApplyIndex = '/tiny-distribution/v1/promoter-apply/index'; 36 | // 申请配置 37 | const promoterLevelConfig = '/tiny-distribution/v1/promoter-level/config'; 38 | // 申请 39 | const promoterApplyCreate = '/tiny-distribution/v1/promoter-apply/create'; 40 | 41 | // 区域代理 42 | // 申请进度 43 | const regionalAgentApplySchedule = 44 | '/tiny-distribution/v1/regional-agent-apply/index'; 45 | // 申请配置 46 | const regionalLevelConfig = '/tiny-distribution/v1/regional-agent/config'; 47 | // 申请 48 | const regionalApplyCreate = '/tiny-distribution/v1/regional-agent-apply/create'; 49 | 50 | // 级别列表 51 | const promoterLevelIndex = '/tiny-distribution/v1/promoter-level/index'; 52 | 53 | // 上级分销商 54 | const distributionMemberParent = '/tiny-distribution/v1/member/parent'; 55 | // 下级分销商 56 | const distributionMemberChild = '/tiny-distribution/v1/member/child'; 57 | 58 | // 自推订单 59 | const promoterRecordIndex = '/tiny-distribution/v1/promoter-record/index'; 60 | // 自推订单 61 | const promoterRecordSelf = '/tiny-distribution/v1/promoter-record/self'; 62 | // 自推订单统计 63 | const promoterRecordSelfStat = 64 | '/tiny-distribution/v1/promoter-record/self-stat'; 65 | // 团队订单 66 | const promoterRecordTeam = '/tiny-distribution/v1/promoter-record/team'; 67 | // 团队订单统计 68 | const promoterRecordTeamStat = 69 | '/tiny-distribution/v1/promoter-record/team-stat'; 70 | 71 | // 团队订单统计 72 | const memberQrCode = 73 | '/tiny-distribution/v1/member/qr-code'; 74 | 75 | // 提现银行卡 76 | const bankNumberIndex = 77 | '/tiny-distribution/v1/bank-number/index'; 78 | 79 | export { 80 | distributionMemberIndex, 81 | bankAccountIndex, 82 | bankAccountDelete, 83 | bankAccountUpdate, 84 | bankAccountCreate, 85 | bankAccountView, 86 | withdrawConfig, 87 | withdrawCreate, 88 | withdrawList, 89 | promoterApplyIndex, 90 | promoterLevelConfig, 91 | promoterApplyCreate, 92 | promoterLevelIndex, 93 | promoterApplySchedule, 94 | distributionMemberParent, 95 | distributionMemberChild, 96 | promoterRecordIndex, 97 | promoterRecordSelf, 98 | promoterRecordSelfStat, 99 | promoterRecordTeam, 100 | promoterRecordTeamStat, 101 | regionalAgentApplySchedule, 102 | regionalLevelConfig, 103 | regionalApplyCreate, 104 | memberQrCode, 105 | bankNumberIndex 106 | }; 107 | -------------------------------------------------------------------------------- /api/login.js: -------------------------------------------------------------------------------- 1 | /** 2 | *@des 登录注册相关接口 3 | *@author stav stavyan@qq.com 4 | *@blog https://stavtop.club 5 | *@date 2019/11/15 15:14:47 6 | *@param login.js 7 | */ 8 | 9 | // 密码注册 10 | const registerByPass = '/tiny-shop/v1/site/register'; 11 | 12 | // 密码登录 13 | const loginByPass = '/tiny-shop/v1/site/login'; 14 | 15 | // 微信授权登录 16 | const wechatH5Login = '/tiny-shop/v1/third-party/wechat'; 17 | 18 | // 微信小程序授权登录 19 | const mpWechatLogin = '/tiny-shop/v1/third-party/wechat-mp'; 20 | 21 | // App微信授权登录 22 | const thirdPartyWechatOpenPlatform = '/tiny-shop/v1/third-party/wechat-open-platform'; 23 | 24 | // Ios苹果扥估 25 | const thirdPartyApple = '/tiny-shop/v1/third-party/apple'; 26 | 27 | // 密码重置 28 | const updatePassword = '/tiny-shop/v1/site/up-pwd'; 29 | 30 | // 第三方绑定 31 | const authLogin = '/tiny-shop/v1/member/auth/create'; 32 | 33 | // 查询绑定状态 34 | const isBindingCheck = '/tiny-shop/v1/member/auth/is-binding'; 35 | 36 | // 手机号登录 37 | const loginBySmsCode = '/tiny-shop/v1/site/mobile-login'; 38 | 39 | // 获取手机验证码 40 | const smsCode = '/tiny-shop/v1/site/sms-code'; 41 | 42 | // 退出登录 43 | const logout = '/tiny-shop/v1/site/logout'; 44 | 45 | // 刷新token 46 | const refreshToken = '/tiny-shop/v1/site/refresh'; 47 | 48 | // 登录令牌有效性检测 49 | const verifyAccessToken = '/tiny-shop/v1/site/verify-access-token'; 50 | 51 | export { 52 | registerByPass, 53 | loginByPass, 54 | isBindingCheck, 55 | wechatH5Login, 56 | mpWechatLogin, 57 | thirdPartyWechatOpenPlatform, 58 | thirdPartyApple, 59 | authLogin, 60 | updatePassword, 61 | smsCode, 62 | loginBySmsCode, 63 | logout, 64 | refreshToken, 65 | verifyAccessToken 66 | }; 67 | -------------------------------------------------------------------------------- /api/merchant.js: -------------------------------------------------------------------------------- 1 | // 商户详情 2 | const merchantView = '/merchants/v1/merchant/view'; 3 | // 商户列表 4 | const merchantIndex = '/merchants/v1/merchant/index'; 5 | // 经纬度转地址 6 | const locationToAddress = '/tiny-shop/v1/index/location-to-address'; 7 | // 地址转经纬度 8 | const addressToLocation = '/tiny-shop/v1/index/address-to-location'; 9 | 10 | export { merchantView, merchantIndex, locationToAddress, addressToLocation }; 11 | -------------------------------------------------------------------------------- /api/pet.js: -------------------------------------------------------------------------------- 1 | const petIndex = '/pet/v1/pet/index'; 2 | const petList = '/pet/v1/pet/list'; 3 | const petMyList = '/pet/v1/pet/my-list'; 4 | const petView = '/pet/v1/pet/view'; 5 | const petMyView = '/pet/v1/pet/my-view'; 6 | const petLike = '/pet/v1/pet/like'; 7 | const petShare = '/pet/v1/pet/share'; 8 | const petForm = '/pet/v1/pet/form'; 9 | const petStateOn = '/pet/v1/pet/state-on'; 10 | const petStateOff = '/pet/v1/pet/state-off'; 11 | const petTrash = '/pet/v1/pet/trash'; 12 | const notifyMyList = '/pet/v1/notify/my-list'; 13 | const notifyReadOn = '/pet/v1/notify/read-on'; 14 | const notifyReadOff = '/pet/v1/notify/read-off'; 15 | const notifyTrash = '/pet/v1/notify/trash'; 16 | const applyList = '/pet/v1/apply/list'; 17 | const applyMyNotify = '/pet/v1/apply/my-notify'; 18 | const applyMyList = '/pet/v1/apply/my-list'; 19 | const applyView = '/pet/v1/apply/view'; 20 | const applyAgree = '/pet/v1/apply/agree'; 21 | const applyRefuse = '/pet/v1/apply/refuse'; 22 | const applyForm = '/pet/v1/apply/form'; 23 | const applyTrash = '/pet/v1/apply/trash'; 24 | const commentList = '/pet/v1/comment/list'; 25 | const commentView = '/pet/v1/comment/view'; 26 | const commentLike = '/pet/v1/comment/like'; 27 | const commentForm = '/pet/v1/comment/form'; 28 | const commentTrash = '/pet/v1/comment/trash'; 29 | const postList = '/pet/v1/post/list'; 30 | const postTopList = '/pet/v1/post/top-list'; 31 | const postMyList = '/pet/v1/post/my-list'; 32 | const postView = '/pet/v1/post/view'; 33 | const postMyView = '/pet/v1/post/my-view'; 34 | const postLike = '/pet/v1/post/like'; 35 | const postShare = '/pet/v1/post/share'; 36 | const postForm = '/pet/v1/post/form'; 37 | const postStateOn = '/pet/v1/post/state-on'; 38 | const postStateOff = '/pet/v1/post/state-off'; 39 | const postTrash = '/pet/v1/post/trash'; 40 | const postCommentList = '/pet/v1/post-comment/list'; 41 | const postCommentView = '/pet/v1/post-comment/view'; 42 | const postCommentLike = '/pet/v1/post-comment/like'; 43 | const postCommentForm = '/pet/v1/post-comment/form'; 44 | const postCommentTrash = '/pet/v1/post-comment/trash'; 45 | const provincesCitys = '/pet/v1/provinces/citys'; 46 | const fileVideos = '/pet/v1/file/videos'; 47 | const fileImages = '/pet/v1/file/images'; 48 | 49 | export { 50 | petIndex, 51 | petList, 52 | petMyList, 53 | petView, 54 | petMyView, 55 | petForm, 56 | petStateOn, 57 | petStateOff, 58 | petTrash, 59 | petLike, 60 | petShare, 61 | notifyMyList, 62 | notifyReadOn, 63 | notifyReadOff, 64 | notifyTrash, 65 | applyList, 66 | applyMyNotify, 67 | applyMyList, 68 | applyView, 69 | applyAgree, 70 | applyRefuse, 71 | applyForm, 72 | applyTrash, 73 | commentList, 74 | commentView, 75 | commentLike, 76 | commentForm, 77 | commentTrash, 78 | postList, 79 | postTopList, 80 | postMyList, 81 | postView, 82 | postMyView, 83 | postLike, 84 | postShare, 85 | postForm, 86 | postStateOn, 87 | postStateOff, 88 | postTrash, 89 | postCommentList, 90 | postCommentView, 91 | postCommentLike, 92 | postCommentForm, 93 | postCommentTrash, 94 | provincesCitys, 95 | fileVideos, 96 | fileImages 97 | } 98 | -------------------------------------------------------------------------------- /api/websocket.js: -------------------------------------------------------------------------------- 1 | // 客服上传图片 2 | const tinyServiceUploadFile = '/tiny-service/v1/common/file/images'; 3 | // 客服配置 4 | const questionsIndex = '/tiny-service/v1/questions/index'; 5 | 6 | // 问题详情 7 | const questionsView = '/tiny-service/v1/questions/view'; 8 | 9 | // 请求路由 10 | // 当前会话历史消息 11 | const memberConversation = 'member.conversation'; 12 | 13 | export { 14 | tinyServiceUploadFile, 15 | questionsIndex, 16 | questionsView, 17 | memberConversation 18 | }; 19 | -------------------------------------------------------------------------------- /common/router.js: -------------------------------------------------------------------------------- 1 | /* 2 | * 路由对象 3 | * 中心思想:需要路由鉴权,由于uni-app没有vue中的全局钩子函数,所以封装了Router对象。 4 | * 说明:应用中的路由跳转尽量使用该Router的方法,并配合config中的路由表对象进行跳转。 5 | * 6 | * 示例:this.$mRouter.push({route:this.$mRoutesConfig.main,query:{a:1}}) 7 | * 8 | */ 9 | class Router { 10 | constructor(arg) { 11 | this.callBack = () => {}; 12 | } 13 | 14 | beforeEach(callBack) { 15 | if (callBack instanceof Function) this.callBack = callBack; 16 | } 17 | 18 | push(to) { 19 | this.callBack('navigateTo', to); 20 | } 21 | 22 | redirectTo(to) { 23 | this.callBack('redirectTo', to); 24 | } 25 | 26 | reLaunch(to) { 27 | this.callBack('reLaunch', to); 28 | } 29 | 30 | switchTab(to) { 31 | this.callBack('switchTab', to); 32 | } 33 | 34 | back(delta) { 35 | uni.navigateBack({ 36 | delta 37 | }) 38 | } 39 | } 40 | 41 | export default new Router(); 42 | -------------------------------------------------------------------------------- /common/utils.js: -------------------------------------------------------------------------------- 1 | export default { 2 | 3 | } 4 | -------------------------------------------------------------------------------- /components/cu-custom/index.vue: -------------------------------------------------------------------------------- 1 | 17 | 18 | 67 | 68 | 70 | -------------------------------------------------------------------------------- /components/home/rf-category-nav/index.vue: -------------------------------------------------------------------------------- 1 | 18 | 19 | 46 | 47 | 74 | -------------------------------------------------------------------------------- /components/home/rf-mp-live/index.vue: -------------------------------------------------------------------------------- 1 | 20 | 21 | 51 | 52 | 115 | -------------------------------------------------------------------------------- /components/home/rf-swiper-slide/index.vue: -------------------------------------------------------------------------------- 1 | 28 | 29 | 55 | 56 | 84 | -------------------------------------------------------------------------------- /components/mescroll-uni/components/mescroll-down.css: -------------------------------------------------------------------------------- 1 | /* 下拉刷新区域 */ 2 | .mescroll-downwarp { 3 | position: absolute; 4 | top: -100%; 5 | left: 0; 6 | width: 100%; 7 | height: 100%; 8 | text-align: center; 9 | } 10 | 11 | /* 下拉刷新--内容区,定位于区域底部 */ 12 | .mescroll-downwarp .downwarp-content { 13 | position: absolute; 14 | left: 0; 15 | bottom: 0; 16 | width: 100%; 17 | min-height: 60rpx; 18 | padding: 20rpx 0; 19 | text-align: center; 20 | } 21 | 22 | /* 下拉刷新--提示文本 */ 23 | .mescroll-downwarp .downwarp-tip { 24 | display: inline-block; 25 | font-size: 28rpx; 26 | vertical-align: middle; 27 | margin-left: 16rpx; 28 | /* color: gray; 已在style设置color,此处删去*/ 29 | } 30 | 31 | /* 下拉刷新--旋转进度条 */ 32 | .mescroll-downwarp .downwarp-progress { 33 | display: inline-block; 34 | width: 32rpx; 35 | height: 32rpx; 36 | border-radius: 50%; 37 | border: 2rpx solid gray; 38 | border-bottom-color: transparent !important; /*已在style设置border-color,此处需加 !important*/ 39 | vertical-align: middle; 40 | } 41 | 42 | /* 旋转动画 */ 43 | .mescroll-downwarp .mescroll-rotate { 44 | animation: mescrollDownRotate 0.6s linear infinite; 45 | } 46 | 47 | @keyframes mescrollDownRotate { 48 | 0% { 49 | transform: rotate(0deg); 50 | } 51 | 52 | 100% { 53 | transform: rotate(360deg); 54 | } 55 | } -------------------------------------------------------------------------------- /components/mescroll-uni/components/mescroll-down.vue: -------------------------------------------------------------------------------- 1 | 2 | 10 | 11 | 44 | 45 | 48 | -------------------------------------------------------------------------------- /components/mescroll-uni/components/mescroll-empty.vue: -------------------------------------------------------------------------------- 1 | 8 | 15 | 16 | 48 | 49 | 91 | -------------------------------------------------------------------------------- /components/mescroll-uni/components/mescroll-top.vue: -------------------------------------------------------------------------------- 1 | 2 | 13 | 14 | 49 | 50 | 84 | -------------------------------------------------------------------------------- /components/mescroll-uni/components/mescroll-up.css: -------------------------------------------------------------------------------- 1 | /* 上拉加载区域 */ 2 | .mescroll-upwarp { 3 | box-sizing: border-box; 4 | min-height: 110rpx; 5 | padding: 30rpx 0; 6 | text-align: center; 7 | clear: both; 8 | } 9 | 10 | /*提示文本 */ 11 | .mescroll-upwarp .upwarp-tip, 12 | .mescroll-upwarp .upwarp-nodata { 13 | display: inline-block; 14 | font-size: 28rpx; 15 | vertical-align: middle; 16 | /* color: gray; 已在style设置color,此处删去*/ 17 | } 18 | 19 | .mescroll-upwarp .upwarp-tip { 20 | margin-left: 16rpx; 21 | } 22 | 23 | /*旋转进度条 */ 24 | .mescroll-upwarp .upwarp-progress { 25 | display: inline-block; 26 | width: 32rpx; 27 | height: 32rpx; 28 | border-radius: 50%; 29 | border: 2rpx solid gray; 30 | border-bottom-color: transparent !important; /*已在style设置border-color,此处需加 !important*/ 31 | vertical-align: middle; 32 | } 33 | 34 | /* 旋转动画 */ 35 | .mescroll-upwarp .mescroll-rotate { 36 | animation: mescrollUpRotate 0.6s linear infinite; 37 | } 38 | 39 | @keyframes mescrollUpRotate { 40 | 0% { 41 | transform: rotate(0deg); 42 | } 43 | 44 | 100% { 45 | transform: rotate(360deg); 46 | } 47 | } -------------------------------------------------------------------------------- /components/mescroll-uni/components/mescroll-up.vue: -------------------------------------------------------------------------------- 1 | 2 | 13 | 14 | 36 | 37 | 40 | -------------------------------------------------------------------------------- /components/mescroll-uni/mescroll-body.css: -------------------------------------------------------------------------------- 1 | .mescroll-body { 2 | position: relative; /* 下拉刷新区域相对自身定位 */ 3 | height: auto; /* 不可固定高度,否则overflow:hidden导致无法滑动; 同时使设置的最小高生效,实现列表不满屏仍可下拉*/ 4 | overflow: hidden; /* 当有元素写在mescroll-body标签前面时,可遮住下拉刷新区域 */ 5 | box-sizing: border-box; /* 避免设置padding出现双滚动条的问题 */ 6 | } 7 | 8 | /* 使sticky生效: 父元素不能overflow:hidden或者overflow:auto属性 */ 9 | .mescroll-body.mescorll-sticky{ 10 | overflow: unset !important 11 | } 12 | 13 | /* 适配 iPhoneX */ 14 | @supports (bottom: constant(safe-area-inset-bottom)) or (bottom: env(safe-area-inset-bottom)) { 15 | .mescroll-safearea { 16 | padding-bottom: constant(safe-area-inset-bottom); 17 | padding-bottom: env(safe-area-inset-bottom); 18 | } 19 | } -------------------------------------------------------------------------------- /components/mescroll-uni/mescroll-mixins.js: -------------------------------------------------------------------------------- 1 | // mescroll-body 和 mescroll-uni 通用 2 | 3 | // import MescrollUni from "./mescroll-uni.vue"; 4 | // import MescrollBody from "./mescroll-body.vue"; 5 | 6 | const MescrollMixin = { 7 | // components: { // 非H5端无法通过mixin注册组件, 只能在main.js中注册全局组件或具体界面中注册 8 | // MescrollUni, 9 | // MescrollBody 10 | // }, 11 | data() { 12 | return { 13 | mescroll: null //mescroll实例对象 14 | } 15 | }, 16 | // 注册系统自带的下拉刷新 (配置down.native为true时生效, 还需在pages配置enablePullDownRefresh:true;详请参考mescroll-native的案例) 17 | onPullDownRefresh(){ 18 | this.mescroll && this.mescroll.onPullDownRefresh(); 19 | }, 20 | // 注册列表滚动事件,用于判定在顶部可下拉刷新,在指定位置可显示隐藏回到顶部按钮 (此方法为页面生命周期,无法在子组件中触发, 仅在mescroll-body生效) 21 | onPageScroll(e) { 22 | this.mescroll && this.mescroll.onPageScroll(e); 23 | }, 24 | // 注册滚动到底部的事件,用于上拉加载 (此方法为页面生命周期,无法在子组件中触发, 仅在mescroll-body生效) 25 | onReachBottom() { 26 | this.mescroll && this.mescroll.onReachBottom(); 27 | }, 28 | methods: { 29 | // mescroll组件初始化的回调,可获取到mescroll对象 30 | mescrollInit(mescroll) { 31 | this.mescroll = mescroll; 32 | this.mescrollInitByRef(); // 兼容字节跳动小程序 33 | }, 34 | // 以ref的方式初始化mescroll对象 (兼容字节跳动小程序) 35 | mescrollInitByRef() { 36 | if(!this.mescroll || !this.mescroll.resetUpScroll){ 37 | let mescrollRef = this.$refs.mescrollRef; 38 | if(mescrollRef) this.mescroll = mescrollRef.mescroll 39 | } 40 | }, 41 | // 下拉刷新的回调 (mixin默认resetUpScroll) 42 | downCallback() { 43 | if(this.mescroll.optUp.use){ 44 | this.mescroll.resetUpScroll() 45 | }else{ 46 | setTimeout(()=>{ 47 | this.mescroll.endSuccess(); 48 | }, 500) 49 | } 50 | }, 51 | // 上拉加载的回调 52 | upCallback() { 53 | // mixin默认延时500自动结束加载 54 | setTimeout(()=>{ 55 | this.mescroll.endErr(); 56 | }, 500) 57 | } 58 | }, 59 | mounted() { 60 | this.mescrollInitByRef(); // 兼容字节跳动小程序, 避免未设置@init或@init此时未能取到ref的情况 61 | } 62 | 63 | } 64 | 65 | export default MescrollMixin; 66 | -------------------------------------------------------------------------------- /components/mescroll-uni/mescroll-uni-option.js: -------------------------------------------------------------------------------- 1 | // 全局配置 2 | // mescroll-body 和 mescroll-uni 通用 3 | const GlobalOption = { 4 | down: { 5 | // 其他down的配置参数也可以写,这里只展示了常用的配置: 6 | textInOffset: '下拉刷新', // 下拉的距离在offset范围内的提示文本 7 | textOutOffset: '释放更新', // 下拉的距离大于offset范围的提示文本 8 | textLoading: '加载中 ...', // 加载中的提示文本 9 | textSuccess: '加载成功', // 加载成功的文本 10 | textErr: '加载失败', // 加载失败的文本 11 | beforeEndDelay: 100, // 延时结束的时长 (显示加载成功/失败的时长) 12 | offset: 80, // 在列表顶部,下拉大于80px,松手即可触发下拉刷新的回调 13 | native: false // 是否使用系统自带的下拉刷新; 默认false; 仅在mescroll-body生效 (值为true时,还需在pages配置enablePullDownRefresh:true;详请参考mescroll-native的案例) 14 | }, 15 | up: { 16 | // 其他up的配置参数也可以写,这里只展示了常用的配置: 17 | textLoading: '加载中 ...', // 加载中的提示文本 18 | textNoMore: '-- END --', // 没有更多数据的提示文本 19 | offset: 150, // 距底部多远时,触发upCallback,仅mescroll-uni生效 ( mescroll-body配置的是pages.json的 onReachBottomDistance ) 20 | toTop: { 21 | // 回到顶部按钮,需配置src才显示 22 | src: "https://www.mescroll.com/img/mescroll-totop.png", // 图片路径 (建议放入static目录, 如 /static/img/mescroll-totop.png ) 23 | offset: 1000, // 列表滚动多少距离才显示回到顶部按钮,默认1000px 24 | right: 20, // 到右边的距离, 默认20 (支持"20rpx", "20px", "20%"格式的值, 纯数字则默认单位rpx) 25 | bottom: 120, // 到底部的距离, 默认120 (支持"20rpx", "20px", "20%"格式的值, 纯数字则默认单位rpx) 26 | width: 72 // 回到顶部图标的宽度, 默认72 (支持"20rpx", "20px", "20%"格式的值, 纯数字则默认单位rpx) 27 | }, 28 | empty: { 29 | use: true, // 是否显示空布局 30 | icon: "https://www.mescroll.com/img/mescroll-empty.png", // 图标路径 (建议放入static目录, 如 /static/img/mescroll-empty.png ) 31 | tip: '~ 空空如也 ~' // 提示 32 | } 33 | } 34 | } 35 | 36 | export default GlobalOption 37 | -------------------------------------------------------------------------------- /components/mescroll-uni/mescroll-uni.css: -------------------------------------------------------------------------------- 1 | .mescroll-uni-warp{ 2 | height: 100%; 3 | } 4 | 5 | .mescroll-uni-content{ 6 | height: 100%; 7 | } 8 | 9 | .mescroll-uni { 10 | position: relative; 11 | width: 100%; 12 | height: 100%; 13 | min-height: 200rpx; 14 | overflow-y: auto; 15 | box-sizing: border-box; /* 避免设置padding出现双滚动条的问题 */ 16 | } 17 | 18 | /* 定位的方式固定高度 */ 19 | .mescroll-uni-fixed{ 20 | z-index: 1; 21 | position: fixed; 22 | top: 0; 23 | left: 0; 24 | right: 0; 25 | bottom: 0; 26 | width: auto; /* 使right生效 */ 27 | height: auto; /* 使bottom生效 */ 28 | } 29 | 30 | /* 适配 iPhoneX */ 31 | @supports (bottom: constant(safe-area-inset-bottom)) or (bottom: env(safe-area-inset-bottom)) { 32 | .mescroll-safearea { 33 | padding-bottom: constant(safe-area-inset-bottom); 34 | padding-bottom: env(safe-area-inset-bottom); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /components/mescroll-uni/mixins/mescroll-comp.js: -------------------------------------------------------------------------------- 1 | /** 2 | * mescroll-body写在子组件时,需通过mescroll的mixins补充子组件缺少的生命周期 3 | */ 4 | const MescrollCompMixin = { 5 | // 因为子组件无onPageScroll和onReachBottom的页面生命周期,需在页面传递进到子组件 (一级) 6 | onPageScroll(e) { 7 | this.handlePageScroll(e) 8 | }, 9 | onReachBottom() { 10 | this.handleReachBottom() 11 | }, 12 | // 当down的native: true时, 还需传递此方法进到子组件 13 | onPullDownRefresh(){ 14 | this.handlePullDownRefresh() 15 | }, 16 | // mescroll-body写在子子子...组件的情况 (多级) 17 | data() { 18 | return { 19 | mescroll: { 20 | onPageScroll: e=>{ 21 | this.handlePageScroll(e) 22 | }, 23 | onReachBottom: ()=>{ 24 | this.handleReachBottom() 25 | }, 26 | onPullDownRefresh: ()=>{ 27 | this.handlePullDownRefresh() 28 | } 29 | } 30 | } 31 | }, 32 | methods:{ 33 | handlePageScroll(e){ 34 | let item = this.$refs["mescrollItem"]; 35 | if(item && item.mescroll) item.mescroll.onPageScroll(e); 36 | }, 37 | handleReachBottom(){ 38 | let item = this.$refs["mescrollItem"]; 39 | if(item && item.mescroll) item.mescroll.onReachBottom(); 40 | }, 41 | handlePullDownRefresh(){ 42 | let item = this.$refs["mescrollItem"]; 43 | if(item && item.mescroll) item.mescroll.onPullDownRefresh(); 44 | } 45 | } 46 | } 47 | 48 | export default MescrollCompMixin; 49 | -------------------------------------------------------------------------------- /components/mescroll-uni/mixins/mescroll-more-item.js: -------------------------------------------------------------------------------- 1 | /** 2 | * mescroll-more-item的mixins, 仅在多个 mescroll-body 写在子组件时使用 (参考 mescroll-more 案例) 3 | */ 4 | const MescrollMoreItemMixin = { 5 | // 支付宝小程序不支持props的mixin,需写在具体的页面中 6 | // #ifndef MP-ALIPAY || MP-DINGTALK 7 | props:{ 8 | i: Number, // 每个tab页的专属下标 9 | index: { // 当前tab的下标 10 | type: Number, 11 | default(){ 12 | return 0 13 | } 14 | } 15 | }, 16 | // #endif 17 | data() { 18 | return { 19 | downOption:{ 20 | auto:false // 不自动加载 21 | }, 22 | upOption:{ 23 | auto:false // 不自动加载 24 | }, 25 | isInit: false // 当前tab是否已初始化 26 | } 27 | }, 28 | watch:{ 29 | // 监听下标的变化 30 | index(val){ 31 | if (this.i === val && !this.isInit) { 32 | this.isInit = true; // 标记为true 33 | this.mescroll && this.mescroll.triggerDownScroll(); 34 | } 35 | } 36 | }, 37 | methods: { 38 | // 以ref的方式初始化mescroll对象 (兼容字节跳动小程序) 39 | mescrollInitByRef() { 40 | if(!this.mescroll || !this.mescroll.resetUpScroll){ 41 | // 字节跳动小程序编辑器不支持一个页面存在相同的ref, 多mescroll的ref需动态生成, 格式为'mescrollRef下标' 42 | let mescrollRef = this.$refs.mescrollRef || this.$refs['mescrollRef'+this.i]; 43 | if(mescrollRef) this.mescroll = mescrollRef.mescroll 44 | } 45 | }, 46 | // mescroll组件初始化的回调,可获取到mescroll对象 (覆盖mescroll-mixins.js的mescrollInit, 为了标记isInit) 47 | mescrollInit(mescroll) { 48 | this.mescroll = mescroll; 49 | this.mescrollInitByRef && this.mescrollInitByRef(); // 兼容字节跳动小程序 50 | // 自动加载当前tab的数据 51 | if(this.i === this.index){ 52 | this.isInit = true; // 标记为true 53 | this.mescroll.triggerDownScroll(); 54 | } 55 | }, 56 | } 57 | } 58 | 59 | export default MescrollMoreItemMixin; 60 | -------------------------------------------------------------------------------- /components/mescroll-uni/mixins/mescroll-more.js: -------------------------------------------------------------------------------- 1 | /** 2 | * mescroll-body写在子组件时, 需通过mescroll的mixins补充子组件缺少的生命周期 3 | */ 4 | const MescrollMoreMixin = { 5 | data() { 6 | return { 7 | tabIndex: 0, // 当前tab下标 8 | mescroll: { 9 | onPageScroll: e=>{ 10 | this.handlePageScroll(e) 11 | }, 12 | onReachBottom: ()=>{ 13 | this.handleReachBottom() 14 | }, 15 | onPullDownRefresh: ()=>{ 16 | this.handlePullDownRefresh() 17 | } 18 | } 19 | } 20 | }, 21 | // 因为子组件无onPageScroll和onReachBottom的页面生命周期,需在页面传递进到子组件 22 | onPageScroll(e) { 23 | this.handlePageScroll(e) 24 | }, 25 | onReachBottom() { 26 | this.handleReachBottom() 27 | }, 28 | // 当down的native: true时, 还需传递此方法进到子组件 29 | onPullDownRefresh(){ 30 | this.handlePullDownRefresh() 31 | }, 32 | methods:{ 33 | handlePageScroll(e){ 34 | let mescroll = this.getMescroll(this.tabIndex); 35 | mescroll && mescroll.onPageScroll(e); 36 | }, 37 | handleReachBottom(){ 38 | let mescroll = this.getMescroll(this.tabIndex); 39 | mescroll && mescroll.onReachBottom(); 40 | }, 41 | handlePullDownRefresh(){ 42 | let mescroll = this.getMescroll(this.tabIndex); 43 | mescroll && mescroll.onPullDownRefresh(); 44 | }, 45 | // 根据下标获取对应子组件的mescroll 46 | getMescroll(i){ 47 | if(!this.mescrollItems) this.mescrollItems = []; 48 | if(!this.mescrollItems[i]) { 49 | // v-for中的refs 50 | let vForItem = this.$refs["mescrollItem"]; 51 | if(vForItem){ 52 | this.mescrollItems[i] = vForItem[i] 53 | }else{ 54 | // 普通的refs,不可重复 55 | this.mescrollItems[i] = this.$refs["mescrollItem"+i]; 56 | } 57 | } 58 | let item = this.mescrollItems[i] 59 | return item ? item.mescroll : null 60 | }, 61 | // 切换tab,恢复滚动条位置 62 | tabChange(i){ 63 | let mescroll = this.getMescroll(i); 64 | if(mescroll){ 65 | // 延时(比$nextTick靠谱一些),确保元素已渲染 66 | setTimeout(()=>{ 67 | mescroll.scrollTo(mescroll.getScrollTop(),0) 68 | },30) 69 | } 70 | } 71 | } 72 | } 73 | 74 | export default MescrollMoreMixin; 75 | -------------------------------------------------------------------------------- /components/mescroll-uni/wxs/renderjs.js: -------------------------------------------------------------------------------- 1 | // 使用renderjs直接操作window对象,实现动态控制app和h5的bounce 2 | // bounce: iOS橡皮筋,Android半月弧,h5浏览器下拉背景等效果 (下拉刷新时禁止) 3 | // https://uniapp.dcloud.io/frame?id=renderjs 4 | 5 | // 与wxs的me实例一致 6 | var me = {} 7 | 8 | // 初始化window对象的touch事件 (仅初始化一次) 9 | if(window && !window.$mescrollRenderInit){ 10 | window.$mescrollRenderInit = true 11 | 12 | 13 | window.addEventListener('touchstart', function(e){ 14 | if (me.disabled()) return; 15 | me.startPoint = me.getPoint(e); // 记录起点 16 | }, {passive: true}) 17 | 18 | 19 | window.addEventListener('touchmove', function(e){ 20 | if (me.disabled()) return; 21 | if (me.getScrollTop() > 0) return; // 需在顶部下拉,才禁止bounce 22 | 23 | var curPoint = me.getPoint(e); // 当前点 24 | var moveY = curPoint.y - me.startPoint.y; // 和起点比,移动的距离,大于0向下拉,小于0向上拉 25 | // 向下拉 26 | if (moveY > 0) { 27 | // 可下拉的条件 28 | if (!me.isDownScrolling && !me.optDown.isLock && (!me.isUpScrolling || (me.isUpScrolling && me.isUpBoth))) { 29 | 30 | // 只有touch在mescroll的view上面,才禁止bounce 31 | var el = e.target; 32 | var isMescrollTouch = false; 33 | while (el && el.tagName && el.tagName !== 'UNI-PAGE-BODY' && el.tagName != "BODY") { 34 | var cls = el.classList; 35 | if (cls && cls.contains('mescroll-render-touch')) { 36 | isMescrollTouch = true 37 | break; 38 | } 39 | el = el.parentNode; // 继续检查其父元素 40 | } 41 | // 禁止bounce (不会对swiper和iOS侧滑返回造成影响) 42 | if (isMescrollTouch && e.cancelable && !e.defaultPrevented) e.preventDefault(); 43 | } 44 | } 45 | }, {passive: false}) 46 | } 47 | 48 | /* 获取滚动条的位置 */ 49 | me.getScrollTop = function() { 50 | return me.scrollTop || 0 51 | } 52 | 53 | /* 是否禁用下拉刷新 */ 54 | me.disabled = function(){ 55 | return !me.optDown || !me.optDown.use || me.optDown.native 56 | } 57 | 58 | /* 根据点击滑动事件获取第一个手指的坐标 */ 59 | me.getPoint = function(e) { 60 | if (!e) { 61 | return {x: 0,y: 0} 62 | } 63 | if (e.touches && e.touches[0]) { 64 | return {x: e.touches[0].pageX,y: e.touches[0].pageY} 65 | } else if (e.changedTouches && e.changedTouches[0]) { 66 | return {x: e.changedTouches[0].pageX,y: e.changedTouches[0].pageY} 67 | } else { 68 | return {x: e.clientX,y: e.clientY} 69 | } 70 | } 71 | 72 | /** 73 | * 监听逻辑层数据的变化 (实时更新数据) 74 | */ 75 | function propObserver(wxsProp) { 76 | me.optDown = wxsProp.optDown 77 | me.scrollTop = wxsProp.scrollTop 78 | me.isDownScrolling = wxsProp.isDownScrolling 79 | me.isUpScrolling = wxsProp.isUpScrolling 80 | me.isUpBoth = wxsProp.isUpBoth 81 | } 82 | 83 | /* 导出模块 */ 84 | const renderBiz = { 85 | data() { 86 | return { 87 | propObserver: propObserver, 88 | } 89 | } 90 | } 91 | 92 | export default renderBiz; -------------------------------------------------------------------------------- /components/rf-back-top/index.vue: -------------------------------------------------------------------------------- 1 | 11 | 53 | 86 | -------------------------------------------------------------------------------- /components/rf-badge/rf-badge.vue: -------------------------------------------------------------------------------- 1 | 11 | 12 | 74 | 75 | 102 | -------------------------------------------------------------------------------- /components/rf-emoji/rf-emoji.vue: -------------------------------------------------------------------------------- 1 | 27 | 28 | 91 | 92 | 126 | -------------------------------------------------------------------------------- /components/rf-empty/index.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | 47 | 48 | 78 | -------------------------------------------------------------------------------- /components/rf-image/rf-image.vue: -------------------------------------------------------------------------------- 1 | 22 | 23 | 67 | 68 | 74 | -------------------------------------------------------------------------------- /components/rf-kefu/index.vue: -------------------------------------------------------------------------------- 1 | 20 | 56 | 99 | -------------------------------------------------------------------------------- /components/rf-list-cell/index.vue: -------------------------------------------------------------------------------- 1 | 22 | 23 | 76 | 77 | 118 | -------------------------------------------------------------------------------- /components/rf-live/index.vue: -------------------------------------------------------------------------------- 1 | 10 | 63 | 98 | -------------------------------------------------------------------------------- /components/rf-load-progress/rf-load-progress.vue: -------------------------------------------------------------------------------- 1 | 17 | 18 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /components/rf-loading/loaders/bounce.vue: -------------------------------------------------------------------------------- 1 | 15 | 16 | 25 | 26 | 79 | -------------------------------------------------------------------------------- /components/rf-loading/loaders/double-bounce.vue: -------------------------------------------------------------------------------- 1 | 15 | 16 | 25 | 26 | 73 | -------------------------------------------------------------------------------- /components/rf-loading/loaders/double-cube.vue: -------------------------------------------------------------------------------- 1 | 29 | 30 | 39 | 40 | 102 | -------------------------------------------------------------------------------- /components/rf-loading/loaders/double-dot.vue: -------------------------------------------------------------------------------- 1 | 15 | 16 | 25 | 26 | 91 | -------------------------------------------------------------------------------- /components/rf-loading/loaders/rotate-plane.vue: -------------------------------------------------------------------------------- 1 | 13 | 14 | 23 | 24 | 59 | -------------------------------------------------------------------------------- /components/rf-loading/loaders/scale-out.vue: -------------------------------------------------------------------------------- 1 | 13 | 14 | 23 | 24 | 55 | -------------------------------------------------------------------------------- /components/rf-loading/loaders/shrink-rect.vue: -------------------------------------------------------------------------------- 1 | 18 | 19 | 28 | 29 | 89 | -------------------------------------------------------------------------------- /components/rf-nav/index.vue: -------------------------------------------------------------------------------- 1 | 15 | 37 | 62 | -------------------------------------------------------------------------------- /components/rf-parser/libs/CssHandler.js: -------------------------------------------------------------------------------- 1 | // eslint-disable 2 | const cfg = require('./config.js'), 3 | isLetter = c => (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'); 4 | 5 | function CssHandler(tagStyle) { 6 | var styles = Object.assign(Object.create(null), cfg.userAgentStyles); 7 | for (var item in tagStyle) 8 | styles[item] = (styles[item] ? styles[item] + ';' : '') + tagStyle[item]; 9 | this.styles = styles; 10 | } 11 | 12 | CssHandler.prototype.getStyle = function(data) { 13 | this.styles = new parser(data, this.styles).parse(); 14 | }; 15 | CssHandler.prototype.match = function(name, attrs) { 16 | var tmp, matched = (tmp = this.styles[name]) ? tmp + ';' : ''; 17 | if (attrs.class) { 18 | var items = attrs.class.split(' '); 19 | for (var i = 0, item; item = items[i]; i++) 20 | if (tmp = this.styles['.' + item]) 21 | matched += tmp + ';'; 22 | } 23 | if (tmp = this.styles['#' + attrs.id]) 24 | matched += tmp + ';'; 25 | return matched; 26 | }; 27 | module.exports = CssHandler; 28 | 29 | function parser(data, init) { 30 | this.data = data; 31 | this.floor = 0; 32 | this.i = 0; 33 | this.list = []; 34 | this.res = init; 35 | this.state = this.Space; 36 | } 37 | 38 | parser.prototype.parse = function() { 39 | for (var c; c = this.data[this.i]; this.i++) 40 | this.state(c); 41 | return this.res; 42 | }; 43 | parser.prototype.section = function() { 44 | return this.data.substring(this.start, this.i); 45 | }; 46 | // 状态机 47 | parser.prototype.Space = function(c) { 48 | if (c == '.' || c == '#' || isLetter(c)) { 49 | this.start = this.i; 50 | this.state = this.Name; 51 | } else if (c == '/' && this.data[this.i + 1] == '*') 52 | this.Comment(); 53 | else if (!cfg.blankChar[c] && c != ';') 54 | this.state = this.Ignore; 55 | }; 56 | parser.prototype.Comment = function() { 57 | this.i = this.data.indexOf('*/', this.i) + 1; 58 | if (!this.i) this.i = this.data.length; 59 | this.state = this.Space; 60 | }; 61 | parser.prototype.Ignore = function(c) { 62 | if (c == '{') this.floor++; 63 | else if (c == '}' && !--this.floor) this.state = this.Space; 64 | }; 65 | parser.prototype.Name = function(c) { 66 | if (cfg.blankChar[c]) { 67 | this.list.push(this.section()); 68 | this.state = this.NameSpace; 69 | } else if (c == '{') { 70 | this.list.push(this.section()); 71 | this.Content(); 72 | } else if (c == ',') { 73 | this.list.push(this.section()); 74 | this.Comma(); 75 | } else if (!isLetter(c) && (c < '0' || c > '9') && c != '-' && c != '_') 76 | this.state = this.Ignore; 77 | }; 78 | parser.prototype.NameSpace = function(c) { 79 | if (c == '{') this.Content(); 80 | else if (c == ',') this.Comma(); 81 | else if (!cfg.blankChar[c]) this.state = this.Ignore; 82 | }; 83 | parser.prototype.Comma = function() { 84 | while (cfg.blankChar[this.data[++this.i]]) ; 85 | if (this.data[this.i] == '{') this.Content(); 86 | else { 87 | this.start = this.i--; 88 | this.state = this.Name; 89 | } 90 | }; 91 | parser.prototype.Content = function() { 92 | this.start = ++this.i; 93 | if ((this.i = this.data.indexOf('}', this.i)) == -1) this.i = this.data.length; 94 | var content = this.section(); 95 | for (var i = 0, item; item = this.list[i++];) 96 | if (this.res[item]) this.res[item] += ';' + content; 97 | else this.res[item] = content; 98 | this.list = []; 99 | this.state = this.Space; 100 | }; 101 | -------------------------------------------------------------------------------- /components/rf-parser/libs/config.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable */ 2 | /* 配置文件 */ 3 | // #ifdef MP-WEIXIN 4 | const canIUse = wx.canIUse('editor'); // 高基础库标识,用于兼容 5 | // #endif 6 | module.exports = { 7 | // 出错占位图 8 | errorImg: null, 9 | // 过滤器函数 10 | filter: null, 11 | // 代码高亮函数 12 | highlight: null, 13 | // 文本处理函数 14 | onText: null, 15 | // 实体编码列表 16 | entities: { 17 | quot: '"', 18 | apos: '\'', 19 | semi: ';', 20 | nbsp: '\xA0', 21 | ensp: '\u2002', 22 | emsp: '\u2003', 23 | ndash: '–', 24 | mdash: '—', 25 | middot: '·', 26 | lsquo: '‘', 27 | rsquo: '’', 28 | ldquo: '“', 29 | rdquo: '”', 30 | bull: '•', 31 | hellip: '…' 32 | }, 33 | blankChar: makeMap(' ,\xA0,\t,\r,\n,\f'), 34 | boolAttrs: makeMap('allowfullscreen,autoplay,autostart,controls,ignore,loop,muted'), 35 | // 块级标签,将被转为 div 36 | blockTags: makeMap('address,article,aside,body,caption,center,cite,footer,header,html,nav,section' + ( 37 | // #ifdef MP-WEIXIN 38 | canIUse ? '' : 39 | // #endif 40 | ',pre')), 41 | // 将被移除的标签 42 | ignoreTags: makeMap( 43 | 'area,base,canvas,frame,input,link,map,meta,param,script,source,style,svg,textarea,title,track,wbr' 44 | // #ifdef MP-WEIXIN 45 | + (canIUse ? ',rp' : '') 46 | // #endif 47 | // #ifndef APP-PLUS 48 | + ',iframe' 49 | // #endif 50 | ), 51 | // 只能被 rich-text 显示的标签 52 | richOnlyTags: makeMap('a,colgroup,fieldset,legend,table' 53 | // #ifdef MP-WEIXIN 54 | + (canIUse ? ',bdi,bdo,caption,rt,ruby' : '') 55 | // #endif 56 | ), 57 | // 自闭合的标签 58 | selfClosingTags: makeMap( 59 | 'area,base,br,col,circle,ellipse,embed,frame,hr,img,input,line,link,meta,param,path,polygon,rect,source,track,use,wbr' 60 | ), 61 | // 信任的标签 62 | trustTags: makeMap( 63 | 'a,abbr,ad,audio,b,blockquote,br,code,col,colgroup,dd,del,dl,dt,div,em,fieldset,h1,h2,h3,h4,h5,h6,hr,i,img,ins,label,legend,li,ol,p,q,source,span,strong,sub,sup,table,tbody,td,tfoot,th,thead,tr,title,ul,video' 64 | // #ifdef MP-WEIXIN 65 | + (canIUse ? ',bdi,bdo,caption,pre,rt,ruby' : '') 66 | // #endif 67 | // #ifdef APP-PLUS 68 | + ',embed,iframe' 69 | // #endif 70 | ), 71 | // 默认的标签样式 72 | userAgentStyles: { 73 | address: 'font-style:italic', 74 | big: 'display:inline;font-size:1.2em', 75 | blockquote: 'background-color:#f6f6f6;border-left:3px solid #dbdbdb;color:#6c6c6c;padding:5px 0 5px 10px', 76 | caption: 'display:table-caption;text-align:center', 77 | center: 'text-align:center', 78 | cite: 'font-style:italic', 79 | dd: 'margin-left:40px', 80 | mark: 'background-color:yellow', 81 | pre: 'font-family:monospace;white-space:pre;overflow:scroll', 82 | s: 'text-decoration:line-through', 83 | img: 'display:block', 84 | small: 'display:inline;font-size:0.8em', 85 | u: 'text-decoration:underline' 86 | } 87 | }; 88 | 89 | function makeMap(str) { 90 | var map = Object.create(null), 91 | list = str.split(','); 92 | for (var i = list.length; i--;) 93 | map[list[i]] = true; 94 | return map; 95 | } 96 | -------------------------------------------------------------------------------- /components/rf-parser/libs/handler.wxs: -------------------------------------------------------------------------------- 1 | var inline = { 2 | abbr: 1, 3 | b: 1, 4 | big: 1, 5 | code: 1, 6 | del: 1, 7 | em: 1, 8 | i: 1, 9 | ins: 1, 10 | label: 1, 11 | q: 1, 12 | small: 1, 13 | span: 1, 14 | strong: 1 15 | } 16 | module.exports = { 17 | use: function(item) { 18 | return !item.c && !inline[item.name] && (item.attrs.style || '').indexOf('display:inline') == -1 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /components/rf-popup-ad/index.vue: -------------------------------------------------------------------------------- 1 | 14 | 43 | 90 | -------------------------------------------------------------------------------- /components/rf-poster/index.vue: -------------------------------------------------------------------------------- 1 | 26 | 27 | 73 | 74 | 109 | -------------------------------------------------------------------------------- /components/rf-protocol-popup/index.vue: -------------------------------------------------------------------------------- 1 | 31 | 32 | 71 | 72 | 141 | -------------------------------------------------------------------------------- /components/rf-recommend/rf-recommend.vue: -------------------------------------------------------------------------------- 1 | 11 | 73 | 102 | -------------------------------------------------------------------------------- /components/rf-site-open/index.vue: -------------------------------------------------------------------------------- 1 | 14 | 37 | 87 | -------------------------------------------------------------------------------- /components/rf-swiper-slide/index.vue: -------------------------------------------------------------------------------- 1 | 28 | 29 | 55 | 56 | 83 | -------------------------------------------------------------------------------- /components/rf-top-drawer/index.vue: -------------------------------------------------------------------------------- 1 | 23 | 24 | 72 | 73 | 107 | -------------------------------------------------------------------------------- /components/rf-top-dropdown/index.vue: -------------------------------------------------------------------------------- 1 | 23 | 24 | 72 | 73 | 110 | -------------------------------------------------------------------------------- /components/tm-upload/readme.md: -------------------------------------------------------------------------------- 1 | 在此基础上面修改https://ext.dcloud.net.cn/plugin?id=63 感谢原作者 2 | 3 | 除原版功能外,有以下改动: 4 | 5 | 1.增加视频上传功能(type设置为video即为视频模式,可播放可全屏,多视频); 6 | 2.修复组件复用时预览Bug; 7 | 3.修复组件复用时上传进度Bug; 8 | 9 | 用法请参考原版 10 | 在原版data基础上增加type,header,videoContext 11 | -------------------------------------------------------------------------------- /components/uni-collapse/uni-collapse.vue: -------------------------------------------------------------------------------- 1 | 6 | 40 | 54 | -------------------------------------------------------------------------------- /components/uni-drawer/drawer.vue: -------------------------------------------------------------------------------- 1 | 17 | 18 | 49 | 50 | 116 | -------------------------------------------------------------------------------- /components/uni-drawer/uni-drawer.vue: -------------------------------------------------------------------------------- 1 | 17 | 18 | 90 | 91 | 150 | -------------------------------------------------------------------------------- /config/assets.config.js: -------------------------------------------------------------------------------- 1 | //微信:egvh56ufy7hh ,QQ:821898835 import indexConfig from './index.config.js'; 2 | const PATH = indexConfig.assetsPath; 3 | /* 4 | * 图片静态资源表,所有图片资源路径在这统一管理,不应该写死在页面中,该数据挂载到Vue原型中。 5 | * 页面使用:this.$mAssetsPath.grid_1 6 | * CSS背景:应尽量使用:style="" 行内样式设置背景图 7 | * PATH说明:本地路径或者服务器路径 8 | * 9 | * 举例: 需要在data中映射 grid_1: this.$mAssetsPath.grid_1 10 | * 11 | * 特别注意:经测试小程序中不支持 该用法 12 | */ 13 | 14 | export default { 15 | // 默认头像 16 | headImg: PATH + '/missing-face.png', 17 | 18 | // 出错填充图片 19 | errorImage: PATH + '/errorImage.jpg', 20 | 21 | // 品牌logo 22 | logo: PATH + '/logo.jpg', 23 | 24 | // 商城新闻 25 | newsBg: PATH + '/news.png', 26 | 27 | // 商城新闻 28 | userBg: PATH + '/user-bg.png', 29 | 30 | // vip背景 31 | vipCardBg: PATH + '/vip-card.png', 32 | 33 | // vip价格 34 | vipPrice: PATH + '/vip-price.png', 35 | 36 | // 弧形背景 37 | arc: PATH + '/arc.png', 38 | 39 | // 500 40 | noNetWorkImg: PATH + '/noNetWork.png', 41 | 42 | // 404 43 | notFoundImg: PATH + '/notFound.png', 44 | 45 | // 升级图标 46 | upgradeTop: PATH + '/upgrade-top.png', 47 | 48 | // 返回顶部 49 | backTop: PATH + '/top.png', 50 | 51 | // 分享引导背景 52 | shareBg: PATH + '/share-bg.png', 53 | 54 | // 分销tag 55 | distribution: PATH + '/distribution.png', 56 | 57 | // 包邮tag 58 | pinkage: PATH + '/pinkage.png', 59 | 60 | // 预售tag 61 | presale: PATH + '/presale.png', 62 | 63 | // 开放站点 64 | openSiteBg: PATH + '/open-site-bg.png', 65 | 66 | // 虚拟tag 67 | virtual: PATH + '/virtual.png', 68 | 69 | // 登录背景 70 | loginBg: PATH + '/login-bg.png', 71 | 72 | // 登录插画 73 | loginPic: PATH + '/login-pic.png', 74 | 75 | // 砍价标签 76 | wholesaleTag: PATH + '/wholesale-tag.png', 77 | 78 | // 拼团标签 79 | groupTag: PATH + '/group-tag.png', 80 | 81 | // 砍价标签 82 | bargainTag: PATH + '/bargain-tag.png', 83 | 84 | // 砍价标签 85 | discountTag: PATH + '/discount-tag.png', 86 | 87 | // 微信授权登录 88 | wechat: PATH + '/wechat.png', 89 | 90 | // 微信授权登录 91 | apple: PATH + '/apple.png', 92 | 93 | // QQ授权登录 94 | qq: PATH + '/qq.png', 95 | 96 | // 新浪授权登录 97 | weibo: PATH + '/weibo.png', 98 | 99 | // 微信授权登录 100 | money: PATH + '/money.png', 101 | 102 | // 微信授权登录 103 | moneyBg: PATH + '/money-bg.png', 104 | 105 | // 赠品标签 106 | giftTag: PATH + '/gift.png', 107 | 108 | // 默认图片 109 | defaultImg: PATH + '/default-img.png', 110 | 111 | // 三角形 112 | triangleTag: PATH + '/triangle-tag.png', 113 | 114 | // 正方形 115 | squareTag: PATH + '/square-tag.png', 116 | 117 | // 圆形 118 | circleTag: PATH + '/circle-tag.png', 119 | 120 | // 圆柱 121 | columnTag: PATH + '/column-tag.png' 122 | }; 123 | -------------------------------------------------------------------------------- /config/index.config.js: -------------------------------------------------------------------------------- 1 | const CONFIG = { 2 | // 开发环境配置 3 | development: { 4 | assetsPath: '/static', // 静态资源路径 5 | basePath: 'https://izhaochong.noooya.com/static', // 网络资源路径 6 | //baseUrl: 'http://sf3.com/api', // 后台接口请求地址 7 | baseUrl: 'https://izhaochong.noooya.com/api', // 后台接口请求地址 8 | hostUrl: 'https://izhaochong.noooya.com/h5', // H5地址(前端运行地址) 9 | websocketUrl: '', // websocket服务端地址 10 | weixinAppId: 'wxc4bbbe1b3b1b4a71' // 微信公众号appid 11 | }, 12 | // 生产环境配置 13 | production: { 14 | assetsPath: '/static', // 静态资源路径 15 | basePath: 'https://izhaochong.noooya.com/static', // 网络资源路径 16 | baseUrl: 'https://izhaochong.noooya.com/api', // 后台接口请求地址 17 | hostUrl: 'https://izhaochong.noooya.com/h5', // H5地址(前端运行地址) 18 | websocketUrl: '', // websocket服务端地址 19 | weixinAppId: 'wxc4bbbe1b3b1b4a71' // 微信公众号appid 20 | } 21 | 22 | }; 23 | export default CONFIG[process.env.NODE_ENV]; 24 | -------------------------------------------------------------------------------- /config/routes.config.js: -------------------------------------------------------------------------------- 1 | /* 2 | * 路由表对象: 3 | * 该文件挂载在Vue原型中 $mRoutesConfig 4 | * 作用:调用$mRouter对象的方法 传入以下对应的路由对象,详细见common目录下的router.js 5 | * 示例:this.$mRouter.push({route:this.$mRoutesConfig.main,query:{a:1}}) 6 | * 注意:所有在pages目录下新建的页面都必须在"路由表"中进行声明,并且在框架的pages.json注册。 7 | * 8 | * 配置参数项说明: 9 | * name:可选配置 (路由名称) 10 | * path:必填配置 (路由地址) 11 | * requiresAuth:可选配置 (是否权限路由) 12 | */ 13 | 14 | export default { 15 | // 权限路由 在main.js可实现路由拦截 所以路由都需要注册 待完善 16 | promoCode: { 17 | name: '创建订单', 18 | path: '/pages/order/create/order', 19 | requiresAuth: true 20 | }, 21 | 22 | // 非权限路由 23 | main: { 24 | name: '首页', 25 | path: '/pages/index/index' 26 | }, 27 | category: { 28 | name: '分类', 29 | path: '/pages/category/category' 30 | }, 31 | cart: { 32 | name: '购物车', 33 | path: '/pages/cart/cart' 34 | }, 35 | login: { 36 | name: '登录', 37 | path: '/pages/public/login' 38 | }, 39 | index: { 40 | name: '注册', 41 | path: '/pages/public/register' 42 | }, 43 | loginType: { 44 | name: '登录类型', 45 | path: '/pages/public/logintype' 46 | } 47 | }; 48 | -------------------------------------------------------------------------------- /config/websocket.config.js: -------------------------------------------------------------------------------- 1 | /* 2 | * websocket 请求路由说明 3 | * 连接成功后会发送一个 fd 回来,为自己的客户端id,注意保存,后续以这个判断消息是自己发的还是别人发的 4 | * 5 | * 公共状态码说明 6 | * 1006: 意外断开 7 | * 2000: OK。一切正常 8 | * 2001: 连接成功 9 | * 2002: 心跳成功 10 | * 2003: 排队中 11 | * 2004: 排队成功 12 | * 2005: xxx客服为您服务 13 | * 2006: xxx用户来了 14 | * 4000: 客户端未响应连接关闭数据,无效的操作参数,等等 15 | * 4001: 用户验证失败 16 | * 4002: 正常报错提示 17 | * 4004: 所请求的资源不存在 18 | * 4101: 已在别处登录 19 | * 4102: 用户已离线 20 | * 4103: 当前接待人数过多 21 | * 4104: 客服不在线 22 | * 5000: 内部服务器错误。 这可能是由于内部程序错误引起的。 23 | * 24 | */ 25 | 26 | export default { 27 | // 登录 28 | login: 'site.login', 29 | 30 | // 客服列表 31 | serviceIndex: 'service.index', 32 | 33 | // 连接客服 34 | queueUpMatching: 'queueUp.matching', 35 | 36 | // 排队查询 37 | queueUpIndex: 'queueUp.index', 38 | 39 | // 发送消息 40 | serviceMessage: 'service.message', 41 | 42 | // 主动结束会话 43 | memberClose: 'member.close', 44 | 45 | // 客服转接[只接收] 46 | bubbleTransferring: 'bubble.transferring', 47 | 48 | // 被客服结束会话[只接收] 49 | bubbleClose: 'bubble.close', 50 | 51 | // 当前会话历史消息 52 | memberConversation: 'member.conversation', 53 | 54 | // 自动回复 发送消息 55 | ruleMessage: 'rule.message', 56 | 57 | // 自动回复 发送消息 58 | conversationAll: 'member.conversationAll', 59 | 60 | // 心跳 61 | ping: 'site.ping' 62 | }; 63 | -------------------------------------------------------------------------------- /pages/index/notice/detail.vue: -------------------------------------------------------------------------------- 1 | //微信:egvh56ufy7hh ,QQ:821898835 2 | 27 | 28 | 42 | 43 | 51 | -------------------------------------------------------------------------------- /pages/pet/city.vue: -------------------------------------------------------------------------------- 1 | 20 | 21 | 99 | 100 | 118 | -------------------------------------------------------------------------------- /pages/pet/my-apply.vue: -------------------------------------------------------------------------------- 1 | 21 | 22 | 85 | 86 | 101 | -------------------------------------------------------------------------------- /pages/pet/web.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 40 | 41 | 48 | -------------------------------------------------------------------------------- /pages/set/helper/detail.vue: -------------------------------------------------------------------------------- 1 | 12 | 13 | 46 | 47 | 63 | -------------------------------------------------------------------------------- /pages/set/helper/index.vue: -------------------------------------------------------------------------------- 1 | 19 | 20 | 56 | 57 | 70 | -------------------------------------------------------------------------------- /pages/user/live.vue: -------------------------------------------------------------------------------- 1 | 2 | 24 | 25 | 45 | 46 | 52 | -------------------------------------------------------------------------------- /uni.scss: -------------------------------------------------------------------------------- 1 | @import 'uview-ui/theme.scss'; 2 | 3 | /* 页面左右间距 */ 4 | $spacing-lg: 30rpx; 5 | $spacing-base: 20rpx; 6 | $spacing-sm: 10rpx; 7 | 8 | $color-white: #fff; 9 | $color-black: #000; 10 | 11 | $page-row-spacing: 30rpx; 12 | $page-color-base: #f8f8f8; 13 | $page-color-light: #f8f6fc; 14 | $base-color: #fa436a; 15 | 16 | /* 文字尺寸 */ 17 | $font-sm: 24rpx; 18 | $font-base: 28rpx; 19 | $font-lg: 32rpx; 20 | 21 | /*文字颜色*/ 22 | $font-color-dark: #303133; 23 | $font-color-base: #606266; 24 | $font-color-light: #909399; 25 | $font-color-disabled: #C0C4CC; 26 | $font-color-spec: #4399fc; 27 | 28 | /* 边框颜色 */ 29 | $border-color-dark: #DCDFE6; 30 | $border-color-base: #E4E7ED; 31 | $border-color-light: #EBEEF5; 32 | 33 | /* 图片加载中颜色 */ 34 | $image-bg-color: #eee; 35 | 36 | /* 行为相关颜色 */ 37 | $uni-color-primary:#fa436a; 38 | $uni-color-success: #4cd964; 39 | $uni-color-warning: #f0ad4e; 40 | $uni-color-error: #dd524d; 41 | 42 | -------------------------------------------------------------------------------- /utils/router.js: -------------------------------------------------------------------------------- 1 | /* 2 | * 路由对象 3 | * 中心思想:需要路由鉴权,由于uni-app没有vue中的全局钩子函数,所以封装了Router对象。 4 | * 说明:应用中的路由跳转尽量使用该Router的方法,并配合config中的路由表对象进行跳转。 5 | * 6 | * 示例:this.$mRouter.push({route:this.$mRoutesConfig.main,query:{a:1}}) 7 | * 8 | */ 9 | class Router { 10 | constructor() { 11 | this.callBack = () => {}; 12 | } 13 | 14 | beforeEach(callBack) { 15 | if (callBack instanceof Function) this.callBack = callBack; 16 | } 17 | 18 | push(to) { 19 | this.callBack('navigateTo', to); 20 | } 21 | 22 | redirectTo(to) { 23 | this.callBack('redirectTo', to); 24 | } 25 | 26 | reLaunch(to) { 27 | this.callBack('reLaunch', to); 28 | } 29 | 30 | switchTab(to) { 31 | this.callBack('switchTab', to); 32 | } 33 | 34 | back(delta) { 35 | // #ifdef H5 36 | history.back(); 37 | // #endif 38 | // #ifndef H5 39 | uni.navigateBack({ 40 | delta 41 | }); 42 | // #endif 43 | } 44 | } 45 | 46 | export default new Router(); 47 | -------------------------------------------------------------------------------- /uview-ui/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 www.uviewui.com 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /uview-ui/README.md: -------------------------------------------------------------------------------- 1 |

2 | logo 3 |

4 |

uView

5 |

多平台快速开发的UI框架

6 | 7 | 8 | ## 说明 9 | 10 | uView UI,是[uni-app](https://uniapp.dcloud.io/)生态优秀的UI框架,全面的组件和便捷的工具会让您信手拈来,如鱼得水 11 | 12 | ## 特性 13 | 14 | - 兼容安卓,iOS,微信小程序,H5,QQ小程序,百度小程序,支付宝小程序,头条小程序 15 | - 60+精选组件,功能丰富,多端兼容,让您快速集成,开箱即用 16 | - 众多贴心的JS利器,让您飞镖在手,召之即来,百步穿杨 17 | - 众多的常用页面和布局,让您专注逻辑,事半功倍 18 | - 详尽的文档支持,现代化的演示效果 19 | - 按需引入,精简打包体积 20 | 21 | 22 | ## 安装 23 | 24 | ```bash 25 | # npm方式安装 26 | npm i uview-ui 27 | ``` 28 | 29 | ## 快速上手 30 | 31 | 1. `main.js`引入uView库 32 | ```js 33 | // main.js 34 | import uView from 'uview-ui'; 35 | Vue.use(uView); 36 | ``` 37 | 38 | 2. `App.vue`引入基础样式(注意style标签需声明scss属性支持) 39 | ```css 40 | /* App.vue */ 41 | 44 | ``` 45 | 46 | 3. `uni.scss`引入全局scss变量文件 47 | ```css 48 | /* uni.scss */ 49 | @import "uview-ui/theme.scss"; 50 | ``` 51 | 52 | 4. `pages.json`配置easycom规则(按需引入) 53 | 54 | ```js 55 | // pages.json 56 | { 57 | "easycom": { 58 | // npm安装的方式不需要前面的"@/",下载安装的方式需要"@/" 59 | // npm安装方式 60 | "^u-(.*)": "uview-ui/components/u-$1/u-$1.vue" 61 | // 下载安装方式 62 | // "^u-(.*)": "@/uview-ui/components/u-$1/u-$1.vue" 63 | }, 64 | // 此为本身已有的内容 65 | "pages": [ 66 | // ...... 67 | ] 68 | } 69 | ``` 70 | 71 | 请通过[快速上手](https://uviewui.com/components/quickstart.html)了解更详细的内容 72 | 73 | ## 使用方法 74 | 配置easycom规则后,自动按需引入,无需`import`组件,直接引用即可。 75 | 76 | ```html 77 | 80 | ``` 81 | 82 | 请通过[快速上手](https://uviewui.com/components/quickstart.html)了解更详细的内容 83 | 84 | ## 链接 85 | 86 | - [官方文档](https://uviewui.com/) 87 | - [更新日志](https://uviewui.com/components/changelog.html) 88 | - [升级指南](https://uviewui.com/components/changelog.html) 89 | - [关于我们](https://uviewui.com/cooperation/about.html) 90 | 91 | ## 预览 92 | 93 | 您可以通过**微信**扫码,查看最佳的演示效果。 94 |
95 |
96 | 97 | 98 | 105 | ## 版权信息 106 | uView遵循[MIT](https://en.wikipedia.org/wiki/MIT_License)开源协议,意味着您无需支付任何费用,也无需授权,即可将uView应用到您的产品中。 107 | -------------------------------------------------------------------------------- /uview-ui/components/u-cell-group/u-cell-group.vue: -------------------------------------------------------------------------------- 1 | 11 | 12 | 51 | 52 | 71 | -------------------------------------------------------------------------------- /uview-ui/components/u-checkbox-group/u-checkbox-group.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 113 | 114 | 124 | -------------------------------------------------------------------------------- /uview-ui/components/u-collapse/u-collapse.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 96 | 97 | 100 | -------------------------------------------------------------------------------- /uview-ui/components/u-full-screen/u-full-screen.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 38 | 39 | 53 | -------------------------------------------------------------------------------- /uview-ui/components/u-gap/u-gap.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 51 | 52 | 55 | -------------------------------------------------------------------------------- /uview-ui/components/u-grid-item/u-grid-item.vue: -------------------------------------------------------------------------------- 1 | 12 | 13 | 81 | 82 | 127 | -------------------------------------------------------------------------------- /uview-ui/components/u-grid/u-grid.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 90 | 91 | 109 | -------------------------------------------------------------------------------- /uview-ui/components/u-index-anchor/u-index-anchor.vue: -------------------------------------------------------------------------------- 1 | 14 | 15 | 68 | 69 | 90 | -------------------------------------------------------------------------------- /uview-ui/components/u-line/u-line.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 77 | 78 | 85 | -------------------------------------------------------------------------------- /uview-ui/components/u-link/u-link.vue: -------------------------------------------------------------------------------- 1 | 11 | 12 | 82 | 83 | 90 | -------------------------------------------------------------------------------- /uview-ui/components/u-loading-page/u-loading-page.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 22 | 23 | 26 | -------------------------------------------------------------------------------- /uview-ui/components/u-mask/u-mask.vue: -------------------------------------------------------------------------------- 1 | 9 | 10 | 102 | 103 | 124 | -------------------------------------------------------------------------------- /uview-ui/components/u-parse/libs/CssHandler.js: -------------------------------------------------------------------------------- 1 | const cfg = require('./config.js'), 2 | isLetter = c => (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'); 3 | 4 | function CssHandler(tagStyle) { 5 | var styles = Object.assign(Object.create(null), cfg.userAgentStyles); 6 | for (var item in tagStyle) 7 | styles[item] = (styles[item] ? styles[item] + ';' : '') + tagStyle[item]; 8 | this.styles = styles; 9 | } 10 | CssHandler.prototype.getStyle = function(data) { 11 | this.styles = new parser(data, this.styles).parse(); 12 | } 13 | CssHandler.prototype.match = function(name, attrs) { 14 | var tmp, matched = (tmp = this.styles[name]) ? tmp + ';' : ''; 15 | if (attrs.class) { 16 | var items = attrs.class.split(' '); 17 | for (var i = 0, item; item = items[i]; i++) 18 | if (tmp = this.styles['.' + item]) 19 | matched += tmp + ';'; 20 | } 21 | if (tmp = this.styles['#' + attrs.id]) 22 | matched += tmp + ';'; 23 | return matched; 24 | } 25 | module.exports = CssHandler; 26 | 27 | function parser(data, init) { 28 | this.data = data; 29 | this.floor = 0; 30 | this.i = 0; 31 | this.list = []; 32 | this.res = init; 33 | this.state = this.Space; 34 | } 35 | parser.prototype.parse = function() { 36 | for (var c; c = this.data[this.i]; this.i++) 37 | this.state(c); 38 | return this.res; 39 | } 40 | parser.prototype.section = function() { 41 | return this.data.substring(this.start, this.i); 42 | } 43 | // 状态机 44 | parser.prototype.Space = function(c) { 45 | if (c == '.' || c == '#' || isLetter(c)) { 46 | this.start = this.i; 47 | this.state = this.Name; 48 | } else if (c == '/' && this.data[this.i + 1] == '*') 49 | this.Comment(); 50 | else if (!cfg.blankChar[c] && c != ';') 51 | this.state = this.Ignore; 52 | } 53 | parser.prototype.Comment = function() { 54 | this.i = this.data.indexOf('*/', this.i) + 1; 55 | if (!this.i) this.i = this.data.length; 56 | this.state = this.Space; 57 | } 58 | parser.prototype.Ignore = function(c) { 59 | if (c == '{') this.floor++; 60 | else if (c == '}' && !--this.floor) { 61 | this.list = []; 62 | this.state = this.Space; 63 | } 64 | } 65 | parser.prototype.Name = function(c) { 66 | if (cfg.blankChar[c]) { 67 | this.list.push(this.section()); 68 | this.state = this.NameSpace; 69 | } else if (c == '{') { 70 | this.list.push(this.section()); 71 | this.Content(); 72 | } else if (c == ',') { 73 | this.list.push(this.section()); 74 | this.Comma(); 75 | } else if (!isLetter(c) && (c < '0' || c > '9') && c != '-' && c != '_') 76 | this.state = this.Ignore; 77 | } 78 | parser.prototype.NameSpace = function(c) { 79 | if (c == '{') this.Content(); 80 | else if (c == ',') this.Comma(); 81 | else if (!cfg.blankChar[c]) this.state = this.Ignore; 82 | } 83 | parser.prototype.Comma = function() { 84 | while (cfg.blankChar[this.data[++this.i]]); 85 | if (this.data[this.i] == '{') this.Content(); 86 | else { 87 | this.start = this.i--; 88 | this.state = this.Name; 89 | } 90 | } 91 | parser.prototype.Content = function() { 92 | this.start = ++this.i; 93 | if ((this.i = this.data.indexOf('}', this.i)) == -1) this.i = this.data.length; 94 | var content = this.section(); 95 | for (var i = 0, item; item = this.list[i++];) 96 | if (this.res[item]) this.res[item] += ';' + content; 97 | else this.res[item] = content; 98 | this.list = []; 99 | this.state = this.Space; 100 | } 101 | -------------------------------------------------------------------------------- /uview-ui/components/u-parse/libs/config.js: -------------------------------------------------------------------------------- 1 | /* 配置文件 */ 2 | var cfg = { 3 | // 出错占位图 4 | errorImg: null, 5 | // 过滤器函数 6 | filter: null, 7 | // 代码高亮函数 8 | highlight: null, 9 | // 文本处理函数 10 | onText: null, 11 | // 实体编码列表 12 | entities: { 13 | quot: '"', 14 | apos: "'", 15 | semi: ';', 16 | nbsp: '\xA0', 17 | ensp: '\u2002', 18 | emsp: '\u2003', 19 | ndash: '–', 20 | mdash: '—', 21 | middot: '·', 22 | lsquo: '‘', 23 | rsquo: '’', 24 | ldquo: '“', 25 | rdquo: '”', 26 | bull: '•', 27 | hellip: '…' 28 | }, 29 | blankChar: makeMap(' ,\xA0,\t,\r,\n,\f'), 30 | boolAttrs: makeMap('allowfullscreen,autoplay,autostart,controls,ignore,loop,muted'), 31 | // 块级标签,将被转为 div 32 | blockTags: makeMap('address,article,aside,body,caption,center,cite,footer,header,html,nav,pre,section'), 33 | // 将被移除的标签 34 | ignoreTags: makeMap('area,base,canvas,frame,iframe,input,link,map,meta,param,script,source,style,svg,textarea,title,track,wbr'), 35 | // 只能被 rich-text 显示的标签 36 | richOnlyTags: makeMap('a,colgroup,fieldset,legend'), 37 | // 自闭合的标签 38 | selfClosingTags: makeMap('area,base,br,col,circle,ellipse,embed,frame,hr,img,input,line,link,meta,param,path,polygon,rect,source,track,use,wbr'), 39 | // 信任的标签 40 | trustTags: makeMap('a,abbr,ad,audio,b,blockquote,br,code,col,colgroup,dd,del,dl,dt,div,em,fieldset,h1,h2,h3,h4,h5,h6,hr,i,img,ins,label,legend,li,ol,p,q,source,span,strong,sub,sup,table,tbody,td,tfoot,th,thead,tr,title,ul,video'), 41 | // 默认的标签样式 42 | userAgentStyles: { 43 | address: 'font-style:italic', 44 | big: 'display:inline;font-size:1.2em', 45 | blockquote: 'background-color:#f6f6f6;border-left:3px solid #dbdbdb;color:#6c6c6c;padding:5px 0 5px 10px', 46 | caption: 'display:table-caption;text-align:center', 47 | center: 'text-align:center', 48 | cite: 'font-style:italic', 49 | dd: 'margin-left:40px', 50 | mark: 'background-color:yellow', 51 | pre: 'font-family:monospace;white-space:pre;overflow:scroll', 52 | s: 'text-decoration:line-through', 53 | small: 'display:inline;font-size:0.8em', 54 | u: 'text-decoration:underline' 55 | } 56 | } 57 | 58 | function makeMap(str) { 59 | var map = Object.create(null), 60 | list = str.split(','); 61 | for (var i = list.length; i--;) 62 | map[list[i]] = true; 63 | return map; 64 | } 65 | 66 | // #ifdef MP-WEIXIN 67 | if (wx.canIUse('editor')) { 68 | cfg.blockTags.pre = void 0; 69 | cfg.ignoreTags.rp = true; 70 | Object.assign(cfg.richOnlyTags, makeMap('bdi,bdo,caption,rt,ruby')); 71 | Object.assign(cfg.trustTags, makeMap('bdi,bdo,caption,pre,rt,ruby')); 72 | } 73 | // #endif 74 | 75 | // #ifdef APP-PLUS 76 | cfg.ignoreTags.iframe = void 0; 77 | Object.assign(cfg.trustTags, makeMap('embed,iframe')); 78 | // #endif 79 | 80 | module.exports = cfg; 81 | -------------------------------------------------------------------------------- /uview-ui/components/u-parse/libs/handler.wxs: -------------------------------------------------------------------------------- 1 | var inline = { 2 | abbr: 1, 3 | b: 1, 4 | big: 1, 5 | code: 1, 6 | del: 1, 7 | em: 1, 8 | i: 1, 9 | ins: 1, 10 | label: 1, 11 | q: 1, 12 | small: 1, 13 | span: 1, 14 | strong: 1, 15 | sub: 1, 16 | sup: 1 17 | } 18 | module.exports = { 19 | use: function(item) { 20 | return !item.c && !inline[item.name] && (item.attrs.style || '').indexOf('display:inline') == -1 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /uview-ui/components/u-row/u-row.vue: -------------------------------------------------------------------------------- 1 | 11 | 12 | 65 | 66 | 85 | -------------------------------------------------------------------------------- /uview-ui/components/u-table/u-table.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 76 | 77 | 85 | -------------------------------------------------------------------------------- /uview-ui/components/u-td/u-td.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 51 | 52 | 67 | -------------------------------------------------------------------------------- /uview-ui/components/u-th/u-th.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 48 | 49 | 63 | -------------------------------------------------------------------------------- /uview-ui/components/u-time-line-item/u-time-line-item.vue: -------------------------------------------------------------------------------- 1 | 12 | 13 | 52 | 53 | 84 | -------------------------------------------------------------------------------- /uview-ui/components/u-time-line/u-time-line.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 23 | 24 | 44 | -------------------------------------------------------------------------------- /uview-ui/components/u-top-tips/u-top-tips.vue: -------------------------------------------------------------------------------- 1 | 7 | 8 | 69 | 70 | 122 | -------------------------------------------------------------------------------- /uview-ui/components/u-tr/u-tr.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 18 | 19 | 26 | -------------------------------------------------------------------------------- /uview-ui/index.scss: -------------------------------------------------------------------------------- 1 | // 引入公共基础类 2 | @import "./libs/css/common.scss"; 3 | @import "./libs/css/color.scss"; 4 | 5 | // 非nvue的样式 6 | /* #ifndef APP-NVUE */ 7 | @import "./libs/css/style.vue.scss"; 8 | /* #endif */ 9 | 10 | // nvue的特有样式 11 | /* #ifdef APP-NVUE */ 12 | @import "./libs/css/style.nvue.scss"; 13 | /* #endif */ 14 | 15 | // 小程序特有的样式 16 | /* #ifdef MP */ 17 | @import "./libs/css/style.mp.scss"; 18 | /* #endif */ 19 | 20 | // H5特有的样式 21 | /* #ifdef H5 */ 22 | @import "./libs/css/style.h5.scss"; 23 | /* #endif */ -------------------------------------------------------------------------------- /uview-ui/libs/config/config.js: -------------------------------------------------------------------------------- 1 | // 此版本发布于2020-03-17 2 | let version = '1.8.4'; 3 | 4 | export default { 5 | v: version, 6 | version: version, 7 | // 主题名称 8 | type: [ 9 | 'primary', 10 | 'success', 11 | 'info', 12 | 'error', 13 | 'warning' 14 | ] 15 | } -------------------------------------------------------------------------------- /uview-ui/libs/config/zIndex.js: -------------------------------------------------------------------------------- 1 | // uniapp在H5中各API的z-index值如下: 2 | /** 3 | * actionsheet: 999 4 | * modal: 999 5 | * navigate: 998 6 | * tabbar: 998 7 | * toast: 999 8 | */ 9 | 10 | export default { 11 | toast: 10090, 12 | noNetwork: 10080, 13 | // popup包含popup,actionsheet,keyboard,picker的值 14 | popup: 10075, 15 | mask: 10070, 16 | navbar: 980, 17 | topTips: 975, 18 | sticky: 970, 19 | indexListSticky: 965, 20 | } -------------------------------------------------------------------------------- /uview-ui/libs/css/color.scss: -------------------------------------------------------------------------------- 1 | .u-type-primary-light { 2 | color: $u-type-primary-light; 3 | } 4 | 5 | .u-type-warning-light { 6 | color: $u-type-warning-light; 7 | } 8 | 9 | .u-type-success-light { 10 | color: $u-type-success-light; 11 | } 12 | 13 | .u-type-error-light { 14 | color: $u-type-error-light; 15 | } 16 | 17 | .u-type-info-light { 18 | color: $u-type-info-light; 19 | } 20 | 21 | .u-type-primary-light-bg { 22 | background-color: $u-type-primary-light; 23 | } 24 | 25 | .u-type-warning-light-bg { 26 | background-color: $u-type-warning-light; 27 | } 28 | 29 | .u-type-success-light-bg { 30 | background-color: $u-type-success-light; 31 | } 32 | 33 | .u-type-error-light-bg { 34 | background-color: $u-type-error-light; 35 | } 36 | 37 | .u-type-info-light-bg { 38 | background-color: $u-type-info-light; 39 | } 40 | 41 | .u-type-primary-dark { 42 | color: $u-type-primary-dark; 43 | } 44 | 45 | .u-type-warning-dark { 46 | color: $u-type-warning-dark; 47 | } 48 | 49 | .u-type-success-dark { 50 | color: $u-type-success-dark; 51 | } 52 | 53 | .u-type-error-dark { 54 | color: $u-type-error-dark; 55 | } 56 | 57 | .u-type-info-dark { 58 | color: $u-type-info-dark; 59 | } 60 | 61 | .u-type-primary-dark-bg { 62 | background-color: $u-type-primary-dark; 63 | } 64 | 65 | .u-type-warning-dark-bg { 66 | background-color: $u-type-warning-dark; 67 | } 68 | 69 | .u-type-success-dark-bg { 70 | background-color: $u-type-success-dark; 71 | } 72 | 73 | .u-type-error-dark-bg { 74 | background-color: $u-type-error-dark; 75 | } 76 | 77 | .u-type-info-dark-bg { 78 | background-color: $u-type-info-dark; 79 | } 80 | 81 | .u-type-primary-disabled { 82 | color: $u-type-primary-disabled; 83 | } 84 | 85 | .u-type-warning-disabled { 86 | color: $u-type-warning-disabled; 87 | } 88 | 89 | .u-type-success-disabled { 90 | color: $u-type-success-disabled; 91 | } 92 | 93 | .u-type-error-disabled { 94 | color: $u-type-error-disabled; 95 | } 96 | 97 | .u-type-info-disabled { 98 | color: $u-type-info-disabled; 99 | } 100 | 101 | .u-type-primary { 102 | color: $u-type-primary; 103 | } 104 | 105 | .u-type-warning { 106 | color: $u-type-warning; 107 | } 108 | 109 | .u-type-success { 110 | color: $u-type-success; 111 | } 112 | 113 | .u-type-error { 114 | color: $u-type-error; 115 | } 116 | 117 | .u-type-info { 118 | color: $u-type-info; 119 | } 120 | 121 | .u-type-primary-bg { 122 | background-color: $u-type-primary; 123 | } 124 | 125 | .u-type-warning-bg { 126 | background-color: $u-type-warning; 127 | } 128 | 129 | .u-type-success-bg { 130 | background-color: $u-type-success; 131 | } 132 | 133 | .u-type-error-bg { 134 | background-color: $u-type-error; 135 | } 136 | 137 | .u-type-info-bg { 138 | background-color: $u-type-info; 139 | } 140 | 141 | .u-main-color { 142 | color: $u-main-color; 143 | } 144 | 145 | .u-content-color { 146 | color: $u-content-color; 147 | } 148 | 149 | .u-tips-color { 150 | color: $u-tips-color; 151 | } 152 | 153 | .u-light-color { 154 | color: $u-light-color; 155 | } 156 | -------------------------------------------------------------------------------- /uview-ui/libs/css/common.scss: -------------------------------------------------------------------------------- 1 | .u-relative, 2 | .u-rela { 3 | position: relative; 4 | } 5 | 6 | .u-absolute, 7 | .u-abso { 8 | position: absolute; 9 | } 10 | 11 | // nvue不能用标签命名样式,不能放在微信组件中,否则微信开发工具会报警告,无法使用标签名当做选择器 12 | /* #ifndef APP-NVUE */ 13 | image { 14 | display: inline-block; 15 | } 16 | 17 | // 在weex,也即nvue中,所有元素默认为border-box 18 | view, 19 | text { 20 | box-sizing: border-box; 21 | } 22 | /* #endif */ 23 | 24 | .u-font-xs { 25 | font-size: 22rpx; 26 | } 27 | 28 | .u-font-sm { 29 | font-size: 26rpx; 30 | } 31 | 32 | .u-font-md { 33 | font-size: 28rpx; 34 | } 35 | 36 | .u-font-lg { 37 | font-size: 30rpx; 38 | } 39 | 40 | .u-font-xl { 41 | font-size: 34rpx; 42 | } 43 | 44 | .u-flex { 45 | /* #ifndef APP-NVUE */ 46 | display: flex; 47 | /* #endif */ 48 | flex-direction: row; 49 | align-items: center; 50 | } 51 | 52 | .u-flex-wrap { 53 | flex-wrap: wrap; 54 | } 55 | 56 | .u-flex-nowrap { 57 | flex-wrap: nowrap; 58 | } 59 | 60 | .u-col-center { 61 | align-items: center; 62 | } 63 | 64 | .u-col-top { 65 | align-items: flex-start; 66 | } 67 | 68 | .u-col-bottom { 69 | align-items: flex-end; 70 | } 71 | 72 | .u-row-center { 73 | justify-content: center; 74 | } 75 | 76 | .u-row-left { 77 | justify-content: flex-start; 78 | } 79 | 80 | .u-row-right { 81 | justify-content: flex-end; 82 | } 83 | 84 | .u-row-between { 85 | justify-content: space-between; 86 | } 87 | 88 | .u-row-around { 89 | justify-content: space-around; 90 | } 91 | 92 | .u-text-left { 93 | text-align: left; 94 | } 95 | 96 | .u-text-center { 97 | text-align: center; 98 | } 99 | 100 | .u-text-right { 101 | text-align: right; 102 | } 103 | 104 | .u-flex-col { 105 | /* #ifndef APP-NVUE */ 106 | display: flex; 107 | /* #endif */ 108 | flex-direction: column; 109 | } 110 | 111 | // 定义flex等分 112 | @for $i from 0 through 12 { 113 | .u-flex-#{$i} { 114 | flex: $i; 115 | } 116 | } 117 | 118 | // 定义字体(px)单位,小于20都为px单位字体 119 | @for $i from 9 to 20 { 120 | .u-font-#{$i} { 121 | font-size: $i + px; 122 | } 123 | } 124 | 125 | // 定义字体(rpx)单位,大于或等于20的都为rpx单位字体 126 | @for $i from 20 through 40 { 127 | .u-font-#{$i} { 128 | font-size: $i + rpx; 129 | } 130 | } 131 | 132 | // 定义内外边距,历遍1-80 133 | @for $i from 0 through 80 { 134 | // 只要双数和能被5除尽的数 135 | @if $i % 2 == 0 or $i % 5 == 0 { 136 | // 得出:u-margin-30或者u-m-30 137 | .u-margin-#{$i}, .u-m-#{$i} { 138 | margin: $i + rpx!important; 139 | } 140 | 141 | // 得出:u-padding-30或者u-p-30 142 | .u-padding-#{$i}, .u-p-#{$i} { 143 | padding: $i + rpx!important; 144 | } 145 | 146 | @each $short, $long in l left, t top, r right, b bottom { 147 | // 缩写版,结果如: u-m-l-30 148 | // 定义外边距 149 | .u-m-#{$short}-#{$i} { 150 | margin-#{$long}: $i + rpx!important; 151 | } 152 | 153 | // 定义内边距 154 | .u-p-#{$short}-#{$i} { 155 | padding-#{$long}: $i + rpx!important; 156 | } 157 | 158 | // 完整版,结果如:u-margin-left-30 159 | // 定义外边距 160 | .u-margin-#{$long}-#{$i} { 161 | margin-#{$long}: $i + rpx!important; 162 | } 163 | 164 | // 定义内边距 165 | .u-padding-#{$long}-#{$i} { 166 | padding-#{$long}: $i + rpx!important; 167 | } 168 | } 169 | } 170 | } 171 | 172 | // 重置nvue的默认关于flex的样式 173 | .u-reset-nvue { 174 | flex-direction: row; 175 | align-items: center; 176 | } -------------------------------------------------------------------------------- /uview-ui/libs/css/style.components.scss: -------------------------------------------------------------------------------- 1 | // 定义混入指令,用于在非nvue环境下的flex定义,因为nvue没有display属性,会报错 2 | @mixin vue-flex($direction: row) { 3 | /* #ifndef APP-NVUE */ 4 | display: flex; 5 | flex-direction: $direction; 6 | /* #endif */ 7 | } -------------------------------------------------------------------------------- /uview-ui/libs/css/style.h5.scss: -------------------------------------------------------------------------------- 1 | /* H5的时候,隐藏滚动条 */ 2 | ::-webkit-scrollbar { 3 | display: none; 4 | width: 0 !important; 5 | height: 0 !important; 6 | -webkit-appearance: none; 7 | background: transparent; 8 | } 9 | -------------------------------------------------------------------------------- /uview-ui/libs/css/style.mp.scss: -------------------------------------------------------------------------------- 1 | /* start--微信小程序编译后页面有组件名的元素,特别处理--start */ 2 | /* #ifdef MP-WEIXIN || MP-QQ */ 3 | u-td, u-th { 4 | flex: 1; 5 | align-self: stretch; 6 | } 7 | 8 | .u-td { 9 | height: 100%; 10 | } 11 | 12 | u-icon { 13 | display: inline-flex; 14 | align-items: center; 15 | } 16 | 17 | // 各家小程序宫格组件外层设置为100%,避免受到父元素display: flex;的影响 18 | u-grid { 19 | width: 100%; 20 | flex: 0 0 100%; 21 | } 22 | 23 | // 避免小程序线条组件因为父组件display: flex;而失效 24 | u-line { 25 | flex: 1; 26 | } 27 | 28 | u-switch { 29 | display: inline-flex; 30 | align-items: center; 31 | } 32 | 33 | u-dropdown { 34 | flex: 1; 35 | } 36 | /* #endif */ 37 | /* end-微信小程序编译后页面有组件名的元素,特别处理--end */ 38 | 39 | 40 | /* #ifdef MP-QQ || MP-TOUTIAO */ 41 | // 需要做这一切额外的兼容,都是因为TX的无能 42 | u-icon { 43 | line-height: 0; 44 | } 45 | /* #endif */ 46 | 47 | /* start--头条小程序编译后页面有组件名的元素,特别处理--start */ 48 | // 由于头条小程序不支持直接组件名形式写样式,目前只能在写组件的时候给组件加上对应的类名 49 | /* #ifdef MP-TOUTIAO */ 50 | .u-td, .u-th, .u-tr { 51 | flex: 1; 52 | align-self: stretch; 53 | } 54 | 55 | .u-row, .u-col { 56 | flex: 1; 57 | align-self: stretch; 58 | } 59 | 60 | // 避免小程序线条组件因为父组件display: flex;而失效 61 | .u-line { 62 | flex: 1; 63 | } 64 | 65 | .u-dropdown { 66 | flex: 1; 67 | } 68 | /* #endif */ 69 | /* end-头条小程序编译后页面有组件名的元素,特别处理--end */ 70 | 71 | 72 | 73 | -------------------------------------------------------------------------------- /uview-ui/libs/css/style.nvue.scss: -------------------------------------------------------------------------------- 1 | .nvue { 2 | font-size: 24rpx; 3 | } -------------------------------------------------------------------------------- /uview-ui/libs/function/$parent.js: -------------------------------------------------------------------------------- 1 | // 获取父组件的参数,因为支付宝小程序不支持provide/inject的写法 2 | // this.$parent在非H5中,可以准确获取到父组件,但是在H5中,需要多次this.$parent.$parent.xxx 3 | // 这里默认值等于undefined有它的含义,因为最顶层元素(组件)的$parent就是undefined,意味着不传name 4 | // 值(默认为undefined),就是查找最顶层的$parent 5 | export default function $parent(name = undefined) { 6 | let parent = this.$parent; 7 | // 通过while历遍,这里主要是为了H5需要多层解析的问题 8 | while (parent) { 9 | // 父组件 10 | if (parent.$options && parent.$options.name !== name) { 11 | // 如果组件的name不相等,继续上一级寻找 12 | parent = parent.$parent; 13 | } else { 14 | return parent; 15 | } 16 | } 17 | return false; 18 | } -------------------------------------------------------------------------------- /uview-ui/libs/function/addUnit.js: -------------------------------------------------------------------------------- 1 | import validation from './test.js'; 2 | 3 | // 添加单位,如果有rpx,%,px等单位结尾或者值为auto,直接返回,否则加上rpx单位结尾 4 | export default function addUnit(value = 'auto', unit = 'rpx') { 5 | value = String(value); 6 | // 用uView内置验证规则中的number判断是否为数值 7 | return validation.number(value) ? `${value}${unit}` : value; 8 | } -------------------------------------------------------------------------------- /uview-ui/libs/function/bem.js: -------------------------------------------------------------------------------- 1 | function bem(name, conf) { 2 | 3 | } 4 | 5 | module.exports.bem = bem; 6 | -------------------------------------------------------------------------------- /uview-ui/libs/function/color.js: -------------------------------------------------------------------------------- 1 | // 为了让用户能够自定义主题,会逐步弃用此文件,各颜色通过css提供 2 | // 为了给某些特殊场景使用和向后兼容,无需删除此文件(2020-06-20) 3 | let color = { 4 | primary: "#2979ff", 5 | primaryDark: "#2b85e4", 6 | primaryDisabled: "#a0cfff", 7 | primaryLight: "#ecf5ff", 8 | bgColor: "#f3f4f6", 9 | 10 | info: "#909399", 11 | infoDark: "#82848a", 12 | infoDisabled: "#c8c9cc", 13 | infoLight: "#f4f4f5", 14 | 15 | warning: "#ff9900", 16 | warningDark: "#f29100", 17 | warningDisabled: "#fcbd71", 18 | warningLight: "#fdf6ec", 19 | 20 | error: "#fa3534", 21 | errorDark: "#dd6161", 22 | errorDisabled: "#fab6b6", 23 | errorLight: "#fef0f0", 24 | 25 | success: "#19be6b", 26 | successDark: "#18b566", 27 | successDisabled: "#71d5a1", 28 | successLight: "#dbf1e1", 29 | 30 | mainColor: "#303133", 31 | contentColor: "#606266", 32 | tipsColor: "#909399", 33 | lightColor: "#c0c4cc", 34 | borderColor: "#e4e7ed" 35 | } 36 | 37 | export default color; -------------------------------------------------------------------------------- /uview-ui/libs/function/debounce.js: -------------------------------------------------------------------------------- 1 | let timeout = null; 2 | 3 | /** 4 | * 防抖原理:一定时间内,只有最后一次操作,再过wait毫秒后才执行函数 5 | * 6 | * @param {Function} func 要执行的回调函数 7 | * @param {Number} wait 延时的时间 8 | * @param {Boolean} immediate 是否立即执行 9 | * @return null 10 | */ 11 | function debounce(func, wait = 500, immediate = false) { 12 | // 清除定时器 13 | if (timeout !== null) clearTimeout(timeout); 14 | // 立即执行,此类情况一般用不到 15 | if (immediate) { 16 | var callNow = !timeout; 17 | timeout = setTimeout(function() { 18 | timeout = null; 19 | }, wait); 20 | if (callNow) typeof func === 'function' && func(); 21 | } else { 22 | // 设置定时器,当最后一次操作后,timeout不会再被清除,所以在延时wait毫秒后执行func回调方法 23 | timeout = setTimeout(function() { 24 | typeof func === 'function' && func(); 25 | }, wait); 26 | } 27 | } 28 | 29 | export default debounce 30 | -------------------------------------------------------------------------------- /uview-ui/libs/function/deepClone.js: -------------------------------------------------------------------------------- 1 | // 判断arr是否为一个数组,返回一个bool值 2 | function isArray (arr) { 3 | return Object.prototype.toString.call(arr) === '[object Array]'; 4 | } 5 | 6 | // 深度克隆 7 | function deepClone (obj) { 8 | // 对常见的“非”值,直接返回原来值 9 | if([null, undefined, NaN, false].includes(obj)) return obj; 10 | if(typeof obj !== "object" && typeof obj !== 'function') { 11 | //原始类型直接返回 12 | return obj; 13 | } 14 | var o = isArray(obj) ? [] : {}; 15 | for(let i in obj) { 16 | if(obj.hasOwnProperty(i)){ 17 | o[i] = typeof obj[i] === "object" ? deepClone(obj[i]) : obj[i]; 18 | } 19 | } 20 | return o; 21 | } 22 | 23 | export default deepClone; 24 | -------------------------------------------------------------------------------- /uview-ui/libs/function/deepMerge.js: -------------------------------------------------------------------------------- 1 | import deepClone from "./deepClone"; 2 | 3 | // JS对象深度合并 4 | function deepMerge(target = {}, source = {}) { 5 | target = deepClone(target); 6 | if (typeof target !== 'object' || typeof source !== 'object') return false; 7 | for (var prop in source) { 8 | if (!source.hasOwnProperty(prop)) continue; 9 | if (prop in target) { 10 | if (typeof target[prop] !== 'object') { 11 | target[prop] = source[prop]; 12 | } else { 13 | if (typeof source[prop] !== 'object') { 14 | target[prop] = source[prop]; 15 | } else { 16 | if (target[prop].concat && source[prop].concat) { 17 | target[prop] = target[prop].concat(source[prop]); 18 | } else { 19 | target[prop] = deepMerge(target[prop], source[prop]); 20 | } 21 | } 22 | } 23 | } else { 24 | target[prop] = source[prop]; 25 | } 26 | } 27 | return target; 28 | } 29 | 30 | export default deepMerge; -------------------------------------------------------------------------------- /uview-ui/libs/function/getParent.js: -------------------------------------------------------------------------------- 1 | // 获取父组件的参数,因为支付宝小程序不支持provide/inject的写法 2 | // this.$parent在非H5中,可以准确获取到父组件,但是在H5中,需要多次this.$parent.$parent.xxx 3 | export default function getParent(name, keys) { 4 | let parent = this.$parent; 5 | // 通过while历遍,这里主要是为了H5需要多层解析的问题 6 | while (parent) { 7 | // 父组件 8 | if (parent.$options.name !== name) { 9 | // 如果组件的name不相等,继续上一级寻找 10 | parent = parent.$parent; 11 | } else { 12 | let data = {}; 13 | // 判断keys是否数组,如果传过来的是一个数组,那么直接使用数组元素值当做键值去父组件寻找 14 | if(Array.isArray(keys)) { 15 | keys.map(val => { 16 | data[val] = parent[val] ? parent[val] : ''; 17 | }) 18 | } else { 19 | // 历遍传过来的对象参数 20 | for(let i in keys) { 21 | // 如果子组件有此值则用,无此值则用父组件的值 22 | // 判断是否空数组,如果是,则用父组件的值,否则用子组件的值 23 | if(Array.isArray(keys[i])) { 24 | if(keys[i].length) { 25 | data[i] = keys[i]; 26 | } else { 27 | data[i] = parent[i]; 28 | } 29 | } else if(keys[i].constructor === Object) { 30 | // 判断是否对象,如果是对象,且有属性,那么使用子组件的值,否则使用父组件的值 31 | if(Object.keys(keys[i]).length) { 32 | data[i] = keys[i]; 33 | } else { 34 | data[i] = parent[i]; 35 | } 36 | } else { 37 | // 只要子组件有传值,即使是false值,也是“传值”了,也需要覆盖父组件的同名参数 38 | data[i] = (keys[i] || keys[i] === false) ? keys[i] : parent[i]; 39 | } 40 | } 41 | } 42 | return data; 43 | } 44 | } 45 | 46 | return {}; 47 | } -------------------------------------------------------------------------------- /uview-ui/libs/function/guid.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 本算法来源于简书开源代码,详见:https://www.jianshu.com/p/fdbf293d0a85 3 | * 全局唯一标识符(uuid,Globally Unique Identifier),也称作 uuid(Universally Unique IDentifier) 4 | * 一般用于多个组件之间,给它一个唯一的标识符,或者v-for循环的时候,如果使用数组的index可能会导致更新列表出现问题 5 | * 最可能的情况是左滑删除item或者对某条信息流"不喜欢"并去掉它的时候,会导致组件内的数据可能出现错乱 6 | * v-for的时候,推荐使用后端返回的id而不是循环的index 7 | * @param {Number} len uuid的长度 8 | * @param {Boolean} firstU 将返回的首字母置为"u" 9 | * @param {Nubmer} radix 生成uuid的基数(意味着返回的字符串都是这个基数),2-二进制,8-八进制,10-十进制,16-十六进制 10 | */ 11 | function guid(len = 32, firstU = true, radix = null) { 12 | let chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split(''); 13 | let uuid = []; 14 | radix = radix || chars.length; 15 | 16 | if (len) { 17 | // 如果指定uuid长度,只是取随机的字符,0|x为位运算,能去掉x的小数位,返回整数位 18 | for (let i = 0; i < len; i++) uuid[i] = chars[0 | Math.random() * radix]; 19 | } else { 20 | let r; 21 | // rfc4122标准要求返回的uuid中,某些位为固定的字符 22 | uuid[8] = uuid[13] = uuid[18] = uuid[23] = '-'; 23 | uuid[14] = '4'; 24 | 25 | for (let i = 0; i < 36; i++) { 26 | if (!uuid[i]) { 27 | r = 0 | Math.random() * 16; 28 | uuid[i] = chars[(i == 19) ? (r & 0x3) | 0x8 : r]; 29 | } 30 | } 31 | } 32 | // 移除第一个字符,并用u替代,因为第一个字符为数值时,该guuid不能用作id或者class 33 | if (firstU) { 34 | uuid.shift(); 35 | return 'u' + uuid.join(''); 36 | } else { 37 | return uuid.join(''); 38 | } 39 | } 40 | 41 | export default guid; 42 | -------------------------------------------------------------------------------- /uview-ui/libs/function/queryParams.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 对象转url参数 3 | * @param {*} data,对象 4 | * @param {*} isPrefix,是否自动加上"?" 5 | */ 6 | function queryParams(data = {}, isPrefix = true, arrayFormat = 'brackets') { 7 | let prefix = isPrefix ? '?' : '' 8 | let _result = [] 9 | if (['indices', 'brackets', 'repeat', 'comma'].indexOf(arrayFormat) == -1) arrayFormat = 'brackets'; 10 | for (let key in data) { 11 | let value = data[key] 12 | // 去掉为空的参数 13 | if (['', undefined, null].indexOf(value) >= 0) { 14 | continue; 15 | } 16 | // 如果值为数组,另行处理 17 | if (value.constructor === Array) { 18 | // e.g. {ids: [1, 2, 3]} 19 | switch (arrayFormat) { 20 | case 'indices': 21 | // 结果: ids[0]=1&ids[1]=2&ids[2]=3 22 | for (let i = 0; i < value.length; i++) { 23 | _result.push(key + '[' + i + ']=' + value[i]) 24 | } 25 | break; 26 | case 'brackets': 27 | // 结果: ids[]=1&ids[]=2&ids[]=3 28 | value.forEach(_value => { 29 | _result.push(key + '[]=' + _value) 30 | }) 31 | break; 32 | case 'repeat': 33 | // 结果: ids=1&ids=2&ids=3 34 | value.forEach(_value => { 35 | _result.push(key + '=' + _value) 36 | }) 37 | break; 38 | case 'comma': 39 | // 结果: ids=1,2,3 40 | let commaStr = ""; 41 | value.forEach(_value => { 42 | commaStr += (commaStr ? "," : "") + _value; 43 | }) 44 | _result.push(key + '=' + commaStr) 45 | break; 46 | default: 47 | value.forEach(_value => { 48 | _result.push(key + '[]=' + _value) 49 | }) 50 | } 51 | } else { 52 | _result.push(key + '=' + value) 53 | } 54 | } 55 | return _result.length ? prefix + _result.join('&') : '' 56 | } 57 | 58 | export default queryParams; 59 | -------------------------------------------------------------------------------- /uview-ui/libs/function/random.js: -------------------------------------------------------------------------------- 1 | function random(min, max) { 2 | if (min >= 0 && max > 0 && max >= min) { 3 | let gab = max - min + 1; 4 | return Math.floor(Math.random() * gab + min); 5 | } else { 6 | return 0; 7 | } 8 | } 9 | 10 | export default random; 11 | -------------------------------------------------------------------------------- /uview-ui/libs/function/randomArray.js: -------------------------------------------------------------------------------- 1 | // 打乱数组 2 | function randomArray(array = []) { 3 | // 原理是sort排序,Math.random()产生0<= x < 1之间的数,会导致x-0.05大于或者小于0 4 | return array.sort(() => Math.random() - 0.5); 5 | } 6 | 7 | export default randomArray 8 | -------------------------------------------------------------------------------- /uview-ui/libs/function/route.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 路由跳转方法,该方法相对于直接使用uni.xxx的好处是使用更加简单快捷 3 | * 并且带有路由拦截功能 4 | */ 5 | 6 | class Router { 7 | constructor() { 8 | // 原始属性定义 9 | this.config = { 10 | type: 'navigateTo', 11 | url: '', 12 | delta: 1, // navigateBack页面后退时,回退的层数 13 | params: {}, // 传递的参数 14 | animationType: 'pop-in', // 窗口动画,只在APP有效 15 | animationDuration: 300, // 窗口动画持续时间,单位毫秒,只在APP有效 16 | intercept: false, // 是否需要拦截 17 | } 18 | // 因为route方法是需要对外赋值给另外的对象使用,同时route内部有使用this,会导致route失去上下文 19 | // 这里在构造函数中进行this绑定 20 | this.route = this.route.bind(this) 21 | } 22 | 23 | // 判断url前面是否有"/",如果没有则加上,否则无法跳转 24 | addRootPath(url) { 25 | return url[0] === '/' ? url : `/${url}` 26 | } 27 | 28 | // 整合路由参数 29 | mixinParam(url, params) { 30 | url = url && this.addRootPath(url) 31 | 32 | // 使用正则匹配,主要依据是判断是否有"/","?","="等,如“/page/index/index?name=mary" 33 | // 如果有url中有get参数,转换后无需带上"?" 34 | let query = '' 35 | if (/.*\/.*\?.*=.*/.test(url)) { 36 | // object对象转为get类型的参数 37 | query = uni.$u.queryParams(params, false); 38 | // 因为已有get参数,所以后面拼接的参数需要带上"&"隔开 39 | return url += "&" + query 40 | } else { 41 | // 直接拼接参数,因为此处url中没有后面的query参数,也就没有"?/&"之类的符号 42 | query = uni.$u.queryParams(params); 43 | return url += query 44 | } 45 | } 46 | 47 | // 对外的方法名称 48 | async route(options = {}, params = {}) { 49 | // 合并用户的配置和内部的默认配置 50 | let mergeConfig = {} 51 | 52 | if (typeof options === 'string') { 53 | // 如果options为字符串,则为route(url, params)的形式 54 | mergeConfig.url = this.mixinParam(options, params) 55 | mergeConfig.type = 'navigateTo' 56 | } else { 57 | mergeConfig = uni.$u.deepClone(options, this.config) 58 | // 否则正常使用mergeConfig中的url和params进行拼接 59 | mergeConfig.url = this.mixinParam(options.url, options.params) 60 | } 61 | 62 | if(params.intercept) { 63 | this.config.intercept = params.intercept 64 | } 65 | // params参数也带给拦截器 66 | mergeConfig.params = params 67 | // 合并内外部参数 68 | mergeConfig = uni.$u.deepMerge(this.config, mergeConfig) 69 | // 判断用户是否定义了拦截器 70 | if (typeof uni.$u.routeIntercept === 'function') { 71 | // 定一个promise,根据用户执行resolve(true)或者resolve(false)来决定是否进行路由跳转 72 | const isNext = await new Promise((resolve, reject) => { 73 | uni.$u.routeIntercept(mergeConfig, resolve) 74 | }) 75 | // 如果isNext为true,则执行路由跳转 76 | isNext && this.openPage(mergeConfig) 77 | } else { 78 | this.openPage(mergeConfig) 79 | } 80 | } 81 | 82 | // 执行路由跳转 83 | openPage(config) { 84 | // 解构参数 85 | const { 86 | url, 87 | type, 88 | delta, 89 | animationType, 90 | animationDuration 91 | } = config 92 | if (config.type == 'navigateTo' || config.type == 'to') { 93 | uni.navigateTo({ 94 | url, 95 | animationType, 96 | animationDuration 97 | }); 98 | } 99 | if (config.type == 'redirectTo' || config.type == 'redirect') { 100 | uni.redirectTo({ 101 | url 102 | }); 103 | } 104 | if (config.type == 'switchTab' || config.type == 'tab') { 105 | uni.switchTab({ 106 | url 107 | }); 108 | } 109 | if (config.type == 'reLaunch' || config.type == 'launch') { 110 | uni.reLaunch({ 111 | url 112 | }); 113 | } 114 | if (config.type == 'navigateBack' || config.type == 'back') { 115 | uni.navigateBack({ 116 | delta 117 | }); 118 | } 119 | } 120 | } 121 | 122 | export default (new Router()).route -------------------------------------------------------------------------------- /uview-ui/libs/function/sys.js: -------------------------------------------------------------------------------- 1 | export function os() { 2 | return uni.getSystemInfoSync().platform; 3 | }; 4 | 5 | export function sys() { 6 | return uni.getSystemInfoSync(); 7 | } 8 | 9 | 10 | -------------------------------------------------------------------------------- /uview-ui/libs/function/throttle.js: -------------------------------------------------------------------------------- 1 | let timer, flag; 2 | /** 3 | * 节流原理:在一定时间内,只能触发一次 4 | * 5 | * @param {Function} func 要执行的回调函数 6 | * @param {Number} wait 延时的时间 7 | * @param {Boolean} immediate 是否立即执行 8 | * @return null 9 | */ 10 | function throttle(func, wait = 500, immediate = true) { 11 | if (immediate) { 12 | if (!flag) { 13 | flag = true; 14 | // 如果是立即执行,则在wait毫秒内开始时执行 15 | typeof func === 'function' && func(); 16 | timer = setTimeout(() => { 17 | flag = false; 18 | }, wait); 19 | } 20 | } else { 21 | if (!flag) { 22 | flag = true 23 | // 如果是非立即执行,则在wait毫秒内的结束处执行 24 | timer = setTimeout(() => { 25 | flag = false 26 | typeof func === 'function' && func(); 27 | }, wait); 28 | } 29 | 30 | } 31 | }; 32 | export default throttle 33 | -------------------------------------------------------------------------------- /uview-ui/libs/function/timeFormat.js: -------------------------------------------------------------------------------- 1 | // padStart 的 polyfill,因为某些机型或情况,还无法支持es7的padStart,比如电脑版的微信小程序 2 | // 所以这里做一个兼容polyfill的兼容处理 3 | if (!String.prototype.padStart) { 4 | // 为了方便表示这里 fillString 用了ES6 的默认参数,不影响理解 5 | String.prototype.padStart = function(maxLength, fillString = ' ') { 6 | if (Object.prototype.toString.call(fillString) !== "[object String]") throw new TypeError( 7 | 'fillString must be String') 8 | let str = this 9 | // 返回 String(str) 这里是为了使返回的值是字符串字面量,在控制台中更符合直觉 10 | if (str.length >= maxLength) return String(str) 11 | 12 | let fillLength = maxLength - str.length, 13 | times = Math.ceil(fillLength / fillString.length) 14 | while (times >>= 1) { 15 | fillString += fillString 16 | if (times === 1) { 17 | fillString += fillString 18 | } 19 | } 20 | return fillString.slice(0, fillLength) + str; 21 | } 22 | } 23 | 24 | // 其他更多是格式化有如下: 25 | // yyyy:mm:dd|yyyy:mm|yyyy年mm月dd日|yyyy年mm月dd日 hh时MM分等,可自定义组合 26 | function timeFormat(dateTime = null, fmt = 'yyyy-mm-dd') { 27 | // 如果为null,则格式化当前时间 28 | if (!dateTime) dateTime = Number(new Date()); 29 | // 如果dateTime长度为10或者13,则为秒和毫秒的时间戳,如果超过13位,则为其他的时间格式 30 | if (dateTime.toString().length == 10) dateTime *= 1000; 31 | let date = new Date(dateTime); 32 | let ret; 33 | let opt = { 34 | "y+": date.getFullYear().toString(), // 年 35 | "m+": (date.getMonth() + 1).toString(), // 月 36 | "d+": date.getDate().toString(), // 日 37 | "h+": date.getHours().toString(), // 时 38 | "M+": date.getMinutes().toString(), // 分 39 | "s+": date.getSeconds().toString() // 秒 40 | // 有其他格式化字符需求可以继续添加,必须转化成字符串 41 | }; 42 | for (let k in opt) { 43 | ret = new RegExp("(" + k + ")").exec(fmt); 44 | if (ret) { 45 | fmt = fmt.replace(ret[1], (ret[1].length == 1) ? (opt[k]) : (opt[k].padStart(ret[1].length, "0"))) 46 | }; 47 | }; 48 | return fmt; 49 | } 50 | 51 | export default timeFormat 52 | -------------------------------------------------------------------------------- /uview-ui/libs/function/timeFrom.js: -------------------------------------------------------------------------------- 1 | import timeFormat from '../../libs/function/timeFormat.js'; 2 | 3 | /** 4 | * 时间戳转为多久之前 5 | * @param String timestamp 时间戳 6 | * @param String | Boolean format 如果为时间格式字符串,超出一定时间范围,返回固定的时间格式; 7 | * 如果为布尔值false,无论什么时间,都返回多久以前的格式 8 | */ 9 | function timeFrom(dateTime = null, format = 'yyyy-mm-dd') { 10 | // 如果为null,则格式化当前时间 11 | if (!dateTime) dateTime = Number(new Date()); 12 | // 如果dateTime长度为10或者13,则为秒和毫秒的时间戳,如果超过13位,则为其他的时间格式 13 | if (dateTime.toString().length == 10) dateTime *= 1000; 14 | let timestamp = + new Date(Number(dateTime)); 15 | 16 | let timer = (Number(new Date()) - timestamp) / 1000; 17 | // 如果小于5分钟,则返回"刚刚",其他以此类推 18 | let tips = ''; 19 | switch (true) { 20 | case timer < 300: 21 | tips = '刚刚'; 22 | break; 23 | case timer >= 300 && timer < 3600: 24 | tips = parseInt(timer / 60) + '分钟前'; 25 | break; 26 | case timer >= 3600 && timer < 86400: 27 | tips = parseInt(timer / 3600) + '小时前'; 28 | break; 29 | case timer >= 86400 && timer < 2592000: 30 | tips = parseInt(timer / 86400) + '天前'; 31 | break; 32 | default: 33 | // 如果format为false,则无论什么时间戳,都显示xx之前 34 | if(format === false) { 35 | if(timer >= 2592000 && timer < 365 * 86400) { 36 | tips = parseInt(timer / (86400 * 30)) + '个月前'; 37 | } else { 38 | tips = parseInt(timer / (86400 * 365)) + '年前'; 39 | } 40 | } else { 41 | tips = timeFormat(timestamp, format); 42 | } 43 | } 44 | return tips; 45 | } 46 | 47 | export default timeFrom; 48 | -------------------------------------------------------------------------------- /uview-ui/libs/function/toast.js: -------------------------------------------------------------------------------- 1 | function toast(title, duration = 1500) { 2 | uni.showToast({ 3 | title: title, 4 | icon: 'none', 5 | duration: duration 6 | }) 7 | } 8 | 9 | export default toast 10 | -------------------------------------------------------------------------------- /uview-ui/libs/function/trim.js: -------------------------------------------------------------------------------- 1 | function trim(str, pos = 'both') { 2 | if (pos == 'both') { 3 | return str.replace(/^\s+|\s+$/g, ""); 4 | } else if (pos == "left") { 5 | return str.replace(/^\s*/, ''); 6 | } else if (pos == 'right') { 7 | return str.replace(/(\s*$)/g, ""); 8 | } else if (pos == 'all') { 9 | return str.replace(/\s+/g, ""); 10 | } else { 11 | return str; 12 | } 13 | } 14 | 15 | export default trim 16 | -------------------------------------------------------------------------------- /uview-ui/libs/function/type2icon.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 根据主题type值,获取对应的图标 3 | * @param String type 主题名称,primary|info|error|warning|success 4 | * @param String fill 是否使用fill填充实体的图标 5 | */ 6 | function type2icon(type = 'success', fill = false) { 7 | // 如果非预置值,默认为success 8 | if (['primary', 'info', 'error', 'warning', 'success'].indexOf(type) == -1) type = 'success'; 9 | let iconName = ''; 10 | // 目前(2019-12-12),info和primary使用同一个图标 11 | switch (type) { 12 | case 'primary': 13 | iconName = 'info-circle'; 14 | break; 15 | case 'info': 16 | iconName = 'info-circle'; 17 | break; 18 | case 'error': 19 | iconName = 'close-circle'; 20 | break; 21 | case 'warning': 22 | iconName = 'error-circle'; 23 | break; 24 | case 'success': 25 | iconName = 'checkmark-circle'; 26 | break; 27 | default: 28 | iconName = 'checkmark-circle'; 29 | } 30 | // 是否是实体类型,加上-fill,在icon组件库中,实体的类名是后面加-fill的 31 | if (fill) iconName += '-fill'; 32 | return iconName; 33 | } 34 | 35 | export default type2icon 36 | -------------------------------------------------------------------------------- /uview-ui/libs/mixin/mixin.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | data() { 3 | return {} 4 | }, 5 | onLoad() { 6 | // getRect挂载到$u上,因为这方法需要使用in(this),所以无法把它独立成一个单独的文件导出 7 | this.$u.getRect = this.$uGetRect 8 | }, 9 | methods: { 10 | // 查询节点信息 11 | // 目前此方法在支付宝小程序中无法获取组件跟接点的尺寸,为支付宝的bug(2020-07-21) 12 | // 解决办法为在组件根部再套一个没有任何作用的view元素 13 | $uGetRect(selector, all) { 14 | return new Promise(resolve => { 15 | uni.createSelectorQuery(). 16 | in(this)[all ? 'selectAll' : 'select'](selector) 17 | .boundingClientRect(rect => { 18 | if (all && Array.isArray(rect) && rect.length) { 19 | resolve(rect) 20 | } 21 | if (!all && rect) { 22 | resolve(rect) 23 | } 24 | }) 25 | .exec() 26 | }) 27 | }, 28 | getParentData(parentName = '') { 29 | // 避免在created中去定义parent变量 30 | if(!this.parent) this.parent = false; 31 | // 这里的本质原理是,通过获取父组件实例(也即u-radio-group的this) 32 | // 将父组件this中对应的参数,赋值给本组件(u-radio的this)的parentData对象中对应的属性 33 | // 之所以需要这么做,是因为所有端中,头条小程序不支持通过this.parent.xxx去监听父组件参数的变化 34 | this.parent = this.$u.$parent.call(this, parentName); 35 | if(this.parent) { 36 | // 历遍parentData中的属性,将parent中的同名属性赋值给parentData 37 | Object.keys(this.parentData).map(key => { 38 | this.parentData[key] = this.parent[key]; 39 | }); 40 | } 41 | }, 42 | // 阻止事件冒泡 43 | preventEvent(e) { 44 | e && e.stopPropagation && e.stopPropagation() 45 | } 46 | }, 47 | onReachBottom() { 48 | uni.$emit('uOnReachBottom') 49 | }, 50 | beforeDestroy() { 51 | // 判断当前页面是否存在parent和chldren,一般在checkbox和checkbox-group父子联动的场景会有此情况 52 | // 组件销毁时,移除子组件在父组件children数组中的实例,释放资源,避免数据混乱 53 | if(this.parent && uni.$u.test.array(this.parent.children)) { 54 | // 组件销毁时,移除父组件中的children数组中对应的实例 55 | const childrenList = this.parent.children 56 | childrenList.map((child, index) => { 57 | // 如果相等,则移除 58 | if(child === this) { 59 | childrenList.splice(index, 1) 60 | } 61 | }) 62 | } 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /uview-ui/libs/mixin/mpShare.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | onLoad() { 3 | // 设置默认的转发参数 4 | this.$u.mpShare = { 5 | title: '', // 默认为小程序名称 6 | path: '', // 默认为当前页面路径 7 | imageUrl: '' // 默认为当前页面的截图 8 | } 9 | }, 10 | onShareAppMessage() { 11 | return this.$u.mpShare 12 | }, 13 | // #ifdef MP-WEIXIN 14 | onShareTimeline() { 15 | return this.$u.mpShare 16 | } 17 | // #endif 18 | } 19 | -------------------------------------------------------------------------------- /uview-ui/libs/store/index.js: -------------------------------------------------------------------------------- 1 | // 暂时不用vuex模块方式实现,将该方法直接放入到/store/index.js中 2 | const module = { 3 | actions: { 4 | $uStore({rootState}, params) { 5 | let nameArr = params.name.split('.'); 6 | if(nameArr.length >= 2) { 7 | let obj = rootState[nameArr[0]]; 8 | for(let i = 1; i < nameArr.length - 1; i ++) { 9 | obj = obj[nameArr[i]]; 10 | } 11 | obj[nameArr[nameArr.length - 1]] = params.value; 12 | } else { 13 | rootState[params.name] = params.value; 14 | } 15 | } 16 | } 17 | } 18 | 19 | export default module -------------------------------------------------------------------------------- /uview-ui/libs/util/emitter.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 递归使用 call 方式this指向 3 | * @param componentName // 需要找的组件的名称 4 | * @param eventName // 事件名称 5 | * @param params // 需要传递的参数 6 | */ 7 | function broadcast(componentName, eventName, params) { 8 | // 循环子节点找到名称一样的子节点 否则 递归 当前子节点 9 | this.$children.map(child=>{ 10 | if (componentName===child.$options.name) { 11 | child.$emit.apply(child,[eventName].concat(params)) 12 | }else { 13 | broadcast.apply(child,[componentName,eventName].concat(params)) 14 | } 15 | }) 16 | } 17 | export default { 18 | methods: { 19 | /** 20 | * 派发 (向上查找) (一个) 21 | * @param componentName // 需要找的组件的名称 22 | * @param eventName // 事件名称 23 | * @param params // 需要传递的参数 24 | */ 25 | dispatch(componentName, eventName, params) { 26 | let parent = this.$parent || this.$root;//$parent 找到最近的父节点 $root 根节点 27 | let name = parent.$options.name; // 获取当前组件实例的name 28 | // 如果当前有节点 && 当前没名称 且 当前名称等于需要传进来的名称的时候就去查找当前的节点 29 | // 循环出当前名称的一样的组件实例 30 | while (parent && (!name||name!==componentName)) { 31 | parent = parent.$parent; 32 | if (parent) { 33 | name = parent.$options.name; 34 | } 35 | } 36 | // 有节点表示当前找到了name一样的实例 37 | if (parent) { 38 | parent.$emit.apply(parent,[eventName].concat(params)) 39 | } 40 | }, 41 | /** 42 | * 广播 (向下查找) (广播多个) 43 | * @param componentName // 需要找的组件的名称 44 | * @param eventName // 事件名称 45 | * @param params // 需要传递的参数 46 | */ 47 | broadcast(componentName, eventName, params) { 48 | broadcast.call(this,componentName, eventName, params) 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /uview-ui/libs/util/province.js: -------------------------------------------------------------------------------- 1 | var provinceData=[{"label":"北京市","value":"11"},{"label":"天津市","value":"12"},{"label":"河北省","value":"13"},{"label":"山西省","value":"14"},{"label":"内蒙古自治区","value":"15"},{"label":"辽宁省","value":"21"},{"label":"吉林省","value":"22"},{"label":"黑龙江省","value":"23"},{"label":"上海市","value":"31"},{"label":"江苏省","value":"32"},{"label":"浙江省","value":"33"},{"label":"安徽省","value":"34"},{"label":"福建省","value":"35"},{"label":"江西省","value":"36"},{"label":"山东省","value":"37"},{"label":"河南省","value":"41"},{"label":"湖北省","value":"42"},{"label":"湖南省","value":"43"},{"label":"广东省","value":"44"},{"label":"广西壮族自治区","value":"45"},{"label":"海南省","value":"46"},{"label":"重庆市","value":"50"},{"label":"四川省","value":"51"},{"label":"贵州省","value":"52"},{"label":"云南省","value":"53"},{"label":"西藏自治区","value":"54"},{"label":"陕西省","value":"61"},{"label":"甘肃省","value":"62"},{"label":"青海省","value":"63"},{"label":"宁夏回族自治区","value":"64"},{"label":"新疆维吾尔自治区","value":"65"},{"label":"台湾","value":"66"},{"label":"香港","value":"67"},{"label":"澳门","value":"68"}];export default provinceData; -------------------------------------------------------------------------------- /uview-ui/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "uview-ui", 3 | "version": "1.8.4", 4 | "description": "uView UI,是uni-app生态优秀的UI框架,全面的组件和便捷的工具会让您信手拈来,如鱼得水", 5 | "main": "index.js", 6 | "keywords": [ 7 | "uview", 8 | "uView", 9 | "uni-app", 10 | "uni-app ui", 11 | "uniapp", 12 | "uviewui", 13 | "uview ui", 14 | "uviewUI", 15 | "uViewui", 16 | "uViewUI", 17 | "uView UI", 18 | "uni ui", 19 | "uni UI", 20 | "uniapp ui", 21 | "ui", 22 | "UI框架", 23 | "uniapp ui框架", 24 | "uniapp UI" 25 | ], 26 | "scripts": { 27 | "test": "echo \"Error: no test specified\" && exit 1" 28 | }, 29 | "repository": { 30 | "type": "git", 31 | "url": "" 32 | }, 33 | "devDependencies": { 34 | "node-sass": "^4.14.0", 35 | "sass-loader": "^8.0.2" 36 | }, 37 | "author": "uView", 38 | "license": "MIT" 39 | } 40 | -------------------------------------------------------------------------------- /uview-ui/theme.scss: -------------------------------------------------------------------------------- 1 | // 此文件为uView的主题变量,这些变量目前只能通过uni.scss引入才有效,另外由于 2 | // uni.scss中引入的样式会同时混入到全局样式文件和单独每一个页面的样式中,造成微信程序包太大, 3 | // 故uni.scss只建议放scss变量名相关样式,其他的样式可以通过main.js或者App.vue引入 4 | 5 | $u-main-color: #303133; 6 | $u-content-color: #606266; 7 | $u-tips-color: #909399; 8 | $u-light-color: #c0c4cc; 9 | $u-border-color: #e4e7ed; 10 | $u-bg-color: #f3f4f6; 11 | 12 | $u-type-primary: #2979ff; 13 | $u-type-primary-light: #ecf5ff; 14 | $u-type-primary-disabled: #a0cfff; 15 | $u-type-primary-dark: #2b85e4; 16 | 17 | $u-type-warning: #ff9900; 18 | $u-type-warning-disabled: #fcbd71; 19 | $u-type-warning-dark: #f29100; 20 | $u-type-warning-light: #fdf6ec; 21 | 22 | $u-type-success: #19be6b; 23 | $u-type-success-disabled: #71d5a1; 24 | $u-type-success-dark: #18b566; 25 | $u-type-success-light: #dbf1e1; 26 | 27 | $u-type-error: #fa3534; 28 | $u-type-error-disabled: #fab6b6; 29 | $u-type-error-dark: #dd6161; 30 | $u-type-error-light: #fef0f0; 31 | 32 | $u-type-info: #909399; 33 | $u-type-info-disabled: #c8c9cc; 34 | $u-type-info-dark: #82848a; 35 | $u-type-info-light: #f4f4f5; 36 | 37 | $u-form-item-height: 70rpx; 38 | $u-form-item-border-color: #dcdfe6; 39 | --------------------------------------------------------------------------------