69 files modified
506 files added
| | |
| | | if(args){ |
| | | // 处理args参数,如直达到某新页面等 |
| | | console.log('args', args) |
| | | if(args.indexOf('lzzzsc-app') >= 0) { |
| | | args = args.replace("lzzzsc-app://", "/") |
| | | if(args.indexOf('pig-app') >= 0) { |
| | | args = args.replace("pig-app://", "/") |
| | | return uni.redirectTo({ |
| | | url: args |
| | | }) |
| | |
| | | console.log('getConfig', res.data) |
| | | if(res.code == 1){ |
| | | try { |
| | | const token = uni.getStorageSync('lzsc-token'); |
| | | const token = uni.getStorageSync('pig-token'); |
| | | if (!token) { |
| | | /* |
| | | uni.redirectTo({ |
| | |
| | | </script> |
| | | |
| | | <style> |
| | | uni-view { |
| | | box-sizing: border-box; |
| | | } |
| | | checkbox .uni-checkbox-input { |
| | | border-radius: 50%; |
| | | width: 38rpx; |
| | | height: 38rpx |
| | | } |
| | | /*每个页面公共css */ |
| | | .startBar { |
| | | width: 100%; |
| | |
| | | { |
| | | "version" : "1", |
| | | "prompt" : "template", |
| | | "title" : "齐享购商城注册协议和隐私政策", |
| | | "message" : " 请你务必审慎阅读、充分理解“注册协议”和“隐私政策”各条款,包括但不限于:为了更好的向你提供服务,我们需要收集你的设备标识、操作日志等信息用于分析、优化应用性能。<br/> 你可阅读<a href=\"https://www.ncmiruo.com/index/?gp=1 \">《注册协议》</a>和<a href=\"https://www.ncmiruo.com/?gp=2 \">《隐私政策》</a>了解详细信息。并且我们会申请读取您的设备信息,以向您提供安全风控服务。同时您应特别注意前述协议中免除或者限制我们责任的条款、对您权利进行限制的条款。如您已详细阅读并同意金喜易购服务协议和隐私政策,请点击【同意并继续】开始使用我们的服务。", |
| | | "title" : "小猪优选商城注册协议和隐私政策", |
| | | "message" : " 请你务必审慎阅读、充分理解“注册协议”和“隐私政策”各条款,包括但不限于:为了更好的向你提供服务,我们需要收集你的设备标识、操作日志等信息用于分析、优化应用性能。<br/> 你可阅读<a href=\"https://qxg1996.lllykj.com/?gp=1 \">《注册协议》</a>和<a href=\"https://qxg1996.lllykj.com/?gp=2 \">《隐私政策》</a>了解详细信息。并且我们会申请读取您的设备信息,以向您提供安全风控服务。同时您应特别注意前述协议中免除或者限制我们责任的条款、对您权利进行限制的条款。如您已详细阅读并同意小猪优选服务协议和隐私政策,请点击【同意并继续】开始使用我们的服务。", |
| | | "buttonAccept" : "同意并继续", |
| | | "buttonRefuse" : "暂不同意", |
| | | "hrefLoader" : "system", |
| | | "backToExit" : "false", |
| | | "second" : { |
| | | "title" : "确认提示", |
| | | "message" : " 进入应用前,你需先同意<a href=\"https://www.ncmiruo.com/?gp=1\">《注册协议》</a>和<a href=\"https://www.ncmiruo.com/?gp=2\">《隐私政策》</a>,否则将退出应用。", |
| | | "message" : " 进入应用前,你需先同意<a href=\"https://qxg1996.lllykj.com/?gp=1\">《注册协议》</a>和<a href=\"https://qxg1996.lllykj.com/?gp=2\">《隐私政策》</a>,否则将退出应用。", |
| | | "buttonAccept" : "同意并继续", |
| | | "buttonRefuse" : "退出应用" |
| | | }, |
| | |
| | | import Vue from 'vue' |
| | | import './uni.promisify.adaptor' |
| | | import util from './util.js' |
| | | |
| | | Vue.config.productionTip = false |
| | | App.mpType = 'app' |
| | | |
| | | Vue.prototype.$webHost = 'https://rbb98765.zrgy-bbg.com' |
| | | Vue.prototype.$util = util |
| | | Vue.prototype.$baseUrl = 'https://tmy.xjzbh.com' |
| | | Vue.prototype.$baseUrl = 'https://qxg1996.lllykj.com' |
| | | Vue.prototype.$bank = [ |
| | | '中国工商银行', |
| | | '中国建设银行', |
| | |
| | | { |
| | | "name" : "齐享购", |
| | | "appid" : "__UNI__3333B1D", |
| | | "name" : "小猪优选", |
| | | "appid" : "__UNI__42A33E9", |
| | | "description" : "", |
| | | "versionName" : "1.4.0", |
| | | "versionCode" : 140, |
| | | "versionName" : "1.3.7", |
| | | "versionCode" : 137, |
| | | "transformPx" : false, |
| | | /* 5+App特有相关 */ |
| | | "app-plus" : { |
| | | "statusbar" : { |
| | | "immersed" : false |
| | | "immersed" : true |
| | | }, |
| | | "compatible" : { |
| | | "ignoreVersion" : true |
| | |
| | | "<uses-permission android:name=\"android.permission.WRITE_SMS\"/>" |
| | | ], |
| | | "minSdkVersion" : 29, |
| | | "schemes" : "miruo-app", |
| | | "schemes" : "pig-app", |
| | | "targetSdkVersion" : 30, |
| | | "abiFilters" : [ "arm64-v8a" ] |
| | | }, |
| | |
| | | "com.apple.developer.associated-domains" : [ "applinks:www.ncmiruo.com" ] |
| | | } |
| | | }, |
| | | "urltypes" : "miruo-app" |
| | | "urltypes" : "pig-app" |
| | | }, |
| | | /* SDK配置 */ |
| | | "sdkConfigs" : { |
| | |
| | | "description" : "核身服务", |
| | | "platforms" : "Android,iOS", |
| | | "url" : "https://ext.dcloud.net.cn/plugin?id=10378", |
| | | "android_package_name" : "", |
| | | "ios_bundle_id" : "com.qxg.app", |
| | | "android_package_name" : "com.lelin.xzyx", |
| | | "ios_bundle_id" : "com.lelin.xzyx", |
| | | "isCloud" : true, |
| | | "bought" : 1, |
| | | "pid" : "10378", |
| | | "parameters" : {} |
| | | } |
| | | }, |
| | | "DC-WBNormal" : { |
| | | "__plugin_info__" : { |
| | | "name" : "DC-WBNormal", |
| | | "description" : "WB Normal SDK uni-app 插件", |
| | | "platforms" : "Android", |
| | | "url" : "https://ext.dcloud.net.cn/plugin?id=1491", |
| | | "android_package_name" : "com.lelin.xzyx", |
| | | "ios_bundle_id" : "com.lelin.xzyx", |
| | | "isCloud" : true, |
| | | "bought" : 1, |
| | | "pid" : "1491", |
| | | "parameters" : {} |
| | | } |
| | | } |
| | | } |
| | | }, |
| | |
| | | "path": "pages/index/index", |
| | | "style": { |
| | | "navigationStyle":"custom", |
| | | "navigationBarTitleText": "齐享购" |
| | | "navigationBarTitleText": "小猪优选" |
| | | } |
| | | }, |
| | | { |
| | | "path" : "pages/cates/cates", |
| | | "style" : |
| | | { |
| | | "navigationStyle":"custom", |
| | | "navigationBarTitleText": "分类" |
| | | } |
| | | }, |
| | |
| | | { |
| | | "path": "pages/quanyi/index", |
| | | "style": { |
| | | "navigationStyle":"custom", |
| | | "navigationBarTitleText": "会员权益" |
| | | } |
| | | }, |
| | | { |
| | | "path": "pages/quanyi/add", |
| | | "style": { |
| | | "navigationBarTitleText": "绑卡" |
| | | "navigationBarTitleText": "添加银行卡" |
| | | } |
| | | }, |
| | | { |
| | | "path": "pages/quanshou/index", |
| | | "style": { |
| | | "navigationStyle":"custom", |
| | | "navigationBarTitleText": "会员权收" |
| | | } |
| | | }, |
| | |
| | | "path": "pages/web/xieyi", |
| | | "style": { |
| | | "navigationBarTitleText": "协议" |
| | | } |
| | | }, |
| | | { |
| | | "path": "pages/vip/index", |
| | | "style": { |
| | | "navigationBarTitleText": "会员中心" |
| | | } |
| | | } |
| | | ], |
| | |
| | | "text": "首页" |
| | | }, |
| | | { |
| | | "pagePath": "pages/cates/cates", |
| | | "iconPath": "static/imgs/tab-2.png", |
| | | "selectedIconPath": "static/imgs/tab-s-2.png", |
| | | "text": "分类" |
| | | "pagePath": "pages/vip/index", |
| | | "iconPath": "/static/imgs/tab-2.png", |
| | | "selectedIconPath": "/static/imgs/tab-s-2.png", |
| | | "text": "会员中心" |
| | | }, |
| | | // { |
| | | // "pagePath": "pages/cates/cates", |
| | | // "iconPath": "/static/imgs/tb2.png", |
| | | // "selectedIconPath": "/static/imgs/tb2.png", |
| | | // "text": "分类" |
| | | // }, |
| | | { |
| | | "pagePath": "pages/carts/carts", |
| | | "iconPath": "static/imgs/tab-3.png", |
| | |
| | | }, |
| | | "globalStyle": { |
| | | "navigationBarTextStyle": "black", |
| | | "navigationBarTitleText": "齐享购", |
| | | "navigationBarTitleText": "小猪优选", |
| | | "navigationBarBackgroundColor": "#F8F8F8", |
| | | "backgroundColor": "#F8F8F8" |
| | | }, |
| | |
| | | <view class="noData" v-else> |
| | | <image src="/static/imgs/noData.png" mode="" style="margin-top: 200upx;"></image> |
| | | <view class="">没有购物车信息</view> |
| | | <view class="noDataBtn" @tap="$util.goSwitch('/pages/cates/cates')">去看看</view> |
| | | <view class="noDataBtn" @tap="$util.goSwitch('/pages/index/index')">去看看</view> |
| | | </view> |
| | | </view> |
| | | <view class="cartsControll" v-if="cartsData.length > 0"> |
| | |
| | | <view class="goods-title">{{itm.title}}</view> |
| | | <view class="goods-price"> |
| | | <view>¥</view> |
| | | <view class="red">{{itm.price}}</view> |
| | | <view class="red">{{itm.vprice}}</view> |
| | | </view> |
| | | </view> |
| | | </view> |
| | |
| | | <view class="">{{goodsData.title}}</view> |
| | | <view class=""> |
| | | <text>¥</text> |
| | | <text>{{goodsData.price}}</text> |
| | | <text>积分:{{goodsData.points}}</text> |
| | | <text>{{goodsData.vprice}}</text> |
| | | <!-- <text>积分:{{goodsData.points}}</text> --> |
| | | <text>原价:¥{{goodsData.price}}</text> |
| | | </view> |
| | | <view class="collect" @tap="collectGoods"> |
| | | <image :src="goodsData.collect == 1 ? '/static/imgs/colls.png' : '/static/imgs/coll.png'" mode=""></image> |
| | |
| | | <template> |
| | | <view class="index"> |
| | | <view class="status_bar"></view> |
| | | <view class="index-top"> |
| | | <view class="index-title"> |
| | | <view class="index-title-view index-title-view1"> |
| | | <view class="index-title-view-lf"> |
| | | <image src="@/static/imgs/index-logo.png" mode=""></image> |
| | | </view> |
| | | <view class="index-title-view-lf2">趋势好货放心购</view> |
| | | </view> |
| | | <view class="index-title-view index-title-view2"> |
| | | <view class="index-title-view-rf"> |
| | | <view class=""> |
| | | <image src="@/static/imgs/qiandao.png" mode=""></image> |
| | | <text>签到打卡</text> |
| | | </view> |
| | | </view> |
| | | <view class="index-title-view-rf"> |
| | | <view class=""> |
| | | <image src="@/static/imgs/kefu.png" mode=""></image> |
| | | <text>联系客服</text> |
| | | <view class="page-container index"> |
| | | <image class="page-bg" src="@/static/imgs/index-top.png" mode="scaleToFill"></image> |
| | | <view class="content"> |
| | | <!-- #ifdef APP-PLUS --> |
| | | <view class="uni-popup" :style="{top:isNativeHead?'':StatusBar}" v-if="contactsFlag"> |
| | | <view class="ani uni-custom uni-popup__wrapper"> |
| | | <view class="uni-popup__wrapper-box"> |
| | | <view class="title">通讯权限</view> |
| | | <view class="content">便于实现好友推荐、联系人同步等功能</view> |
| | | <view class="btn-group"> |
| | | <button class="cancel-btn" @click="handleReject">拒绝</button> |
| | | <button class="allow-btn" @click="handleAuthorize">允许</button> |
| | | </view> |
| | | </view> |
| | | </view> |
| | | </view> |
| | | <view class="search"> |
| | | <view class="search-1"> |
| | | <image src="@/static/imgs/s2.png" mode=""></image> |
| | | <input type="text" placeholder="请输入关键词" /> |
| | | <!-- #endif --> |
| | | <view class="hLogo"> |
| | | <view class="hLogoView"> |
| | | <view class="hLogo-1"> |
| | | <image class="h-logo" src="/static/imgs/index-logo.png" mode=""></image> |
| | | </view> |
| | | <view class="search-2"> |
| | | <view class="">搜索</view> |
| | | </view> |
| | | </view> |
| | | <view class="cates"> |
| | | <view class="cates-v" v-for="(item, index) in catesNavData" @tap="$util.goPages('/pages/catesList/catesList?catesId=' + item.id + '&title=' + item.title)"> |
| | | <image class="cates-v-icon" :src="item.icon" mode=""></image> |
| | | <view class="">{{item.title}}</view> |
| | | <view class="hLogo-2" @tap="$util.goPages('../search/search')"> |
| | | <image class="s-icon" src="/static/imgs/search.png" mode=""></image> |
| | | <input type="text" placeholder="请搜索您想要的商品" /> |
| | | </view> |
| | | </view> |
| | | </view> |
| | | |
| | | <view class="banner"> |
| | | <swiper class="swiper" circular :indicator-dots="indicatorDots" :indicator-color="indicatorColor" :autoplay="autoplay" :indicator-active-color="indicatorActiveColor" :interval="interval" :duration="duration"> |
| | | <swiper-item v-for="(item, index) in bannerData" @tap="$util.goPages('/pages/ginfo/ginfo?id=' + item.goodsid)"> |
| | | <image lazy-load :src="item.icon" mode=""></image> |
| | | </swiper-item> |
| | | </swiper> |
| | | <view class="cates" v-if="catesNavData"> |
| | | <view class="cates-v" v-for="(item, index) in catesNavData" @tap="$util.goPages('/pages/catesList/catesList?catesId=' + item.id + '&title=' + item.title)"> |
| | | <image class="cates-v-icon" :src="item.icon" mode=""></image> |
| | | <view class="">{{item.title}}</view> |
| | | </view> |
| | | <view class="comm"> |
| | | <view class="comm-1"> |
| | | <view class="comm-title"> |
| | | <image src="/static/imgs/ptyx.png" mode=""></image> |
| | | <!-- <view class="cates-v" @tap="$util.goSwitch('/pages/cates/cates')"> |
| | | <image class="cates-v-icon" src="/static/imgs/more.png" mode=""></image> |
| | | <view class="">更多</view> |
| | | </view> --> |
| | | </view> |
| | | <view class="comm-goods"> |
| | | <view class="comm-goods-v" v-for="(item, index) in prefGoods" @click="$util.goPages('/pages/ginfo/ginfo?id=' + item.id)"> |
| | | <view class=""> |
| | | <image :src="item.icon" mode=""></image> |
| | | <text>¥{{item.price}}</text> |
| | | |
| | | <view class="ad1" @tap="$util.goPages('/pages/catesList/catesList?catesId=' + '7' + '&title=' + '家居百货')"> |
| | | <image src="/static/imgs/ad1.png" mode=""></image> |
| | | </view> |
| | | |
| | | <view class="ad2" @tap="$util.goPages('/pages/catesList/catesList?catesId=' + '11' + '&title=' + '服装鞋包')"> |
| | | <image src="/static/imgs/ad2.png" mode=""></image> |
| | | </view> |
| | | |
| | | <view class="ad3" @tap="$util.goPages('/pages/catesList/catesList?catesId=' + '3' + '&title=' + '手机数码')"> |
| | | <image src="/static/imgs/ad3.png" mode=""></image> |
| | | </view> |
| | | |
| | | <view class="c-goods" v-if="hotCates" v-for="(item, index) in hotCates"> |
| | | <view class="ca-ad" v-if="index % 2 == 0"> |
| | | <image src="/static/imgs/c1.png" mode=""></image> |
| | | </view> |
| | | <view class="comm-2"></view> |
| | | <view class="comm-3"> |
| | | <view class="comm-title"> |
| | | <image src="@/static/imgs/jfdh.png" mode=""></image> |
| | | <view class="ca-ad" v-else> |
| | | <image src="/static/imgs/c2.png" mode=""></image> |
| | | </view> |
| | | <view class="comm-goods"> |
| | | <view class="comm-goods-v" v-for="(item, index) in pointGoods" @click="$util.goPages('/pages/ginfo/ginfo?id=' + item.id)"> |
| | | <view class=""> |
| | | <image :src="item.icon" mode=""></image> |
| | | <text>∮{{item.points}}</text> |
| | | </view> |
| | | </view> |
| | | </view> |
| | | </view> |
| | | </view> |
| | | <view class="hots"> |
| | | <view class="hots-title" @tap="$util.goPages('/pages/catesList/catesList?is_hot=1&title=热门推荐')"> |
| | | <image class="hots-icon" src="@/static/imgs/rmtj.png" mode=""></image> |
| | | <view class="hots-rgt"> |
| | | <text>大家都在买</text> |
| | | <image src="@/static/imgs/right.png" mode=""></image> |
| | | </view> |
| | | </view> |
| | | <view class="hots-goods"> |
| | | <view class="hots-goods-v" v-for="(item, index) in hotGoods" @click="$util.goPages('/pages/ginfo/ginfo?id=' + item.id)"> |
| | | <view class=""> |
| | | <image :src="item.icon" mode=""></image> |
| | | <text>¥{{item.price}}</text> |
| | | </view> |
| | | </view> |
| | | </view> |
| | | </view> |
| | | <view class="goods-main"> |
| | | <view class="goods-main-view"> |
| | | <view class="goods-list"> |
| | | <view class="goods-item" v-for="(itm, index) in goodsData" @click="$util.goPages('/pages/ginfo/ginfo?id=' + itm.id)"> |
| | | <view class="cGoods"> |
| | | <scroll-view class="scroll-view_H" scroll-x="true"> |
| | | <view class="scroll-view-item_H" v-for="(itm, index) in item.goods" @tap="$util.goPages('/pages/ginfo/ginfo?id=' + itm.id)"> |
| | | <image lazy-load class="goods-icon" :src="itm.icon" mode=""></image> |
| | | <view class="goods-title">{{itm.title}}</view> |
| | | <view class="goods-price"> |
| | | <view>¥</view> |
| | | <view class="red">{{itm.price}}</view> |
| | | <view class="hyj"> |
| | | <image src="@/static/imgs/hyj.png" mode=""></image> |
| | | </view> |
| | | <view>¥</view> |
| | | <view class="red">{{itm.price}}</view> |
| | | <view class="red">{{itm.vprice}}</view> |
| | | </view> |
| | | </view> |
| | | </scroll-view> |
| | | </view> |
| | | </view> |
| | | <view class="login-desc" v-if="!userInfo" @tap="$util.goPages('../login/login')"> |
| | | <image class="login-icon" src="/static/imgs/logo-icon.png" mode=""></image> |
| | | <view class="login-font">登录小猪优选,打开美好生活</view> |
| | | <view class="login-btn">立即登录</view> |
| | | </view> |
| | | </view> |
| | | |
| | | <uni-popup ref="popup2" type="center" :is-mask-click="false"> |
| | | <view class="popup-content"> |
| | | <view class="edu-view edu-view2"> |
| | | <image src="/static/imgs/close.png" class="close-edu" mode="" @tap="$refs.popup2.close()"></image> |
| | | <view class="edu-view-desc2">认证领取额度</view> |
| | | <image class="edu-icon-succ" src="/static/imgs/auths.png" mode=""></image> |
| | | <view class="edu-view-desc3"> |
| | | 请您先认证个人信息,然后立即领取额度 |
| | | </view> |
| | | <view class="edu-btns" @tap="goLingqu">立即领取</view> |
| | | <view class="edu-btns" @tap="go_auth">立即领取</view> |
| | | <!-- <view class="edu-btns" @tap="$util.goPages('/pages/idcard/idcard')">立即领取</view> --> |
| | | </view> |
| | | </view> |
| | | </uni-popup> |
| | |
| | | <script> |
| | | import permision from "@/js_sdk/wa-permission/permission.js" |
| | | export default { |
| | | props: { |
| | | // 开启动画 |
| | | animation: { |
| | | type: Boolean, |
| | | default: true |
| | | }, |
| | | type: { |
| | | type: String, |
| | | default: 'top' |
| | | }, |
| | | //是否是原生头部 |
| | | isNativeHead:{ |
| | | type: Boolean, |
| | | default: true |
| | | }, |
| | | }, |
| | | data() { |
| | | return { |
| | | scrollIndex: 0, |
| | | scrollCurrent: '', |
| | | contactsFlag: false, |
| | | staHeight: 0, |
| | | paddingHeight: 0, |
| | | indicatorDots: true, |
| | |
| | | duration: 500, |
| | | bannerData: [], |
| | | catesNavData: [], |
| | | goodsData: [], |
| | | prefGoods: [], |
| | | hotGoods: [], |
| | | pointGoods: [], |
| | | catesHotData: [], |
| | | userInfo: null, |
| | | config: null, |
| | | statusBarHeight: 30, |
| | | StatusBar: 0, |
| | | hotGoods: null, |
| | | newGoods: null, |
| | | hotCates: null, |
| | | } |
| | | }, |
| | | onShow() { |
| | | this.getData() |
| | | this.getConfig() |
| | | this.getUserInfo() |
| | | // #ifdef APP-PLUS |
| | | plus.navigator.setStatusBarBackground('transparent'); |
| | | // #endif |
| | | }, |
| | | created() { |
| | | }, |
| | | onLoad() { |
| | | const systemInfo = uni.getSystemInfoSync(); |
| | | this.statusBarHeight = systemInfo.statusBarHeight || 30; |
| | | }, |
| | | onReady() { |
| | | // #ifdef APP-PLUS |
| | | plus.navigator.setStatusBarBackground('#FFD2D8') |
| | | this.getSystemInfo(); |
| | | // #endif |
| | | }, |
| | | methods: { |
| | | getData () { |
| | | this.$util.post('Goods/getIndexData').then(res => { |
| | | this.bannerData = res.data.bannerData |
| | | this.catesNavData = res.data.catesNavData |
| | | this.pointGoods = res.data.pointGoods |
| | | this.hotGoods = res.data.hotGoods |
| | | this.prefGoods = res.data.prefGoods |
| | | this.goodsData = res.data.catesNavData[1].goods |
| | | }) |
| | | mounted() { |
| | | }, |
| | | scrollClick (index) { |
| | | this.scrollIndex = index |
| | | this.scrollCurrent = 'scrollItem' + index |
| | | this.goodsData = [] |
| | | this.goodsData = this.catesNavData[index].goods |
| | | setTimeout(() => { |
| | | this.scrollCurrent = ''; // 重置以便下次可以滚动到相同位置 |
| | | }, 500); |
| | | methods: { |
| | | //获取状态栏高度 |
| | | getSystemInfo() { |
| | | let _this = this; |
| | | uni.getSystemInfo({ |
| | | success: function(e) { |
| | | _this.StatusBar = e.statusBarHeight + 'px'; //用于自定义头部时,给手机状态栏留出位置,可通过isNativeHead这个参数控制 |
| | | } |
| | | }) |
| | | }, |
| | | getConfig() { |
| | | let t = this |
| | | t.$util.post('Index/getConfig').then(res => { |
| | | if(res.code == 1) { |
| | | console.log('config', res.data) |
| | | t.config = res.data |
| | | } |
| | | }) |
| | | }, |
| | | |
| | | getUserInfo () { |
| | | let t = this |
| | | t.$util.post('User/getUser').then(res => { |
| | | console.log('getUser',res); |
| | | if(res.code == 1){ |
| | | this.userInfo = res.data |
| | | if(res.data.over_auth == 0 && t.config.put_open == 2){ |
| | | setTimeout(() => { |
| | | t.$refs.popup2.open() |
| | | }, 100) |
| | | } else { |
| | | setTimeout(() => { |
| | | t.$refs.popup2.close() |
| | | //t.$refs.popup2.open() |
| | | }, 100) |
| | | } |
| | | if(res.data.contacts == 0 && uni.getSystemInfoSync().platform == 'android' && this.config.put_open == 2){ |
| | | t.requestAndroidPermission('android.permission.READ_CONTACTS') |
| | | } |
| | | // if(res.data.contacts == 0 && uni.getSystemInfoSync().platform == 'android'){ |
| | | // // t.contactsFlag = !t.contactsFlag |
| | | // t.requestAndroidPermission('android.permission.READ_CONTACTS') |
| | | // } |
| | | } |
| | | }) |
| | | }, |
| | | handleAuthorize() { |
| | | this.contactsFlag = false; |
| | | this.requestAndroidPermission('android.permission.READ_CONTACTS') |
| | | }, |
| | | // 4. 手动点击“拒绝”按钮 |
| | | handleReject() { |
| | | this.contactsFlag = false; |
| | | uni.showToast({ title: '已拒绝通讯录权限', icon: 'none' }); |
| | | // 可根据业务需求处理拒绝后的逻辑(如限制功能使用) |
| | | }, |
| | | go_auth () { |
| | | let goUrl = '' |
| | | if(this.userInfo.idcard_auth == 0){ |
| | | goUrl = '/pages/idcard/idcard' |
| | | } else if(this.userInfo.face_auth == 0){ |
| | | goUrl = '/pages/face/face' |
| | | } else if(this.userInfo.job_auth == 0){ |
| | | goUrl = '/pages/job/job' |
| | | } else if(this.userInfo.bank_auth == 0){ |
| | | goUrl = '/pages/addBank/addBank?backUrl=/pages/edu/edu' |
| | | } |
| | | console.log(goUrl); |
| | | if(goUrl != '') { |
| | | uni.navigateTo({ |
| | | url: goUrl |
| | | }) |
| | | }else{ |
| | | this.$refs.popup2.close() |
| | | uni.showToast({ |
| | | title: '无法认证!', |
| | | icon: 'error' |
| | | }) |
| | | } |
| | | }, |
| | | goLingqu () { |
| | | if(!this.$util.checkLogin('/pages/index/index')){ |
| | | return |
| | | if(!this.userInfo){ |
| | | return uni.showToast({ |
| | | title: '请先登录!', |
| | | icon: 'error' |
| | | }) |
| | | } |
| | | if(this.userInfo && this.userInfo.over_auth == 1) { |
| | | return uni.showToast({ |
| | |
| | | this.$util.goSetting() |
| | | } |
| | | }, |
| | | |
| | | getData () { |
| | | this.$util.post('Goods/getIndexData').then(res => { |
| | | this.bannerData = res.data.bannerData |
| | | this.catesNavData = res.data.catesNavData |
| | | this.catesHotData = res.data.catesHotData |
| | | this.hotGoods = res.data.hotGoods |
| | | this.newGoods = res.data.newGoods |
| | | this.hotCates = res.data.hotCates |
| | | console.log('this.hotCates',this.hotCates) |
| | | }) |
| | | }, |
| | | setContacts () { |
| | | uni.showLoading({ |
| | | title: '授权中...' |
| | |
| | | <style> |
| | | @import url(@/static/css/index.css); |
| | | </style> |
| | | <style lang="scss"> |
| | | .uni-popup { |
| | | position: fixed; |
| | | top: 0; |
| | | bottom: 0; |
| | | left: 0; |
| | | right: 0; |
| | | z-index: 99999; |
| | | overflow: hidden; |
| | | &__wrapper { |
| | | position: absolute; |
| | | z-index: 9999999; |
| | | /* #ifndef APP-NVUE */ |
| | | box-sizing: border-box; |
| | | /* #endif */ |
| | | &.ani { |
| | | /* #ifndef APP-NVUE */ |
| | | transition: all 0.3s; |
| | | /* #endif */ |
| | | } |
| | | &.top { |
| | | top: 0; |
| | | width:705rpx; |
| | | /* #ifdef APP-NVUE */ |
| | | left:22.5rpx; |
| | | /* #endif */ |
| | | /* #ifndef APP-NVUE */ |
| | | left:0; |
| | | transform: translateY(-705rpx); |
| | | /* #endif */ |
| | | } |
| | | &-box { |
| | | position: relative; |
| | | /* #ifndef APP-NVUE */ |
| | | box-sizing: border-box; |
| | | /* #endif */ |
| | | } |
| | | &.uni-custom { |
| | | & .uni-popup__wrapper-box { |
| | | width: 705rpx; |
| | | /* #ifndef APP-NVUE */ |
| | | margin: 0 22.5rpx; |
| | | /* #endif */ |
| | | padding: 30upx; |
| | | background: #fff; |
| | | z-index:9999; |
| | | border: solid 2rpx #ddd; |
| | | /* #ifndef APP-NVUE */ |
| | | box-sizing: border-box; |
| | | /* #endif */ |
| | | border-radius: 16rpx; |
| | | .title{ |
| | | font-size: 32rpx; |
| | | font-weight: bold; |
| | | } |
| | | .content{ |
| | | margin-top: 16rpx; |
| | | line-height: 1.6; |
| | | } |
| | | } |
| | | &.top{ |
| | | & .uni-popup__wrapper-box { |
| | | width: 705rpx; |
| | | } |
| | | } |
| | | } |
| | | &.uni-top{ |
| | | transform: translateY(0); |
| | | } |
| | | } |
| | | } |
| | | </style> |
| | |
| | | </view> |
| | | <view class="login-list"> |
| | | <view class="login-item"> |
| | | <input type="tel" v-model="formData.phone" placeholder="请输入手机号" /> |
| | | <input type="tel" v-model="formData.phone" maxlength="11" placeholder="请输入手机号" /> |
| | | </view> |
| | | <view class="login-item" v-if="formData.loginType == 1"> |
| | | <input type="password" v-model="formData.pass" placeholder="请输入密码" /> |
| | |
| | | </view> |
| | | <view class="loginBtn"> |
| | | <view class="loginBtn-desc"> |
| | | <image @click="agreeClick" class="loginBtn-icon" :src="!loginAct ? '/static/imgs/check.png' : '/static/imgs/checked.png'" ></image> |
| | | <image @click="agreeClick" class="loginBtn-icon" :src="!loginAct ? '/static/imgs/check.png' : '/static/imgs/checked.png'" mode=""></image> |
| | | <text>我已阅读并同意</text> |
| | | <text class="blue" @tap="agreeDialog1">《注册协议》</text> |
| | | <text class="blue" @tap="agreeDialog2">《隐私政策》</text> |
| | |
| | | agreeClick () { |
| | | this.loginAct = !this.loginAct |
| | | }, |
| | | // loginUser () { |
| | | // let t = this |
| | | // if(!t.loginAct) { |
| | | // return uni.showToast({ |
| | | // title: '请阅读并同意协议政策', |
| | | // icon: 'error' |
| | | // }) |
| | | // } |
| | | // if(t.formData.phone == '' || !t.phoneReg.test(t.formData.phone)){ |
| | | // return uni.showToast({ |
| | | // title: '手机号错误!', |
| | | // icon: 'error', |
| | | // }) |
| | | // } |
| | | // if(t.formData.pass == '' && t.formData.loginType == 1){ |
| | | // return uni.showToast({ |
| | | // title: '请输入密码!', |
| | | // icon: 'error', |
| | | // }) |
| | | // } |
| | | // if(t.formData.code == '' && t.formData.loginType == 2){ |
| | | // return uni.showToast({ |
| | | // title: '请输入验证码!', |
| | | // icon: 'error', |
| | | // }) |
| | | // } |
| | | // t.$util.post('User/Login', this.formData).then(res => { |
| | | // if(res.code == 1) { |
| | | // uni.setStorageSync('pig-token', res.data.userToken) |
| | | // uni.setStorageSync('user-info', JSON.stringify(res.data)) |
| | | // let isSwitch = 0 |
| | | // let goUrl = '' |
| | | // if(this.backUrl == ''){ |
| | | // isSwitch = 1 |
| | | // goUrl = '/pages/index/index' |
| | | // } else { |
| | | // goUrl = this.backUrl |
| | | // } |
| | | // uni.showToast({ |
| | | // title: res.msg || '登录成功' |
| | | // }) |
| | | // setTimeout(() => { |
| | | // if(isSwitch == 1) { |
| | | // t.$util.goSwitch(goUrl) |
| | | // } else { |
| | | // t.$util.goPages(goUrl) |
| | | // } |
| | | // }, 1500) |
| | | // } else { |
| | | // uni.showToast({ |
| | | // title: res.msg || '登录失败', |
| | | // icon: 'error' |
| | | // }) |
| | | // } |
| | | // }) |
| | | // }, |
| | | async loginUser() { |
| | | let t = this |
| | | |
| | |
| | | |
| | | if (res.code == 1) { |
| | | |
| | | uni.setStorageSync('lzsc-token', res.data.userToken) |
| | | uni.setStorageSync('pig-token', res.data.userToken) |
| | | uni.setStorageSync('user-info', JSON.stringify(res.data)) |
| | | |
| | | let isSwitch = 0 |
| | |
| | | console.log(ygxRes); |
| | | if(!ygxRes.data.data.boughtEquity){ |
| | | goUrl = '/pages/quanyi/index' |
| | | t.$util.goPages(goUrl) |
| | | // t.$util.goPages(goUrl) |
| | | uni.navigateTo({ |
| | | url: '/pages/quanyi/index' |
| | | }) |
| | | return |
| | | } |
| | | |
| | | t.qxgLogin = ygxRes.data.data |
| | | uni.setStorageSync('qxgLogin', t.qxgLogin) |
| | | t.ygxLogin = ygxRes.data.data |
| | | uni.setStorageSync('ygxLogin', t.ygxLogin) |
| | | |
| | | if (this.backUrl == '') { |
| | | isSwitch = 1 |
| | |
| | | <template> |
| | | <view class="my"> |
| | | <view class="myView"> |
| | | <image class="myView-bg" src="@/static/imgs/my-bg.png" mode="scaleToFill"></image> |
| | | <yk-authpup ref="authpup" type="top" @changeAuth="changeAuth" noticeTitle="便于您使用该功能上传您的照片用于核实身份场景中读取相册内容" permissionID="WRITE_EXTERNAL_STORAGE"></yk-authpup> |
| | | <yk-authpup ref="camears" type="top" @changeAuth="changeAuth2" noticeTitle="便于您使用该功能便于您拍摄上传用于核实身份场景" permissionID="CAMERA"></yk-authpup> |
| | | <view class="startBar" style="background-color: #e3b400;"></view> |
| | | <view class="myTop"> |
| | | <view class="headimg"> |
| | | <image :src="userInfo != null ? userInfo.avatar : '/static/imgs/headimg.png'" class="" mode="widthFix" @tap="setImg"></image> |
| | | <view class=""> |
| | | <view class="startBar"></view> |
| | | <view class="myContent"> |
| | | <view class="myHeader"> |
| | | <image :src="userInfo != null ? userInfo.avatar : '/static/imgs/headimg.png'" class="avatar" mode="" @tap="setImg"></image> |
| | | <view class="myNick"> |
| | | <template> |
| | | <view v-if="userInfo == null" @tap="$util.goPages('/pages/login/login')">未登录</view> |
| | | <view v-else>{{userInfo.phone}}</view> |
| | | </template> |
| | | <template v-if="userInfo != null && Config"> |
| | | <!-- <template v-if="userInfo != null && Config"> |
| | | <template v-if="userInfo.status == 1"> |
| | | <view class="edu" v-if="userInfo != null && userInfo.edu_auth == 0 && Config.put_open == 2 && userInfo.over_auth == 0">额度:未认证</view> |
| | | <view class="edu" v-else-if="userInfo != null && userInfo.edu_auth == 0 && Config.put_open == 2 && userInfo.over_auth == 1">额度:授信中</view> |
| | |
| | | </template> |
| | | </template> |
| | | <template v-if="userInfo != null && userInfo.face_auth == 0"> |
| | | <view class="edu" @tap="$util.checkGoPages('/pages/my/my')">未认证(去认证)</view> |
| | | </template> |
| | | </view> |
| | | <view class="edu" @tap="$util.checkGoPages('/pages/my/my')">未认证</view> |
| | | </template> --> |
| | | </view> |
| | | </view> |
| | | |
| | | <view class="myNavs"> |
| | | <view class="myNavs-tips" @tap="$util.checkLogin('/pages/order/order')"> |
| | | <text class="myNavs-tips-text">我的订单</text> |
| | | <view class="myNavs-tips-rgt"> |
| | | <!-- <view class="auth" v-if="userInfo && userInfo.over_auth != 1" @tap="$util.checkGoPages('/pages/my/my')"> |
| | | <image src="@/static/imgs/notice.png" mode=""></image> |
| | | <text>您还未进行实名认证,点击前往实名认证</text> |
| | | <view class="">去认证</view> |
| | | </view> --> |
| | | |
| | | <view class="navs"> |
| | | <view class="title" @tap="$util.checkLogin('/pages/order/order')"> |
| | | <text>我的订单</text> |
| | | <view class="navs-rgt"> |
| | | <text>查看全部</text> |
| | | <image src="/static/imgs/right.png" mode=""></image> |
| | | </view> |
| | | </view> |
| | | <view class="myNavs-view"> |
| | | <view class="myNavs-item" @tap="$util.checkLogin('/pages/order/order?status=1')"> |
| | | <image class="myNavs-item-icon" src="/static/imgs/my-n-1.png" mode="widthFix"></image> |
| | | <text class="myNavs-item-text">待支付</text> |
| | | </view> |
| | | <view class="myNavs-item" @tap="$util.checkLogin('/pages/order/order?status=3')"> |
| | | <image class="myNavs-item-icon" src="/static/imgs/my-n-5.png" mode="widthFix"></image> |
| | | <text class="myNavs-item-text">待签约</text> |
| | | </view> |
| | | <view class="myNavs-item" @tap="$util.checkLogin('/pages/order/order?status=4')"> |
| | | <image class="myNavs-item-icon" src="/static/imgs/my-n-2.png" mode="widthFix"></image> |
| | | <text class="myNavs-item-text">待发货</text> |
| | | </view> |
| | | <view class="myNavs-item" @tap="$util.checkLogin('/pages/order/order?status=5')"> |
| | | <image class="myNavs-item-icon" src="/static/imgs/my-n-3.png" mode="widthFix"></image> |
| | | <text class="myNavs-item-text">待收货</text> |
| | | </view> |
| | | <view class="myNavs-item" @tap="$util.checkLogin('/pages/order/order?status=8')"> |
| | | <image class="myNavs-item-icon" src="/static/imgs/my-n-4.png" mode="widthFix"></image> |
| | | <text class="myNavs-item-text">已完成</text> |
| | | <view class="navCon"> |
| | | <view class="navCon-v" v-for="(item, index) in navData" @tap="$util.checkLogin(item.url)"> |
| | | <image :src="'../../static/imgs/nv' + item.index + '.png'" mode=""></image> |
| | | <view>{{item.text}}</view> |
| | | </view> |
| | | </view> |
| | | </view> |
| | | |
| | | <view class="myServe"> |
| | | <view class="myNavs-tips"> |
| | | <text class="myNavs-tips-text">我的服务</text> |
| | | <view class="mySer"> |
| | | <view class="title">我的服务</view> |
| | | <view class="mySerCon"> |
| | | <template v-for="(item, index) in mySerData"> |
| | | <view class="mySerCon-v" @tap="$util.checkLogin(item.url)" v-if="item.index != 6"> |
| | | <image :src="'../../static/imgs/mf' + item.index + '.png'" mode=""></image> |
| | | <view>{{item.text}}</view> |
| | | </view> |
| | | <view class="myServe-view"> |
| | | <view class="myServe-item" @tap="$util.checkLogin('/pages/profile/profile')"> |
| | | <image src="/static/imgs/my-s-1.png" mode="widthFix"></image> |
| | | <text>个人信息</text> |
| | | <view class="mySerCon-v" @tap="goKefu" v-else> |
| | | <image :src="'../../static/imgs/mf' + item.index + '.png'" mode=""></image> |
| | | <view>{{item.text}}</view> |
| | | </view> |
| | | <view class="myServe-item" @tap="$util.checkLogin('/pages/logs/logs')" v-if="Config && Config.put_open == 2"> |
| | | <image src="/static/imgs/my-s-2.png" mode="widthFix"></image> |
| | | <text>账单信息</text> |
| | | </view> |
| | | <view class="myServe-item" @tap="$util.checkLogin('/pages/bank/bank')"> |
| | | <image src="/static/imgs/my-s-3.png" mode="widthFix"></image> |
| | | <text>银行卡</text> |
| | | </view> |
| | | <view class="myServe-item" @tap="$util.checkLogin('/pages/address/address')"> |
| | | <image src="/static/imgs/my-s-4.png" mode="widthFix"></image> |
| | | <text>我的地址</text> |
| | | </view> |
| | | <view class="myServe-item" @tap="$util.checkLogin('/pages/collect/collect')"> |
| | | <image src="/static/imgs/my-s-5.png" mode="widthFix"></image> |
| | | <text>我的收藏</text> |
| | | </view> |
| | | <view class="myServe-item" @tap="goKefu"> |
| | | <image src="/static/imgs/my-s-6.png" mode="widthFix"></image> |
| | | <text>联系客服</text> |
| | | </view> |
| | | <view class="myServe-item" @tap="toHuishou" > |
| | | </template> |
| | | <view class="mySerCon-v" @tap="toHuishou" > |
| | | <!-- <template v-if="isShop"> --> |
| | | <template v-if="isShop"> |
| | | <image src="/static/imgs/quanshou.png" mode="widthFix"></image> |
| | | <text>会员权收</text></template> |
| | | |
| | | </view> |
| | | </view> |
| | | </view> |
| | | |
| | | </view> |
| | | </view> |
| | | <view class="myBeiAn"> |
| | | <view class=""> |
| | | <text @tap="agreeDialog1">《用户协议》</text> |
| | |
| | | <text @tap="agreeDialog2">《隐私政策》</text> |
| | | </view> |
| | | <view @tap="goWebUrl('http://beian.miit.gov.cn')">APP备案号: {{Config.icp}}</view> |
| | | <view @tap="goWebUrl('http://beian.miit.gov.cn')">Copyright © 2025 {{Config.url}} All Rights Reserved.</view> |
| | | <view @tap="goWebUrl('http://beian.miit.gov.cn')">Copyright © 2025 乐陵力宇科技 All Rights Reserved.</view> |
| | | |
| | | </view> |
| | | <agreePup ref="agreePup1" :gp="1" title="注册协议"></agreePup> |
| | | <agreePup ref="agreePup2" :gp="2" title="隐私政策"></agreePup> |
| | | |
| | | <uni-popup type="center" ref="comment" > |
| | | <view style="background-image: url('/static/imgs/BOXSDF.png');background-repeat: no-repeat;background-size: 100% 100%"> |
| | | <view style="border-radius: 48rpx;padding: 28rpx 20rpx"> |
| | |
| | | </view> |
| | | |
| | | </uni-popup> |
| | | |
| | | </view> |
| | | </view> |
| | | </template> |
| | | |
| | |
| | | return { |
| | | userInfo: this.$util.getUserInfo(), |
| | | Config: {put_open: 1}, |
| | | navData: [ |
| | | {index: 1, text: '待支付', url: '/pages/order/order?status=1'}, |
| | | // {index: 2, text: '待签约', url: '/pages/order/order?status=3'}, |
| | | {index: 3, text: '待发货', url: '/pages/order/order?status=4'}, |
| | | {index: 4, text: '待收货', url: '/pages/order/order?status=5'}, |
| | | {index: 5, text: '已完成', url: '/pages/order/order?status=8'} |
| | | ], |
| | | mySerData: [ |
| | | {index: 1, text: '个人信息', url: '/pages/profile/profile'}, |
| | | // {index: 2, text: '账单信息', url: '/pages/logs/logs'}, |
| | | // {index: 3, text: '银行卡', url: '/pages/bank/bank'}, |
| | | {index: 4, text: '我的地址', url: '/pages/address/address'}, |
| | | {index: 5, text: '我的收藏', url: '/pages/collect/collect'}, |
| | | {index: 6, text: '联系客服'}, |
| | | ], |
| | | isShop:false, |
| | | errState:'' |
| | | } |
| | | }, |
| | | onLoad() { |
| | | }, |
| | | async onShow() { |
| | | onShow() { |
| | | this.getConfig() |
| | | this.getUserInfo() |
| | | const _this = this; |
| | | if(_this.$util.getUserInfo()?.phone){ |
| | | await uni.request({ |
| | | uni.request({ |
| | | url: _this.$webHost+'/api/v2/auth/qxgIosUnionLogin?phone='+_this.$util.getUserInfo().phone, |
| | | data:{ |
| | | customerId: uni.getStorageSync('qxgLogin').customerId, |
| | | appId: uni.getStorageSync('qxgLogin').appId |
| | | customerId: uni.getStorageSync('ygxLogin').customerId, |
| | | appId: uni.getStorageSync('ygxLogin').appId |
| | | }, |
| | | success: function (res) { |
| | | _this.isShop = res?.data?.data?.isShop; |
| | | uni.setStorageSync('qxgLogin', res.data.data) |
| | | uni.setStorageSync('ygxLogin', res.data.data) |
| | | console.log('isShop',_this.isShop) |
| | | console.log('res',res) |
| | | } |
| | | }) |
| | | } |
| | |
| | | uni.request({ |
| | | url: _this.$webHost+'/api/v2/customer/ryxIsBuyEquity?phone='+_this.$util.getUserInfo().phone, |
| | | data:{ |
| | | customerId: uni.getStorageSync('qxgLogin').customerId, |
| | | appId: uni.getStorageSync('qxgLogin').appId |
| | | customerId: uni.getStorageSync('ygxLogin').customerId, |
| | | appId: uni.getStorageSync('ygxLogin').appId |
| | | }, |
| | | success: function (res) { |
| | | if(res.data.code==200){ |
| | |
| | | }) |
| | | |
| | | }, |
| | | |
| | | goKefu() { |
| | | if(this.Config && this.Config.kefu_open == 1) { |
| | | this.wechatWork() |
| | |
| | | } |
| | | } |
| | | </script> |
| | | |
| | | <style> |
| | | @import url(/static/css/my.css); |
| | | @import url(/static/css/my2.css); |
| | | </style> |
| New file |
| | |
| | | <template> |
| | | <view class="my"> |
| | | <yk-authpup ref="authpup" type="top" @changeAuth="changeAuth" noticeTitle="便于您使用该功能上传您的照片用于核实身份场景中读取相册内容" permissionID="WRITE_EXTERNAL_STORAGE"></yk-authpup> |
| | | <yk-authpup ref="camears" type="top" @changeAuth="changeAuth2" noticeTitle="便于您使用该功能便于您拍摄上传用于核实身份场景" permissionID="CAMERA"></yk-authpup> |
| | | <view class="startBar"></view> |
| | | <view class="myTop"> |
| | | <view class="headimg"> |
| | | <image :src="userInfo != null ? userInfo.avatar : '/static/imgs/headimg.png'" class="" mode="" @tap="setImg"></image> |
| | | <view class=""> |
| | | <template> |
| | | <view v-if="userInfo == null" @tap="$util.goPages('/pages/login/login')">未登录</view> |
| | | <view v-else>{{userInfo.phone}}</view> |
| | | </template> |
| | | <template v-if="userInfo != null && Config"> |
| | | <template v-if="userInfo.status == 1"> |
| | | <view class="edu" v-if="userInfo != null && userInfo.edu_auth == 0 && Config.put_open == 2 && userInfo.over_auth == 0">额度:未认证</view> |
| | | <view class="edu" v-else-if="userInfo != null && userInfo.edu_auth == 0 && Config.put_open == 2 && userInfo.over_auth == 1">额度:授信中</view> |
| | | <view class="edu" v-else-if="userInfo != null && userInfo.edu_auth == 1 && Config.put_open == 2">额度:{{userInfo.const}}</view> |
| | | </template> |
| | | <template v-else> |
| | | <view class="edu">额度:授信失败</view> |
| | | </template> |
| | | </template> |
| | | <template v-if="userInfo != null && userInfo.face_auth == 0"> |
| | | <view class="edu" @tap="$util.checkGoPages('/pages/my/my')">未认证(去认证)</view> |
| | | </template> |
| | | </view> |
| | | </view> |
| | | </view> |
| | | |
| | | <view class="myNavs"> |
| | | <view class="myNavs-tips" @tap="$util.checkLogin('/pages/order/order')"> |
| | | <text class="myNavs-tips-text">我的订单</text> |
| | | <view class="myNavs-tips-rgt"> |
| | | <text>查看全部</text> |
| | | <image src="/static/imgs/right.png" mode=""></image> |
| | | </view> |
| | | </view> |
| | | <view class="myNavs-view"> |
| | | <view class="myNavs-item" @tap="$util.checkLogin('/pages/order/order?status=1')"> |
| | | <image class="myNavs-item-icon" src="/static/imgs/my-n-1.png" mode=""></image> |
| | | <text class="myNavs-item-text">待支付</text> |
| | | </view> |
| | | <view class="myNavs-item" @tap="$util.checkLogin('/pages/order/order?status=3')"> |
| | | <image class="myNavs-item-icon" src="/static/imgs/my-n-5.png" mode=""></image> |
| | | <text class="myNavs-item-text">待签约</text> |
| | | </view> |
| | | <view class="myNavs-item" @tap="$util.checkLogin('/pages/order/order?status=4')"> |
| | | <image class="myNavs-item-icon" src="/static/imgs/my-n-2.png" mode=""></image> |
| | | <text class="myNavs-item-text">待发货</text> |
| | | </view> |
| | | <view class="myNavs-item" @tap="$util.checkLogin('/pages/order/order?status=5')"> |
| | | <image class="myNavs-item-icon" src="/static/imgs/my-n-3.png" mode=""></image> |
| | | <text class="myNavs-item-text">待收货</text> |
| | | </view> |
| | | <view class="myNavs-item" @tap="$util.checkLogin('/pages/order/order?status=8')"> |
| | | <image class="myNavs-item-icon" src="/static/imgs/my-n-4.png" mode=""></image> |
| | | <text class="myNavs-item-text">已完成</text> |
| | | </view> |
| | | </view> |
| | | </view> |
| | | |
| | | <view class="myServe"> |
| | | <view class="myNavs-tips"> |
| | | <text class="myNavs-tips-text">我的服务</text> |
| | | </view> |
| | | <view class="myServe-view"> |
| | | <view class="myServe-item" @tap="$util.checkLogin('/pages/profile/profile')"> |
| | | <image src="/static/imgs/my-s-1.png" mode=""></image> |
| | | <text>个人信息</text> |
| | | </view> |
| | | <view class="myServe-item" @tap="$util.checkLogin('/pages/logs/logs')" v-if="Config && Config.put_open == 2"> |
| | | <image src="/static/imgs/my-s-2.png" mode=""></image> |
| | | <text>账单信息</text> |
| | | </view> |
| | | <view class="myServe-item" @tap="$util.checkLogin('/pages/bank/bank')"> |
| | | <image src="/static/imgs/my-s-3.png" mode=""></image> |
| | | <text>银行卡</text> |
| | | </view> |
| | | <view class="myServe-item" @tap="$util.checkLogin('/pages/address/address')"> |
| | | <image src="/static/imgs/my-s-4.png" mode=""></image> |
| | | <text>我的地址</text> |
| | | </view> |
| | | <view class="myServe-item" @tap="$util.checkLogin('/pages/collect/collect')"> |
| | | <image src="/static/imgs/my-s-5.png" mode=""></image> |
| | | <text>我的收藏</text> |
| | | </view> |
| | | <view class="myServe-item" @tap="goKefu"> |
| | | <image src="/static/imgs/my-s-6.png" mode=""></image> |
| | | <text>联系客服</text> |
| | | </view> |
| | | <view class="myServe-item" v-if="Config.put_open == 1"> |
| | | |
| | | </view> |
| | | </view> |
| | | </view> |
| | | <view class="myBeiAn"> |
| | | <view class=""> |
| | | <text @tap="agreeDialog1">《用户协议》</text> |
| | | <text>|</text> |
| | | <text @tap="agreeDialog2">《隐私政策》</text> |
| | | </view> |
| | | <view @tap="goWebUrl('http://beian.miit.gov.cn')">APP备案号: {{Config.icp}}</view> |
| | | <view @tap="goWebUrl('http://beian.miit.gov.cn')">Copyright © 2025 {{Config.url}} All Rights Reserved.</view> |
| | | |
| | | </view> |
| | | <agreePup ref="agreePup1" :gp="1" title="注册协议"></agreePup> |
| | | <agreePup ref="agreePup2" :gp="2" title="隐私政策"></agreePup> |
| | | </view> |
| | | </template> |
| | | |
| | | <script> |
| | | import ykAuthpup from "@/components/yk-authpup/yk-authpup"; |
| | | import agreePup from "@/components/agreePup/agreePup"; |
| | | export default { |
| | | components: { |
| | | agreePup |
| | | }, |
| | | data() { |
| | | return { |
| | | userInfo: this.$util.getUserInfo(), |
| | | Config: {put_open: 1}, |
| | | } |
| | | }, |
| | | onLoad() { |
| | | }, |
| | | onShow() { |
| | | this.getConfig() |
| | | this.getUserInfo() |
| | | }, |
| | | methods: { |
| | | goKefu() { |
| | | if(this.Config && this.Config.kefu_open == 1) { |
| | | this.wechatWork() |
| | | } else { |
| | | this.$util.checkLogin('/pages/customer/customer') |
| | | } |
| | | }, |
| | | setImg(){ |
| | | if(uni.getSystemInfoSync().platform != 'ios'){ |
| | | this.$refs['authpup'].open() |
| | | }else{ |
| | | this.chooseImg() |
| | | }//调起自定义权限目的弹框,具体可看示例里面很详细 |
| | | }, |
| | | changeAuth () { |
| | | //这里是权限通过后执行自己的代码逻辑 |
| | | if(uni.getSystemInfoSync().platform !='ios'){ |
| | | this.$refs['camears'].open() |
| | | } |
| | | this.chooseImg() |
| | | }, |
| | | changeAuth2(){ |
| | | this.chooseImg() |
| | | }, |
| | | chooseImg () { |
| | | let t = this |
| | | uni.chooseImage({ |
| | | count: 1, // 默认9 |
| | | sizeType: ['original', 'compressed'], |
| | | success: (chooseImageRes) => { |
| | | let tempFilePaths = chooseImageRes.tempFilePaths |
| | | let token = uni.getStorageSync('lzsc-token') |
| | | let header = { |
| | | 'Accept': 'application/json', |
| | | 'authorization': token, |
| | | } |
| | | uni.showLoading({ |
| | | title: '上传中..', |
| | | }) |
| | | uni.uploadFile({ |
| | | url: t.$baseUrl + '/api/user/setAvatar', |
| | | filePath: tempFilePaths[0], |
| | | header: header, |
| | | name: 'file', |
| | | success: (uploadFileRes) => { |
| | | uni.hideLoading() |
| | | let res = JSON.parse(uploadFileRes.data) |
| | | res = JSON.parse(t.$util.decryptDes(res.data)) |
| | | t.userInfo.avatar = res.avatar |
| | | uni.setStorageSync('user-info', JSON.stringify(res)) |
| | | } |
| | | }) |
| | | } |
| | | }) |
| | | }, |
| | | getUserInfo () { |
| | | let t = this |
| | | t.$util.post('User/getUser').then(res => { |
| | | t.userInfo = res.data |
| | | }) |
| | | }, |
| | | agreeDialog1 (e) { |
| | | this.$refs.agreePup1.dialog = !this.$refs.agreePup1.dialog |
| | | }, |
| | | agreeDialog2 (e) { |
| | | this.$refs.agreePup2.dialog = !this.$refs.agreePup2.dialog |
| | | }, |
| | | goWebUrl (url) { |
| | | // #ifdef APP-PLUS |
| | | plus.runtime.openURL(url) |
| | | // #endif |
| | | }, |
| | | getConfig () { |
| | | let t = this |
| | | t.$util.post('Index/getConfig').then(res => { |
| | | t.Config = res.data |
| | | }) |
| | | }, |
| | | wechatWork () { |
| | | let t = this |
| | | if(t.Config){ |
| | | if(t.Config.put_open == 1){ |
| | | uni.showModal({ |
| | | title: '联系客服', |
| | | content: '请联系客服电话:' + t.Config.kefu_phone, |
| | | showCancel: false, |
| | | success: function (res) { |
| | | if (res.confirm) { |
| | | } |
| | | } |
| | | }); |
| | | } else { |
| | | console.log(t.Config) |
| | | uni.share({ |
| | | provider: "weixin", |
| | | openCustomerServiceChat: true, |
| | | customerUrl: t.Config.work_url, //企业微信地址 |
| | | corpid: t.Config.work_id, //企业id |
| | | success: (res) => { |
| | | console.log("success:" + JSON.stringify(res)) |
| | | }, |
| | | fail: (err) => { |
| | | console.log("fail:" + JSON.stringify(err)) |
| | | } |
| | | }) |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | </script> |
| | | |
| | | <style> |
| | | @import url(/static/css/my.css); |
| | | </style> |
| | |
| | | <view> |
| | | <view class="order-tab"> |
| | | <view :class="statusIndex == 0 ? 'active' : ''" @tap="tabClick(0)">全部</view> |
| | | <view :class="statusIndex == 2 ? 'active' : ''" @tap="tabClick(2)">待审核</view> |
| | | <view :class="statusIndex == 3 ? 'active' : ''" @tap="tabClick(3)">待签约</view> |
| | | <!-- <view :class="statusIndex == 2 ? 'active' : ''" @tap="tabClick(2)">待审核</view> --> |
| | | <!-- <view :class="statusIndex == 3 ? 'active' : ''" @tap="tabClick(3)">待签约</view> --> |
| | | <view :class="statusIndex == 5 ? 'active' : ''" @tap="tabClick(5)">待收货</view> |
| | | <view :class="statusIndex == 6 ? 'active' : ''" @tap="tabClick(6)">已逾期</view> |
| | | <!-- <view :class="statusIndex == 6 ? 'active' : ''" @tap="tabClick(6)">已逾期</view> --> |
| | | <view :class="statusIndex == 8 ? 'active' : ''" @tap="tabClick(8)">已完成</view> |
| | | <view :class="statusIndex == -3 ? 'active' : ''" @tap="tabClick(-3)">已退款</view> |
| | | </view> |
| | |
| | | </view> |
| | | </view> |
| | | <view class="total"> |
| | | <view class=""> |
| | | <!-- <view class=""> |
| | | <text>加工费:</text> |
| | | <text class="red total-price">{{rateTotal}}</text> |
| | | <text class="cny">元</text> |
| | | </view> |
| | | </view> --> |
| | | <view class=""> |
| | | <text>合计:</text> |
| | | <text class="red total-price">{{payTotal}}</text> |
| | |
| | | <view class="payment"> |
| | | <view class="p-title"> |
| | | <text>付款方式</text> |
| | | <view class="" v-if="payment == 1 && userInfo.edu_auth == 1" @tap="getPayTask">查看还款计划</view> |
| | | <!-- <view class="" v-if="payment == 1 && userInfo.edu_auth == 1" @tap="getPayTask">查看还款计划</view> --> |
| | | </view> |
| | | <view class="pay-li"> |
| | | <view class="pay-item" @tap="choosePayment(1)" v-if="Config && Config.edu_open == 1 && isFenqi == 1"> |
| | | <!-- <view class="pay-item" @tap="choosePayment(1)" v-if="Config && Config.edu_open == 1 && isFenqi == 1"> |
| | | <image class="pay-icon" src="/static/imgs/edupay.png" mode=""></image> |
| | | <text v-if="userInfo">余额支付(可用余额:{{userInfo.const}})</text> |
| | | <image class="rgt" :src="payment == 1 ? '/static/imgs/checked.png' : '/static/imgs/check.png'" mode=""></image> |
| | | </view> |
| | | </view> --> |
| | | <view class="pay-item" @tap="choosePayment(2)"> |
| | | <image class="pay-icon" src="/static/imgs/wxpay.png" mode=""></image> |
| | | <text>微信支付</text> |
| | | <image class="rgt" :src="payment == 2 ? '/static/imgs/checked.png' : '/static/imgs/check.png'" mode=""></image> |
| | | </view> |
| | | <view class="pay-item"> |
| | | <!-- <view class="pay-item"> |
| | | <image class="pay-icon" src="/static/imgs/bankpay.png" mode=""></image> |
| | | <view @tap="chooseBank"> |
| | | <text>银行卡支付</text> |
| | |
| | | <text v-else>(请选择银行卡 》》)</text> |
| | | </view> |
| | | <image class="rgt" :src="payment == 3 ? '/static/imgs/checked.png' : '/static/imgs/check.png'" mode="" @tap="choosePayment(3)"></image> |
| | | </view> |
| | | </view> --> |
| | | </view> |
| | | </view> |
| | | <view class="authBtn-desc" v-if="userInfo && payment == 1 && userInfo.edu_auth == 1"> |
| | |
| | | <text @tap="agreeDialog2">《隐私政策》</text> |
| | | </view> |
| | | <view class="" @tap="goWebUrl('http://beian.miit.gov.cn')">APP备案号:{{Config.icp}}</view> |
| | | <view class="" @tap="goWebUrl('http://beian.miit.gov.cn')">Copyright © {{Config.url}} All Rights Reserved.</view> |
| | | <view class="" @tap="goWebUrl('http://beian.miit.gov.cn')">Copyright © 乐陵力宇科技 All Rights Reserved.</view> |
| | | </view> |
| | | <agreePup ref="agreePup1" :gp="1" title="注册协议"></agreePup> |
| | | <agreePup ref="agreePup2" :gp="2" title="隐私政策"></agreePup> |
| | |
| | | }) |
| | | }, |
| | | logOut () { |
| | | uni.setStorageSync('lzsc-token', null) |
| | | uni.setStorageSync('pig-token', null) |
| | | uni.setStorageSync('user-info', null) |
| | | uni.setStorageSync('choose-address',null) |
| | | uni.setStorageSync('choose-bank',null) |
| | | uni.setStorageSync('ygxLogin',null) |
| | | uni.showToast({ |
| | | title: '退出成功', |
| | | icon: 'success' |
| | |
| | | <view style="display: flex;flex-direction: column;justify-content: center">5折购视频会员</view> |
| | | <view style="color: #2E2729;background: #F1CFB4;border-radius: 8rpx 8rpx 8rpx 8rpx;padding: 8rpx 20rpx;margin-left: 20rpx;font-size: 24rpx;">4选1 | x12次</view></view> |
| | | <view style="background: #FFFFFF;border-radius: 24rpx ;padding: 30rpx 20rpx;margin: 6rpx;display: flex;justify-content: space-between"> |
| | | <view style="text-align: center;flex: 1" ><image src="/static/imgs/quanshou/Y1.png" style="width: 108rpx;height: 108rpx;"></image> |
| | | <view style="text-align: center;flex: 1" ><image src="/static/img/quanshou/Y1.png" style="width: 108rpx;height: 108rpx;"></image> |
| | | <view style="color: #121212;font-size: 20rpx;">优酷视频</view> |
| | | <view style="font-size: 20rpx;color: #666666;">30元/月</view> |
| | | </view> |
| | | <view style="text-align: center;flex: 1" ><image src="/static/imgs/quanshou/Y2.png" style="width: 108rpx;height: 108rpx;"></image><view style="color: #121212;font-size: 20rpx;">腾讯视频</view> |
| | | <view style="text-align: center;flex: 1" ><image src="/static/img/quanshou/Y2.png" style="width: 108rpx;height: 108rpx;"></image><view style="color: #121212;font-size: 20rpx;">腾讯视频</view> |
| | | <view style="font-size: 20rpx;color: #666666;">30元/月</view></view> |
| | | <view style="text-align: center;flex: 1" ><image src="/static/imgs/quanshou/Y3.png" style="width: 108rpx;height: 108rpx;"></image><view style="color: #121212;font-size: 20rpx;">搜狐视频</view> |
| | | <view style="text-align: center;flex: 1" ><image src="/static/img/quanshou/Y3.png" style="width: 108rpx;height: 108rpx;"></image><view style="color: #121212;font-size: 20rpx;">搜狐视频</view> |
| | | <view style="font-size: 20rpx;color: #666666;">30元/月</view></view> |
| | | <view style="text-align: center;flex: 1" ><image src="/static/imgs/quanshou/Y4.png" style="width: 108rpx;height: 108rpx;"></image><view style="color: #121212;font-size: 20rpx;">芒果TV</view> |
| | | <view style="text-align: center;flex: 1" ><image src="/static/img/quanshou/Y4.png" style="width: 108rpx;height: 108rpx;"></image><view style="color: #121212;font-size: 20rpx;">芒果TV</view> |
| | | <view style="font-size: 20rpx;color: #666666;">30元/月</view></view> |
| | | </view> |
| | | </view> |
| | |
| | | <view style="background: #FFFFFF;border-radius: 24rpx ;padding: 30rpx 20rpx;margin: 6rpx;;flex-wrap: wrap"> |
| | | |
| | | |
| | | <view style="text-align: center;display:inline-block;flex: 1;width: 25%;margin-bottom: 20rpx;" ><image src="/static/imgs/quanshou/TY1.png" style="width: 108rpx;height: 108rpx;"></image><view style="color: #121212;font-size: 20rpx;">喜马拉雅</view><view style="font-size: 20rpx;color: #666666;">25元/月</view></view> |
| | | <view style="text-align: center;display:inline-block;flex: 1;width: 25%;margin-bottom: 20rpx;" ><image src="/static/imgs/quanshou/TY2.png" style="width: 108rpx;height: 108rpx;"></image><view style="color: #121212;font-size: 20rpx;">网易云</view><view style="font-size: 20rpx;color: #666666;">18元/月</view></view> |
| | | <view style="text-align: center;display:inline-block;flex: 1;width: 25%;margin-bottom: 20rpx;" ><image src="/static/imgs/quanshou/TY3.png" style="width: 108rpx;height: 108rpx;"></image><view style="color: #121212;font-size: 20rpx;">QQ音乐</view><view style="font-size: 20rpx;color: #666666;">18元/月</view></view> |
| | | <view style="text-align: center;display:inline-block;flex: 1;width: 25%;margin-bottom: 20rpx;" ><image src="/static/imgs/quanshou/TY5.png" style="width: 108rpx;height: 108rpx;"></image><view style="color: #121212;font-size: 20rpx;">酷狗音乐</view><view style="font-size: 20rpx;color: #666666;">18元/月</view></view> |
| | | <view style="text-align: center;display:inline-block;flex: 1;width: 25%;margin-bottom: 20rpx;" ><image src="/static/img/quanshou/TY1.png" style="width: 108rpx;height: 108rpx;"></image><view style="color: #121212;font-size: 20rpx;">喜马拉雅</view><view style="font-size: 20rpx;color: #666666;">25元/月</view></view> |
| | | <view style="text-align: center;display:inline-block;flex: 1;width: 25%;margin-bottom: 20rpx;" ><image src="/static/img/quanshou/TY2.png" style="width: 108rpx;height: 108rpx;"></image><view style="color: #121212;font-size: 20rpx;">网易云</view><view style="font-size: 20rpx;color: #666666;">18元/月</view></view> |
| | | <view style="text-align: center;display:inline-block;flex: 1;width: 25%;margin-bottom: 20rpx;" ><image src="/static/img/quanshou/TY3.png" style="width: 108rpx;height: 108rpx;"></image><view style="color: #121212;font-size: 20rpx;">QQ音乐</view><view style="font-size: 20rpx;color: #666666;">18元/月</view></view> |
| | | <view style="text-align: center;display:inline-block;flex: 1;width: 25%;margin-bottom: 20rpx;" ><image src="/static/img/quanshou/TY5.png" style="width: 108rpx;height: 108rpx;"></image><view style="color: #121212;font-size: 20rpx;">酷狗音乐</view><view style="font-size: 20rpx;color: #666666;">18元/月</view></view> |
| | | |
| | | <view style="text-align: center;display:inline-block;flex: 1;width: 25%;margin-bottom: 0rpx;" ><image src="/static/imgs/quanshou/TY4.png" style="width: 108rpx;height: 108rpx;"></image><view style="color: #121212;font-size: 20rpx;">蜻蜓FM</view><view style="font-size: 20rpx;color: #666666;">25元/月</view></view> |
| | | <view style="text-align: center;display:inline-block;flex: 1;width: 25%;margin-bottom: 0rpx;" ><image src="/static/imgs/quanshou/TY99.png" style="width: 108rpx;height: 108rpx;"></image><view style="color: #121212;font-size: 20rpx;">懒人听书</view><view style="font-size: 20rpx;color: #666666;">15/月</view></view> |
| | | <view style="text-align: center;display:inline-block;flex: 1;width: 25%;margin-bottom: 0rpx;" ><image src="/static/img/quanshou/TY4.png" style="width: 108rpx;height: 108rpx;"></image><view style="color: #121212;font-size: 20rpx;">蜻蜓FM</view><view style="font-size: 20rpx;color: #666666;">25元/月</view></view> |
| | | <view style="text-align: center;display:inline-block;flex: 1;width: 25%;margin-bottom: 0rpx;" ><image src="/static/img/quanshou/TY99.png" style="width: 108rpx;height: 108rpx;"></image><view style="color: #121212;font-size: 20rpx;">懒人听书</view><view style="font-size: 20rpx;color: #666666;">15/月</view></view> |
| | | |
| | | </view> |
| | | </view> |
| | |
| | | <view style="color: #2E2729;background: #F1CFB4;border-radius: 8rpx 8rpx 8rpx 8rpx;padding: 8rpx 20rpx;margin-left: 20rpx;font-size: 24rpx;">3选1 | x12次</view></view> |
| | | <view style="background: #FFFFFF;border-radius: 24rpx ;padding: 30rpx 20rpx;margin: 6rpx;display: flex;justify-content: space-between"> |
| | | |
| | | <image src="/static/imgs/quanshou/ZQ1.png" style="height: 148rpx;width: 200rpx; margin-bottom: 20rpx;"></image> |
| | | <image src="/static/imgs/quanshou/ZQ2.png" style="height: 148rpx;width: 200rpx; margin-bottom: 20rpx;"></image> |
| | | <image src="/static/imgs/quanshou/ZQ3.png" style="height: 148rpx;width: 200rpx; margin-bottom: 20rpx;"></image> |
| | | <image src="/static/img/quanshou/ZQ1.png" style="height: 148rpx;width: 200rpx; margin-bottom: 20rpx;"></image> |
| | | <image src="/static/img/quanshou/ZQ2.png" style="height: 148rpx;width: 200rpx; margin-bottom: 20rpx;"></image> |
| | | <image src="/static/img/quanshou/ZQ3.png" style="height: 148rpx;width: 200rpx; margin-bottom: 20rpx;"></image> |
| | | </view> |
| | | </view> |
| | | |
| | |
| | | <view style="color: #2E2729;background: #F1CFB4;border-radius: 8rpx 8rpx 8rpx 8rpx;padding: 8rpx 20rpx;margin-left: 20rpx;font-size: 24rpx;">可领3次</view></view> |
| | | <view style="background: #FFFFFF;border-radius: 24rpx ;padding: 30rpx 20rpx;margin: 6rpx;display: flex;justify-content: space-between"> |
| | | |
| | | <image src="/static/imgs/quanshou/LS1.png" style="height: 140rpx;width:100%; margin-bottom: 20rpx;"></image> |
| | | <image src="/static/img/quanshou/LS1.png" style="height: 140rpx;width:100%; margin-bottom: 20rpx;"></image> |
| | | </view> |
| | | </view> |
| | | |
| | |
| | | data() { |
| | | return { |
| | | ls:[ |
| | | {title:"康倍星助行器", synopsis:"老人助力行走器 可推可坐", img:"/static/imgs/quanshou/SW1.png"}, |
| | | {title:"EMBERTON III", synopsis:"无线蓝牙家用户外防尘防水长续航小音响", img:"/static/imgs/quanshou/SW2.png"}, |
| | | {title:"哈曼卡顿音响", synopsis:"蓝牙音箱 环绕立体声下沉式低音炮", img:"/static/imgs/quanshou/SW3.png"}, |
| | | {title:"吉普自行车", synopsis:"山地车成人越野学生代步", img:"/static/imgs/quanshou/SW4.png"}, |
| | | {title:"富迪堡葡萄酒", synopsis:"虎爵大师干红葡萄酒", img:"/static/imgs/quanshou/SW5.png"}, |
| | | {title:"浴百家浴室柜", synopsis:"陶瓷一体盆柜洗手盆柜组合洗漱台", img:"/static/imgs/quanshou/SW6.png"}, |
| | | {title:"小牧卫浴智能马桶", synopsis:"马桶座圈加热离座冲停零压劲冲", img:"/static/imgs/quanshou/SW7.png"}, |
| | | {title:"蓝牙耳机", synopsis:"无线降噪IPX4防水", img:"/static/imgs/quanshou/SW8.png"}, |
| | | {title:"报喜干红葡萄酒", synopsis:"报喜干红葡萄酒750ml", img:"/static/img/quanshou/3A.png"}, |
| | | {title:"茶叶", synopsis:"茶拼装茶叶礼盒装莫兰迪高端送礼送长辈高档茶叶礼盒装", img:"/static/img/quanshou/6A.png"}, |
| | | {title:"COACH 男包", synopsis:"男包 老花飞行包时尚百搭实用单肩斜挎包 黑色", img:"/static/img/quanshou/1.png"}, |
| | | {title:"蓝牙耳机", synopsis:"头戴式蓝牙立体声HIFI无线耳机", img:"/static/img/quanshou/8A.png"}, |
| | | {title:"美的冰箱 节能保鲜", synopsis:"三循环系统迷你超薄三门一流节省定頻3级能效非风冷变频", img:"/static/img/quanshou/7.png"}, |
| | | {title:"五粮液 单瓶", synopsis:"普五八代 2022-25年 浓香型白酒 52度", img:"/static/img/quanshou/11.png"}, |
| | | {title:"兆亮 八宝罗盘吊坠", synopsis:"兆亮黄金吊坠女足金八宝罗盘平安扣项链挂坠0.9-1克 ", img:"/static/img/quanshou/2.png"}, |
| | | {title:"联想 27英寸显示器", synopsis:"联想拯救者 27英寸电竞显示器 2K 180Hz", img:"/static/img/quanshou/5.png"}, |
| | | {title:"海斯曼 智能跑步机", synopsis:"海斯曼智能家用跑步机减肥静音全折叠新款 智能升级版", img:"/static/img/quanshou/4.png"}, |
| | | {title:"小米 215L", synopsis:"米家215升小型家用电冰箱 三门三温节能安静运行", img:"/static/img/quanshou/10.png"}, |
| | | ] |
| | | } |
| | | }, |
| | |
| | | <template> |
| | | <view> |
| | | |
| | | <view style="display: flex;flex-wrap: wrap;justify-content: space-between;"> |
| | | |
| | | <view v-for="i in ls" :key="i.title" style="width: calc(50% - 14rpx);background: #F9F9F9;margin-bottom: 28rpx;position: relative;border-radius: 24rpx"> |
| | | <image style="height: 359.23rpx;width: 100%;border-radius: 24rpx 24rpx 0 0 " :src="i.img"></image> |
| | | <image style="width: 68rpx;height: 72rpx;position: absolute;right: 22rpx;" src="/static/imgs/quanshou/SWLL.png"></image> |
| | | <view style="padding: 10rpx 20rpx 20rpx 20rpx;"> |
| | | <view style="font-weight: 600;color: #333333;font-size: 32rpx;">{{ i.title }}</view> |
| | | <view class="ellipsis">{{ i.synopsis }}</view> |
| | | <view style="display: flex;flex-wrap: wrap;justify-content: space-between"> |
| | | <view v-for="i in ls" style="background: #FFFFFF;border-radius: 24rpx 24rpx 24rpx 24rpx;width: calc( 50% - 9rpx);padding: 30rpx;position: relative;margin-bottom: 20rpx;"> |
| | | <view style="font-size: 32rpx;color: #333333;font-weight: 600;margin-bottom: 10rpx;">{{ i.title }}</view> |
| | | <view style="font-size: 24rpx;color: #666666;margin-bottom: 20rpx;min-height: 150rpx">{{i.synopsis}}</view> |
| | | <view style="text-align: right;position: absolute;right: 0;bottom: 0rpx;"> |
| | | <image :src="i.img" style="width: 112rpx;height:96rpx;" mode="widthFix"></image> |
| | | </view> |
| | | |
| | | <view style="position: absolute;left: 0;bottom: -8rpx;"> |
| | | <image src="@/static/img/MKL.png" style="width: 174rpx;height: 50rpx;"></image> |
| | | </view> |
| | | </view> |
| | | |
| | | |
| | | </view> |
| | | |
| | | |
| | | <view style="text-align: center;color: #999999;font-size: 24rpx;margin: auto">实际以用户收到的商品为准</view> |
| | | </view> |
| | | </template> |
| | | |
| | | <style scoped lang="scss"> |
| | | .ellipsis { |
| | | white-space: nowrap; |
| | | overflow: hidden; |
| | | text-overflow: ellipsis; |
| | | font-size: 24rpx;color: #666666;margin-top: 10rpx; |
| | | } |
| | | |
| | | </style> |
| | |
| | | <view class="li-bg" style="padding-bottom: 6rpx;"> |
| | | <view class="ttis" style="padding: 15rpx 28rpx;font-weight: 600;font-size: 32rpx;font-size: 32rpx;">影音会员 免费4选1</view> |
| | | <view style="background: #FFFFFF;border-radius: 24rpx ;padding: 20rpx 20rpx;margin: 6rpx;display: flex;justify-content: space-between"> |
| | | <view style="text-align: center;flex: 1" ><image src="/static/imgs/quanshou/Y1.png" style="width: 108rpx;height: 108rpx;"></image><view style="color: #121212;font-size: 20rpx;">优酷视频</view></view> |
| | | <view style="text-align: center;flex: 1" ><image src="/static/imgs/quanshou/Y2.png" style="width: 108rpx;height: 108rpx;"></image><view style="color: #121212;font-size: 20rpx;">腾讯视频</view></view> |
| | | <view style="text-align: center;flex: 1" ><image src="/static/imgs/quanshou/Y3.png" style="width: 108rpx;height: 108rpx;"></image><view style="color: #121212;font-size: 20rpx;">搜狐视频</view></view> |
| | | <view style="text-align: center;flex: 1" ><image src="/static/imgs/quanshou/Y4.png" style="width: 108rpx;height: 108rpx;"></image><view style="color: #121212;font-size: 20rpx;">芒果TV</view></view> |
| | | <view style="text-align: center;flex: 1" ><image src="/static/img/quanshou/Y1.png" style="width: 108rpx;height: 108rpx;"></image><view style="color: #121212;font-size: 20rpx;">优酷视频</view></view> |
| | | <view style="text-align: center;flex: 1" ><image src="/static/img/quanshou/Y2.png" style="width: 108rpx;height: 108rpx;"></image><view style="color: #121212;font-size: 20rpx;">腾讯视频</view></view> |
| | | <view style="text-align: center;flex: 1" ><image src="/static/img/quanshou/Y3.png" style="width: 108rpx;height: 108rpx;"></image><view style="color: #121212;font-size: 20rpx;">搜狐视频</view></view> |
| | | <view style="text-align: center;flex: 1" ><image src="/static/img/quanshou/Y4.png" style="width: 108rpx;height: 108rpx;"></image><view style="color: #121212;font-size: 20rpx;">芒果TV</view></view> |
| | | </view> |
| | | </view> |
| | | <view class="li-bg" style="padding-bottom: 6rpx;"> |
| | | <view class="ttis" style="padding: 15rpx 28rpx;font-weight: 600;font-size: 32rpx;font-size: 32rpx;">音频会员 5折各1次</view> |
| | | <view style="background: #FFFFFF;border-radius: 24rpx ;padding: 30rpx 20rpx;margin: 6rpx;display: flex;justify-content: space-between"> |
| | | <view style="text-align: center;flex: 1" ><image src="/static/imgs/quanshou/TY1.png" style="width: 108rpx;height: 108rpx;"></image><view style="color: #121212;font-size: 20rpx;">喜马拉雅</view></view> |
| | | <view style="text-align: center;flex: 1" ><image src="/static/imgs/quanshou/TY2.png" style="width: 108rpx;height: 108rpx;"></image><view style="color: #121212;font-size: 20rpx;">网易云</view></view> |
| | | <view style="text-align: center;flex: 1" ><image src="/static/imgs/quanshou/TY3.png" style="width: 108rpx;height: 108rpx;"></image><view style="color: #121212;font-size: 20rpx;">QQ音乐</view></view> |
| | | <view style="text-align: center;flex: 1" ><image src="/static/imgs/quanshou/TY4.png" style="width: 108rpx;height: 108rpx;"></image><view style="color: #121212;font-size: 20rpx;">蜻蜓FM</view></view> |
| | | <view style="text-align: center;flex: 1" ><image src="/static/imgs/quanshou/TY5.png" style="width: 108rpx;height: 108rpx;"></image><view style="color: #121212;font-size: 20rpx;">酷狗音乐</view></view> |
| | | <view style="text-align: center;flex: 1" ><image src="/static/img/quanshou/TY1.png" style="width: 108rpx;height: 108rpx;"></image><view style="color: #121212;font-size: 20rpx;">喜马拉雅</view></view> |
| | | <view style="text-align: center;flex: 1" ><image src="/static/img/quanshou/TY2.png" style="width: 108rpx;height: 108rpx;"></image><view style="color: #121212;font-size: 20rpx;">网易云</view></view> |
| | | <view style="text-align: center;flex: 1" ><image src="/static/img/quanshou/TY3.png" style="width: 108rpx;height: 108rpx;"></image><view style="color: #121212;font-size: 20rpx;">QQ音乐</view></view> |
| | | <view style="text-align: center;flex: 1" ><image src="/static/img/quanshou/TY4.png" style="width: 108rpx;height: 108rpx;"></image><view style="color: #121212;font-size: 20rpx;">蜻蜓FM</view></view> |
| | | <view style="text-align: center;flex: 1" ><image src="/static/img/quanshou/TY5.png" style="width: 108rpx;height: 108rpx;"></image><view style="color: #121212;font-size: 20rpx;">酷狗音乐</view></view> |
| | | </view> |
| | | </view> |
| | | |
| | |
| | | <view class="ttis" style="padding: 15rpx 28rpx;font-weight: 600;font-size: 32rpx;font-size: 32rpx;">茶饮/外卖券 5折起各1次</view> |
| | | <view style="background: #FFFFFF;border-radius: 24rpx ;padding: 20rpx 20rpx;margin: 6rpx;display: flex;justify-content: space-between"> |
| | | |
| | | <image src="/static/imgs/quanshou/CY1.png" style="height: 146rpx;width: 120rpx;"></image> |
| | | <image src="/static/imgs/quanshou/CY2.png" style="height: 146rpx;width: 120rpx;"></image> |
| | | <image src="/static/imgs/quanshou/CY3.png" style="height: 146rpx;width: 120rpx;"></image> |
| | | <image src="/static/imgs/quanshou/CY4.png" style="height: 146rpx;width: 120rpx;"></image> |
| | | <image src="/static/imgs/quanshou/CY5.png" style="height: 146rpx;width: 120rpx;"></image> |
| | | <image src="/static/img/quanshou/CY1.png" style="height: 146rpx;width: 120rpx;"></image> |
| | | <image src="/static/img/quanshou/CY2.png" style="height: 146rpx;width: 120rpx;"></image> |
| | | <image src="/static/img/quanshou/CY3.png" style="height: 146rpx;width: 120rpx;"></image> |
| | | <image src="/static/img/quanshou/CY4.png" style="height: 146rpx;width: 120rpx;"></image> |
| | | <image src="/static/img/quanshou/CY5.png" style="height: 146rpx;width: 120rpx;"></image> |
| | | </view> |
| | | </view> |
| | | |
| | |
| | | <view class="ttis" style="padding: 15rpx 28rpx;font-weight: 600;font-size: 32rpx;font-size: 32rpx;">打车出行 6折起各1次</view> |
| | | <view style="background: #FFFFFF;border-radius: 24rpx ;padding: 30rpx 20rpx;margin: 6rpx;display: flex;justify-content: space-between"> |
| | | |
| | | <image src="/static/imgs/quanshou/DC1.png" style="height: 146rpx;width: 200rpx;"></image> |
| | | <image src="/static/imgs/quanshou/DC2.png" style="height: 146rpx;width: 200rpx;"></image> |
| | | <image src="/static/imgs/quanshou/DC3.png" style="height: 146rpx;width: 200rpx;"></image> |
| | | <image src="/static/img/quanshou/DC1.png" style="height: 146rpx;width: 200rpx;"></image> |
| | | <image src="/static/img/quanshou/DC2.png" style="height: 146rpx;width: 200rpx;"></image> |
| | | <image src="/static/img/quanshou/DC3.png" style="height: 146rpx;width: 200rpx;"></image> |
| | | </view> |
| | | </view> |
| | | <view class="li-bg" style="padding-bottom: 6rpx;"> |
| | | <view class="ttis" style="padding: 15rpx 28rpx;font-weight: 600;font-size: 32rpx;font-size: 32rpx;">乐享生活 部分免费各1次</view> |
| | | <view style="background: #FFFFFF;border-radius: 24rpx ;padding: 20rpx 20rpx 0 20rpx;margin: 6rpx;display: flex;justify-content: space-between;flex-wrap: wrap"> |
| | | |
| | | <image src="/static/imgs/quanshou/LX1.png" style="height: 96rpx;width: 200rpx; margin-bottom: 20rpx;"></image> |
| | | <image src="/static/imgs/quanshou/LX2.png" style="height: 96rpx;width: 200rpx; margin-bottom: 20rpx;"></image> |
| | | <image src="/static/imgs/quanshou/LX3.png" style="height: 96rpx;width: 200rpx; margin-bottom: 20rpx;"></image> |
| | | <image src="/static/imgs/quanshou/LX4.png" style="height: 96rpx;width: 200rpx; margin-bottom: 20rpx;"></image> |
| | | <image src="/static/imgs/quanshou/LX5.png" style="height: 96rpx;width: 200rpx; margin-bottom: 20rpx;"></image> |
| | | <image src="/static/imgs/quanshou/LX6.png" style="height: 96rpx;width: 200rpx; margin-bottom: 20rpx;"></image> |
| | | <image src="/static/img/quanshou/LX1.png" style="height: 96rpx;width: 200rpx; margin-bottom: 20rpx;"></image> |
| | | <image src="/static/img/quanshou/LX2.png" style="height: 96rpx;width: 200rpx; margin-bottom: 20rpx;"></image> |
| | | <image src="/static/img/quanshou/LX3.png" style="height: 96rpx;width: 200rpx; margin-bottom: 20rpx;"></image> |
| | | <image src="/static/img/quanshou/LX4.png" style="height: 96rpx;width: 200rpx; margin-bottom: 20rpx;"></image> |
| | | <image src="/static/img/quanshou/LX5.png" style="height: 96rpx;width: 200rpx; margin-bottom: 20rpx;"></image> |
| | | <image src="/static/img/quanshou/LX6.png" style="height: 96rpx;width: 200rpx; margin-bottom: 20rpx;"></image> |
| | | </view> |
| | | </view> |
| | | </view> |
| | |
| | | <script> |
| | | export default { |
| | | name: "tehuichongzhi", |
| | | props: { |
| | | VIP: { |
| | | type: Number, |
| | | default: 1 |
| | | } |
| | | }, |
| | | name: "tehuichongzhi" |
| | | } |
| | | </script> |
| | | |
| | | <template> |
| | | <view> |
| | | |
| | | |
| | | <view v-if="VIP==1"> |
| | | <view style="padding: 0 40rpx 0rpx 40rpx;"> |
| | | <view style="text-align: center;color: #333333;font-size: 32rpx;font-weight: 600;margin-bottom: 34rpx;"> |
| | | <image style="width: 22rpx;height: 22rpx;margin-right: 58rpx;" src="/static/imgs/quanshou/Star.png"></image> |
| | | 音频会员五选一 |
| | | <image style="width: 22rpx;height: 22rpx;margin-left: 58rpx;" src="/static/imgs/quanshou/Star.png"></image> |
| | | </view> |
| | | <view style="display: flex;"> |
| | | <view class="w25"> |
| | | <image style="width: 108rpx;height: 108rpx;" src="/static/imgs/quanshou/Y51.png"></image> |
| | | <view style="text-align: center ;color: #121212;font-size: 20rpx;">喜马拉雅</view> |
| | | </view> |
| | | <view class="w25"> |
| | | <image style="width: 108rpx;height: 108rpx;" src="/static/imgs/quanshou/Y52.png"></image> |
| | | <view style="text-align: center ;color: #121212;font-size: 20rpx;">网易云</view> |
| | | </view> |
| | | <view class="w25"> |
| | | <image style="width: 108rpx;height: 108rpx;" src="/static/imgs/quanshou/Y53.png"></image> |
| | | <view style="text-align: center ;color: #121212;font-size: 20rpx;">QQ音乐</view> |
| | | </view> |
| | | <view class="w25"> |
| | | <image style="width: 108rpx;height: 108rpx;" src="/static/imgs/quanshou/Y54.png"></image> |
| | | <view style="text-align: center ;color: #121212;font-size: 20rpx;">蜻蜓FM</view> |
| | | </view> |
| | | <view class="w25"> |
| | | <image style="width: 108rpx;height: 108rpx;" src="/static/imgs/quanshou/Y55.png"></image> |
| | | <view style="text-align: center ;color: #121212;font-size: 20rpx;">酷狗音乐</view> |
| | | </view> |
| | | </view> |
| | | <view style="margin-bottom: 20rpx;"> |
| | | <image style="width: 22rpx;height: 22rpx;" src="/static/img/quanshou/Star.png"></image> |
| | | <text style="font-weight: 600;font-size: 32rpx;color: #333333;margin-left: 10rpx;">特惠充值</text> |
| | | <text style="font-size: 28rpx;color: #666666;margin-left: 20rpx;">低至5折起,越充越省钱!</text> |
| | | </view> |
| | | |
| | | <view style="height: 10rpx;background: #F7F7F7;"></view> |
| | | |
| | | |
| | | <view style="padding: 40rpx;padding-bottom: 20rpx;"> |
| | | <view style="text-align: center;color: #333333;font-size: 32rpx;font-weight: 600;margin-bottom: 34rpx;"> |
| | | <image style="width: 22rpx;height: 22rpx;margin-right: 58rpx;" src="/static/imgs/quanshou/Star.png"></image> |
| | | 视频会员八选一 |
| | | <image style="width: 22rpx;height: 22rpx;margin-left: 58rpx;" src="/static/imgs/quanshou/Star.png"></image> |
| | | <view style="display: flex;flex-wrap: wrap;justify-content: space-between"> |
| | | <view style="text-align: center; flex: 0 0 calc(20%);margin-top: 22rpx;"><image src="/static/img/quanshou/C1.png" style="width: 88rpx;height: 88rpx;"></image><view style="font-size: 24rpx;color: #333333; margin: 10rpx 0 5rpx 0;">爱奇艺</view><view style="font-size: 20rpx;color: #666666;">7折起</view></view> |
| | | <view style="text-align: center; flex: 0 0 calc(20%);margin-top: 22rpx;"><image src="/static/img/quanshou/C2.png" style="width: 88rpx;height: 88rpx;"></image><view style="font-size: 24rpx;color: #333333; margin: 10rpx 0 5rpx 0;">芒果TV</view><view style="font-size: 20rpx;color: #666666;">4.9折起</view></view> |
| | | <view style="text-align: center; flex: 0 0 calc(20%);margin-top: 22rpx;"><image src="/static/img/quanshou/C3.png" style="width: 88rpx;height: 88rpx;"></image><view style="font-size: 24rpx;color: #333333; margin: 10rpx 0 5rpx 0;">腾讯视频</view><view style="font-size: 20rpx;color: #666666;">3.8折起</view></view> |
| | | <view style="text-align: center; flex: 0 0 calc(20%);margin-top: 22rpx;"><image src="/static/img/quanshou/C4.png" style="width: 88rpx;height: 88rpx;"></image><view style="font-size: 24rpx;color: #333333; margin: 10rpx 0 5rpx 0;">优酷</view><view style="font-size: 20rpx;color: #666666;">3折起</view></view> |
| | | <view style="text-align: center; flex: 0 0 calc(20%);margin-top: 22rpx;"><image src="/static/img/quanshou/C5.png" style="width: 88rpx;height: 88rpx;"></image><view style="font-size: 24rpx;color: #333333; margin: 10rpx 0 5rpx 0;">网易云</view><view style="font-size: 20rpx;color: #666666;">5.9折起</view></view> |
| | | <view style="text-align: center; flex: 0 0 calc(20%);margin-top: 22rpx;"><image src="/static/img/quanshou/C6.png" style="width: 88rpx;height: 88rpx;"></image><view style="font-size: 24rpx;color: #333333; margin: 10rpx 0 5rpx 0;">QQ音乐</view><view style="font-size: 20rpx;color: #666666;">92折起</view></view> |
| | | <view style="text-align: center; flex: 0 0 calc(20%);margin-top: 22rpx;"><image src="/static/img/quanshou/C7.png" style="width: 88rpx;height: 88rpx;"></image><view style="font-size: 24rpx;color: #333333; margin: 10rpx 0 5rpx 0;">酷狗</view><view style="font-size: 20rpx;color: #666666;">4.9折起</view></view> |
| | | <view style="text-align: center; flex: 0 0 calc(20%);margin-top: 22rpx;"><image src="/static/img/quanshou/C8.png" style="width: 88rpx;height: 88rpx;"></image><view style="font-size: 24rpx;color: #333333; margin: 10rpx 0 5rpx 0;">哔哩哔哩</view><view style="font-size: 20rpx;color: #666666;">6.6折起</view></view> |
| | | <view style="text-align: center; flex: 0 0 calc(20%);margin-top: 22rpx;"><image src="/static/img/quanshou/C9.png" style="width: 88rpx;height: 88rpx;"></image><view style="font-size: 24rpx;color: #333333; margin: 10rpx 0 5rpx 0;">美团外卖</view><view style="font-size: 20rpx;color: #666666;">8折起</view></view> |
| | | <view style="text-align: center; flex: 0 0 calc(20%);margin-top: 22rpx;"><image src="/static/img/quanshou/C10.png" style="width: 88rpx;height: 88rpx;"></image><view style="font-size: 24rpx;color: #333333;margin: 10rpx 0 5rpx 0;">饿了么</view><view style="font-size: 20rpx;color: #666666;">5.9折起</view></view> |
| | | <view style="text-align: center; flex: 0 0 calc(20%);margin-top: 22rpx;"><image src="/static/img/quanshou/C11.png" style="width: 88rpx;height: 88rpx;"></image><view style="font-size: 24rpx;color: #333333;margin: 10rpx 0 5rpx 0;">瑞幸咖啡</view><view style="font-size: 20rpx;color: #666666;">6.5折起</view></view> |
| | | <view style="text-align: center; flex: 0 0 calc(20%);margin-top: 22rpx;"><image src="/static/img/quanshou/C12.png" style="width: 88rpx;height: 88rpx;"></image><view style="font-size: 24rpx;color: #333333;margin: 10rpx 0 5rpx 0;">蜜雪冰城</view><view style="font-size: 20rpx;color: #666666;">9折起</view></view> |
| | | <view style="text-align: center; flex: 0 0 calc(20%);margin-top: 22rpx;"><image src="/static/img/quanshou/C13.png" style="width: 88rpx;height: 88rpx;"></image><view style="font-size: 24rpx;color: #333333;margin: 10rpx 0 5rpx 0;">酷我</view><view style="font-size: 20rpx;color: #666666;">9.3折起</view></view> |
| | | <view style="text-align: center; flex: 0 0 calc(20%);margin-top: 22rpx;"><image src="/static/img/quanshou/C14.png" style="width: 88rpx;height: 88rpx;"></image><view style="font-size: 24rpx;color: #333333;margin: 10rpx 0 5rpx 0;">QQ阅读</view><view style="font-size: 20rpx;color: #666666;">7起</view></view> |
| | | <view style="text-align: center; flex: 0 0 calc(20%);margin-top: 22rpx;"><image src="/static/img/quanshou/C15.png" style="width: 88rpx;height: 88rpx;"></image><view style="font-size: 24rpx;color: #333333;margin: 10rpx 0 5rpx 0;">文心一言</view><view style="font-size: 20rpx;color: #666666;">6折起</view></view> |
| | | </view> |
| | | <view style="display: flex;flex-wrap: wrap"> |
| | | <view class="w25"> |
| | | <image style="width: 108rpx;height: 108rpx;" src="/static/imgs/quanshou/S81.png"></image> |
| | | <view style="text-align: center ;color: #121212;font-size: 20rpx;">优酷</view> |
| | | </view> |
| | | <view class="w25"> |
| | | <image style="width: 108rpx;height: 108rpx;" src="/static/imgs/quanshou/S82.png"></image> |
| | | <view style="text-align: center ;color: #121212;font-size: 20rpx;">腾讯视频</view> |
| | | </view> |
| | | <view class="w25"> |
| | | <image style="width: 108rpx;height: 108rpx;" src="/static/imgs/quanshou/S83.png"></image> |
| | | <view style="text-align: center ;color: #121212;font-size: 20rpx;">搜狐视频</view> |
| | | </view> |
| | | <view class="w25"> |
| | | <image style="width: 108rpx;height: 108rpx;" src="/static/imgs/quanshou/S84.png"></image> |
| | | <view style="text-align: center ;color: #121212;font-size: 20rpx;">芒果TV</view> |
| | | </view> |
| | | <view class="w25"> |
| | | <image style="width: 108rpx;height: 108rpx;" src="/static/imgs/quanshou/S85.png"></image> |
| | | <view style="text-align: center ;color: #121212;font-size: 20rpx;">爱奇艺</view> |
| | | </view> |
| | | <view class="w25"> |
| | | <image style="width: 108rpx;height: 108rpx;" src="/static/imgs/quanshou/S86.png"></image> |
| | | <view style="text-align: center ;color: #121212;font-size: 20rpx;">Bilibili</view> |
| | | </view> |
| | | <view class="w25"> |
| | | <image style="width: 108rpx;height: 108rpx;" src="/static/imgs/quanshou/S87.png"></image> |
| | | <view style="text-align: center ;color: #121212;font-size: 20rpx;">斗鱼直播</view> |
| | | </view> |
| | | <view class="w25"> |
| | | <image style="width: 108rpx;height: 108rpx;" src="/static/imgs/quanshou/S89.png"></image> |
| | | <view style="text-align: center ;color: #121212;font-size: 20rpx;">虎牙直播</view> |
| | | </view> |
| | | </view> |
| | | </view> |
| | | <view style="height: 10rpx;background: #F7F7F7;"></view> |
| | | <view style="padding: 40rpx;padding-bottom: 20rpx;"> |
| | | <view style="text-align: center;color: #333333;font-size: 32rpx;font-weight: 600;margin-bottom: 34rpx;"> |
| | | <image style="width: 22rpx;height: 22rpx;margin-right: 58rpx;" src="/static/imgs/quanshou/Star.png"></image> |
| | | 外卖会员四选一 |
| | | <image style="width: 22rpx;height: 22rpx;margin-left: 58rpx;" src="/static/imgs/quanshou/Star.png"></image> |
| | | </view> |
| | | <view style="display: flex;flex-wrap: wrap"> |
| | | <view class="w25"> |
| | | <image style="width: 108rpx;height: 108rpx;" src="/static/imgs/quanshou/W41.png"></image> |
| | | <view style="text-align: center ;color: #121212;font-size: 20rpx;">美团</view> |
| | | </view> |
| | | <view class="w25"> |
| | | <image style="width: 108rpx;height: 108rpx;" src="/static/imgs/quanshou/W42.png"></image> |
| | | <view style="text-align: center ;color: #121212;font-size: 20rpx;">饿了么</view> |
| | | </view> |
| | | <view class="w25"> |
| | | <image style="width: 108rpx;height: 108rpx;" src="/static/imgs/quanshou/W43.png"></image> |
| | | <view style="text-align: center ;color: #121212;font-size: 20rpx;">京东外卖</view> |
| | | </view> |
| | | <view class="w25"> |
| | | <image style="width: 108rpx;height: 108rpx;" src="/static/imgs/quanshou/W44.png"></image> |
| | | <view style="text-align: center ;color: #121212;font-size: 20rpx;">盒马</view> |
| | | </view> |
| | | |
| | | </view> |
| | | </view> |
| | | <view style="height: 10rpx;background: #F7F7F7;"></view> |
| | | |
| | | <view style="padding: 40rpx;padding-bottom:20rpx;"> |
| | | <view style="text-align: center;color: #333333;font-size: 32rpx;font-weight: 600;margin-bottom: 34rpx;"> |
| | | <image style="width: 22rpx;height: 22rpx;margin-right: 58rpx;" src="/static/imgs/quanshou/Star.png"></image> |
| | | 生活交通代金券 |
| | | <image style="width: 22rpx;height: 22rpx;margin-left: 58rpx;" src="/static/imgs/quanshou/Star.png"></image> |
| | | </view> |
| | | <view style="display: flex;flex-wrap: wrap"> |
| | | <view class="w33"><image style="width: 200rpx;height: 148rpx;" src="/static/imgs/quanshou/SH1.png"></image></view> |
| | | <view class="w33"><image style="width: 200rpx;height: 148rpx;" src="/static/imgs/quanshou/SH2.png"></image></view> |
| | | <view class="w33"><image style="width: 200rpx;height: 148rpx;" src="/static/imgs/quanshou/SH3.png"></image></view> |
| | | <view class="w33"><image style="width: 200rpx;height: 148rpx;" src="/static/imgs/quanshou/SH4.png"></image></view> |
| | | <view class="w33"><image style="width: 200rpx;height: 148rpx;" src="/static/imgs/quanshou/SH5.png"></image></view> |
| | | <view class="w33"><image style="width: 200rpx;height: 148rpx;" src="/static/imgs/quanshou/SH6.png"></image></view> |
| | | <view class="w33" style="margin-bottom: 0;"><image style="width: 200rpx;height: 148rpx;" src="/static/imgs/quanshou/SH7.png"></image></view> |
| | | <view class="w33" style="margin-bottom: 0;"><image style="width: 200rpx;height: 148rpx;" src="/static/imgs/quanshou/SH8.png"></image></view> |
| | | <view class="w33" style="margin-bottom: 0;"><image style="width: 200rpx;height: 148rpx;" src="/static/imgs/quanshou/SH9.png"></image></view> |
| | | </view> |
| | | </view> |
| | | </view> |
| | | |
| | | |
| | | <view v-if="VIP==2"> |
| | | <view style="padding: 0 40rpx 0rpx 40rpx;"> |
| | | <view style="text-align: center;color: #333333;font-size: 32rpx;font-weight: 600;margin-bottom: 34rpx;"> |
| | | <image style="width: 22rpx;height: 22rpx;margin-right: 58rpx;" src="/static/imgs/quanshou/Star.png"></image> |
| | | 粉钻VIP特权 |
| | | <image style="width: 22rpx;height: 22rpx;margin-left: 58rpx;" src="/static/imgs/quanshou/Star.png"></image> |
| | | </view> |
| | | <view style="display: flex;justify-content: space-between;flex-wrap: wrap"> |
| | | <view class="w50"> |
| | | <view><image style="width: 100rpx;height: 100rpx;" src="/static/imgs/quanshou/FZV1.png"></image></view> |
| | | <view style="margin-left: 10rpx;display: flex;flex-direction: column;justify-content: center ;"> |
| | | <view style="font-size: 28rpx;color: #5B320D;font-weight: 600;min-height: 40rpx">优酷季卡</view> |
| | | <view style="font-size: 24rpx;color: #5B320D;">价值¥198</view> |
| | | </view> |
| | | </view> |
| | | <view class="w50"> |
| | | <view><image style="width: 100rpx;height: 100rpx;" src="/static/imgs/quanshou/FZV2.png"></image></view> |
| | | <view style="margin-left: 10rpx;display: flex;flex-direction: column;justify-content: center ;"> |
| | | <view style="font-size: 28rpx;color: #5B320D;font-weight: 600;min-height: 40rpx">爱奇艺季卡</view> |
| | | <view style="font-size: 24rpx;color: #5B320D;">价值¥88</view> |
| | | </view> |
| | | </view> |
| | | <view class="w50"> |
| | | <view><image style="width: 100rpx;height: 100rpx;" src="/static/imgs/quanshou/FZV3.png"></image></view> |
| | | <view style="margin-left: 10rpx;display: flex;flex-direction: column;justify-content: center ;"> |
| | | <view style="font-size: 28rpx;color: #5B320D;font-weight: 600;min-height: 40rpx">QQ音乐季卡</view> |
| | | <view style="font-size: 24rpx;color: #5B320D;">价值¥198</view> |
| | | </view> |
| | | </view> |
| | | <view class="w50"> |
| | | <view><image style="width: 100rpx;height: 100rpx;" src="/static/imgs/quanshou/FZV4.png"></image></view> |
| | | <view style="margin-left: 10rpx;display: flex;flex-direction: column;justify-content: center ;"> |
| | | <view style="font-size: 28rpx;color: #5B320D;font-weight: 600;min-height: 40rpx">黑胶季卡</view> |
| | | <view style="font-size: 24rpx;color: #5B320D;">价值¥145</view> |
| | | </view> |
| | | </view> |
| | | <view class="w50"> |
| | | <view><image style="width: 100rpx;height: 100rpx;" src="/static/imgs/quanshou/FZV5.png"></image></view> |
| | | <view style="margin-left: 10rpx;display: flex;flex-direction: column;justify-content: center ;"> |
| | | <view style="font-size: 28rpx;color: #5B320D;font-weight: 600;min-height: 40rpx">芒果TV季卡</view> |
| | | <view style="font-size: 24rpx;color: #5B320D;">价值¥99</view> |
| | | </view> |
| | | </view> |
| | | <view class="w50"> |
| | | <view><image style="width: 100rpx;height: 100rpx;" src="/static/imgs/quanshou/FZV6.png"></image></view> |
| | | <view style="margin-left: 10rpx;display: flex;flex-direction: column;justify-content: center ;"> |
| | | <view style="font-size: 28rpx;color: #5B320D;font-weight: 600;min-height: 40rpx">得到季卡</view> |
| | | <view style="font-size: 24rpx;color: #5B320D;">价值¥1168</view> |
| | | </view> |
| | | </view> |
| | | </view> |
| | | </view> |
| | | <view style="height: 10rpx;background: #F7F7F7;"></view> |
| | | <view style="padding: 40rpx;padding-bottom: 20rpx;"> |
| | | <view style="text-align: center;color: #333333;font-size: 32rpx;font-weight: 600;margin-bottom: 34rpx;"> |
| | | <image style="width: 22rpx;height: 22rpx;margin-right: 58rpx;" src="/static/imgs/quanshou/Star.png"></image> |
| | | 红包免费领 |
| | | <image style="width: 22rpx;height: 22rpx;margin-left: 58rpx;" src="/static/imgs/quanshou/Star.png"></image> |
| | | </view> |
| | | <view style="display: flex;flex-wrap: wrap"> |
| | | <view class="w33" style="margin-bottom: 20rpx;"><image style="width: 208rpx;height: 178rpx;" src="/static/imgs/quanshou/KB1.png"></image></view> |
| | | <view class="w33" style="margin-bottom: 20rpx;"><image style="width: 208rpx;height: 178rpx;" src="/static/imgs/quanshou/KB2.png"></image></view> |
| | | <view class="w33" style="margin-bottom: 20rpx;"><image style="width: 208rpx;height: 178rpx;" src="/static/imgs/quanshou/KB3.png"></image></view> |
| | | <view class="w33" style="margin-bottom: 20rpx;"><image style="width: 208rpx;height: 178rpx;" src="/static/imgs/quanshou/KB4.png"></image></view> |
| | | <view class="w33" style="margin-bottom: 20rpx;"><image style="width: 208rpx;height: 178rpx;" src="/static/imgs/quanshou/KB5.png"></image></view> |
| | | <view class="w33" style="margin-bottom: 20rpx;"><image style="width: 208rpx;height: 178rpx;" src="/static/imgs/quanshou/KB6.png"></image></view> |
| | | </view> |
| | | </view> |
| | | <view style="height: 10rpx;background: #F7F7F7;"></view> |
| | | |
| | | <view style="padding: 40rpx;padding-bottom: 0rpx;"> |
| | | <view style="text-align: center;color: #333333;font-size: 32rpx;font-weight: 600;margin-bottom: 34rpx;"> |
| | | <image style="width: 22rpx;height: 22rpx;margin-right: 58rpx;" src="/static/imgs/quanshou/Star.png"></image> |
| | | 专属特惠 |
| | | <image style="width: 22rpx;height: 22rpx;margin-left: 58rpx;" src="/static/imgs/quanshou/Star.png"></image> |
| | | </view> |
| | | <view style="display: flex;flex-wrap: wrap"> |
| | | <view class="w100" style="margin-bottom: 20rpx;"><image style="width: 100%;height: 170rpx;" src="/static/imgs/quanshou/ZC1.png"></image></view> |
| | | <view class="w100" style="margin-bottom: 20rpx;"><image style="width: 100%;height: 170rpx;" src="/static/imgs/quanshou/ZC2.png"></image></view> |
| | | <view class="w100" style="margin-bottom: 0rpx;"><image style="width: 100%;height: 170rpx;" src="/static/imgs/quanshou/ZC3.png"></image></view> |
| | | |
| | | </view> |
| | | </view> |
| | | |
| | | </view> |
| | | |
| | | |
| | | |
| | | |
| | | </view> |
| | | </template> |
| | | |
| | | <style scoped lang="scss"> |
| | | .w25 { |
| | | width: 20%; |
| | | text-align: center; |
| | | margin-bottom: 24rpx; |
| | | } |
| | | .w33{ |
| | | width: 33%; |
| | | text-align: center; |
| | | margin-bottom: 15rpx; |
| | | } |
| | | .w50{ |
| | | width: calc(50% - 20rpx); |
| | | background: #FFEAF9;border-radius: 24rpx; |
| | | padding: 20rpx; |
| | | display: flex; |
| | | margin-bottom: 20rpx; |
| | | } |
| | | .w100{ |
| | | width: 100%; |
| | | } |
| | | |
| | | </style> |
| | |
| | | <template> |
| | | <view> |
| | | <view style="margin-bottom: 20rpx;"> |
| | | <image style="width: 22rpx;height: 22rpx;" src="/static/imgs/quanshou/Star.png"></image> |
| | | <image style="width: 22rpx;height: 22rpx;" src="/static/img/quanshou/Star.png"></image> |
| | | <text style="font-weight: 600;font-size: 32rpx;color: #333333;margin-left: 10rpx;">限量好券</text> |
| | | <text style="font-size: 28rpx;color: #666666;margin-left: 20rpx;">大额立减,省钱利器</text> |
| | | </view> |
| | | |
| | | <view style="display: flex;flex-wrap: wrap;justify-content: space-between"> |
| | | <view style="width: calc( 50% - 9rpx)"><image src="/static/imgs/quanshou/H1.png" style="width: 100%;height: 270rpx;margin-bottom: 10rpx;"></image></view> |
| | | <view style="width: calc( 50% - 9rpx)"><image src="/static/imgs/quanshou/H2.png" style="width: 100%;height: 270rpx;margin-bottom: 10rpx;"></image></view> |
| | | <view style="width: calc( 50% - 9rpx)"><image src="/static/imgs/quanshou/H3.png" style="width: 100%;height: 270rpx;margin-bottom: 10rpx;"></image></view> |
| | | <view style="width: calc( 50% - 9rpx)"><image src="/static/imgs/quanshou/H4.png" style="width: 100%;height: 270rpx;margin-bottom: 10rpx;"></image></view> |
| | | <view style="width: calc( 50% - 9rpx)"><image src="/static/imgs/quanshou/H5.png" style="width: 100%;height: 270rpx;margin-bottom: 10rpx;"></image></view> |
| | | <view style="width: calc( 50% - 9rpx)"><image src="/static/imgs/quanshou/H6.png" style="width: 100%;height: 270rpx;margin-bottom: 10rpx;"></image></view> |
| | | <view style="width: calc( 50% - 9rpx)"><image src="/static/img/quanshou/H1.png" style="width: 100%;height: 270rpx;margin-bottom: 10rpx;"></image></view> |
| | | <view style="width: calc( 50% - 9rpx)"><image src="/static/img/quanshou/H2.png" style="width: 100%;height: 270rpx;margin-bottom: 10rpx;"></image></view> |
| | | <view style="width: calc( 50% - 9rpx)"><image src="/static/img/quanshou/H3.png" style="width: 100%;height: 270rpx;margin-bottom: 10rpx;"></image></view> |
| | | <view style="width: calc( 50% - 9rpx)"><image src="/static/img/quanshou/H4.png" style="width: 100%;height: 270rpx;margin-bottom: 10rpx;"></image></view> |
| | | <view style="width: calc( 50% - 9rpx)"><image src="/static/img/quanshou/H5.png" style="width: 100%;height: 270rpx;margin-bottom: 10rpx;"></image></view> |
| | | <view style="width: calc( 50% - 9rpx)"><image src="/static/img/quanshou/H6.png" style="width: 100%;height: 270rpx;margin-bottom: 10rpx;"></image></view> |
| | | |
| | | </view> |
| | | |
| | |
| | | <script> |
| | | |
| | | import tehuichongzhi from "@/pages/quanshou/components/tehuichongzhi.vue"; //虚拟 |
| | | import lanyaerji from "@/pages/quanshou/components/lanyaerji.vue"; // 实物 |
| | | |
| | | export default { |
| | | name: "index", |
| | | components: { |
| | | tehuichongzhi, |
| | | lanyaerji, |
| | | }, |
| | | data() { |
| | | return { |
| | | tips:'', |
| | | active: 0, |
| | | VIP: 1, // 1黄金 2铂金 3黑金 |
| | | VIP: 2, // 1黄金 2铂金 3黑金 |
| | | lst:[], |
| | | vipConfig: { |
| | | 1: { |
| | | bg: "/static/imgs/quanshou/TBBG1.png", |
| | | box: "/static/imgs/quanshou/NEWBOX1.png", |
| | | title: "/static/imgs/quanshou/VIPTXT1.png", |
| | | level: "/static/imgs/quanshou/VIP1.png", |
| | | bg: "/static/img/quanshou/TBBG1.png", |
| | | box: "/static/img/quanshou/VIPBOX1.png", |
| | | title: "/static/img/quanshou/VIPTXT1.png", |
| | | level: "/static/img/quanshou/VIPLVL1.png", |
| | | textClass: "vip1-text", |
| | | progressBg: "#BBA767", |
| | | growText: " 88800/100000", |
| | | benefitText: "297.00" |
| | | }, |
| | | 2: { |
| | | bg: "/static/imgs/quanshou/TBBG2.png", |
| | | box: "/static/imgs/quanshou/NEWBOX2.png", |
| | | title: "/static/imgs/quanshou/VIPTXT2.png", |
| | | level: "/static/imgs/quanshou/VIP2.png", |
| | | bg: "/static/img/quanshou/TBBG2.png", |
| | | box: "/static/img/quanshou/VIPBOX2.png", |
| | | title: "/static/img/quanshou/VIPTXT2.png", |
| | | level: "/static/img/quanshou/VIPLVL2.png", |
| | | textClass: "vip2-text", |
| | | progressBg: "#8094A6", |
| | | growText: " 88800/100000", |
| | | benefitText: "594.00" |
| | | }, |
| | | 3: { |
| | | bg: "/static/imgs/quanshou/TBBG3.png", |
| | | box: "/static/imgs/quanshou/VIPBOX3.png", |
| | | title: "/static/imgs/quanshou/VIPTXT3.png", |
| | | level: "/static/imgs/quanshou/VIPLVL3.png", |
| | | bg: "/static/img/quanshou/TBBG3.png", |
| | | box: "/static/img/quanshou/VIPBOX3.png", |
| | | title: "/static/img/quanshou/VIPTXT3.png", |
| | | level: "/static/img/quanshou/VIPLVL3.png", |
| | | textClass: "vip3-text", |
| | | progressBg: "#7B776E", |
| | | growText: " 88800/100000", |
| | |
| | | } |
| | | }, |
| | | total: 0, |
| | | isAgree: 0, |
| | | }; |
| | | }, |
| | | computed: { |
| | |
| | | onLoad(pro) { |
| | | |
| | | const _this = this; |
| | | this.isAgree = uni.getStorageSync('boughtEquity') |
| | | uni.request({ |
| | | url: _this.$webHost+'/api/v2/customer/getRyxBenefitsRecordList?phone='+_this.$util.getUserInfo().phone, |
| | | data:{ |
| | | customerId: uni.getStorageSync('qxgLogin').customerId, |
| | | appId: uni.getStorageSync('qxgLogin').appId |
| | | }, |
| | | url: _this.$webHost+'/api/v2/customer/getRyxBenefitsRecordList?phone='+uni.getStorageSync('phone')+'&appId='+'47be9559-6b1b-42dd-84ed-25d028065013', |
| | | success: function (res) { |
| | | if(res.data.code==200){ |
| | | _this.lst = res.data.data; |
| | |
| | | _this.total += parseFloat(item.amount); |
| | | } |
| | | }) |
| | | console.log('_this.lst',_this.lst) |
| | | _this.total = Intl.NumberFormat('zh-CN', { |
| | | minimumFractionDigits: 2, |
| | | maximumFractionDigits: 2, |
| | |
| | | }) |
| | | }, |
| | | methods: { |
| | | goHome(){ |
| | | uni.switchTab({ |
| | | url: '/pages/index/index' |
| | | }); |
| | | // uni.navigateBack() |
| | | }, |
| | | numbs(period) { |
| | | const obj ={ |
| | | 1:'一', |
| | |
| | | toHuiyuan(){ |
| | | const _this = this; |
| | | uni.request({ |
| | | url: _this.$webHost+'/api/v2/memberEquity/getUrlByShop/'+_this.$util.getUserInfo().phone, |
| | | data:{ |
| | | customerId: uni.getStorageSync('qxgLogin').customerId, |
| | | appId: uni.getStorageSync('qxgLogin').appId |
| | | }, |
| | | url: _this.$webHost+'/api/v2/memberEquity/getUrlByShop/'+uni.getStorageSync('phone'), |
| | | success: function (res) { |
| | | if(res.data.code==200){ |
| | | uni.request( { |
| | | url: _this.$webHost+'/api/v2/memberEquity/clickUrlByShop/'+_this.$util.getUserInfo().phone, |
| | | url: _this.$webHost+'/api/v2/memberEquity/clickUrlByShop/'+uni.getStorageSync('phone'), |
| | | }) |
| | | uni.navigateTo( { |
| | | url: '/pages/web/index?webUel=' + encodeURIComponent(res.data.data.url) |
| | | url: '/pages/users/web_page/index?webUel=' + encodeURIComponent(res.data.data.url) |
| | | }) |
| | | } else { |
| | | uni.showToast( { |
| | | title: res.data.data || res.data.msg, |
| | | icon: 'none' |
| | | }) |
| | | _this.tips = res.data.data || res.data.msg; |
| | | _this.$refs.life.open() |
| | | // uni.showToast( { |
| | | // title: res.data.data || res.data.msg, |
| | | // icon: 'none' |
| | | // }) |
| | | } |
| | | } |
| | | }) |
| | |
| | | getTips(){ |
| | | const _this = this; |
| | | uni.request({ |
| | | url: _this.$webHost+'/api/v2/shop/findExpressNo?phone='+_this.$util.getUserInfo().phone, |
| | | data:{ |
| | | customerId: uni.getStorageSync('qxgLogin').customerId, |
| | | appId: uni.getStorageSync('qxgLogin').appId |
| | | }, |
| | | url: _this.$webHost+'/api/v2/shop/findExpressNo?phone='+uni.getStorageSync('phone'), |
| | | success: function (res) { |
| | | if(res.data.code==200){ |
| | | _this.tips = res.data.data; |
| | |
| | | </script> |
| | | |
| | | <template> |
| | | <view style="background: white;"> |
| | | <view style="background: url('/static/img/qsBg.png') no-repeat top center; background-size: 100%;background-color: #210E0E;height: 100%;"> |
| | | <!-- 顶部 VIP 卡片 --> |
| | | <view class="vip-box" :style="{ backgroundImage: `url(${currentVip.box})` }" > |
| | | <view style="position: relative"> |
| | | <image :src="currentVip.level" style="height: 200rpx;width: 100%;"></image> |
| | | <view style="position: absolute;top: 120rpx;left: 48rpx;color: #754200;font-size: 28rpx;" :class="VIP==1?'vip1-num':'vip2-num'">已购会员{{ total }}</view> |
| | | <!-- <view--> |
| | | <!-- class="vip-bg"--> |
| | | <!-- :style="{ backgroundImage: `url(${currentVip.bg})` }"--> |
| | | <!-- >--> |
| | | <!-- <view--> |
| | | <!-- class="vip-box"--> |
| | | <!-- :style="{ backgroundImage: `url(${currentVip.box})` }"--> |
| | | <!-- >--> |
| | | <!-- <view>--> |
| | | <!-- <image :src="currentVip.title" style="width: 160rpx;height: 45rpx;" />--> |
| | | <!-- </view>--> |
| | | |
| | | <!-- <view class="gradient-text big-text" :class="currentVip.textClass">--> |
| | | <!-- 成长值 {{ currentVip.growText }}--> |
| | | <!-- </view>--> |
| | | |
| | | <!-- <view--> |
| | | <!-- class="progress-bar"--> |
| | | <!-- :style="{ background: currentVip.progressBg }"--> |
| | | <!-- >--> |
| | | <!-- <view class="progress-inner" v-if="VIP==1" style="width: 29.7%"/>--> |
| | | <!-- <view class="progress-inner" v-if="VIP==2" style="width: 59.4%"/>--> |
| | | <!-- <view class="progress-inner" v-if="VIP==3" style="width: 89.1%"/>--> |
| | | <!-- </view>--> |
| | | |
| | | <!-- <view class="gradient-text small-text" :class="currentVip.textClass">--> |
| | | <!-- 已购会员{{ total }}--> |
| | | <!-- </view>--> |
| | | |
| | | <!-- <image--> |
| | | <!-- :src="currentVip.level"--> |
| | | <!-- style="width: 210rpx;height: 210rpx;position: absolute;top: -70rpx;right: 0;"--> |
| | | <!-- />--> |
| | | <!-- </view>--> |
| | | <!-- </view>--> |
| | | <!-- 新版 --> |
| | | <view style="padding: 0 30rpx;"> |
| | | <!-- 返回 --> |
| | | <view class="head" style="position: relative;height: 90rpx;"> |
| | | <view style="display: flex;justify-content: flex-start;position: absolute;left: 0;top: 30rpx;z-index: 9;color: #FFFFFF;"> |
| | | <view @tap="goHome" id="home" class="home acea-row row-center-wrapper iconfont icon-fanhui2 h5_back" style="background: url('/static/img/back.png') no-repeat top center; background-size: 100%;width: 40rpx;height: 40rpx;"> |
| | | <!-- <view @tap="goHome" id="home" class="home acea-row row-center-wrapper iconfont icon-fanhui2 h5_back icon-shouye4" :style="{ height: '80rpx',lineHeight: '80rpx'}" >--> |
| | | </view> |
| | | <view class="card-wrap" style="margin-top: 38rpx;"> |
| | | <view class="card-item" v-for="i in lst" :class="i.isBuy?'card-item-buy':''"> |
| | | <!-- <view class="card-title">{{numbs(i.period)}}期会员</view>--> |
| | | <view class="card-title">{{i.buyDate}}</view> |
| | | <view class="card-price"> |
| | | <text>¥</text> |
| | | <text class="card-num" >{{ i.amount }}</text> |
| | | </view> |
| | | <view class="card-date" style="height: 40rpx"> </view> |
| | | <!-- <view class="card-date">{{ i.buyDate }}</view>--> |
| | | <view class="has-buy">{{ i.isBuy?'已扣款' : '待扣款' }}</view> |
| | | </view> |
| | | <!-- 尊享会员年卡 --> |
| | | <view style="background: url('/static/img/qyBg2.png') no-repeat top center; background-size: 100%;width: 100%;height: 300rpx;padding: 40rpx;margin-top: 230rpx;"> |
| | | <view style="font-size: 44rpx;font-weight: bold;background: -webkit-linear-gradient(#FFEEE7, #F4936F);-webkit-background-clip: text;-webkit-text-fill-color: transparent;">尊享会员年卡</view> |
| | | <view style="font-size: 28rpx;font-weight: 400;background: -webkit-linear-gradient(#FFEEE7, #F4936F);-webkit-background-clip: text;-webkit-text-fill-color: transparent;">会员预计最高节省1359.27元</view> |
| | | <view style="display: flex;margin-top: 30rpx;align-items: self-end;"> |
| | | <view v-if="lst.length" style="font-size: 24rpx;width: 70%;"> |
| | | <p style="background: -webkit-linear-gradient(#FFEEE7, #F4936F);-webkit-background-clip: text;-webkit-text-fill-color: transparent;font-size: 36rpx;">¥{{lst[0].amount.toFixed(2)}} <span style="font-size: 24rpx;">{{lst[0].isBuy?'已扣款' : '待扣款'}}</span></p> |
| | | <p style="background: -webkit-linear-gradient(#FFEEE7, #F4936F);-webkit-background-clip: text;-webkit-text-fill-color: transparent;">{{lst[0].buyDate}}</p> |
| | | </view> |
| | | <view style="width: 164rpx;height: 58rpx;text-align: center;line-height: 58rpx;background-color: #FFEEE7;border-radius: 18rpx;margin-top: 40rpx;display: flex;justify-content: center;align-items: center;"> |
| | | <!-- <checkbox-group activeColor="#fff" @change='isAgree=!isAgree' style="">--> |
| | | <!-- <checkbox disabled :checked="isAgree ? true : false" iconColor="#794007" iconSize="30" size="38" :name="1" shape="circle">{{isAgree?'已开通':'未开通'}}--> |
| | | <!-- </checkbox>--> |
| | | <!-- </checkbox-group>--> |
| | | <checkbox-group activeColor="#fff" @change='isAgree=!isAgree' style=""> |
| | | <checkbox disabled checked="true" iconColor="#794007" iconSize="30" size="38" :name="1" shape="circle">{{isAgree?'已开通':'已开通'}} |
| | | </checkbox> |
| | | </checkbox-group> |
| | | <!-- <view style="color: #210E0E;font-size: 24rpx;"></view> --> |
| | | </view> |
| | | </view> |
| | | </view> |
| | | <!-- 专享会员生活权益 --> |
| | | <view> |
| | | <view class="content-title" style="text-align: center;display: flex;align-items: center;justify-content: center;margin-top: 50rpx;margin-bottom: 40rpx;"> |
| | | <image style="width: 111rpx;height: 8rpx;" src="/static/img/qsLeft.png"></image> |
| | | <view style="font-size: 36rpx;color: #FFEEE7;margin: 0 20rpx;">专享会员生活权益</view> |
| | | <image style="width: 111rpx;height: 8rpx;" src="/static/img/qsRight.png"></image> |
| | | </view> |
| | | <view class="life" style="background: url('/static/img/qsLife.png') no-repeat top center; background-size: 100%;width: 100%;height: 1506rpx;"> |
| | | |
| | | </view> |
| | | <view style="width: 690rpx;margin-top: 40rpx;text-align: center;"> |
| | | <button @click="toHuiyuan" style="height: 100rpx;padding: 10rpx 0;color: #370606;border-radius: 50rpx;font-size: 34rpx;background-image: linear-gradient(to right, #FFEAE2, #FF6F55);">兑换生活权益</button> |
| | | <view style="color: #FFFFFF;font-size: 24rpx;padding-top: 20rpx;padding-bottom: 10rpx;">以上权益仅为预览展示,实际以兑换页面为准</view> |
| | | </view> |
| | | <view class="content-title" style="text-align: center;display: flex;align-items: center;justify-content: center;margin-top: 50rpx;margin-bottom: 40rpx;"> |
| | | <image style="width: 111rpx;height: 8rpx;" src="/static/img/qsLeft.png"></image> |
| | | <view style="font-size: 36rpx;color: #FFEEE7;margin: 0 20rpx;">专享会员实物权益</view> |
| | | <image style="width: 111rpx;height: 8rpx;" src="/static/img/qsRight.png"></image> |
| | | </view> |
| | | <view class="physical" style="background: url('/static/img/qsPhysical.png') no-repeat top center; background-size: 100%;width: 100%;height: 1580rpx;"> |
| | | |
| | | </view> |
| | | <view style="width: 690rpx;margin-top: 40rpx;text-align: center;"> |
| | | <button @click="getTips" style="height: 100rpx;padding: 10rpx 0;color: #370606;border-radius: 50rpx;font-size: 34rpx;background-image: linear-gradient(to right, #FFEAE2, #FF6F55);">查询实物权益</button> |
| | | <view style="color: #FFFFFF;font-size: 24rpx;padding-top: 20rpx;padding-bottom: 40rpx;">以上权益仅为预览展示,实际以商城发出为准</view> |
| | | </view> |
| | | </view> |
| | | </view> |
| | | |
| | | <!-- 会员购买 + 权益部分 --> |
| | | <view class="content-wrap"> |
| | | <!-- <view class="content-wrap">--> |
| | | <!-- <view class="card-wrap">--> |
| | | <!-- <view class="card-item" v-for="i in lst">--> |
| | | <!-- <view class="card-title">{{numbs(i.period)}}期会员</view>--> |
| | | <!-- <view class="card-price">--> |
| | | <!-- <text>¥</text>--> |
| | | <!-- <text class="card-num">{{ i.amount }}</text>--> |
| | | <!-- <text>/{{i.dateType}}</text>--> |
| | | <!-- </view>--> |
| | | <!-- <view class="card-date">{{ i.buyDate }}</view>--> |
| | | <!-- <view class="has-buy">{{ i.isBuy?'已扣款' : '待扣款' }}</view>--> |
| | | <!-- </view>--> |
| | | <!-- </view>--> |
| | | |
| | | <!-- <view class="tab-wrap">--> |
| | | <!-- <text @click="active=0" :class="active==0?'active':''">实物权益</text>--> |
| | | <!-- <text @click="active=1" :class="active==1?'active':''">虚拟权益</text>--> |
| | | <!-- </view>--> |
| | | |
| | | <view class="tab-wrap"> |
| | | <text @click="active=0" :class="active==0?'active':''">实物权益</text> |
| | | <text @click="active=1" :class="active==1?'active':''">虚拟权益</text> |
| | | </view> |
| | | <!-- <view class="note" style="margin-bottom: 20rpx;" v-if="active==0">页面展示为实物样例,实际以用户收到的商品为准</view>--> |
| | | |
| | | <view class="note" style="margin-bottom: 20rpx;text-align: center" v-if="active==0">页面展示为实物样例,实际以用户收到的商品为准</view> |
| | | <!-- <lanyaerji v-if="active==0" />--> |
| | | |
| | | <lanyaerji v-if="active==0" style="margin:0 30rpx;"/> |
| | | <!-- <template v-else>--> |
| | | <!-- <xianlianghaojjuab v-show="VIP==1" />--> |
| | | <!-- <tehuichongzhi v-show="VIP==1" style="margin-top: 50rpx;" />--> |
| | | <!-- <list v-show="VIP==2" style="margin-top: 10rpx;" />--> |
| | | <!-- <heijing v-show="VIP==3" style="margin-top: 10rpx;" />--> |
| | | <!-- </template>--> |
| | | |
| | | <tehuichongzhi v-else :VIP="VIP" style="margin-top: 50rpx;" /> |
| | | |
| | | <view style="text-align: center;margin: 30rpx;"> |
| | | <button class="exchange-btn" v-if="active==0" @click="getTips">我要查物流</button> |
| | | <button class="exchange-btn" v-else @click="toHuiyuan">我要兑换</button> |
| | | <view class="note" v-if="active==0">* 页面为实物样例,实际用户收到的商品为准</view> |
| | | <view class="note" v-else>* 页面为虚拟权益预览,实际用户以当日兑换内容为准</view> |
| | | </view> |
| | | </view> |
| | | <!-- <view style="margin-top: 30rpx;text-align: center">--> |
| | | <!-- <button class="exchange-btn" v-if="active==0" @click="getTips">查询物流单号</button>--> |
| | | <!-- <button class="exchange-btn" v-else @click="toHuiyuan">兑换我的虚拟权益</button>--> |
| | | <!-- <view class="note" v-if="active==0"></view>--> |
| | | <!-- <view class="note" v-else>* 虚拟权益以实际兑换为准</view>--> |
| | | <!-- </view>--> |
| | | <!-- </view>--> |
| | | |
| | | |
| | | <uni-popup type="center" ref="comment" > |
| | | <view style="background-image: url('/static/imgs/BOXSDF.png');border-radius: 48rpx;padding: 28rpx ;width: 650rpx;background-repeat: no-repeat;background-size: 100% 100%"> |
| | | <view style="border-radius: 48rpx;padding: 28rpx 0;width: 538rpx;background: #FFFFFF;padding-top: 0;"> |
| | | <view style="background-image: linear-gradient(to bottom, #FFB8B8, #FFFBFC);width: 100%;height: 200rpx;border-radius: 48rpx;"> |
| | | <view style="text-align: center;padding-top: 30rpx;" > |
| | | <image src="/static/imgs/yifa.png" style="width:372rpx;height: 240rpx;"></image> |
| | | <image src="/static/img/yifa.png" style="width: 370rpx;height: 274rpx;"></image> |
| | | </view> |
| | | <view style="font-size: 32rpx;font-weight: 600;color: #333333;text-align: center;margin-top: 34rpx;margin-bottom: 80rpx;padding: 0 28rpx;"> |
| | | </view> |
| | | <view style="font-size: 32rpx;font-weight: 600;color: #333333;text-align: center;margin-top: 134rpx;margin-bottom: 80rpx;padding: 0 28rpx;"> |
| | | <view>{{ tips }}</view> |
| | | </view> |
| | | <view @click="$refs.comment.close()" style="font-weight: 500;font-size: 32rpx;color: #fff;text-align: center;padding: 24rpx 28rpx;border-top: 2rpx solid #EEEEEE;background: #FF1472;border-radius: 40rpx ;">好的</view> |
| | | <view @click="$refs.comment.close()" style="font-weight: 500;font-size: 32rpx;color: #ffffff;text-align: center;padding: 24rpx 28rpx;border-top: 2rpx solid #EEEEEE;background-color: #EE2626;margin-left: 30rpx;margin-right: 30rpx;border-radius: 56rpx">好的</view> |
| | | </view> |
| | | </uni-popup> |
| | | |
| | | <uni-popup type="center" ref="life" > |
| | | <view style="border-radius: 48rpx;padding: 28rpx 0;width: 538rpx;background: #FFFFFF;padding-top: 0;"> |
| | | <view style="background-image: linear-gradient(to bottom, #FFB8B8, #FFFBFC);width: 100%;height: 200rpx;border-radius: 48rpx;"> |
| | | <view style="text-align: center;padding-top: 30rpx;"> |
| | | <image src="/static/img/qsLifeIcon.png" style="width: 370rpx;height: 238rpx;"></image> |
| | | </view> |
| | | </view> |
| | | <view style="font-size: 32rpx;font-weight: 600;color: #333333;text-align: center;margin-top: 134rpx;margin-bottom: 80rpx;padding: 0 28rpx;"> |
| | | <view>{{ tips }}</view> |
| | | </view> |
| | | <view @click="$refs.life.close()" style="font-weight: 500;font-size: 32rpx;color: #ffffff;text-align: center;padding: 24rpx 28rpx;border-top: 2rpx solid #EEEEEE;background-color: #EE2626;margin-left: 30rpx;margin-right: 30rpx;border-radius: 56rpx">好的</view> |
| | | </view> |
| | | </uni-popup> |
| | | </view> |
| | | </template> |
| | | |
| | | <style scoped lang="scss"> |
| | | |
| | | /* 顶部 VIP 样式 */ |
| | | .vip-bg { |
| | | background-size: 100%; |
| | |
| | | padding-bottom: 150rpx; |
| | | } |
| | | .vip-box { |
| | | background-repeat: no-repeat;padding:20rpx 30rpx 60rpx 30rpx; |
| | | background-repeat: no-repeat; |
| | | background-size: 100% 100%; |
| | | height: 280rpx; |
| | | margin: 0 30rpx; |
| | | padding: 35rpx; |
| | | position: relative; |
| | | } |
| | | .gradient-text { |
| | | -webkit-background-clip: text; |
| | |
| | | |
| | | /* 内容区 */ |
| | | .content-wrap { |
| | | padding: 30rpx 0; |
| | | background: #fff; |
| | | border-radius: 50rpx 50rpx 0 0; |
| | | padding: 30rpx; |
| | | background: #F4F4F4; |
| | | border-radius: 24rpx 24rpx 0 0; |
| | | position: relative; |
| | | top: -60rpx; |
| | | top: -100rpx; |
| | | } |
| | | .card-wrap { |
| | | display: flex; |
| | |
| | | margin-bottom: 40rpx; |
| | | } |
| | | .card-item { |
| | | background: #f5f5f5; |
| | | background: #fff; |
| | | border-radius: 24rpx; |
| | | padding-top: 60rpx; |
| | | text-align: center; |
| | | //width: calc(50% - 14rpx); |
| | | width: 100%; |
| | | padding-bottom: 48rpx; |
| | | width: calc(50% - 15rpx); |
| | | position: relative; |
| | | } |
| | | .card-title { |
| | |
| | | margin: 0 8rpx; |
| | | } |
| | | .card-date { |
| | | font-size: 24rpx; |
| | | margin-top: 28rpx; |
| | | border-radius: 0rpx 0rpx 24rpx 24rpx; |
| | | background: #fff; |
| | | //background: #EAEAEA; |
| | | color: #666666; |
| | | padding: 16rpx 0; |
| | | font-size: 20rpx; |
| | | color: #666; |
| | | margin-top: 18rpx; |
| | | } |
| | | .has-buy { |
| | | background: #FF922C; |
| | | border-radius: 8rpx; |
| | | border-radius: 0 24rpx 0 24rpx; |
| | | height: 42rpx; |
| | | width: 92rpx; |
| | | font-size: 24rpx; |
| | | color: #fff; |
| | | position: absolute; |
| | | top: -21rpx; |
| | | left: 28rpx; |
| | | top: 0; |
| | | right: 0; |
| | | line-height: 42rpx; |
| | | display: none; |
| | | } |
| | | .card-item-buy { |
| | | background: #fff; |
| | | } |
| | | .card-item-buy{ |
| | | .card-date{ |
| | | //background: #FF922C; |
| | | background: #fff; |
| | | color: white; |
| | | } |
| | | .has-buy{ |
| | | display: block; |
| | | } |
| | | |
| | | } |
| | | /* tab */ |
| | | .tab-wrap { |
| | | display: flex; |
| | |
| | | display: block; |
| | | width: 50rpx; |
| | | height: 8rpx; |
| | | background: linear-gradient( 91deg, #FDFAFF 0%, #F9C969 100%); |
| | | background: linear-gradient(271deg, #FFE4A1 0%, #FFC57A 51%, #FFE1B9 100%); |
| | | border-radius: 32rpx; |
| | | position: absolute; |
| | | bottom: -20rpx; |
| | |
| | | font-weight: 600; |
| | | font-size: 36rpx; |
| | | color: #FFD39A; |
| | | padding: 10rpx; |
| | | background: linear-gradient( 91deg, #A97132 0%, #542C09 100%); |
| | | padding: 26rpx; |
| | | background: linear-gradient(271deg, #2A1601 0%, #3B2106 51%); |
| | | border-radius: 200rpx; |
| | | } |
| | | .note { |
| | | font-size: 24rpx; |
| | | color: #999; |
| | | margin-top: 20rpx; |
| | | } |
| | | .vip2-num{ |
| | | color: #8E1768 !important; |
| | | } |
| | | </style> |
| | |
| | | <script> |
| | | import offIcon from '@/static/imgs/icons/off.png' |
| | | import leftIcon from '@/static/imgs/icons/left.png' |
| | | import kkIcon from '@/static/imgs/icons/kk.png' |
| | | import offIcon from '@/static/img/off.png' |
| | | import leftIcon from '@/static/img/left.png' |
| | | import kkIcon from '@/static/img/kk.png' |
| | | import addAddress from "@/pages/quanyi/components/addAddress"; |
| | | import agreement from "@/pages/quanyi/components/agreement"; |
| | | |
| | |
| | | showTextBox: false, |
| | | loginAct: false, |
| | | $webHost:'https://rbb98765.zrgy-bbg.com', |
| | | protocolChecked: [1], |
| | | protocolChecked: [0], |
| | | offIcon,leftIcon,kkIcon, |
| | | callbackData:{}, |
| | | addressDetail: { |
| | |
| | | customStyle() { |
| | | return { |
| | | height: "100rpx", |
| | | background: "#FF1472", |
| | | background: "#EE2626", |
| | | color: "#fff", |
| | | borderRadius: "24rpx", |
| | | borderRadius: "50rpx", |
| | | fontSize: "34rpx", |
| | | }; |
| | | }, |
| | |
| | | uni.request({ |
| | | url: _this.$webHost+'/api/v2/customer/getCstAddress', |
| | | data:{ |
| | | customerId: uni.getStorageSync('qxgLogin').customerId, |
| | | sourceId: uni.getStorageSync('qxgLogin').appId |
| | | customerId: uni.getStorageSync('ygxLogin').customerId, |
| | | sourceId: uni.getStorageSync('ygxLogin').appId |
| | | }, |
| | | success: function (res) { |
| | | _this.addressDetail = res.data.data; |
| | |
| | | |
| | | |
| | | uni.request({ |
| | | url: _this.$webHost+'/api/v2/xinheyuan/bank/list/fake/'+uni.getStorageSync('qxgLogin').customerId, |
| | | url: _this.$webHost+'/api/v2/xinheyuan/bank/list/fake/'+uni.getStorageSync('ygxLogin').customerId, |
| | | success(res){ |
| | | console.log(res.data.data); |
| | | this.bankList = res.data.data; |
| | |
| | | uni.setStorageSync('windowHeight',uni.getSystemInfoSync().windowHeight) |
| | | |
| | | uni.request({ |
| | | url:_this.$webHost+`/api/v2/pay/getPayBindCardInfo/${uni.getStorageSync('qxgLogin').customerId}`, |
| | | url:_this.$webHost+`/api/v2/pay/getPayBindCardInfo/${uni.getStorageSync('ygxLogin').customerId}`, |
| | | method:'get', |
| | | success:function(res){ |
| | | const dy = res.data.data[0]; |
| | |
| | | uni.request( { |
| | | url: _this.$webHost + "/api/v2/renpin/H5/getPlatformProtocolNew", |
| | | data: { |
| | | customerId: uni.getStorageSync('qxgLogin').customerId, |
| | | appId: uni.getStorageSync('qxgLogin').appId |
| | | customerId: uni.getStorageSync('ygxLogin').customerId, |
| | | appId: uni.getStorageSync('ygxLogin').appId |
| | | }, |
| | | method: 'GET', |
| | | success(res) { |
| | | uni.showLoading({}) |
| | | _this.getPlatformProtocolNewList = res.data.data; |
| | | _this.showTextBox = true; |
| | | |
| | | _this.$nextTick(() => { |
| | | if(_this.$refs.textBox){ |
| | | uni.hideLoading(); |
| | | _this.$refs.textBox.open() |
| | | } else { |
| | | setTimeout(() => { |
| | | console.log('setTimeout'); |
| | | uni.hideLoading(); |
| | | _this.$refs.textBox && _this.$refs.textBox.open() |
| | | }, 400); |
| | | } |
| | | }) |
| | | } |
| | | }) |
| | | |
| | | |
| | | }, |
| | | mounted(){ |
| | | this.windowHeight = uni.getSystemInfoSync().windowHeight; |
| | | this.interval = setInterval(() => { |
| | | let newHeight = window.innerHeight; |
| | | if (this.windowHeight !== newHeight) { |
| | | this.windowHeight = newHeight; |
| | | this.handleResize(); |
| | | } |
| | | }, 200); |
| | | }, |
| | | methods: { |
| | | kk(){ |
| | |
| | | const _this = this; |
| | | |
| | | if(this.addressStr.length < 8){ |
| | | |
| | | uni.showToast({ |
| | | title: '请输入详细地址', |
| | | icon: 'none' |
| | |
| | | |
| | | |
| | | uni.request({ |
| | | url: _this.$webHost+'/api/v2/sign/signed/'+uni.getStorageSync('qxgLogin').customerId, |
| | | url: _this.$webHost+'/api/v2/sign/signed/'+uni.getStorageSync('ygxLogin').customerId, |
| | | method:'POST', |
| | | }) |
| | | |
| | |
| | | url: _this.$webHost+'/api/v2/pay/memberPurchaseBenefitsPays', |
| | | method:'POST', |
| | | data:{ |
| | | customerId: uni.getStorageSync('qxgLogin').customerId, |
| | | customerId: uni.getStorageSync('ygxLogin').customerId, |
| | | memberPeriodConfigId: uni.getStorageSync('memberPeriodConfigInfo').id |
| | | }, |
| | | success(){ |
| | |
| | | this.$refs.popup.close() |
| | | }, |
| | | open(){ |
| | | // 通过组件定义的ref调用uni-popup方法 ,如果传入参数 ,type 属性将失效 ,仅支持 ['top','left','bottom','right','center'] |
| | | this.$refs.popup.open() |
| | | }, |
| | | |
| | | validateAndCacheCardInfo() { |
| | | const _this = this; |
| | | |
| | | |
| | | if(!_this.cardNumber.length || _this.cardNumber.length<14 ){ |
| | | return |
| | | } |
| | |
| | | } |
| | | }) |
| | | |
| | | /* uni.request({ |
| | | url: "https://ccdcapi.alipay.com/validateAndCacheCardInfo.json?_input_charset=utf-8&cardBinCheck=true", // 阿里接口 |
| | | data: { |
| | | cardNo: _this.cardNumber, |
| | | }, |
| | | success: function (res) { |
| | | console.log(res.data.validated); |
| | | if (res.data.validated) { |
| | | |
| | | for (let i of uni.getStorageSync("bankList")) { |
| | | console.log(i); |
| | | if (res.data.bank === i.bankCode) { |
| | | _this.bankCode = i.bankCode; |
| | | _this.bankName = i.bankName; |
| | | |
| | | break; |
| | | } |
| | | } |
| | | if(!_this.bankName){ |
| | | uni.showToast({ |
| | | title: "暂不支持该银行或银行卡号有误", |
| | | icon: "none", |
| | | }); |
| | | } |
| | | } |
| | | |
| | | else { |
| | | uni.showToast({ |
| | | title: "暂不支持该银行或银行卡号有误", |
| | | icon: "none", |
| | | }); |
| | | } |
| | | }, |
| | | });*/ |
| | | }, |
| | | submit() { |
| | | const _this = this; |
| | | if(!this.loginAct){uni.showToast({title: '请阅读并同意相关协议', icon: 'none'});return;} |
| | | if(!this.protocolChecked[0]){uni.showToast({title: '请阅读并同意相关协议', icon: 'none'});return;} |
| | | if(!_this.cardName){ |
| | | uni.showToast({ |
| | | title: "请填写您的姓名", |
| | | title: "请填写真实姓名", |
| | | icon: "none", |
| | | }); |
| | | return; |
| | | } |
| | | if(!_this.idCardNo){ |
| | | uni.showToast({ |
| | | title: "请填写您的身份证号", |
| | | title: "请输入身份证号", |
| | | icon: "none", |
| | | }); |
| | | return; |
| | | } |
| | | if(!_this.cardNumber){ |
| | | uni.showToast({ |
| | | title: "请填写银行卡号", |
| | | title: "请输入银行卡号", |
| | | icon: "none", |
| | | }); |
| | | return; |
| | |
| | | }); |
| | | return |
| | | } |
| | | |
| | | if(!_this.addressStr){ |
| | | uni.showToast({ |
| | | title: "请填写您的详细地址", |
| | | title: "请填写详细地址", |
| | | icon: "none", |
| | | }); |
| | | return; |
| | |
| | | |
| | | |
| | | uni.request({ |
| | | url:_this.$webHost+`/api/v2/pay/getPayBindCardInfo/${uni.getStorageSync('qxgLogin').customerId}`, |
| | | url:_this.$webHost+`/api/v2/pay/getPayBindCardInfo/${uni.getStorageSync('ygxLogin').customerId}`, |
| | | method:'get', |
| | | success:function(res){ |
| | | _this.getPayBindCardInfo = res.data.data; |
| | |
| | | data:{ |
| | | ..._this.bindCardId, |
| | | |
| | | "customerId": uni.getStorageSync('qxgLogin').customerId, |
| | | "customerId": uni.getStorageSync('ygxLogin').customerId, |
| | | "cardPhone" : _this.cardPhone, //手机号 |
| | | |
| | | "cardNumber": _this.cardNumber, //卡号 |
| | |
| | | }, |
| | | success(e){ |
| | | if(e.data.code!==200){ |
| | | _this.$util.Tips({ |
| | | title: e.data.data |
| | | // _this.$util.Tips({ |
| | | // title: e.data.data |
| | | // }); |
| | | uni.showToast({ |
| | | title: e.data.data, |
| | | icon: 'none' |
| | | }); |
| | | } |
| | | uni.request({ |
| | | url:_this.$webHost+`/api/v2/pay/getPayBindCardInfo/${uni.getStorageSync('qxgLogin').customerId}`, |
| | | url:_this.$webHost+`/api/v2/pay/getPayBindCardInfo/${uni.getStorageSync('ygxLogin').customerId}`, |
| | | method:'get', |
| | | success:function(res){ |
| | | const ls = res.data.data; |
| | |
| | | |
| | | |
| | | |
| | | if(ls.length>1 && !ls[1].bindStatus){ |
| | | if(ls.length && !ls[1].bindStatus){ |
| | | _this.$refs.codeUi.open() |
| | | _this.isCounting = false; |
| | | _this.countText = ''; |
| | | return; |
| | | } |
| | | if(ls.length>2 && !ls[2].bindStatus){ |
| | | if(ls.length && !ls[2].bindStatus){ |
| | | _this.$refs.setUi.open(); |
| | | _this.isCounting = false; |
| | | _this.countText = ''; |
| | |
| | | |
| | | |
| | | |
| | | _this.kk() |
| | | |
| | | |
| | | |
| | | } |
| | |
| | | }) |
| | | |
| | | |
| | | }, |
| | | agreeClick () { |
| | | this.loginAct = !this.loginAct |
| | | }, |
| | | getSmsCode(){ |
| | | const that = this; |
| | |
| | | return |
| | | } |
| | | |
| | | if (!/^1(3|4|5|7|8|9|6)\d{9}$/i.test(that.cardPhone)) return that.$util.Tips({ |
| | | title: '请输入正确的手机号码' |
| | | if (!/^1(3|4|5|7|8|9|6)\d{9}$/i.test(that.cardPhone)) return uni.showToast({ |
| | | title: '请输入正确的手机号码', |
| | | icon: 'none' |
| | | }); |
| | | |
| | | |
| | |
| | | url: that.$webHost+'/api/v2/xinheyuan/bankcard/save', |
| | | method:'POST', |
| | | data:{ |
| | | "customerId": uni.getStorageSync('qxgLogin').customerId, |
| | | "customerId": uni.getStorageSync('ygxLogin').customerId, |
| | | "nameReal": that.cardName, // 名字 |
| | | "cardNo":that.cardNumber, |
| | | "idCard": that.idCardNo, |
| | |
| | | url: that.$webHost+'/api/v2/pay/bindCardToCodes', |
| | | method:'POST', |
| | | data:{ |
| | | "customerId": uni.getStorageSync('qxgLogin').customerId, |
| | | "customerId": uni.getStorageSync('ygxLogin').customerId, |
| | | "cardName": that.cardName, // 名字 |
| | | "cardIdNo": that.idCardNo, |
| | | |
| | |
| | | } |
| | | const paymentMethod = this.getPayBindCardInfo[1]['paymentMethod']; |
| | | const _this = this; |
| | | const pro = uni.getStorageSync('qxgLogin') |
| | | const pro = uni.getStorageSync('ygxLogin') |
| | | pro['userName'] = _this.cardName; |
| | | uni.request({ |
| | | url: _this.$webHost+'/api/v2/pay/bindCardToCodes', |
| | |
| | | data:{ |
| | | ...callbackData, |
| | | |
| | | "customerId": uni.getStorageSync('qxgLogin').customerId, |
| | | "customerId": uni.getStorageSync('ygxLogin').customerId, |
| | | "cardPhone" : _this.cardPhone, //手机号 |
| | | |
| | | "cardNumber": _this.cardNumber, //卡号 |
| | |
| | | }, |
| | | success(dts){ |
| | | if(dts.data.code!==200){ |
| | | // _this.$util.Tips({ |
| | | // title: dts.data.data |
| | | // }); |
| | | uni.showToast({ |
| | | title: dts.data.data, |
| | | icon: 'none' |
| | | }); |
| | | return |
| | | } |
| | | |
| | | uni.request({ |
| | | url:_this.$webHost+`/api/v2/pay/getPayBindCardInfo/${uni.getStorageSync('qxgLogin').customerId}`, |
| | | url:_this.$webHost+`/api/v2/pay/getPayBindCardInfo/${uni.getStorageSync('ygxLogin').customerId}`, |
| | | method:'get', |
| | | success:function(res){ |
| | | const ls = res.data.data; |
| | |
| | | _this.countText_A = ''; |
| | | _this.$refs.codeUi.close() |
| | | _this.$refs.setUi.open() |
| | | return; |
| | | } |
| | | |
| | | if(!ls || !ls.some(item => item.bindStatus == 0)) {_this.kk();return;} |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | } |
| | | |
| | |
| | | } |
| | | const paymentMethod = this.getPayBindCardInfo[2]['paymentMethod']; |
| | | const _this = this; |
| | | const pro = uni.getStorageSync('qxgLogin') |
| | | const pro = uni.getStorageSync('ygxLogin') |
| | | pro['userName'] = _this.cardName; |
| | | uni.request({ |
| | | url: _this.$webHost+'/api/v2/pay/bindCardToCodes', |
| | |
| | | data:{ |
| | | ...callbackData, |
| | | |
| | | "customerId": uni.getStorageSync('qxgLogin').customerId, |
| | | "customerId": uni.getStorageSync('ygxLogin').customerId, |
| | | "cardPhone" : _this.cardPhone, //手机号 |
| | | |
| | | "cardNumber": _this.cardNumber, //卡号 |
| | |
| | | }, |
| | | success(dts){ |
| | | if(dts.data.code!==200){ |
| | | _this.showToast({ |
| | | title: dts.data.data |
| | | // _this.$util.Tips({ |
| | | // title: dts.data.data |
| | | // }); |
| | | uni.showToast({ |
| | | title: dts.data.data, |
| | | icon: 'none' |
| | | }); |
| | | } |
| | | |
| | | uni.request({ |
| | | url:_this.$webHost+`/api/v2/pay/getPayBindCardInfo/${uni.getStorageSync('qxgLogin').customerId}`, |
| | | url:_this.$webHost+`/api/v2/pay/getPayBindCardInfo/${uni.getStorageSync('ygxLogin').customerId}`, |
| | | method:'get', |
| | | success:function(res){ |
| | | const ls = res.data.data; |
| | |
| | | |
| | | getUserInfo() { |
| | | |
| | | |
| | | // const data = uni.getStorageSync('LOGING_DATA') |
| | | // console.log(data); |
| | | // this.$store.commit("LOGIN", { |
| | | // 'token': data.token |
| | | // }); |
| | | // this.$store.commit('UPDATE_USERINFO', { |
| | | // avatar: data.avatar, |
| | | // nickname: data.nickname, |
| | | // phone: data.phone |
| | | // }); |
| | | // this.$store.commit("SETUID", data.id) |
| | | |
| | | uni.reLaunch({ |
| | | url: '/pages/index/index' |
| | |
| | | </script> |
| | | |
| | | <template> |
| | | <view style="background: #fff;padding-bottom: 20rpx;"> |
| | | <view style="background: #F7F7F7;padding-bottom: 40rpx;"> |
| | | <view > |
| | | <view class="top">为向您提供更好的安全保障,您需要提供银行卡号以完成信息核验</view> |
| | | </view> |
| | | |
| | | <view style="background: white;height: 20rpx;"></view> |
| | | |
| | | <view class="form"> |
| | | <view class="clo" style="display: flex;background: white"> |
| | | <view class="clo"> |
| | | <view class="label"> |
| | | <text>真实姓名</text> |
| | | </view> |
| | | <view class="inp_box"> |
| | | <input maxlength="8" style="width: 400rpx;" v-model="cardName" class="inp" placeholder="请填写您的姓名" /> |
| | | <input maxlength="8" v-model="cardName" class="inp" placeholder="请填写真实姓名" /> |
| | | </view> |
| | | |
| | | </view> |
| | | <view class="clo" style="display: flex;background: white"> |
| | | <view class="clo"> |
| | | <view class="label"> |
| | | <text>身份证号</text> |
| | | </view> |
| | | <view class="inp_box"> |
| | | <input maxlength="18" style="width: 400rpx;" v-model="idCardNo" class="inp" placeholder="请填写您的身份证号" /> |
| | | <input maxlength="18" v-model="idCardNo" class="inp" placeholder="请填写身份证号" /> |
| | | </view> |
| | | |
| | | </view> |
| | | |
| | | <!-- <view style="background: #F7F7F7;height: 20rpx;"></view>--> |
| | | |
| | | |
| | | <view class="clo" style="display: flex"> |
| | | <view class="clo"> |
| | | <view class="label"> |
| | | <text>银行卡号</text> |
| | | </view> |
| | | <view class="inp_box"> |
| | | <input maxlength="30" style="width: 400rpx;" @blur="validateAndCacheCardInfo" v-model="cardNumber" class="inp" placeholder="请填写银行卡号" /> |
| | | <image @click="cardNumber=''" v-show="!bindStatus && cardNumber" :src="offIcon" style="width: 40rpx;height: 40rpx;position: absolute;right: -40rpx;top: 0;"></image> |
| | | <input maxlength="30" @blur="validateAndCacheCardInfo" v-model="cardNumber" class="inp" placeholder="请输入银行卡号" /> |
| | | <image @click="cardNumber=''" v-show="!bindStatus && cardNumber" :src="offIcon" style="width: 40rpx;height: 40rpx;position: absolute;right: 0rpx;top: 30rpx;"></image> |
| | | </view> |
| | | |
| | | </view> |
| | | <view class="clo" style="display: flex"> |
| | | <view class="clo"> |
| | | <view class="label"> |
| | | <text>所属银行</text> |
| | | </view> |
| | | <view class="inp_box" style="flex: 1;z-index: 1" > |
| | | <view :class="bankName?'':'a3'">{{bankName?bankName:'请输入所属银行'}}</view> |
| | | <view class="inp_box" style="z-index: 1" > |
| | | <view style="width: 670rpx;height: 100rpx;border: 1px solid #EEEEEE;border-radius: 20rpx;padding-left: 20rpx;line-height: 100rpx;" :class="bankName?'':'a3'">{{bankName?bankName:'请输入所属银行'}}</view> |
| | | |
| | | </view> |
| | | |
| | | </view> |
| | | <view class="clo" style="display: flex"> |
| | | <view class="clo"> |
| | | <view class="label"> |
| | | <view>手机号码</view> |
| | | <view>银行预留手机号</view> |
| | | </view> |
| | | <view class="inp_box" > |
| | | <input maxlength="11" v-model="cardPhone" class="inp" placeholder="请填写银行预留手机号" /> |
| | | <view class="inp_box" style="position: relative;"> |
| | | <input maxlength="11" v-model="cardPhone" class="inp" placeholder="请填写手机号" /> |
| | | <!-- <view class="code" style="position: absolute;top: 30rpx;right: 0;" @click="getSmsCode">--> |
| | | <!-- <text :class="isCounting?'code_k':'code_a'">{{ isCounting ? countText : '获取验证码' }}</text>--> |
| | | <!-- </view>--> |
| | | </view> |
| | | |
| | | </view> |
| | | <view class="clo" style="display: flex" v-if="!getPayBindCardInfo[0].bindStatus"> |
| | | <view class="clo" v-if="getPayBindCardInfo.length && !getPayBindCardInfo[0].bindStatus"> |
| | | <view class="label"> |
| | | <text>验证码</text> |
| | | </view> |
| | | <view class="inp_box" style="display: flex;flex: 1"> |
| | | <input maxlength="6" v-model="verificationCode" class="inp" type="number" style="width: 200rpx" placeholder="请输入验证码" /> |
| | | <view class="inp_box" style="position: relative;"> |
| | | <input maxlength="6" v-model="verificationCode" class="inp" type="number" placeholder="请填写验证码" /> |
| | | |
| | | <view class="code" style="flex: 1;text-align: right" @click="getSmsCode"> |
| | | <view class="code" style="position: absolute;top: 30rpx;right: 0;" @click="getSmsCode"> |
| | | <text :class="isCounting?'code_k':'code_a'">{{ isCounting ? countText : '获取验证码' }}</text> |
| | | </view> |
| | | </view> |
| | | |
| | | </view> |
| | | |
| | | <view class="clo" style="display: flex;margin-bottom: 20rpx;" @click="$refs.address.open()"> |
| | | <view class="clo" @click="$refs.address.open()"> |
| | | <view class="label" > |
| | | <text>收货地址</text> |
| | | </view> |
| | | <view class="inp_box"> |
| | | <view style="font-size: 28rpx;" v-if="addressStr">{{addressStr}}</view> |
| | | <view style="font-size: 28rpx;color: #BDBDBE;" v-else>请填写您的详细地址</view> |
| | | <view style="font-size: 28rpx;width: 670rpx;height: 100rpx;border: 1px solid #EEEEEE;border-radius: 20rpx;padding-left: 20rpx;line-height: 100rpx;" v-if="addressStr">{{addressStr}}</view> |
| | | <view style="font-size: 28rpx;color: #BDBDBE;width: 670rpx;height: 100rpx;border: 1px solid #EEEEEE;border-radius: 20rpx;padding-left: 20rpx;line-height: 100rpx;" v-else>请填写收货地址</view> |
| | | </view> |
| | | |
| | | </view> |
| | | |
| | | </view> |
| | | |
| | | <!-- <view class="xieyi"> |
| | | <view style="display: flex"> |
| | | <checkbox-group @change="checkboxChange"> |
| | | |
| | | <view style=" padding: 0 30rpx;margin-left: 20rpx;"> |
| | | <checkbox value="1" activeBorderColor="none" activeBackgroundColor="red" style="border-radius: 0" color="#ffffff"/> |
| | | </checkbox-group> |
| | | <view style="margin-top: 2rpx;"> <text>我已同意</text> |
| | | </view> |
| | | </view> |
| | | </view>--> |
| | | |
| | | <view style=" padding: 0 30rpx;margin-top: 30rpx;"> |
| | | <view style="display: flex;"> |
| | | <image @click="agreeClick" style="width: 50rpx;height: 50rpx;" :src="!loginAct ? '/static/imgs/check.png' : '/static/imgs/checked.png'" ></image> |
| | | <text class="protocol-text" style="line-height: 50rpx" > |
| | | 我已阅读并同意<text style="font-size: 24rpx;color: #4766FE" class="link-text" @click="$refs.agreement.open()">《相关协议》</text> |
| | | <uv-checkbox-group |
| | | activeColor="red" |
| | | shape="circle" |
| | | v-model="protocolChecked"> |
| | | <uv-checkbox size="14" :name="1" > |
| | | |
| | | </uv-checkbox> |
| | | <text class="protocol-text" > |
| | | 我已阅读并同意 |
| | | <text style="font-size: 24rpx;" class="link-text" @click="$refs.agreement.open()">《相关协议》</text> |
| | | </text> |
| | | </uv-checkbox-group> |
| | | |
| | | </view> |
| | | |
| | | </view> |
| | | <view class="sub" v-if="show"> |
| | | <button :class="loginAct?'':'nots'" class="sub_btn" @click="submit">提交</button> |
| | | <button :class="protocolChecked[0]?'':'nots'" class="sub_btn" @click="submit">提交</button> |
| | | </view> |
| | | |
| | | <agreement ref="agreement"></agreement> |
| | |
| | | |
| | | </uni-popup> |
| | | |
| | | <uv-popup mode="center" round="20" ref="codeUi" :closeOnClickOverlay="false" bgColor=""> |
| | | <uv-popup mode="center" round="20" ref="codeUi" :closeOnClickOverlay="false" > |
| | | |
| | | <view style="padding: 40rpx;width:calc( 100% - 120rpx);margin: auto;border-radius: 40rpx 40rpx 40rpx 40rpx;background-image: url('/static/imgs/codeUiBACK.png');background-repeat: no-repeat;background-size: 100% 100%;padding-top: 60rpx;"> |
| | | <view style="padding: 40rpx;width: 690rpx;background: url('/static/img/smsBg.png') no-repeat top center; background-size: 100%;height: 650rpx;"> |
| | | <view class="head"> |
| | | <view |
| | | style=" |
| | | text-align: center; |
| | | font-weight: bold; |
| | | font-size: 36rpx; |
| | | position: relative; |
| | | height: 50rpx; |
| | | " |
| | | > |
| | | |
| | | <image |
| | | @click="$refs.codeUi.close()" |
| | | src="@/static/img/off.png" |
| | | style=" |
| | | width: 50rpx; |
| | | height: 50rpx; |
| | | position: absolute; |
| | | right: 0; |
| | | top: -2rpx; |
| | | " |
| | | ></image> |
| | | </view> |
| | | </view> |
| | | <view style=" |
| | | font-weight: bold; |
| | | font-size: 36rpx; |
| | | position: relative; |
| | | margin-bottom: 12rpx; |
| | | text-align: center; |
| | | |
| | | ">短信确认</view> |
| | | <view style="font-size: 28rpx;color: #666666;">为确保安全到账,需再次对您的收款账户进行短信验证</view> |
| | | <view style="font-size: 28rpx;color: #252938;text-align: center;">为确保安全到账,需再次对您的收款账户进行短信验证</view> |
| | | |
| | | <view class="content" style="margin-top: 40rpx;"> |
| | | <view class="content"> |
| | | <uv-form |
| | | :labelStyle="lstyle" |
| | | labelPosition="left" |
| | |
| | | |
| | | > |
| | | <uv-input |
| | | shape="circle" |
| | | :adjustPosition="true" |
| | | readonly |
| | | v-model="cardPhone" |
| | |
| | | |
| | | border="none" |
| | | placeholder="请输入手机号" |
| | | style="height: 100rpx;border: 1px solid #EEEEEE;border-radius: 30rpx;padding: 0 20rpx;" |
| | | ></uv-input> |
| | | </uv-form-item> |
| | | |
| | | <view style="height: 20rpx;"></view> |
| | | |
| | | <uv-form-item |
| | | class="item" |
| | |
| | | v-model="verificationCodeT" |
| | | border="none" |
| | | placeholder="请输入验证码" |
| | | style="height: 100rpx;border: 1px solid #EEEEEE;border-radius: 30rpx;padding: 0 20rpx;" |
| | | > |
| | | <template #suffix> |
| | | <text |
| | | class="code" |
| | | style="color: red;" |
| | | :class="isCounting_A ? 'ks' : ''" |
| | | @click="getCode" |
| | | >{{ isCounting_A ? countText_A : "获取验证码" }}</text |
| | |
| | | </uv-input> |
| | | </uv-form-item> |
| | | <uv-form-item > |
| | | <view class="but" style="width: 100%;margin-top: 20rpx;font-weight: 600;"> |
| | | <view class="but" style="width: 100%;"> |
| | | <uv-button |
| | | :customStyle="customStyle" |
| | | |
| | | shape="circle" |
| | | @click="submitPlan" |
| | | >确定</uv-button |
| | | >确认</uv-button |
| | | > |
| | | </view> |
| | | </uv-form-item> |
| | | </uv-form> |
| | | </view> |
| | | </view> |
| | | <view style="text-align: center;margin-top: 40rpx;"> |
| | | </uv-popup> |
| | | <uv-popup mode="center" round="20" ref="setUi" :closeOnClickOverlay="false" > |
| | | |
| | | <view style="padding: 40rpx;width: 690rpx;background: url('/static/img/smsBg.png') no-repeat top center; background-size: 100%;height: 650rpx;"> |
| | | <view class="head"> |
| | | <view |
| | | style=" |
| | | text-align: center; |
| | | font-weight: bold; |
| | | font-size: 36rpx; |
| | | position: relative; |
| | | height: 50rpx; |
| | | " |
| | | > |
| | | |
| | | <image |
| | | @click="$refs.codeUi.close()" |
| | | src="@/static/imgs/closeA.png" |
| | | style=" width: 50rpx; height: 50rpx; " |
| | | @click="$refs.setUi.close()" |
| | | src="@/static/img/off.png" |
| | | style=" |
| | | width: 50rpx; |
| | | height: 50rpx; |
| | | position: absolute; |
| | | right: 0; |
| | | top: -2rpx; |
| | | " |
| | | ></image> |
| | | </view> |
| | | </uv-popup> |
| | | <uv-popup mode="center" round="20" ref="setUi" :closeOnClickOverlay="false" bgColor="" z-index="999"> |
| | | |
| | | <view style="padding: 40rpx;width:calc( 100% - 120rpx);margin: auto;border-radius: 40rpx 40rpx 40rpx 40rpx;background-image: url('/static/imgs/codeUiBACK.png');background-repeat: no-repeat;background-size: 100% 100%;padding-top: 60rpx;"> |
| | | |
| | | </view> |
| | | <view style=" |
| | | font-weight: bold; |
| | | font-size: 36rpx; |
| | | position: relative; |
| | | margin-bottom: 12rpx; |
| | | text-align: center; |
| | | |
| | | ">本人提交确认</view> |
| | | <view style="font-size: 28rpx;color: #666666;">根据合规要求我们将进行本人提交意愿确认的短信校验,请注意查看短信验证码</view> |
| | | <view style="font-size: 28rpx;color: #252938;text-align: center;">根据合规要求我们将进行本人提交意愿确认的短信校验,请注意查看短信验证码</view> |
| | | |
| | | <view class="content" style="margin-top: 40rpx;"> |
| | | <view class="content"> |
| | | <uv-form |
| | | :labelStyle="lstyle" |
| | | labelPosition="left" |
| | |
| | | |
| | | border="none" |
| | | placeholder="请输入手机号" |
| | | style="height: 100rpx;border: 1px solid #EEEEEE;border-radius: 30rpx;padding: 0 20rpx;" |
| | | ></uv-input> |
| | | </uv-form-item> |
| | | <view style="height: 20rpx;"></view> |
| | | |
| | | <uv-form-item |
| | | class="item" |
| | | label="" |
| | |
| | | v-model="verificationCodeS" |
| | | border="none" |
| | | placeholder="请输入验证码" |
| | | style="height: 100rpx;border: 1px solid #EEEEEE;border-radius: 30rpx;padding: 0 20rpx;" |
| | | > |
| | | <template #suffix> |
| | | <text |
| | | class="code" |
| | | style="color: red;" |
| | | :class="isCounting_B ? 'ks' : ''" |
| | | @click="getCode_san" |
| | | >{{ isCounting_B ? countText_B : "获取验证码" }}</text |
| | |
| | | </uv-input> |
| | | </uv-form-item> |
| | | <uv-form-item > |
| | | <view class="but" style="width: 100%;margin-top: 20rpx;font-weight: 600;"> |
| | | <view class="but" style="width: 100%;"> |
| | | <uv-button |
| | | :customStyle="customStyle" |
| | | shape="circle" |
| | | @click="submitPlan_san" |
| | | >确定</uv-button |
| | | >确认</uv-button |
| | | > |
| | | </view> |
| | | </uv-form-item> |
| | | </uv-form> |
| | | </view> |
| | | </view> |
| | | |
| | | <view style="text-align: center;margin-top: 40rpx;"> |
| | | <image |
| | | @click="$refs.setUi.close()" |
| | | src="@/static/imgs/closeA.png" |
| | | style=" width: 50rpx; height: 50rpx; " |
| | | ></image> |
| | | </view> |
| | | </uv-popup> |
| | | |
| | |
| | | <addAddress :addressDetail="addressDetail" @off="$refs.address.close()" @submit="e => addressDetail = e"></addAddress> |
| | | </uv-popup> |
| | | |
| | | |
| | | <text-box v-if="showTextBox" ref="textBox" :getPlatformProtocolNewList="getPlatformProtocolNewList"></text-box> |
| | | |
| | | |
| | | <!-- <text-box v-if="showTextBox" ref="textBox" :getPlatformProtocolNewList="getPlatformProtocolNewList"></text-box> --> |
| | | </view> |
| | | </template> |
| | | |
| | |
| | | } |
| | | .form{ |
| | | background: #FFFFFF; |
| | | padding-top: 40rpx; |
| | | .clo{ |
| | | display: flex; |
| | | background: #FBFBFB !important; |
| | | border-radius: 24rpx 24rpx 24rpx 24rpx; |
| | | border: 2rpx solid #EEEEEE; |
| | | padding: 30rpx 20rpx; |
| | | margin: 0 40rpx 40rpx; |
| | | |
| | | //display: flex; |
| | | //padding: 30rpx 0rpx; |
| | | padding-bottom: 30rpx; |
| | | margin: 0 40rpx; |
| | | //border-bottom: 1rpx solid #E7E9ED; |
| | | background: #FFFFFF; |
| | | .label{ |
| | | width: 160rpx; |
| | | width: 460rpx; |
| | | height: 40rpx; |
| | | |
| | | font-weight: 600; |
| | |
| | | |
| | | .inp_box{ |
| | | position: relative; |
| | | margin-top: 30rpx; |
| | | .inp{ |
| | | &::placeholder{ |
| | | color: #999999; |
| | | font-size: 30rpx; |
| | | } |
| | | height: 42rpx; |
| | | |
| | | width: 670rpx; |
| | | height: 100rpx; |
| | | border: 1px solid #EEEEEE; |
| | | border-radius: 20rpx; |
| | | padding-left: 20rpx; |
| | | font-weight: 400; |
| | | font-size: 30rpx; |
| | | color: #333333; |
| | |
| | | .code_a{ |
| | | |
| | | font-weight: 400; |
| | | font-size: 24rpx; |
| | | color: #FF1472; |
| | | font-size: 28rpx; |
| | | color: #EE2626; |
| | | padding: 16rpx 20rpx; |
| | | //border: 1rpx solid #EE2626; |
| | | //border-radius: 8rpx 8rpx 8rpx 8rpx; |
| | | |
| | | } |
| | | .code_k{ |
| | | font-weight: 400; |
| | | font-size: 30rpx; |
| | | font-size: 28rpx; |
| | | color: #999999; |
| | | } |
| | | |
| | |
| | | |
| | | .sub{ |
| | | |
| | | |
| | | width: 100%; |
| | | bottom: 50rpx; |
| | | padding: 0 10rpx; |
| | | margin-top: 50rpx; |
| | | padding: 0 30rpx; |
| | | margin-top: 40rpx; |
| | | .sub_btn{ |
| | | background: #FF1472; |
| | | background: #EE2626; |
| | | border-radius: 50rpx 50rpx 50rpx 50rpx; |
| | | padding: 10rpx; |
| | | |
| | |
| | | |
| | | } |
| | | } |
| | | .item{ |
| | | |
| | | background: #FBFBFB; |
| | | border-radius: 24rpx 24rpx 24rpx 24rpx; |
| | | border: 2rpx solid #EEEEEE; |
| | | padding: 0 40rpx; |
| | | } |
| | | ::v-deep .uni-checkbox-input{ |
| | | border-radius: 0; |
| | | transform: scale(0.7); |
| | |
| | | } |
| | | .nots{ |
| | | opacity: 0.5; |
| | | } |
| | | .code{ |
| | | color: #FF1472; |
| | | } |
| | | </style> |
| | |
| | | customStyle() { |
| | | return { |
| | | height: "100rpx", |
| | | background: "#FF1472", |
| | | background: "#EE2626", |
| | | color: "#fff", |
| | | borderRadius: "50rpx", |
| | | fontSize: "34rpx", |
| | |
| | | |
| | | this.detail.consignee = this.detail.consignee || userName |
| | | this.detail.contactPhone = this.detail.contactPhone || mobile |
| | | console.log('8888888888888',this.detail.contactPhone) |
| | | }, |
| | | |
| | | data() { |
| | | return { |
| | | $webHost:'https://rbb98765.zrgy-bbg.com', |
| | | lstyle: { |
| | | color: "#333333", |
| | | fontSize: "30rpx", |
| | |
| | | |
| | | this.detail.cityCode = e.value[1].code |
| | | this.detail.cityName = e.value[1].title |
| | | console.log(e.value[2]); |
| | | |
| | | if(e.value[2]) { |
| | | this.detail.areaCode = e.value[2].code |
| | | this.detail.areaName = e.value[2].title |
| | |
| | | }); |
| | | return; |
| | | } |
| | | const params = uni.getStorageSync('qxgLogin') |
| | | const params = uni.getStorageSync('ygxLogin') |
| | | uni.request({ |
| | | url: _this.$webHost + "/api/v2/customer/appAddCstAddress", |
| | | method: "POST", |
| | |
| | | height: 100rpx; |
| | | " |
| | | > |
| | | <text class="tips"></text> |
| | | <text class="tips">为了提高您的审核通过率</text> |
| | | <view>请完善您的有效地址</view> |
| | | |
| | | <image |
| | | @click="off" |
| | | src="/static/img/close1.png" |
| | | src="/static/img/close.png" |
| | | style=" |
| | | width: 50rpx; |
| | | height: 50rpx; |
| | |
| | | data() { |
| | | return { |
| | | list: [], |
| | | $webHost:'https://rbb98765.zrgy-bbg.com', |
| | | } |
| | | }, |
| | | created() { |
| | | const _this = this; |
| | | uni.request( { |
| | | url: _this.$webHost + "/api/v2/renpin/H5/getPlatformProtocolNew", |
| | | data: { |
| | | customerId: uni.getStorageSync('qxgLogin').customerId, |
| | | appId: uni.getStorageSync('qxgLogin').appId |
| | | }, |
| | | method: 'GET', |
| | | success(res) { |
| | | console.log(res.data.data); |
| | | _this.list = res.data.data; |
| | | } |
| | | }) |
| | |
| | | this.$refs.agreement.open(); |
| | | }, |
| | | toProtocol(e){ |
| | | console.log(e); |
| | | let title = e.name; |
| | | let code = e.code; |
| | | uni.navigateTo({ |
| | |
| | | zIndex="3"> |
| | | <uv-cell-group> |
| | | <view class="popup-title"> |
| | | <view style="margin: auto;text-align: center;padding: 20rpx;">请阅读以下协议</view> |
| | | <view>请阅读以下协议</view> |
| | | </view> |
| | | <view class="setting-list-item"> |
| | | <view |
| | | class="setting-text" |
| | | style="font-size: 32rpx; font-weight: bold; justify-content: left;padding-left: 30rpx;" |
| | | style="font-size: 32rpx; font-weight: bold; justify-content: left" |
| | | >平台服务协议</view |
| | | > |
| | | </view> |
| | | <view class="list" style="height: 50vh;overflow: scroll;"> |
| | | <view class="list" style="height: 50vh;"> |
| | | <view class="li" @click="toProtocol(item)" v-for="(item,index) in list" :key="index" > |
| | | |
| | | <view style="font-size: 30rpx">{{item.name}}</view> |
| | |
| | | display: flex; |
| | | flex-direction: row; |
| | | justify-content: center; |
| | | |
| | | margin: auto; |
| | | margin-top: 38rpx; |
| | | text-align: center; |
| | | } |
| | | .setting-list-item { |
| | | display: flex; |
| New file |
| | |
| | | <script> |
| | | import { |
| | | payBindCardToCodes, |
| | | payVerifySMSCodes, |
| | | xinheyuanBankcardSave, |
| | | } from "@/api/modules/user"; |
| | | export default { |
| | | props: { |
| | | bankDetail: { |
| | | type: Object, |
| | | default() { |
| | | return {}; |
| | | }, |
| | | }, |
| | | queryBind: { |
| | | type: Object, |
| | | default() { |
| | | return {}; |
| | | }, |
| | | }, |
| | | }, |
| | | computed: { |
| | | customStyle() { |
| | | return { |
| | | height: "100rpx", |
| | | background: "#EE2626", |
| | | color: "#fff", |
| | | borderRadius: "50rpx", |
| | | fontSize: "34rpx", |
| | | }; |
| | | }, |
| | | inputStyle() { |
| | | return { |
| | | fontWeight: "400", |
| | | fontSize: "30rpx", |
| | | }; |
| | | }, |
| | | }, |
| | | |
| | | created() { |
| | | this.detail = this.bankDetail; |
| | | this.detail.verificationCode = ""; |
| | | this.detail.bankName = this.queryBind.bankName; |
| | | this.detail.bankId = this.queryBind.cardNumber; |
| | | this.detail.bankPhoneNo = this.queryBind.cardPhone; |
| | | }, |
| | | |
| | | data() { |
| | | return { |
| | | lstyle: { |
| | | color: "#333333", |
| | | fontSize: "30rpx", |
| | | fontWeight: "bold", |
| | | }, |
| | | |
| | | isCounting: false, |
| | | countText: "", |
| | | detail: { |
| | | bankName: "", |
| | | verificationCode: "", |
| | | }, |
| | | bankList: [], |
| | | bankCode: "", |
| | | callbackData: "", |
| | | }; |
| | | }, |
| | | methods: { |
| | | |
| | | submitPlan() { |
| | | const _this = this; |
| | | const pro = uni.getStorageSync("params"); |
| | | |
| | | if (!this.detail.bankPhoneNo) { |
| | | uni.showToast({ |
| | | title: "请输入手机号", |
| | | icon: "none", |
| | | }); |
| | | return; |
| | | } |
| | | if (!this.detail.verificationCode) { |
| | | uni.showToast({ |
| | | title: "请输入验证码", |
| | | icon: "none", |
| | | }); |
| | | return; |
| | | } |
| | | |
| | | const callbackData = uni.getStorageSync("callbackData"); |
| | | const paymentMethod = uni.getStorageSync("payBindCardInf")[1]['paymentMethod']; |
| | | payVerifySMSCodes({ |
| | | ...callbackData, |
| | | customerId: pro.customerId, |
| | | cardName: uni.getStorageSync("userName"), // 真实姓名 |
| | | bankName: _this.detail.bankName, |
| | | cardIdNo: uni.getStorageSync("idCardNo"), |
| | | |
| | | cardPhone: _this.detail.bankPhoneNo, |
| | | paymentMethod:paymentMethod, |
| | | cardNumber: _this.detail.bankId, |
| | | verificationCode: _this.detail.verificationCode, //短信 |
| | | }).then((res) => { |
| | | if(res){ |
| | | this.$emit("submit", this.detail); |
| | | } |
| | | }); |
| | | }, |
| | | off() { |
| | | this.$emit("off"); |
| | | }, |
| | | getCode() { |
| | | if (this.isCounting) { |
| | | return; |
| | | } |
| | | const paymentMethod = uni.getStorageSync("payBindCardInf")[1]['paymentMethod']; |
| | | const _this = this; |
| | | const pro = uni.getStorageSync("params"); |
| | | xinheyuanBankcardSave({ |
| | | customerId: pro.customerId, |
| | | nameReal: uni.getStorageSync("userName"), |
| | | cardNo: _this.detail.bankId, |
| | | idCard: uni.getStorageSync("idCardNo"), |
| | | bankId: "1", |
| | | bankPhoneNo: _this.detail.bankPhoneNo, |
| | | bankCode: _this.bankCode, |
| | | bankName: _this.detail.bankName, |
| | | phone: _this.detail.bankPhoneNo, |
| | | preBindType: "prebc", |
| | | }).then((res) => { |
| | | payBindCardToCodes({ |
| | | cardIdNo: uni.getStorageSync("idCardNo"), |
| | | customerId: pro.customerId, |
| | | cardName: uni.getStorageSync("userName"), |
| | | cardNo: _this.detail.bankId, |
| | | cardPhone: _this.detail.bankPhoneNo, |
| | | cardNumber: _this.detail.bankId, |
| | | bankName: _this.detail.bankName, |
| | | preBindType: "prebc", |
| | | paymentMethod:paymentMethod, |
| | | againType : true |
| | | }).then((res) => { |
| | | if(!res){ |
| | | return |
| | | } |
| | | _this.callbackData = res; |
| | | uni.setStorageSync("callbackData", res); |
| | | |
| | | uni.showToast({ |
| | | title: "验证码已发送", |
| | | icon: "none", |
| | | }); |
| | | uni.setStorageSync("YF", 1); |
| | | |
| | | // 设置倒计时功能 |
| | | let count = 60; |
| | | const timer = setInterval(() => { |
| | | count--; |
| | | if (count <= 0) { |
| | | clearInterval(timer); |
| | | _this.$set(_this, "isCounting", false); |
| | | } else { |
| | | _this.$set(_this, "isCounting", true); |
| | | _this.$set(_this, "countText", `${count}秒后重新获取`); |
| | | } |
| | | }, 1000); |
| | | }); |
| | | }); |
| | | }, |
| | | }, |
| | | }; |
| | | </script> |
| | | |
| | | <template> |
| | | <view> |
| | | <view class="head"> |
| | | <view |
| | | style=" |
| | | text-align: center; |
| | | font-weight: bold; |
| | | font-size: 36rpx; |
| | | position: relative; |
| | | height: 50rpx; |
| | | " |
| | | > |
| | | |
| | | <image |
| | | @click="off" |
| | | src="@/static/img/close.png" |
| | | style=" |
| | | width: 50rpx; |
| | | height: 50rpx; |
| | | position: absolute; |
| | | right: 0; |
| | | top: -2rpx; |
| | | " |
| | | ></image> |
| | | </view> |
| | | </view> |
| | | <view style=" |
| | | font-weight: bold; |
| | | font-size: 36rpx; |
| | | position: relative; |
| | | margin-bottom: 12rpx; |
| | | padding-left: 38rpx; |
| | | ">短信确认</view> |
| | | <view style="font-size: 28rpx;color: #252938; padding-left: 38rpx;">为确保安全到账,需再次对您的收款账户进行短信验证</view> |
| | | <view class="con"> |
| | | <u-form |
| | | :labelStyle="lstyle" |
| | | labelPosition="left" |
| | | :model="detail" |
| | | ref="form" |
| | | labelWidth="100" |
| | | > |
| | | |
| | | <u-form-item |
| | | class="item" |
| | | label="手机号" |
| | | prop="repayTermStr" |
| | | borderBottom |
| | | > |
| | | <u-input |
| | | :adjustPosition="true" |
| | | maxlength="11" |
| | | :customStyle="inputStyle" |
| | | disabledColor="none" |
| | | inputAlign="right" |
| | | v-model="detail.bankPhoneNo" |
| | | border="none" |
| | | placeholder="请输入手机号" |
| | | ></u-input> |
| | | </u-form-item> |
| | | |
| | | <u-form-item |
| | | class="item" |
| | | label="短信验证码" |
| | | prop="needVerify" |
| | | > |
| | | <u-input |
| | | :adjustPosition="true" |
| | | maxlength="6" |
| | | inputAlign="right" |
| | | v-model="detail.verificationCode" |
| | | border="none" |
| | | placeholder="请输入验证码" |
| | | > |
| | | <template #suffix> |
| | | <text |
| | | class="code" |
| | | :class="isCounting ? 'ks' : ''" |
| | | @click="getCode" |
| | | >{{ isCounting ? countText : "获取验证码" }}</text |
| | | > |
| | | </template> |
| | | </u-input> |
| | | </u-form-item> |
| | | <u-form-item > |
| | | <view class="but"> |
| | | <u-button |
| | | :customStyle="customStyle" |
| | | shape="circle" |
| | | @click="submitPlan" |
| | | >确认</u-button |
| | | > |
| | | </view> |
| | | </u-form-item> |
| | | </u-form> |
| | | </view> |
| | | </view> |
| | | </template> |
| | | |
| | | <style scoped lang="scss"> |
| | | .ks { |
| | | color: #999999 !important; |
| | | } |
| | | .but { |
| | | width: 100%; |
| | | margin-top: 46rpx; |
| | | .pack { |
| | | text-align: center; |
| | | margin-top: 20rpx; |
| | | font-size: 30rpx; |
| | | display: flex; |
| | | flex-direction: row; |
| | | justify-content: center; |
| | | } |
| | | } |
| | | .head { |
| | | margin-top: 40rpx; |
| | | padding: 0 40rpx; |
| | | |
| | | font-size: 32rpx; |
| | | color: #252938; |
| | | .title { |
| | | display: flex; |
| | | flex-direction: row; |
| | | text-align: center; |
| | | color: #252938; |
| | | font-size: 32rpx; |
| | | font-weight: bold; |
| | | .num { |
| | | color: #4766fe; |
| | | display: contents; |
| | | } |
| | | } |
| | | } |
| | | |
| | | .con { |
| | | padding: 0 38rpx; |
| | | .pt40 { |
| | | padding-top: 40rpx; |
| | | } |
| | | .mr { |
| | | margin-right: 20rpx; |
| | | } |
| | | .code { |
| | | margin-left: 40rpx; |
| | | font-size: 24rpx; |
| | | color: #4766fe; |
| | | background: none; |
| | | border-radius: 8rpx 8rpx 8rpx 8rpx; |
| | | } |
| | | } |
| | | </style> |
| New file |
| | |
| | | <script> |
| | | import { |
| | | payBindCardToCodes, |
| | | payVerifySMSCodes, |
| | | xinheyuanBankcardSave, |
| | | } from "@/api/modules/user"; |
| | | export default { |
| | | props: { |
| | | bankDetail: { |
| | | type: Object, |
| | | default() { |
| | | return {}; |
| | | }, |
| | | }, |
| | | queryBind: { |
| | | type: Object, |
| | | default() { |
| | | return {}; |
| | | }, |
| | | }, |
| | | }, |
| | | computed: { |
| | | customStyle() { |
| | | return { |
| | | height: "100rpx", |
| | | background: "#EE2626", |
| | | color: "#fff", |
| | | borderRadius: "50rpx", |
| | | fontSize: "34rpx", |
| | | }; |
| | | }, |
| | | inputStyle() { |
| | | return { |
| | | fontWeight: "400", |
| | | fontSize: "30rpx", |
| | | }; |
| | | }, |
| | | }, |
| | | |
| | | created() { |
| | | this.detail = this.bankDetail; |
| | | this.detail.verificationCode = ""; |
| | | this.detail.bankName = this.queryBind.bankName; |
| | | this.detail.bankId = this.queryBind.cardNumber; |
| | | this.detail.bankPhoneNo = this.queryBind.cardPhone; |
| | | }, |
| | | |
| | | data() { |
| | | return { |
| | | lstyle: { |
| | | color: "#333333", |
| | | fontSize: "30rpx", |
| | | fontWeight: "bold", |
| | | }, |
| | | |
| | | isCounting: false, |
| | | countText: "", |
| | | detail: { |
| | | bankName: "", |
| | | verificationCode: "", |
| | | }, |
| | | bankList: [], |
| | | bankCode: "", |
| | | callbackData: "", |
| | | }; |
| | | }, |
| | | methods: { |
| | | |
| | | submitPlan() { |
| | | const _this = this; |
| | | const pro = uni.getStorageSync("params"); |
| | | |
| | | if (!this.detail.bankPhoneNo) { |
| | | uni.showToast({ |
| | | title: "请输入手机号", |
| | | icon: "none", |
| | | }); |
| | | return; |
| | | } |
| | | if (!this.detail.verificationCode) { |
| | | uni.showToast({ |
| | | title: "请输入验证码", |
| | | icon: "none", |
| | | }); |
| | | return; |
| | | } |
| | | |
| | | const callbackData = uni.getStorageSync("callbackData"); |
| | | const paymentMethod = uni.getStorageSync("payBindCardInf")[2]['paymentMethod']; |
| | | payVerifySMSCodes({ |
| | | ...callbackData, |
| | | customerId: pro.customerId, |
| | | cardName: uni.getStorageSync("userName"), // 真实姓名 |
| | | bankName: _this.detail.bankName, |
| | | cardIdNo: uni.getStorageSync("idCardNo"), |
| | | |
| | | cardPhone: _this.detail.bankPhoneNo, |
| | | paymentMethod:paymentMethod, |
| | | cardNumber: _this.detail.bankId, |
| | | verificationCode: _this.detail.verificationCode, //短信 |
| | | }).then((res) => { |
| | | if(res){ |
| | | this.$emit("submit", this.detail); |
| | | } |
| | | }); |
| | | }, |
| | | off() { |
| | | this.$emit("off"); |
| | | }, |
| | | getCode() { |
| | | if (this.isCounting) { |
| | | return; |
| | | } |
| | | const paymentMethod = uni.getStorageSync("payBindCardInf")[2]['paymentMethod']; |
| | | const _this = this; |
| | | const pro = uni.getStorageSync("params"); |
| | | xinheyuanBankcardSave({ |
| | | customerId: pro.customerId, |
| | | nameReal: uni.getStorageSync("userName"), |
| | | cardNo: _this.detail.bankId, |
| | | idCard: uni.getStorageSync("idCardNo"), |
| | | bankId: "1", |
| | | bankPhoneNo: _this.detail.bankPhoneNo, |
| | | bankCode: _this.bankCode, |
| | | bankName: _this.detail.bankName, |
| | | phone: _this.detail.bankPhoneNo, |
| | | preBindType: "prebc", |
| | | }).then((res) => { |
| | | payBindCardToCodes({ |
| | | cardIdNo: uni.getStorageSync("idCardNo"), |
| | | customerId: pro.customerId, |
| | | cardName: uni.getStorageSync("userName"), |
| | | cardNo: _this.detail.bankId, |
| | | cardPhone: _this.detail.bankPhoneNo, |
| | | cardNumber: _this.detail.bankId, |
| | | bankName: _this.detail.bankName, |
| | | preBindType: "prebc", |
| | | paymentMethod:paymentMethod, |
| | | againType : true |
| | | }).then((res) => { |
| | | if(!res){ |
| | | return |
| | | } |
| | | _this.callbackData = res; |
| | | uni.setStorageSync("callbackData", res); |
| | | |
| | | uni.showToast({ |
| | | title: "验证码已发送", |
| | | icon: "none", |
| | | }); |
| | | uni.setStorageSync("YF", 1); |
| | | |
| | | // 设置倒计时功能 |
| | | let count = 60; |
| | | const timer = setInterval(() => { |
| | | count--; |
| | | if (count <= 0) { |
| | | clearInterval(timer); |
| | | _this.$set(_this, "isCounting", false); |
| | | } else { |
| | | _this.$set(_this, "isCounting", true); |
| | | _this.$set(_this, "countText", `${count}秒后重新获取`); |
| | | } |
| | | }, 1000); |
| | | }); |
| | | }); |
| | | }, |
| | | }, |
| | | }; |
| | | </script> |
| | | |
| | | <template> |
| | | <view> |
| | | <view class="head"> |
| | | <view |
| | | style=" |
| | | text-align: center; |
| | | font-weight: bold; |
| | | font-size: 36rpx; |
| | | position: relative; |
| | | height: 50rpx; |
| | | " |
| | | > |
| | | |
| | | <image |
| | | @click="off" |
| | | src="@/static/img/close.png" |
| | | style=" |
| | | width: 50rpx; |
| | | height: 50rpx; |
| | | position: absolute; |
| | | right: 0; |
| | | top: -2rpx; |
| | | " |
| | | ></image> |
| | | </view> |
| | | </view> |
| | | <view style=" |
| | | font-weight: bold; |
| | | font-size: 36rpx; |
| | | position: relative; |
| | | margin-bottom: 12rpx; |
| | | padding-left: 38rpx; |
| | | ">本人提交确认</view> |
| | | <view style="font-size: 28rpx;color: #252938; padding-left: 38rpx;padding-right: 30rpx;">根据合规要求我们将进行本人提交意愿确认的短信校验,请注意查看短信验证码</view> |
| | | <view class="con"> |
| | | <u-form |
| | | :labelStyle="lstyle" |
| | | labelPosition="left" |
| | | :model="detail" |
| | | ref="form" |
| | | labelWidth="100" |
| | | > |
| | | |
| | | <u-form-item |
| | | class="item" |
| | | label="手机号" |
| | | prop="repayTermStr" |
| | | borderBottom |
| | | > |
| | | <u-input |
| | | :adjustPosition="true" |
| | | maxlength="11" |
| | | :customStyle="inputStyle" |
| | | disabledColor="none" |
| | | inputAlign="right" |
| | | v-model="detail.bankPhoneNo" |
| | | border="none" |
| | | placeholder="请输入手机号" |
| | | ></u-input> |
| | | </u-form-item> |
| | | |
| | | <u-form-item |
| | | class="item" |
| | | label="短信验证码" |
| | | prop="needVerify" |
| | | > |
| | | <u-input |
| | | :adjustPosition="true" |
| | | maxlength="6" |
| | | inputAlign="right" |
| | | v-model="detail.verificationCode" |
| | | border="none" |
| | | placeholder="请输入验证码" |
| | | > |
| | | <template #suffix> |
| | | <text |
| | | class="code" |
| | | :class="isCounting ? 'ks' : ''" |
| | | @click="getCode" |
| | | >{{ isCounting ? countText : "获取验证码" }}</text |
| | | > |
| | | </template> |
| | | </u-input> |
| | | </u-form-item> |
| | | <u-form-item > |
| | | <view class="but"> |
| | | <u-button |
| | | :customStyle="customStyle" |
| | | shape="circle" |
| | | @click="submitPlan" |
| | | >确认提交</u-button |
| | | > |
| | | </view> |
| | | </u-form-item> |
| | | </u-form> |
| | | </view> |
| | | </view> |
| | | </template> |
| | | |
| | | <style scoped lang="scss"> |
| | | .ks { |
| | | color: #999999 !important; |
| | | } |
| | | .but { |
| | | width: 100%; |
| | | margin-top: 46rpx; |
| | | .pack { |
| | | text-align: center; |
| | | margin-top: 20rpx; |
| | | font-size: 30rpx; |
| | | display: flex; |
| | | flex-direction: row; |
| | | justify-content: center; |
| | | } |
| | | } |
| | | .head { |
| | | margin-top: 40rpx; |
| | | padding: 0 40rpx; |
| | | |
| | | font-size: 32rpx; |
| | | color: #252938; |
| | | .title { |
| | | display: flex; |
| | | flex-direction: row; |
| | | text-align: center; |
| | | color: #252938; |
| | | font-size: 32rpx; |
| | | font-weight: bold; |
| | | .num { |
| | | color: #4766fe; |
| | | display: contents; |
| | | } |
| | | } |
| | | } |
| | | |
| | | .con { |
| | | padding: 0 38rpx; |
| | | .pt40 { |
| | | padding-top: 40rpx; |
| | | } |
| | | .mr { |
| | | margin-right: 20rpx; |
| | | } |
| | | .code { |
| | | margin-left: 40rpx; |
| | | font-size: 24rpx; |
| | | color: #4766fe; |
| | | background: none; |
| | | border-radius: 8rpx 8rpx 8rpx 8rpx; |
| | | } |
| | | } |
| | | </style> |
| | |
| | | <script> |
| | | |
| | | import textBox from "@/components/textBox/index.vue"; |
| | | import tehuichongzhi from "@/pages/quanshou/components/tehuichongzhi.vue"; //虚拟 |
| | | import lanyaerji from "@/pages/quanshou/components/lanyaerji.vue"; // 实物 |
| | | |
| | | |
| | | export default { |
| | | components: { |
| | | textBox, |
| | | tehuichongzhi, |
| | | lanyaerji, |
| | | textBox |
| | | }, |
| | | |
| | | async created() { |
| | | const _this = this; |
| | | |
| | | await uni.request({ |
| | | // url: _this.$webHost+'/api/v2/auth/ygxLogin?phone='+_this.$util.getUserInfo().phone+'&appId='+'47be9559-6b1b-42dd-84ed-25d028065013', |
| | | url: _this.$webHost+'/api/v2/auth/qxgIosUnionLogin?phone='+_this.$util.getUserInfo().phone, |
| | | data:{ |
| | | customerId: uni.getStorageSync('qxgLogin').customerId, |
| | | appId: uni.getStorageSync('qxgLogin').appId |
| | | }, |
| | | success: function (res) { |
| | | _this.qxgLogin = res.data.data; |
| | | uni.setStorageSync('qxgLogin',_this.qxgLogin) |
| | | _this.ygxLogin = res.data.data; |
| | | uni.setStorageSync('ygxLogin',_this.ygxLogin) |
| | | uni.request({ |
| | | url: _this.$webHost+'/api/v2/buryingPoint/record', |
| | | method:'PUT', |
| | |
| | | }, |
| | | success:function (info){ |
| | | _this.memberPeriodConfigInfo = info.data.data; |
| | | if(_this.memberPeriodConfigInfo['totalBenefitsAmount']) { |
| | | _this.memberPeriodConfigInfo['totalBenefitsAmount'] = _this.memberPeriodConfigInfo['totalBenefitsAmount'].toFixed(2); |
| | | } |
| | | uni.setStorageSync('memberPeriodConfigInfo',_this.memberPeriodConfigInfo) |
| | | _this.showTextBox = true; |
| | | _this.$nextTick(() => { |
| | |
| | | } |
| | | }) |
| | | |
| | | // 获取VIP值 |
| | | uni.request({ |
| | | url: _this.$webHost+'/api/v2/customer/getRyxBenefitsRecordList?phone='+_this.$util.getUserInfo().phone, |
| | | data:{ |
| | | customerId: uni.getStorageSync('qxgLogin').customerId, |
| | | appId: uni.getStorageSync('qxgLogin').appId |
| | | }, |
| | | success: function (res) { |
| | | if(res.data.code==200){ |
| | | _this.lst = res.data.data; |
| | | _this.lst.forEach(item=>{ |
| | | if(item && item.isBuy === 1 && [1,2,3].includes(item.period)) {_this.VIP = item.period;} |
| | | }) |
| | | } else { |
| | | |
| | | |
| | | } |
| | | } |
| | | }) |
| | | |
| | | let mk = setInterval(()=>{ |
| | | this.text -=1; |
| | | if(!this.text){ |
| | | _this.text -=1; |
| | | if(!_this.text){ |
| | | clearInterval( mk) |
| | | } |
| | | },1000) |
| | | this.time= setTimeout(()=>{ |
| | | this.protocolChecked = [1]; |
| | | this.tm = true; |
| | | this.isAgree = true; |
| | | },10000) |
| | | _this.time= setTimeout(()=>{ |
| | | _this.protocolChecked = [1]; |
| | | _this.tm = true; |
| | | },3000) |
| | | |
| | | }, |
| | | |
| | | data() { |
| | | return { |
| | | active: 0, |
| | | VIP: 1, // 1黄金 2铂金 3黑金 |
| | | qxgLogin:{}, |
| | | ygxLogin:{}, |
| | | protocolChecked: [0], |
| | | isAgree: false, |
| | | showTextBox: false, |
| | | isAgree: false, |
| | | tm: null, |
| | | time:null, |
| | | text:10, |
| | | text:3, |
| | | memberPeriodConfigInfo: { |
| | | totalBenefitsAmount: "", |
| | | installmentPeriods: "", |
| | | } |
| | | } |
| | | }, |
| | | |
| | | methods: { |
| | | goHome(){ |
| | | uni.switchTab({ |
| | | uni.reLaunch({ |
| | | url: '/pages/index/index' |
| | | }); |
| | | }, |
| | |
| | | </script> |
| | | |
| | | <template> |
| | | <view class="box" style=""> |
| | | <view style="background: url('/static/img/qyBg.png') no-repeat top center; background-size: 100%;background-color: #210E0E;"> |
| | | |
| | | <view class="head" style="position: relative"> |
| | | |
| | | |
| | | <view style="margin-left: 20rpx;display: flex;justify-content: space-between;"> |
| | | |
| | | <view> |
| | | <view style="margin-top: 60rpx;"><image src="/static/imgs/SMTTA.png" style="width: 378rpx;height: 88rpx;"></image></view> |
| | | |
| | | <view style="margin-top: 10rpx;"> |
| | | <image src="/static/imgs/QQXGLK.png" style="width: 178rpx;height: 54rpx;"></image> |
| | | <view style="display: flex;justify-content: flex-start;position: absolute;left: 0;top: 65rpx;padding-left: 30rpx;z-index: 9;color: #FFFFFF;"> |
| | | <view @tap="goHome" id="home" class="home acea-row row-center-wrapper iconfont icon-fanhui2 h5_back icon-shouye4" :style="{ height: '80rpx',lineHeight: '80rpx'}" style="margin-top: 20rpx;"> |
| | | <uv-icon name="home" color="#ffffff" size="20"></uv-icon> |
| | | </view> |
| | | |
| | | </view> |
| | | <!-- <view style="text-align: center;font-weight: bold;font-size: 36rpx;position: relative;">--> |
| | | <!-- <view class="mm" style="text-align: center">会员权益说明</view>--> |
| | | <!-- </view>--> |
| | | </view> |
| | | |
| | | <view class="title"> |
| | | <view style="margin-top:320rpx;text-align: center;font-weight: bold;line-height:90rpx;font-size:70rpx;background: -webkit-linear-gradient(#ffffff, #F3855B);-webkit-background-clip: text;-webkit-text-fill-color: transparent;"> |
| | | <p>入会有惊喜</p> |
| | | <p>尊享好福利</p> |
| | | </view> |
| | | <view style="font-size:32rpx;background: -webkit-linear-gradient(#ffffff, #F3855B);-webkit-background-clip: text;-webkit-text-fill-color: transparent;text-align: center;letter-spacing: 14rpx;margin-left: 16rpx;margin-top: 10rpx;">欢迎加入商城会员</view> |
| | | </view> |
| | | |
| | | <view class="content" style="overflow-y: scroll;padding: 30rpx;background: #ffffff;border-top-left-radius: 50rpx;border-top-right-radius: 50rpx;margin-top: 60rpx;padding-bottom: 140rpx;"> |
| | | <view class="content-title" style="text-align: center;display: flex;align-items: center;justify-content: center;margin-top: 40rpx;margin-bottom: 10rpx;"> |
| | | <image style="width: 127rpx;height: 18rpx;" src="/static/img/nion1.png"></image> |
| | | <view style="font-size: 36rpx;color: #370606;margin: 0 20rpx;">会员权益说明</view> |
| | | <image style="width: 127rpx;height: 18rpx;" src="/static/img/nion.png"></image> |
| | | </view> |
| | | <view style="color: #370606;text-align: center;font-size: 24rpx;">MEMBERSHIP BENEFIS DESCRIPTON</view> |
| | | <view class="tips" style="background-color: #FFEEE7;border-radius: 32rpx;margin-top: 20rpx;padding: 30rpx;color: #370606;font-size: 28rpx;"> |
| | | <view style="margin-bottom: 20rpx;display: flex;"> |
| | | <view style="width: 40rpx;height: 40rpx;background-color: #F4936F;border-radius: 50%;text-align: center;line-height: 40rpx;flex-shrink: 0;flex-grow: 0;font-size: 28rpx;color: #370606;margin-right: 20rpx;"> |
| | | 1. |
| | | </view> |
| | | <view> |
| | | <image src="/static/imgs/VIPSOA.png" style="width: 272rpx;height: 272rpx;"></image> |
| | | 小猪优选商城会员年卡是本商城为会员特别打造的专属服务。成为会员后,您可享受各类商品折扣、促销优惠、生活权益及专属特权,并根据会员等级获赠相应超值礼品,体验我们为您准备的尊享会员服务。 |
| | | </view> |
| | | </view> |
| | | <view style="margin-bottom: 20rpx;display: flex;"> |
| | | <view style="width: 40rpx;height: 40rpx;background-color: #F4936F;border-radius: 50%;text-align: center;line-height: 40rpx;flex-shrink: 0;flex-grow: 0;font-size: 28rpx;color: #370606;margin-right: 20rpx;"> |
| | | 2. |
| | | </view> |
| | | <view> |
| | | 保险权益赠送:小猪优选商城会员年卡用户有机会获赠涵盖重疾险、意外险、事故险等的综合保障服务。尚未享受持牌机构服务的会员,亦有机会获取此项权益,具体详情请查阅会员中心相关说明。 |
| | | </view> |
| | | </view> |
| | | <view style="margin-bottom: 20rpx;display: flex;"> |
| | | <view style="width: 40rpx;height: 40rpx;background-color: #F4936F;border-radius: 50%;text-align: center;line-height: 40rpx;flex-shrink: 0;flex-grow: 0;font-size: 28rpx;color: #370606;margin-right: 20rpx;"> |
| | | 3. |
| | | </view> |
| | | <view> |
| | | 会员服务一经开通即表示知晓并同意以上内容,自愿加入小猪优选商城会员年卡会员,并同意平台及平台权益合作方在账单日收入会员费,可在个人中心查看订单详情。 |
| | | </view> |
| | | </view> |
| | | <view style="margin-bottom: 20rpx;display: flex;"> |
| | | <view style="width: 40rpx;height: 40rpx;background-color: #F4936F;border-radius: 50%;text-align: center;line-height: 40rpx;flex-shrink: 0;flex-grow: 0;font-size: 28rpx;color: #370606;margin-right: 20rpx;"> |
| | | 4. |
| | | </view> |
| | | <view> |
| | | 平台有权根据实际情况优化调整礼品内容和会员权益,最终解释权归小猪优选商城所有。 |
| | | </view> |
| | | </view> |
| | | </view> |
| | | <view style="background: url('/static/img/qyBg2.png') no-repeat top center; background-size: 100%;width: 100%;height: 290rpx;margin-top: 20rpx;padding: 40rpx;"> |
| | | <view style="margin-bottom:20rpx;font-size: 44rpx;font-weight: bold;background: -webkit-linear-gradient(#FFEEE7, #F4936F);-webkit-background-clip: text;-webkit-text-fill-color: transparent;">尊享会员年卡</view> |
| | | <view style="font-size: 28rpx;"> |
| | | <p style="background: -webkit-linear-gradient(#FFEEE7, #F4936F);-webkit-background-clip: text;-webkit-text-fill-color: transparent;">年卡金额:{{ memberPeriodConfigInfo.totalBenefitsAmount }}元</p> |
| | | <p style="background: -webkit-linear-gradient(#FFEEE7, #F4936F);-webkit-background-clip: text;-webkit-text-fill-color: transparent;">扣款期数:{{ memberPeriodConfigInfo.installmentPeriods }}期(先享后付,免息)</p> |
| | | <p style="background: -webkit-linear-gradient(#FFEEE7, #F4936F);-webkit-background-clip: text;-webkit-text-fill-color: transparent;">有效期:365天</p> |
| | | </view> |
| | | </view> |
| | | |
| | | </view> |
| | | <view class="content" style="overflow-y: scroll;padding: 30rpx;padding-top: 0;margin-top: -30rpx;"> |
| | | <view class="tips" style="font-size: 28rpx;padding: 28rpx 32rpx;background-image: url('/static/imgs/TIPSBACK.png');background-repeat: no-repeat;background-size: 100% 100%;padding-bottom: 32rpx;"> |
| | | <view style="font-size: 28rpx;color: #333333">① {{memberPeriodConfigInfo.showTitle}}商城会员年卡是本商城为会员特别打造的专属服务。成为会员后,您可享受各类商品折扣、促销优惠、生活权益及专属特权,并根据会员等级获赠相应超值礼品,体验我们为您准备的尊享会员服务。</view> |
| | | <view style="font-size: 28rpx;color: #333333">② 保险权益赠送:{{memberPeriodConfigInfo.showTitle}}商城会员年卡用户有机会获赠涵盖重疾险、意外险、事故险等的综合保障服务。尚未享受持牌机构服务的会员,亦有机会获取此项权益,具体详情请查阅会员中心相关说明。</view> |
| | | <view style="font-size: 28rpx;color: #333333">③ 平台保留根据实际情况新增或优化会员权益内容的权利。</view> |
| | | <!-- <view style="margin-top: 30rpx;" class="back">--> |
| | | <!-- <view style="flex: 1">--> |
| | | <!-- <view class="tips" style="font-size: 36rpx;font-weight: bold;color: #794007;margin-bottom: 20rpx;">专享特权</view>--> |
| | | <!-- <view class="tips" style="font-size: 26rpx;color: #794007;margin-bottom: 20rpx;line-height: 44rpx;">小猪优选会员年卡会员 {{ memberPeriodConfigInfo.totalBenefitsAmount }}元/年</view>--> |
| | | <!-- <view class="tips" style="font-size: 26rpx;margin-bottom: 20rpx;color: #794007;line-height: 44rpx;">分期支付:先享后付(提供的实物商品为指定的价值888元的红酒一瓶),分{{ memberPeriodConfigInfo.installmentPeriods }}期支付包年会员服务、免息</view>--> |
| | | <!-- <view class="tips" style="font-size: 26rpx;margin-bottom: 3rpx;color: #794007;line-height: 44rpx;">购买成功后,可在个人中心查看分期订单详情</view>--> |
| | | |
| | | <!-- </view>--> |
| | | <!-- <view style="display: flex;margin-top: 150rpx;">--> |
| | | <!-- <checkbox-group activeColor="#fff" @change='isAgree=!isAgree' style="height: 100px;">--> |
| | | <!-- <checkbox :checked="isAgree ? true : false" iconColor="#794007" iconSize="30" size="38" :name="1" shape="circle">--> |
| | | <!-- </checkbox>--> |
| | | <!-- </checkbox-group>--> |
| | | <!-- </view>--> |
| | | <!-- </view>--> |
| | | <!-- <view class="tips" style="color: #666666;margin-top: 30rpx;font-size: 26rpx">点击按钮即表示知晓并同意以上内容,自愿加入本商城小猪优选会员年卡会员,并同意平台及平台权益合作方在账单日收入会员费</view>--> |
| | | <view style="font-size: 24rpx;color: #666666;display: flex;align-items: center;margin: 40rpx 0;height: 50rpx;justify-content: center;"> |
| | | <checkbox-group activeColor="#fff" @change='isAgree=!isAgree' style=""> |
| | | <checkbox :checked="isAgree ? true : false" iconColor="#794007" iconSize="30" size="38" :name="1" shape="circle"> |
| | | </checkbox> |
| | | </checkbox-group> |
| | | <text style="color: #20110E;">我已阅读并同意</text> |
| | | <!-- <text style="display: inline;font-size: 24rpx;color: #4766FE" @click="link('/pages/protocol/protocol?code=shop_ai_service&title=会员服务协议-YXKJ')">《会员服务协议-YXKJ》</text> |
| | | <text style="display: inline;font-size: 24rpx;color: #4766FE" @click="link('/pages/protocol/protocol?code=shop_auto_service&title=委托扣款确认书-YXKJ')">《委托扣款确认书-YXKJ》</text>--> |
| | | <text style="display: inline;font-size: 24rpx;color: #4766FE" @click="link(`/pages/web/xieyi?code=${memberPeriodConfigInfo.protocolCode}&title=${memberPeriodConfigInfo.protocolName}`)">《会员权益服务协议-小猪优选》</text> |
| | | </view> |
| | | |
| | | |
| | | <view class="QXFJH" style="background-image: url('/static/imgs/QXFJH.png');background-size: 100% 100%;text-align: center;background-repeat: no-repeat;padding: 28rpx 0;margin-top: 18rpx;margin-bottom: 16rpx;color: #333333;line-height: 48rpx;"> |
| | | <view style="font-weight: 600;">{{memberPeriodConfigInfo.showTitle}}商城会员专享特权</view> |
| | | |
| | | <view>年卡费用:{{memberPeriodConfigInfo.totalBenefitsAmount }}元/年</view> |
| | | <view>支付期数:{{memberPeriodConfigInfo.installmentPeriods }}期</view> |
| | | <!-- <view>支付期数:{{memberPeriodConfigInfo.installmentPeriods }}期(每期{{memberPeriodConfigInfo.totalBenefitsAmount / memberPeriodConfigInfo.installmentPeriods}}元)</view>--> |
| | | |
| | | |
| | | </view> |
| | | |
| | | <view style="font-size: 22rpx;padding: 36rpx 32rpx 24rpx 32rpx;background-image: url('/static/imgs/CLOSAN.png');background-repeat: no-repeat;background-size: 100% 100%;margin-bottom: 32rpx;"> |
| | | <view style="font-size: 24rpx;margin-bottom: 30rpx;color: #333333">会员先享后付,包年会员服务、免息,购买成功后可在个人中心查看订单详情。会员服务开通成功不支持取消、退款。</view> |
| | | <view style="font-size: 24rpx;color: #333333">点击按钮即表示知晓并同意以上内容,自愿加入本商城年卡会员,且同意平台及平台权益合作方在账单日收入会员费。</view> |
| | | </view> |
| | | |
| | | |
| | | |
| | | |
| | | <view style="display: flex;gap: 20rpx;"> |
| | | <!-- <view class="tips" style="color: #666666;margin-top: 24rpx;margin-bottom: 20rpx;font-size: 26rpx">*会员服务一经开通不支持取消、退款,会员服务到期前,用户可以选择续订或取消续费。</view>--> |
| | | <view style="position: fixed;bottom: 40rpx;left: 30rpx;width: 690rpx;display: flex;gap: 20rpx;z-index: 2;"> |
| | | <button @click="goHome" style="width: 200rpx;height: 100rpx;padding: 10rpx 0;border-radius: 50rpx;font-size: 34rpx">暂不开通</button> |
| | | <button |
| | | style="height: 100rpx;color: #666666;border-radius: 24rpx;font-size: 34rpx;line-height: 100rpx;width: 170rpx;background-color: unset;" |
| | | @click="goHome" |
| | | >暂不开通</button> |
| | | <button |
| | | style="height: 100rpx;color: white;border-radius: 24rpx;font-size: 34rpx;line-height: 100rpx;flex: 1;" |
| | | :disabled="!tm" |
| | | style="height: 100rpx;padding: 10rpx 0;color: #370606;border-radius: 50rpx;font-size: 34rpx;flex: 1;" |
| | | |
| | | @click="submit" |
| | | |
| | | :class="tm &&protocolChecked.length?'activityBut':'disabledBut'" |
| | | >同意并开通<text v-if="!tm">({{text}}秒)</text></button> |
| | | >同意并开通<text v-if="!tm">({{text}}秒)</text></button> |
| | | </view> |
| | | <view style="display: flex;margin-top: 20rpx;display: flex;font-weight: 600;"> |
| | | <uv-checkbox-group activeColor="#FF1472" @change='isAgree=!isAgree' > |
| | | <uv-checkbox :checked="isAgree ? true : false" activeColor="#FF1472" iconSize="14" size="16" :name="1" shape="circle"> |
| | | </uv-checkbox> |
| | | <view style="font-size: 24rpx;color: #8B8D96">我已阅读并同意<text style="display: inline;font-size: 24rpx;color: #4766FE" @click="link(`/pages/web/xieyi?code=${memberPeriodConfigInfo.protocolCode}&title=${memberPeriodConfigInfo.protocolName}`)">{{ memberPeriodConfigInfo.protocolName }}</text></view> |
| | | </uv-checkbox-group> |
| | | |
| | | <!-- 专享会员生活权益 --> |
| | | <view> |
| | | <view class="content-title" style="text-align: center;display: flex;align-items: center;justify-content: center;margin-top: 50rpx;margin-bottom: 40rpx;"> |
| | | <image style="width: 127rpx;height: 18rpx;" src="/static/img/nion1.png"></image> |
| | | <view style="font-size: 36rpx;color: #370606;margin: 0 20rpx;">专享会员生活权益</view> |
| | | <image style="width: 127rpx;height: 18rpx;" src="/static/img/nion.png"></image> |
| | | </view> |
| | | <view class="life" style="background: url('/static/img/qsLife.png') no-repeat top center; background-size: 100%;width: 100%;height: 1506rpx;"> |
| | | |
| | | </view> |
| | | <view class="tab-wrap"> |
| | | <text @click="active=0" :class="active==0?'active':''">实物权益</text> |
| | | <text @click="active=1" :class="active==1?'active':''">虚拟权益</text> |
| | | <view style="width: 690rpx;margin-top: 20rpx;text-align: center;"> |
| | | <!-- <button @click="toHuiyuan" style="height: 100rpx;padding: 25rpx 0;color: #370606;border-radius: 50rpx;font-size: 34rpx;background-image: linear-gradient(to right, #FFEAE2, #FF6F55);">兑换生活权益</button>--> |
| | | <view style="color: #333;font-size: 24rpx;padding-top: 0rpx;padding-bottom: 10rpx;">以上权益仅为预览展示,实际以兑换页面为准</view> |
| | | </view> |
| | | <view class="note" style="margin-bottom: 20rpx;text-align: center;color: #999;font-size: 24rpx;" v-if="active==0">页面展示为实物样例,实际以用户收到的商品为准</view> |
| | | <view class="note" style="margin-bottom: 20rpx;text-align: center;color: #999;font-size: 24rpx;" v-if="active==1">页面为虚拟权益预览,实际用户以当日兑换内容为准</view> |
| | | <lanyaerji v-if="active==0" style="margin:0 30rpx;"/> |
| | | <tehuichongzhi v-else :VIP="VIP" style="margin-top: 50rpx;" /> |
| | | <view class="content-title" style="text-align: center;display: flex;align-items: center;justify-content: center;margin-top: 50rpx;margin-bottom: 40rpx;"> |
| | | <image style="width: 127rpx;height: 18rpx;" src="/static/img/nion1.png"></image> |
| | | <view style="font-size: 36rpx;margin: 0 20rpx;color: #370606;">专享会员实物权益</view> |
| | | <image style="width: 127rpx;height: 18rpx;" src="/static/img/nion.png"></image> |
| | | </view> |
| | | <view class="physical" style="background: url('/static/img/qsPhysical.png') no-repeat top center; background-size: 100%;width: 100%;height: 1580rpx;"> |
| | | |
| | | </view> |
| | | <view style="width: 690rpx;margin-top: 20rpx;text-align: center;"> |
| | | <!-- <button @click="getTips" style="height: 100rpx;padding: 25rpx 0;color: #370606;border-radius: 50rpx;font-size: 34rpx;background-image: linear-gradient(to right, #FFEAE2, #FF6F55);">查询实物权益</button>--> |
| | | <view style="color: #333;font-size: 24rpx;padding-top: 0rpx;padding-bottom: 40rpx;">以上权益仅为预览展示,实际以商城发出为准</view> |
| | | </view> |
| | | </view> |
| | | |
| | | <!-- <view style="text-align: center;display: flex;flex-direction: row;justify-content: center"><text @click="submit(false)" style="color: #666666;margin-bottom: 20rpx;font-size: 28rpx">不同意</text></view>--> |
| | | </view> |
| | | <textBox v-if="showTextBox" ref="textBox" :code="memberPeriodConfigInfo.protocolCode" :title="memberPeriodConfigInfo.protocolName"></textBox> |
| | | </view> |
| | | </template> |
| | | |
| | | <style scoped lang="scss"> |
| | | /* tab */ |
| | | .tab-wrap { |
| | | display: flex; |
| | | justify-content: space-evenly; |
| | | margin-bottom: 50rpx; |
| | | margin-top: 50rpx; |
| | | } |
| | | .tab-wrap text { |
| | | font-weight: 600; |
| | | font-size: 36rpx; |
| | | color: #666; |
| | | } |
| | | .active { |
| | | color: #333 !important; |
| | | position: relative; |
| | | &::after { |
| | | content: ""; |
| | | display: block; |
| | | width: 50rpx; |
| | | height: 8rpx; |
| | | background: linear-gradient( 91deg, #FDFAFF 0%, #F9C969 100%); |
| | | border-radius: 32rpx; |
| | | position: absolute; |
| | | bottom: -20rpx; |
| | | left: calc(50% - 25rpx); |
| | | } |
| | | } |
| | | .activityBut{ |
| | | background: #FF1472; |
| | | font-weight: 600; |
| | | //background: #EE2626; |
| | | background-image: linear-gradient(to right, #FFEAE2, #FF6F55); |
| | | font-weight: 500; |
| | | } |
| | | .disabledBut{ |
| | | background: #666666; |
| | | font-weight: 600; |
| | | } |
| | | .disabledBut{ |
| | | background: #999 !important; |
| | | background: #dddddd; |
| | | } |
| | | .head{ |
| | | padding: 0rpx 10rpx 0 30rpx; |
| | | padding: 30rpx 30rpx 0 30rpx; |
| | | |
| | | font-size: 32rpx; |
| | | color: #252938; |
| | |
| | | .mr{ |
| | | margin-right: 20rpx; |
| | | } |
| | | .tips{ |
| | | position: relative; |
| | | &::after{ |
| | | content: ''; |
| | | display: block; |
| | | position: absolute; |
| | | bottom: -38rpx; |
| | | right: 22rpx; |
| | | width: 14rpx; |
| | | height: 62rpx; |
| | | background: #FFD3DD; |
| | | border-radius: 78rpx 78rpx 78rpx 78rpx; |
| | | z-index: 2; |
| | | } |
| | | &::before{ |
| | | content: ''; |
| | | display: block; |
| | | position: absolute; |
| | | bottom: -38rpx; |
| | | width: 14rpx; |
| | | height: 62rpx; |
| | | background: #FFD3DD; |
| | | border-radius: 78rpx 78rpx 78rpx 78rpx; |
| | | z-index: 2; |
| | | } |
| | | } |
| | | } |
| | | .QXFJH{ |
| | | position: relative; |
| | | &::after{ |
| | | content: ''; |
| | | display: block; |
| | | position: absolute; |
| | | bottom: -38rpx; |
| | | right: 22rpx; |
| | | width: 14rpx; |
| | | height: 62rpx; |
| | | background: #FFD3DD; |
| | | border-radius: 78rpx 78rpx 78rpx 78rpx; |
| | | z-index: 2; |
| | | } |
| | | &::before{ |
| | | content: ''; |
| | | display: block; |
| | | position: absolute; |
| | | bottom: -38rpx; |
| | | width: 14rpx; |
| | | height: 62rpx; |
| | | left: 32rpx; |
| | | background: #FFD3DD; |
| | | border-radius: 78rpx 78rpx 78rpx 78rpx; |
| | | z-index: 2; |
| | | } |
| | | |
| | | } |
| | | .back{ |
| | | |
| | | background-image: url("/static/imgs/ba.png"); |
| | | // background-image: url("/static/img/ba.png"); |
| | | background-repeat: no-repeat; |
| | | background-size: 100% 100%; |
| | | padding: 22rpx 30rpx; |
| | | display: flex; |
| | | flex-direction: row; |
| | | } |
| | | .box{ |
| | | background-image: url('/static/imgs/QYBACKA.png'); |
| | | background-repeat: no-repeat; |
| | | background-size: 100% 100%; |
| | | background-color: #FFF4FA; |
| | | min-height: 100vh; |
| | | } |
| | | |
| | | </style> |
| | |
| | | <view class="goods-title">{{itm.title}}</view> |
| | | <view class="goods-price"> |
| | | <view>¥</view> |
| | | <view class="red">{{itm.price}}</view> |
| | | <view class="red">{{itm.vprice}}</view> |
| | | </view> |
| | | </view> |
| | | </view> |
| New file |
| | |
| | | <script> |
| | | // import {isBuy, niankas, preOrder} from "@/api/api"; |
| | | // import {orderCreate} from "@/api/order"; |
| | | // import xianlianghaojjuab from "@/pages/quanshou/components/xianlianghaojjuab.vue"; |
| | | // import tehuichongzhi from "@/pages/quanshou/components/tehuichongzhi.vue"; |
| | | import lanyaerji from "@/pages/quanshou/components/lanyaerji.vue"; |
| | | // import list from "@/pages/quanshou/components/list.vue"; |
| | | // import heijing from "@/pages/quanshou/components/heijing.vue"; |
| | | // import agreement from "@/pages/users/login/components/agreement/index.vue"; |
| | | import {mapGetters} from "vuex"; |
| | | export default { |
| | | name: "index", |
| | | components: { |
| | | // xianlianghaojjuab, |
| | | // tehuichongzhi, |
| | | lanyaerji, |
| | | // list, |
| | | // heijing, |
| | | // agreement |
| | | }, |
| | | data() { |
| | | return { |
| | | active: 0, |
| | | ls:[], |
| | | checked: false, |
| | | tips:'', |
| | | // active: 0, |
| | | VIP: 2, // 1黄金 2铂金 3黑金 |
| | | lst:[], |
| | | vipConfig: { |
| | | 1: { |
| | | bg: "/static/img/quanshou/TBBG1.png", |
| | | box: "/static/img/quanshou/VIPBOX1.png", |
| | | title: "/static/img/quanshou/VIPTXT1.png", |
| | | level: "/static/img/quanshou/VIPLVL1.png", |
| | | textClass: "vip1-text", |
| | | progressBg: "#BBA767", |
| | | growText: " 88800/100000", |
| | | benefitText: "297.00" |
| | | }, |
| | | 2: { |
| | | bg: "/static/img/quanshou/TBBG2.png", |
| | | box: "/static/img/quanshou/VIPBOX2.png", |
| | | title: "/static/img/quanshou/VIPTXT2.png", |
| | | level: "/static/img/quanshou/VIPLVL2.png", |
| | | textClass: "vip2-text", |
| | | progressBg: "#8094A6", |
| | | growText: " 88800/100000", |
| | | benefitText: "594.00" |
| | | }, |
| | | 3: { |
| | | bg: "/static/img/quanshou/TBBG3.png", |
| | | box: "/static/img/quanshou/VIPBOX3.png", |
| | | title: "/static/img/quanshou/VIPTXT3.png", |
| | | level: "/static/img/quanshou/VIPLVL3.png", |
| | | textClass: "vip3-text", |
| | | progressBg: "#7B776E", |
| | | growText: " 88800/100000", |
| | | benefitText: "891.00" |
| | | } |
| | | }, |
| | | total: 0, |
| | | }; |
| | | }, |
| | | computed: { |
| | | // ...mapGetters(['isLogin']), |
| | | currentVip() { |
| | | return this.vipConfig[this.VIP] || this.vipConfig[1]; |
| | | } |
| | | }, |
| | | onShow() { |
| | | // if(!this.isLogin){ |
| | | // niankas().then(res=>{ |
| | | // this.ls = res.data |
| | | // }) |
| | | // return; |
| | | // } |
| | | // isBuy(uni.getStorageSync('phone')).then(res=>{ |
| | | // if(!res.data && res.code===200){ |
| | | // niankas().then(res=>{ |
| | | // this.ls = res.data |
| | | // }) |
| | | // } |
| | | // }) |
| | | |
| | | |
| | | }, |
| | | |
| | | |
| | | methods: { |
| | | userAgree() { |
| | | this.$refs.agreement.open() |
| | | }, |
| | | goumaiba(){ |
| | | const _this = this; |
| | | console.log(_this.checked); |
| | | if(!_this.checked){ |
| | | return uni.showToast( { |
| | | icon: 'none', |
| | | title: '请先阅读并同意《会员服务协议》', |
| | | duration: 2000 |
| | | }) |
| | | } |
| | | |
| | | const orderDetails = |
| | | { |
| | | "attrValueId": _this.ls[0].attrValueId, |
| | | "productId": _this.ls[0].productId, |
| | | "productNum": _this.ls[0].productNum, |
| | | } |
| | | preOrder({ |
| | | "preOrderType": "buyNow", |
| | | "orderDetails":[orderDetails] |
| | | }).then(res=>{ |
| | | if(res.code == 200){ |
| | | // /pages/goods/order_payment/index?orderNo=PT160175859249666679688&payPrice=115.01 |
| | | |
| | | const pro = { |
| | | "addressId": 1, |
| | | "orderMerchantRequestList": [ |
| | | { |
| | | "shippingType": 1, |
| | | "merId": 3, |
| | | "remark": "", |
| | | "userCouponId": 0 |
| | | } |
| | | ], |
| | | "isUseIntegral": false, |
| | | "preOrderNo": res.data.orderNo, |
| | | "platUserCouponId": 0 |
| | | } |
| | | |
| | | orderCreate( pro).then(rp=>{ |
| | | uni.navigateTo({ |
| | | url: '/pages/goods/order_payment/index?orderNo='+rp.data.orderNo+'&payPrice='+rp.data.payPrice |
| | | }) |
| | | }) |
| | | |
| | | |
| | | |
| | | |
| | | } |
| | | }).catch( res=>{ |
| | | uni.showToast( { |
| | | icon: 'none', |
| | | title: res, |
| | | duration: 2000 |
| | | }) |
| | | }) |
| | | } |
| | | }, |
| | | } |
| | | </script> |
| | | |
| | | <template> |
| | | <view style="background: white;background-image: url('/static/img/BNM.png');background-repeat: no-repeat;background-size: 100% 420rpx;background-color: #F4F4F4"> |
| | | |
| | | <view style="padding-top: 30rpx;"> |
| | | |
| | | |
| | | <view style="background-image: url('/static/img/A0.png');background-repeat: no-repeat;background-size: 100% 100%;height: 230rpx;padding: 0 30rpx;display: flex;justify-content: space-between;position: relative;margin-left: 17rpx;margin-right: 17rpx;"> |
| | | <view style="font-weight: 400;font-size: 24rpx;color: #FBFFE0;padding-left: 10rpx;position: absolute;bottom: 60rpx;"></view> |
| | | </view> |
| | | |
| | | |
| | | <view style="text-align: center;margin-top: 40rpx;"> |
| | | <image style="width: 127rpx;height: 18rpx;margin-right: 20rpx;" src="@/static/img/nion1.png"></image> |
| | | <text style="font-size: 36rpx;color: #333333;font-weight: 600;">会员尊享特权</text> |
| | | <image style="width: 127rpx;height: 18rpx;margin-left: 20rpx;" src="@/static/img/nion.png"></image> |
| | | </view> |
| | | <view style="margin-top: 20rpx;display: flex;font-weight: 600;justify-content: space-around"> |
| | | <view> |
| | | <image style="height: 88rpx;width: 88rpx;" src="@/static/img/GG1.png"></image> |
| | | <view style="font-size: 24rpx;color: #333333;font-weight: 600;">甄选好物</view> |
| | | </view> |
| | | <view> |
| | | <image style="height: 88rpx;width: 88rpx;" src="@/static/img/GG2.png"></image> |
| | | <view style="font-size: 24rpx;color: #333333;font-weight: 600;">优选权益</view> |
| | | </view> |
| | | <view> |
| | | <image style="height: 88rpx;width: 88rpx;" src="@/static/img/GG3.png"></image> |
| | | <view style="font-size: 24rpx;color: #333333;font-weight: 600;">专享价格</view> |
| | | </view> |
| | | </view> |
| | | <!-- 会员购买 + 权益部分 --> |
| | | <view class="content-wrap"> |
| | | <view class="card-wrap"> |
| | | <view class="card-item" v-for="i in lst"> |
| | | <view class="card-title">{{numbs(i.period)}}期会员</view> |
| | | <view class="card-price"> |
| | | <text>¥</text> |
| | | <text class="card-num">{{ i.amount }}</text> |
| | | <text>/{{i.dateType}}</text> |
| | | </view> |
| | | <view class="card-date">{{ i.buyDate }}</view> |
| | | <view class="has-buy">{{ i.isBuy?'已扣款' : '待扣款' }}</view> |
| | | </view> |
| | | </view> |
| | | |
| | | <view class="tab-wrap"> |
| | | <text @click="active=0" :class="active==0?'active':''">实物权益</text> |
| | | <!-- <text @click="active=1" :class="active==1?'active':''">虚拟权益</text>--> |
| | | </view> |
| | | |
| | | <view class="note" style="margin-bottom: 20rpx;text-align: center;color: #666666" v-if="active==0"> |
| | | <!-- 提供的实物商品为指定的价值888元的红酒一瓶--> |
| | | 为会员提供的实物商品以平台发出商品为准 |
| | | </view> |
| | | |
| | | <lanyaerji v-if="active==0" /> |
| | | |
| | | <template v-else> |
| | | <xianlianghaojjuab v-show="VIP==1" /> |
| | | <tehuichongzhi v-show="VIP==1" style="margin-top: 50rpx;" /> |
| | | <list clssD="kk" v-show="VIP==2" style="margin-top: 10rpx;" /> |
| | | <heijing v-show="VIP==3" style="margin-top: 10rpx;" /> |
| | | </template> |
| | | </view> |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | </view> |
| | | <agreement ref="agreement"></agreement> |
| | | </view> |
| | | </template> |
| | | |
| | | <style scoped lang="scss" > |
| | | .li{ |
| | | height: 314rpx;padding: 40rpx 20rpx;text-align: center;border-radius: 24rpx;border: 4rpx solid #EEEEEE; |
| | | background: white; |
| | | position: relative; |
| | | } |
| | | |
| | | </style> |
| | | |
| | | <style scoped lang="scss"> |
| | | /* 顶部 VIP 样式 */ |
| | | .vip-bg { |
| | | background-size: 100%; |
| | | background-repeat: no-repeat; |
| | | padding-top: 60rpx; |
| | | padding-bottom: 150rpx; |
| | | } |
| | | .vip-box { |
| | | background-repeat: no-repeat; |
| | | background-size: 100% 100%; |
| | | height: 280rpx; |
| | | margin: 0 30rpx; |
| | | padding: 35rpx; |
| | | position: relative; |
| | | } |
| | | .gradient-text { |
| | | -webkit-background-clip: text; |
| | | -webkit-text-fill-color: transparent; |
| | | font-weight: 600; |
| | | } |
| | | .big-text { |
| | | margin-top: 20rpx; |
| | | font-size: 28rpx; |
| | | } |
| | | .small-text { |
| | | margin-top: 20rpx; |
| | | font-size: 24rpx; |
| | | } |
| | | .vip1-text { |
| | | background: linear-gradient(90deg, #754200, #ff9900); |
| | | -webkit-background-clip: text; |
| | | -webkit-text-fill-color: transparent; |
| | | } |
| | | .vip2-text { |
| | | background: linear-gradient(90deg, #425268, #8094A6); |
| | | -webkit-background-clip: text; |
| | | -webkit-text-fill-color: transparent; |
| | | } |
| | | .vip3-text { |
| | | background: linear-gradient(90deg, #ECD4C6, #C79372); |
| | | -webkit-background-clip: text; |
| | | -webkit-text-fill-color: transparent; |
| | | } |
| | | .progress-bar { |
| | | height: 16rpx; |
| | | border-radius: 20rpx; |
| | | width: 100%; |
| | | margin-top: 24rpx; |
| | | position: relative; |
| | | } |
| | | .progress-inner { |
| | | position: absolute; |
| | | background: #fff; |
| | | border-radius: 6rpx; |
| | | left: 0; |
| | | top: 0; |
| | | width: 50%; |
| | | height: 16rpx; |
| | | } |
| | | |
| | | /* 内容区 */ |
| | | .content-wrap { |
| | | padding: 30rpx; |
| | | background: #F4F4F4; |
| | | // border-radius: 24rpx 24rpx 0 0; |
| | | position: relative; |
| | | // top: -100rpx; |
| | | } |
| | | .card-wrap { |
| | | display: flex; |
| | | justify-content: space-between; |
| | | margin-bottom: 40rpx; |
| | | } |
| | | .card-item { |
| | | background: #fff; |
| | | border-radius: 24rpx; |
| | | padding-top: 60rpx; |
| | | text-align: center; |
| | | padding-bottom: 48rpx; |
| | | width: calc(33% - 14rpx); |
| | | position: relative; |
| | | } |
| | | .card-title { |
| | | font-size: 32rpx; |
| | | font-weight: 600; |
| | | margin-bottom: 34rpx; |
| | | } |
| | | .card-price { |
| | | color: #333; |
| | | font-size: 28rpx; |
| | | font-weight: 600; |
| | | } |
| | | .card-num { |
| | | font-size: 48rpx; |
| | | font-weight: bold; |
| | | margin: 0 8rpx; |
| | | } |
| | | .card-date { |
| | | font-size: 20rpx; |
| | | color: #666; |
| | | margin-top: 18rpx; |
| | | } |
| | | .has-buy { |
| | | background: #FF922C; |
| | | border-radius: 0 24rpx 0 24rpx; |
| | | height: 42rpx; |
| | | width: 92rpx; |
| | | font-size: 24rpx; |
| | | color: #fff; |
| | | position: absolute; |
| | | top: 0; |
| | | right: 0; |
| | | line-height: 42rpx; |
| | | } |
| | | |
| | | /* tab */ |
| | | .tab-wrap { |
| | | display: flex; |
| | | justify-content: space-evenly; |
| | | margin-bottom: 50rpx; |
| | | } |
| | | .tab-wrap text { |
| | | font-weight: 600; |
| | | font-size: 36rpx; |
| | | color: #666; |
| | | } |
| | | .active { |
| | | color: #333 !important; |
| | | position: relative; |
| | | &::after { |
| | | content: ""; |
| | | display: block; |
| | | width: 50rpx; |
| | | height: 8rpx; |
| | | background: linear-gradient(271deg, #FFE4A1 0%, #FFC57A 51%, #FFE1B9 100%); |
| | | border-radius: 32rpx; |
| | | position: absolute; |
| | | bottom: -20rpx; |
| | | left: calc(50% - 25rpx); |
| | | } |
| | | } |
| | | |
| | | /* 按钮 */ |
| | | .exchange-btn { |
| | | font-weight: 600; |
| | | font-size: 36rpx; |
| | | color: #FFD39A; |
| | | padding: 26rpx; |
| | | background: linear-gradient(271deg, #2A1601 0%, #3B2106 51%); |
| | | border-radius: 200rpx; |
| | | } |
| | | .note { |
| | | font-size: 24rpx; |
| | | color: #999; |
| | | margin-top: 20rpx; |
| | | } |
| | | |
| | | ::v-deep .li-bg{ |
| | | background: linear-gradient(138deg, #FFE4A1 0%, #FFC57A 68%, #FFE1B9 100%); |
| | | .ttis{ |
| | | color: #8B3D00; |
| | | } |
| | | } |
| | | </style> |
| New file |
| | |
| | | <script> |
| | | export default { |
| | | name: "alipay", |
| | | data() { |
| | | return { |
| | | // webviewUrl: `${this.$rongbeiUrl}/?appId=${uni.getStorageSync('userAppId')}&phone=${uni.getStorageSync('phone')}&appName=rongyouxuan`, // 默认地址 |
| | | webviewUrl: '', // H5地址 |
| | | webviewStyles: { |
| | | progress: { |
| | | color: 'transparent' |
| | | } |
| | | } |
| | | } |
| | | }, |
| | | onLoad(option) { |
| | | // 如果页面传了参数,可以拼接到 url |
| | | if (option && option.url) { |
| | | this.webviewUrl = option.url; |
| | | } |
| | | } |
| | | } |
| | | </script> |
| | | |
| | | <template> |
| | | <view class="container"> |
| | | <web-view |
| | | :webview-styles="webviewStyles" |
| | | :src="webviewUrl" |
| | | /> |
| | | </view> |
| | | </template> |
| | | |
| | | <style scoped lang="scss"> |
| | | .container { |
| | | width: 100%; |
| | | height: 100vh; |
| | | display: flex; |
| | | } |
| | | web-view { |
| | | flex: 1; // 自适应填满 |
| | | } |
| | | </style> |
| New file |
| | |
| | | <script> |
| | | export default { |
| | | name: "authorization", |
| | | data() { |
| | | return { |
| | | checkboxValue: false |
| | | } |
| | | }, |
| | | created() { |
| | | |
| | | }, |
| | | methods: { |
| | | checkboxChange(e) { |
| | | this.checkboxValue = e.detail.value.length > 0 |
| | | }, |
| | | agree(type){ |
| | | |
| | | const obj = { |
| | | '注册协议': 'REGISTRATION_AGREEMENT_APP_HWD', |
| | | '隐私政策': 'PRIVACY_POLICY_APP_HWD', |
| | | '个人信息查询及使用授权': 'PERSONAL_INFORMATION_PROCESSING_LETTER_YOUGOUXUAN' |
| | | } |
| | | |
| | | uni.navigateTo({ |
| | | url: `/pages/web/xieyi?code=${obj[type]}&title=${type}` |
| | | }) |
| | | }, |
| | | submit(){ |
| | | if(!this.checkboxValue){ |
| | | uni.showToast({ |
| | | title: '请先阅读并同意相关协议', |
| | | icon: 'none' |
| | | }) |
| | | return |
| | | } |
| | | |
| | | window.sessionStorage.setItem('LoginAuthorization', 'agree'); |
| | | uni.setStorageSync('LoginAuthorization', 'agree') |
| | | const phone = uni.getStorageSync('phone') |
| | | uni.request({ |
| | | url:this.$webHost+`/api/v2/sign/ygxSigned/${phone}`, |
| | | method: 'POST', |
| | | }) |
| | | |
| | | uni.navigateTo({ |
| | | url: '/pages/web/index' |
| | | }) |
| | | |
| | | } |
| | | } |
| | | } |
| | | </script> |
| | | |
| | | <template> |
| | | |
| | | <view style="display: flex;height: 100%;"> |
| | | <view style="background: white;flex: 1;display: flex;justify-content: end;flex-direction: column;padding-bottom: 50rpx;"> |
| | | |
| | | |
| | | <view style="text-align: center;margin: 0 54rpx;"> |
| | | <view style="margin-bottom: 40rpx; display: flex;justify-content: center"> |
| | | <view> <image src="/static/img/web/SQ1.png" style="width: 120rpx;height: 120rpx"></image></view> |
| | | |
| | | <view style="display: flex;justify-content: center;flex-direction: column"> <image src="/static/img/web/SQ2.png" style="width: 85rpx;height: 32rpx;margin: 0 50rpx;"></image></view> |
| | | <view> <image src="/static/img/web/SQ3.png" style="width: 120rpx;height: 120rpx"></image></view> |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | </view> |
| | | <view style="font-size: 32rpx; color: #333333;font-weight: 600;margin-bottom: 16rpx;">正在进入第三方合作服务平台</view> |
| | | <view style="color: #666666;font-size: 28rpx;text-align: left"> |
| | | 以下服务与本应用无关,您点击确认会跳转到第三方平台的服务页面。为保障您的合法权益,请您仔细阅读第三方用户注册服务协议、隐私政策等内容。如有疑问请联系第三方平台热线:<text style="color: #333333;font-weight: 500">400-996 -0191</text> |
| | | </view> |
| | | </view> |
| | | |
| | | <view style="margin-top: 350rpx;"> |
| | | |
| | | <view style="margin: 0 54rpx;color: #666666"> |
| | | <checkbox-group @change="checkboxChange"> |
| | | <checkbox value="1" :checked="checkboxValue" activeBorderColor="#EE2626" iconColor="#EE2626">已同意阅读并知晓</checkbox> |
| | | <text style="color: #4766FE;" @click="agree('注册协议')">《用户协议》</text>和 |
| | | <text style="color: #4766FE;" @click="agree('隐私政策')">《隐私政策》</text>和 |
| | | <text style="color: #4766FE;" @click="agree('个人信息查询及使用授权')">《个人信息查询及使用授权》</text> |
| | | </checkbox-group> |
| | | </view> |
| | | |
| | | <view style="margin: 20rpx 54rpx;"> |
| | | <button @click="submit" style="font-weight: 600;color: #FFFFFF;font-size: 34rpx;text-align: center;background: #EE2626;border-radius: 50rpx ;padding: 26rpx;" >我知道了</button> |
| | | </view> |
| | | </view> |
| | | |
| | | |
| | | </view> |
| | | </view> |
| | | </template> |
| | | <style scoped> |
| | | page{ |
| | | height: calc( 100vh - calc(44px + env(safe-area-inset-top)) ); |
| | | background: white; |
| | | } |
| | | |
| | | </style> |
| | | |
| | | |
| New file |
| | |
| | | <script> |
| | | export default { |
| | | name: "index", |
| | | data() { |
| | | return { |
| | | webviewUrl: `https://test-half.zrgy-bbg.com?orderNo=2017082991934296064&customerId=2017082994761068546&appId=94e898c4-7eba-4c7d-88c5-852b4f2e4c6e&unControl=true&returnUrl=null&showImage=1&items=60&title=小猪优选&protocol=0`, // 默认地址 |
| | | webviewStyles: { |
| | | progress: { |
| | | color: 'transparent' |
| | | } |
| | | } |
| | | } |
| | | }, |
| | | onLoad(option) { |
| | | // 如果页面传了参数,可以拼接到 url |
| | | if (option && option.path) { |
| | | this.webviewUrl = `${this.webviewUrl}${option.path}`; |
| | | } |
| | | } |
| | | } |
| | | </script> |
| | | |
| | | <template> |
| | | <view class="container"> |
| | | <web-view |
| | | :webview-styles="webviewStyles" |
| | | :src="webviewUrl" |
| | | /> |
| | | </view> |
| | | </template> |
| | | |
| | | <style scoped lang="scss"> |
| | | .container { |
| | | width: 100%; |
| | | height: 100vh; |
| | | display: flex; |
| | | } |
| | | web-view { |
| | | flex: 1; // 自适应填满 |
| | | } |
| | | </style> |
| | |
| | | <template> |
| | | <web-view class="web-view" :webview-styles="webviewStyles" :src="url" :style="{width: windowW + 'px', height: windowH + 'px'}"></web-view> |
| | | </template> |
| | | |
| | | <script> |
| | | export default { |
| | | name: "index", |
| | | data() { |
| | | return { |
| | | windowH: 0, |
| | | windowW: 0, |
| | | webviewUrl: `${this.$rongbeiUrl}/?appId=${uni.getStorageSync('userAppId')}&phone=${uni.getStorageSync('phone')}&appName=rongyouxuan`, // 默认地址 |
| | | webviewStyles: { |
| | | progress: { |
| | | color: 'transparent' |
| | | } |
| | | }, |
| | | url: '' |
| | | } |
| | | } |
| | | }, |
| | | onLoad(option) { |
| | | if(option.webUel) this.url = decodeURIComponent(option.webUel); |
| | | // 蚂蚁智能客服场景参数 |
| | | if(option.scene) this.url += `&scene=${option.scene}`; |
| | | uni.setNavigationBarTitle({ |
| | | title: option.title |
| | | }) |
| | | try { |
| | | const res = uni.getSystemInfoSync(); |
| | | this.windowW = res.windowWidth; |
| | | this.windowH = res.windowHeight; |
| | | } catch (e) { |
| | | // error |
| | | // 如果页面传了参数,可以拼接到 url |
| | | if (option && option.path) { |
| | | this.webviewUrl = `${this.webviewUrl}${option.path}`; |
| | | } |
| | | } |
| | | } |
| | | </script> |
| | | |
| | | <template> |
| | | <view class="container"> |
| | | <web-view |
| | | :webview-styles="webviewStyles" |
| | | :src="webviewUrl" |
| | | /> |
| | | </view> |
| | | </template> |
| | | |
| | | <style scoped lang="scss"> |
| | | .container { |
| | | width: 100%; |
| | | height: 100vh; |
| | | display: flex; |
| | | } |
| | | web-view { |
| | | flex: 1; // 自适应填满 |
| | | } |
| | | </style> |
| | |
| | | console.log(pro); |
| | | let code =pro.code; |
| | | let title = pro.title; |
| | | const _this = this; |
| | | uni.request( { |
| | | url: _this.$webHost+`/api/v2/protocolInfo/getProtocol?appId=b2e24d04-6a97-40a0-9894-a44237c674ac&code=${code}`, |
| | | url: this.$webHost+`/api/v2/protocolInfo/getProtocol?appId=b2e24d04-6a97-40a0-9894-a44237c674ac&code=${code}`, |
| | | success: function (res) { |
| | | _this.text = res.data.data.content; |
| | | this.text = res.data.data.content; |
| | | uni.setNavigationBarTitle({ |
| | | title: title |
| | | }) |
| | |
| | | .c-title{ |
| | | position: fixed; |
| | | left: 0; |
| | | top: var(--status-bar-height); |
| | | top: 44px; |
| | | /* top: var(--status-bar-height); */ |
| | | z-index: 99; |
| | | width: 100%; |
| | | background-color: #ebebeb; |
| | |
| | | .collect-title{ |
| | | position: fixed; |
| | | left: 0; |
| | | top: var(--status-bar-height); |
| | | top: 0; |
| | | z-index: 99; |
| | | width: 100%; |
| | | background-color: #ebebeb; |
| | |
| | | width: 60upx; |
| | | height: 60upx; |
| | | left: 30upx; |
| | | top: 30upx; |
| | | z-index: 999; |
| | | top: 60upx; |
| | | z-index: 9999999; |
| | | } |
| | | .bannerIndex{ |
| | | display: flex; |
| | |
| | | page{ |
| | | background-color: #EEEBEC; |
| | | background-color: #ffffff; |
| | | font-size: 24upx; |
| | | } |
| | | .status_bar { |
| | | height: var(--status-bar-height); |
| | | .content{ |
| | | position: absolute; |
| | | width: 100%; |
| | | padding-bottom: calc(var(--window-bottom)); |
| | | } |
| | | .page-container { |
| | | display: flex; |
| | | flex-direction: column; |
| | | min-height: 100vh; |
| | | position: relative; |
| | | padding-top: 50upx; |
| | | } |
| | | |
| | | .page-bg { |
| | | position: absolute; |
| | | top: 0; |
| | | left: 0; |
| | | width: 100%; |
| | | height: 422rpx; |
| | | z-index: 0; |
| | | } |
| | | .content { |
| | | |
| | | } |
| | | .status-bar { |
| | | width: 100%; |
| | | } |
| | | .index-top{ |
| | | background: url(@/static/imgs/index-bg.png) no-repeat; |
| | | background-size: 100% 100%; |
| | | width: 100%; |
| | | } |
| | | .index-title{ |
| | | padding: 30rpx 0; |
| | | |
| | | .btn-group { |
| | | display: flex; |
| | | margin-top: 30rpx; |
| | | } |
| | | .index-title-view{ |
| | | display: flex; |
| | | align-items: center; |
| | | } |
| | | .index-title-view-lf{ |
| | | margin: 0 32rpx; |
| | | } |
| | | .index-title-view-lf image{ |
| | | width: 144rpx; |
| | | height: 56rpx; |
| | | } |
| | | .index-title-view-lf2{ |
| | | width: 200rpx; |
| | | height: 40rpx; |
| | | background: #FF1472; |
| | | border-radius: 8rpx 8rpx 8rpx 8rpx; |
| | | text-align: center; |
| | | color: #ffffff; |
| | | line-height: 40rpx; |
| | | } |
| | | .index-title-view1{ |
| | | width: 62%; |
| | | } |
| | | .index-title-view2{ |
| | | width: 38%; |
| | | } |
| | | .index-title-view-rf { |
| | | display: flex; |
| | | .cancel-btn { |
| | | flex: 1; |
| | | justify-content: center; |
| | | align-items: center; |
| | | margin-right: 20rpx; |
| | | background-color: #f5f5f5; |
| | | } |
| | | .index-title-view-rf image{ |
| | | width: 40rpx; |
| | | height: 40rpx; |
| | | display: block; |
| | | margin: 0 auto; |
| | | .allow-btn { |
| | | flex: 1; |
| | | background-color: #007aff; |
| | | color: white; |
| | | } |
| | | .search{ |
| | | position: fixed; |
| | | left: 0; |
| | | width: 100%; |
| | | top: var(--status-bar-height); |
| | | z-index: 9999; |
| | | background: #fbf8f8; |
| | | height: 110upx; |
| | | } |
| | | .search-v{ |
| | | width: 94%; |
| | | margin-left: 3%; |
| | | display: flex; |
| | | height: 70upx; |
| | | margin-top: 20upx; |
| | | margin-bottom: 30upx; |
| | | } |
| | | .search-1{ |
| | | width: 76%; |
| | | display: flex; |
| | | justify-content: center; |
| | | align-items: center; |
| | | } |
| | | .search-1 input{ |
| | | width: 76%; |
| | | height: 72rpx; |
| | | background: #FFFFFF; |
| | | border-radius: 50rpx; |
| | | padding-left: 14%; |
| | | font-size: 26upx; |
| | | } |
| | | .search-1 image{ |
| | | position: absolute; |
| | | width: 40rpx; |
| | | height: 40rpx; |
| | | left: 8%; |
| | | } |
| | | .search-2{ |
| | | width: 20%; |
| | | display: flex; |
| | | font-size: 24upx; |
| | | justify-content: center; |
| | | align-items: center; |
| | | color: #9e9d9d; |
| | | background-color: #ffffff; |
| | | border-radius: 30upx; |
| | | } |
| | | .search-2 view{ |
| | | width: 112rpx; |
| | | height: 72rpx; |
| | | text-align: center; |
| | | line-height: 72rpx; |
| | | color: #ffffff; |
| | | background: #FF1472; |
| | | border-radius: 200rpx; |
| | | .search-icon{ |
| | | width: 40upx; |
| | | height: 40upx; |
| | | margin-right: 20upx; |
| | | } |
| | | |
| | | .tabs{ |
| | | display: flex; |
| | | margin-bottom: 20upx; |
| | | } |
| | | .tabs view{ |
| | | padding: 0 35rpx; |
| | | margin-left: 35rpx; |
| | | text-align: center; |
| | | line-height: 56rpx; |
| | | height: 56rpx; |
| | | background: #F3F4F6; |
| | | border-radius: 200rpx; |
| | | color: #364153; |
| | | } |
| | | .tabs .active { |
| | | color: #ffffff; |
| | | background: #FF1472; |
| | | } |
| | | |
| | | .banner{ |
| | | width: 94%; |
| | | margin: 40upx auto 30upx; |
| | | } |
| | | uni-swiper-item{ |
| | | border-radius: 32rpx; |
| | | margin: 20upx auto 20upx; |
| | | } |
| | | .swiper, .swiper image{ |
| | | width: 100%; |
| | | height: 278rpx; |
| | | border-radius: 32rpx; |
| | | height: 400upx; |
| | | border-radius: 16upx; |
| | | } |
| | | .comm{ |
| | | width: 94%; |
| | | margin: 20upx 3% 40upx; |
| | | display: flex; |
| | | } |
| | | .comm .comm-1{ |
| | | width: 48%; |
| | | height: 278rpx; |
| | | border-radius: 32rpx; |
| | | background-color: #ffffff; |
| | | } |
| | | .comm .comm-2{ |
| | | width: 4%; |
| | | height: 278rpx; |
| | | } |
| | | .comm .comm-3{ |
| | | width: 48%; |
| | | height: 278rpx; |
| | | border-radius: 32rpx; |
| | | background-color: #ffffff; |
| | | } |
| | | .comm-title image{ |
| | | width: 128rpx; |
| | | height: 40rpx; |
| | | margin: 24rpx 26rpx; |
| | | } |
| | | .comm-goods{ |
| | | display: flex; |
| | | } |
| | | .comm-goods .comm-goods-v{ |
| | | flex: 1; |
| | | display: flex; |
| | | text-align: center; |
| | | justify-content: center; |
| | | } |
| | | .comm-goods-v text{ |
| | | font-family: PingFang SC, PingFang SC; |
| | | font-weight: 600; |
| | | font-size: 24rpx; |
| | | color: #FB2C36; |
| | | text-align: left; |
| | | font-style: normal; |
| | | text-transform: none; |
| | | } |
| | | .comm-goods image{ |
| | | width: 128rpx; |
| | | height: 128rpx; |
| | | border-radius: 20rpx; |
| | | } |
| | | .hots{ |
| | | width: 94%; |
| | | margin: 20upx auto 40rpx; |
| | | height: 280rpx; |
| | | background: #FFFFFF; |
| | | border-radius: 32rpx 32rpx 32rpx 32rpx; |
| | | } |
| | | .hots-title{ |
| | | padding: 24rpx 26rpx; |
| | | } |
| | | .hots-title .hots-icon{ |
| | | width: 192rpx; |
| | | height: 40rpx; |
| | | border-radius: 0rpx 0rpx 0rpx 0rpx; |
| | | } |
| | | .hots-rgt{ |
| | | float: right; |
| | | display: flex; |
| | | align-items: center; |
| | | } |
| | | .hots-rgt text{ |
| | | font-family: PingFang SC, PingFang SC; |
| | | font-weight: 400; |
| | | font-size: 24rpx; |
| | | color: #666666; |
| | | text-align: left; |
| | | font-style: normal; |
| | | text-transform: none; |
| | | margin-right: 10rpx; |
| | | } |
| | | .hots-rgt image{ |
| | | width: 32rpx; |
| | | height: 32rpx; |
| | | } |
| | | .hots-goods{ |
| | | display: flex; |
| | | } |
| | | .hots-goods .hots-goods-v{ |
| | | flex: 1; |
| | | display: flex; |
| | | text-align: center; |
| | | justify-content: center; |
| | | } |
| | | .hots-goods-v text{ |
| | | font-family: PingFang SC, PingFang SC; |
| | | font-weight: 600; |
| | | font-size: 24rpx; |
| | | color: #FB2C36; |
| | | text-align: left; |
| | | font-style: normal; |
| | | text-transform: none; |
| | | } |
| | | .hots-goods image{ |
| | | width: 136rpx; |
| | | height: 136rpx; |
| | | border-radius: 20rpx; |
| | | } |
| | | |
| | | .cates{ |
| | | width: 94%; |
| | | margin: 0upx 3%; |
| | | display: inline-block; |
| | | border-top-left-radius: 10upx; |
| | | border-top-right-radius: 10upx; |
| | | padding: 0upx 0 0upx 0; |
| | | width: 100%; |
| | | margin: 0; |
| | | border-top-right-radius: 30rpx; |
| | | border-top-left-radius: 30rpx; |
| | | background-color: #ffffff; |
| | | padding: 0; |
| | | display: flex; |
| | | flex-wrap: wrap; /* 确保子元素换行 */ |
| | | } |
| | | .cates-v{ |
| | | float: left; |
| | | width: 20%; |
| | | border-radius: 50%; |
| | | width: 25%; |
| | | margin-bottom: 0upx; |
| | | } |
| | | .cates-v-icon{ |
| | | width: 80upx; |
| | | height: 80upx; |
| | | width: 90rpx; |
| | | height: 90rpx; |
| | | display: block; |
| | | margin: 40upx auto 20upx; |
| | | border-radius: 50%; |
| | | border-radius: 10upx; |
| | | } |
| | | .cates-v view{ |
| | | text-align: center; |
| | |
| | | } |
| | | .goods-main{ |
| | | width: 94%; |
| | | margin: 0upx auto 0upx; |
| | | border-bottom-left-radius: 10upx; |
| | | border-bottom-right-radius: 10upx; |
| | | border-top: 1px solid #eeeeee; |
| | | margin: 10upx auto 30upx; |
| | | background-color: #ffffff; |
| | | border-radius: 10upx; |
| | | } |
| | | .goods-main-title{ |
| | | padding: 20upx; |
| | |
| | | height: 340upx; |
| | | } |
| | | .goods-list{ |
| | | width: 100%; |
| | | width: 96%; |
| | | display: flex; |
| | | margin-left: 2%; |
| | | flex-wrap: wrap; |
| | | justify-content: space-between; |
| | | } |
| | | .hyj{ |
| | | display: flex; |
| | | justify-content: center; |
| | | margin-left: 10rpx; |
| | | margin-right: 10rpx; |
| | | } |
| | | .hyj image{ |
| | | width: 74rpx; |
| | | height: 32rpx; |
| | | } |
| | | .goods-item{ |
| | | width: 48%; |
| | |
| | | margin-bottom: 20upx; |
| | | } |
| | | .goods-price{ |
| | | margin-top: 16upx; |
| | | margin-top: 0upx; |
| | | display: flex; |
| | | align-items: center; |
| | | color: #F75451; |
| | |
| | | padding-bottom: 20upx; |
| | | } |
| | | .goods-price .red{ |
| | | font-size: 26upx !important; |
| | | margin-left: 10upx; |
| | | font-size: 24rpx !important; |
| | | font-weight: 600; |
| | | } |
| | | .goods-title{ |
| | |
| | | |
| | | .auth{ |
| | | width: 94%; |
| | | margin: 30upx auto; |
| | | margin: 110upx auto 0; |
| | | height: 240upx; |
| | | } |
| | | .auth image{ |
| | |
| | | font-weight: 700; |
| | | font-size: 28upx; |
| | | } |
| | | |
| | | .auth{ |
| | | .hLogo{ |
| | | width: 96%; |
| | | padding: 40upx 0; |
| | | margin: 0 auto; |
| | | } |
| | | .hLogoView{ |
| | | display: flex; |
| | | align-items: center; |
| | | } |
| | | .h-logo{ |
| | | width: 211rpx; |
| | | height: 48rpx; |
| | | } |
| | | .hLogo-1{ |
| | | margin: 0 30upx; |
| | | } |
| | | .hLogo-2{ |
| | | position: relative; |
| | | width: 420rpx; |
| | | height: 70rpx; |
| | | background: url(@/static/imgs/input-bg.png) no-repeat; |
| | | background-size: 100% 100%; |
| | | } |
| | | .hLogo-2 .s-icon{ |
| | | position: absolute; |
| | | left: 30rpx; |
| | | top: 20rpx; |
| | | width: 30rpx; |
| | | height: 30rpx; |
| | | } |
| | | .hLogo-2 input{ |
| | | width: 83%; |
| | | height: 70rpx; |
| | | line-height: 70rpx; |
| | | font-size: 28rpx; |
| | | background: transparent; |
| | | padding-left: 70rpx; |
| | | } |
| | | .xxhh-v{ |
| | | width: 96%; |
| | | margin: 0 auto; |
| | | padding: 10upx 0; |
| | | height: 195rpx; |
| | | position: relative; |
| | | } |
| | | .auth-over{ |
| | | background: linear-gradient(#e58585, #d19323); |
| | | .xxhh-v-icon{ |
| | | position: absolute; |
| | | width: 100%; |
| | | height: 100%; |
| | | } |
| | | .xxhh-title{ |
| | | display: flex; |
| | | padding: 20upx; |
| | | align-items: center; |
| | | } |
| | | .xxk-icon{ |
| | | width: 201rpx; |
| | | height: 47rpx; |
| | | margin-right: 23rpx; |
| | | } |
| | | .xxhh-title text{ |
| | | z-index: 99; |
| | | font-size: 22rpx; |
| | | color: #261B18; |
| | | } |
| | | .xxhh-edu{ |
| | | padding-top: 16upx; |
| | | padding-bottom: 16upx; |
| | | z-index: 99; |
| | | } |
| | | .xxhh-edu text{ |
| | | margin-left: 20upx; |
| | | color: #AEA3A2; |
| | | font-size: 24rpx; |
| | | } |
| | | .xxhh-money{ |
| | | padding-top: 0; |
| | | margin-left: 10upx; |
| | | } |
| | | .xxhh-money text{ |
| | | font-size: 48rpx; |
| | | color: #A18685; |
| | | font-weight: 700; |
| | | } |
| | | |
| | | .xxhf{ |
| | | width: 96%; |
| | | margin: 0 auto 30upx; |
| | | height: 325rpx; |
| | | background: url(@/static/imgs/xxhf.png) no-repeat; |
| | | background-size: 100%; |
| | | border-radius: 20upx; |
| | | } |
| | | .auth-over-edu{ |
| | | padding: 30upx 50upx; |
| | | color: #ffffff; |
| | | } |
| | | .auth-over-edu text{ |
| | | display: block; |
| | | } |
| | | .auth-over-edu-til{ |
| | | font-weight: 500; |
| | | font-size: 30upx; |
| | | letter-spacing: 4upx; |
| | | margin-bottom: 14upx; |
| | | } |
| | | .auth-over-edu-price{ |
| | | .xxhf-title{ |
| | | padding: 24upx 80upx; |
| | | color: #5B2D2C; |
| | | font-size: 32rpx; |
| | | font-weight: 700; |
| | | font-size: 80upx; |
| | | letter-spacing: 5upx; |
| | | margin-bottom: 14upx; |
| | | } |
| | | .auth-over-btn{ |
| | | .xxhf-v{ |
| | | width: 96%; |
| | | height: 220rpx; |
| | | margin: 0 auto 5%; |
| | | display: flex; |
| | | background-color: #ffffff; |
| | | border-radius: 20upx; |
| | | } |
| | | .xxhv-v{ |
| | | flex: 1; |
| | | height: 100%; |
| | | } |
| | | .deb-icon{ |
| | | width: 100%; |
| | | height: 100%; |
| | | } |
| | | .xxhv-vv-1{ |
| | | width: 180rpx; |
| | | height: 180rpx; |
| | | margin: 20rpx 0 20rpx 12%; |
| | | background: #EFEFEF; |
| | | border-radius: 14rpx; |
| | | border: 3px solid #FFABB5; |
| | | } |
| | | .xxhv-vv-2{ |
| | | width: 180rpx; |
| | | height: 180rpx; |
| | | margin: 20rpx 0 20rpx 4%; |
| | | background: #EFEFEF; |
| | | border-radius: 14rpx; |
| | | border: 3px solid #FFABB5; |
| | | } |
| | | .xxhv-vv-t{ |
| | | width: 90%; |
| | | height: 46rpx; |
| | | margin: -3rpx auto; |
| | | font-family: Source Han Sans CN; |
| | | font-weight: 400; |
| | | font-size: 26rpx; |
| | | color: #F8F9FD; |
| | | line-height: 52rpx; |
| | | background-size: 100%; |
| | | text-align: center; |
| | | } |
| | | .xxhv-icon{ |
| | | width: 100%; |
| | | height: 134rpx; |
| | | } |
| | | .xx-icon{ |
| | | width: 80upx; |
| | | height: 80upx; |
| | | display: block; |
| | | margin: 27rpx auto; |
| | | border-radius: 10rpx; |
| | | } |
| | | .notice{ |
| | | width: 96%; |
| | | margin: 0 2% 20upx; |
| | | background: #ffffff; |
| | | height: 80upx; |
| | | display: flex; |
| | | border-radius: 20upx; |
| | | } |
| | | .n-icon{ |
| | | width: 50upx; |
| | | height: 50upx; |
| | | margin: 15upx 20upx; |
| | | } |
| | | .marquee-container { |
| | | width: 100%; |
| | | overflow: hidden; |
| | | white-space: nowrap; |
| | | box-sizing: border-box; |
| | | } |
| | | .marquee-content { |
| | | height: 100%; |
| | | line-height: 80upx; |
| | | font-size: 28upx; |
| | | color: #e36900; |
| | | font-weight: 700; |
| | | display: inline-block; |
| | | padding-left: 100%; /* 初始偏移 */ |
| | | animation: marquee 10s linear infinite; /* 动画名称、持续时间、速度曲线、重复次数 */ |
| | | } |
| | | @keyframes marquee { |
| | | 0% { transform: translateX(0); } |
| | | 100% { transform: translateX(-100%); } |
| | | } |
| | | .kttv{ |
| | | width: 156rpx; |
| | | height: 62rpx; |
| | | background-size: 100%; |
| | | position: absolute; |
| | | right: 30upx; |
| | | top: 38%; |
| | | padding: 20upx 50upx; |
| | | border-radius: 30upx; |
| | | background: #ffffff; |
| | | color: #333333; |
| | | font-weight: 700; |
| | | font-size: 28upx; |
| | | box-shadow: 2px 2px 2px #d1233c; |
| | | bottom: 10upx; |
| | | } |
| | | .auth-over-edu-tip{ |
| | | font-weight: 700; |
| | | font-size: 32upx; |
| | | letter-spacing: 5upx; |
| | | margin-bottom: 14upx; |
| | | } |
| | | .auth-2{ |
| | | height: auto; |
| | | .kttv text{ |
| | | color: #ffffff; |
| | | margin-left: 30upx; |
| | | line-height: 62rpx; |
| | | } |
| | | |
| | | .close-edu{ |
| | | position: absolute; |
| | | width: 60upx; |
| | | height: 60upx; |
| | | right: 20upx; |
| | | top: 20upx; |
| | | .ad1{ |
| | | width: 96%; |
| | | margin: 20upx auto 20upx; |
| | | height: 320rpx; |
| | | } |
| | | .ad1 image{ |
| | | width: 100%; |
| | | height: 100%; |
| | | } |
| | | |
| | | .ad2{ |
| | | width: 96%; |
| | | margin: 10upx auto 20upx; |
| | | height: 270rpx; |
| | | } |
| | | .ad2 image{ |
| | | width: 100%; |
| | | height: 100%; |
| | | } |
| | | .ad3{ |
| | | width: 96%; |
| | | margin: 10upx auto 20upx; |
| | | height: 260rpx; |
| | | } |
| | | .ad3 image{ |
| | | width: 100%; |
| | | height: 100%; |
| | | } |
| | | |
| | | .ca-ad{ |
| | | width: 96%; |
| | | margin: 10upx auto 20upx; |
| | | height: 200rpx; |
| | | } |
| | | .ca-ad image{ |
| | | width: 100%; |
| | | height: 100%; |
| | | } |
| | | .cGoods{ |
| | | width: 96%; |
| | | margin: 0 auto 20upx; |
| | | padding: 20rpx 0; |
| | | } |
| | | .scroll-view_H { |
| | | white-space: nowrap; |
| | | width: 100%; |
| | | background-color: #eeeeee; |
| | | } |
| | | |
| | | .scroll-view-item_H { |
| | | display: inline-block; |
| | | width: 25%; |
| | | width: 200rpx; |
| | | padding-top: 20rpx; |
| | | text-align: center; |
| | | font-size: 26rpx; |
| | | padding: 20upx 0; |
| | | font-size: 36rpx; |
| | | background-color: #ffffff; |
| | | margin-right: 20rpx; |
| | | border-radius: 20rpx; |
| | | } |
| | | .scroll-view-v{ |
| | | .scroll-view-item_H image{ |
| | | width: 118rpx; |
| | | height: 128rpx; |
| | | } |
| | | |
| | | .login-desc{ |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: center; |
| | | width: 96%; |
| | | position: fixed; |
| | | left: 2%; |
| | | bottom: calc(var(--window-bottom) + 20rpx); |
| | | height: 100rpx; |
| | | background: rgba(0,0,0,0.7); |
| | | border-radius: 106rpx 106rpx 106rpx 106rpx; |
| | | } |
| | | .scroll-icon{ |
| | | width: 40upx; |
| | | height: 40upx; |
| | | border-radius: 30upx; |
| | | margin-right: 10upx; |
| | | .login-icon{ |
| | | margin-left: 20rpx; |
| | | width: 90rpx; |
| | | height: 90rpx; |
| | | margin-right: 30rpx; |
| | | } |
| | | ::-webkit-scrollbar { |
| | | width: 0px !important; /* 滚动条宽度 */ |
| | | } |
| | | /* 设置滚动条宽度 */ |
| | | .uni-scroll-view::-webkit-scrollbar { |
| | | width: 0px !important; /* 滚动条宽度 */ |
| | | } |
| | | .scroll-active{ |
| | | background-color: #ffb16e; |
| | | .login-font{ |
| | | width: 55%; |
| | | font-size: 26rpx; |
| | | color: #ffffff; |
| | | } |
| | | .login-btn{ |
| | | width: 156rpx; |
| | | height: 54rpx; |
| | | text-align: center; |
| | | color: #ffffff; |
| | | line-height: 54rpx; |
| | | background: #EE2626; |
| | | border-radius: 62rpx 62rpx 62rpx 62rpx; |
| | | } |
| | | .c-goods{ |
| | | background-color: #f5f5f5; |
| | | } |
| New file |
| | |
| | | .myView-bg { |
| | | position: absolute; |
| | | top: 0; |
| | | left: 0; |
| | | width: 100%; |
| | | height: 908rpx; |
| | | z-index: 0; |
| | | } |
| | | .avatar{ |
| | | width: 112rpx; |
| | | height: 112rpx; |
| | | margin: 50rpx 30rpx 50rpx 50rpx; |
| | | border-radius: 50%; |
| | | } |
| | | .myContent{ |
| | | width: 100%; |
| | | position: absolute; |
| | | } |
| | | .myHeader{ |
| | | color: #ffffff; |
| | | display: flex; |
| | | align-items: center; |
| | | font-size: 28rpx; |
| | | } |
| | | .myNick{ |
| | | margin-top: 10rpx; |
| | | } |
| | | .edu { |
| | | margin-top: 10rpx; |
| | | width: 108rpx; |
| | | height: 44rpx; |
| | | background: rgba(255,255,255,0.1); |
| | | border-radius: 66rpx 66rpx 66rpx 66rpx; |
| | | border: 2rpx solid #FFFFFF; |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: center; |
| | | font-size: 20rpx; |
| | | } |
| | | .auth{ |
| | | display: flex; |
| | | align-items: center; |
| | | width: 650rpx; |
| | | height: 86rpx; |
| | | margin: 0 auto; |
| | | background: #FFFFFF; |
| | | border-radius: 68rpx 68rpx 68rpx 68rpx; |
| | | font-size: 24rpx; |
| | | color: #333333; |
| | | } |
| | | .auth image{ |
| | | width: 48rpx; |
| | | height: 48rpx; |
| | | margin: 0 10rpx; |
| | | } |
| | | .auth text{ |
| | | margin-right: 30rpx; |
| | | } |
| | | .auth view{ |
| | | width: 100rpx; |
| | | height: 44rpx; |
| | | background: #EE2626; |
| | | border-radius: 50rpx 50rpx 50rpx 50rpx; |
| | | display: flex; |
| | | justify-content: center; |
| | | align-items: center; |
| | | color: #ffffff; |
| | | } |
| | | |
| | | .navs{ |
| | | width: 650rpx; |
| | | margin: 30rpx auto; |
| | | background-color: #ffffff; |
| | | height: 236rpx; |
| | | border-radius: 20rpx; |
| | | box-shadow: 0px 0px 0px 1px #f5f5f5; |
| | | } |
| | | .navs .title{ |
| | | padding: 30rpx 20rpx; |
| | | font-size: 24rpx; |
| | | } |
| | | .navs .title text{ |
| | | font-size: 28rpx; |
| | | color: #333333; |
| | | font-weight: 700; |
| | | } |
| | | .navs-rgt{ |
| | | display: flex; |
| | | align-items: center; |
| | | float: right; |
| | | } |
| | | .navs-rgt text{ |
| | | font-size: 24rpx !important; |
| | | font-weight: 500 !important; |
| | | } |
| | | .navs .title image{ |
| | | margin-left: 5rpx; |
| | | width: 28rpx; |
| | | height: 28rpx; |
| | | } |
| | | .navCon { |
| | | margin-top: 15rpx; |
| | | display: flex; |
| | | } |
| | | .navCon .navCon-v{ |
| | | flex: 1; |
| | | text-align: center; |
| | | font-size: 24rpx; |
| | | } |
| | | .navCon image{ |
| | | display: block; |
| | | width: 64rpx; |
| | | height: 64rpx; |
| | | margin: 0 auto 10rpx; |
| | | } |
| | | .mySer{ |
| | | width: 650rpx; |
| | | margin: 30rpx auto; |
| | | background-color: #ffffff; |
| | | height: 402rpx; |
| | | border-radius: 20rpx; |
| | | box-shadow: 0px 0px 0px 1px #f5f5f5; |
| | | } |
| | | .mySer .title{ |
| | | padding: 30rpx 20rpx; |
| | | font-size: 28rpx; |
| | | color: #333333; |
| | | font-weight: 700; |
| | | } |
| | | .mySerCon{ |
| | | display: flex; |
| | | flex-wrap: wrap; |
| | | } |
| | | .mySerCon .mySerCon-v{ |
| | | width: 33.33%; |
| | | margin-bottom: 50rpx; |
| | | font-size: 24rpx; |
| | | text-align: center; |
| | | } |
| | | .mySerCon image{ |
| | | width: 72rpx; |
| | | height: 72rpx; |
| | | display: block; |
| | | margin: 0 auto 10rpx; |
| | | } |
| | | .myBeiAn{ |
| | | margin-top: 50rpx; |
| | | text-align: center; |
| | | font-size: 24rpx; |
| | | color: #666666; |
| | | } |
| | | .myBeiAn view{ |
| | | margin-bottom: 10rpx; |
| | | } |
| | |
| | | font-size: 26upx; |
| | | } |
| | | .searchKey{ |
| | | margin-top: 120upx; |
| | | margin-top: 160upx; |
| | | padding: 0 30upx; |
| | | } |
| | | .searchKey .title{ |
| | |
| | | margin-right: 20upx; |
| | | } |
| | | .goodsData{ |
| | | margin-top: 120upx; |
| | | margin-top: 160upx; |
| | | } |
| | | .goods-icon{ |
| | | width: 400upx; |
| | |
| | | ## 1.9.10(2025-07-18) |
| | | - 修复 nvue 下弹窗样式错乱的问题 ,更新依赖 uni-transition 组件 |
| | | - 更新 示例取消 borderRadius 属性 ,如需内容圆角,用户应该直接在内容插槽中实现 |
| | | ## 1.9.9(2025-06-11) |
| | | - 修复 uni-popup-dialog 中 setVal 方法报错的问题 |
| | | - 修复 uni-popup-dialog 数据双向绑定问题。 |
| | | ## 1.9.8(2025-04-16) |
| | | - 修复 更新组件示例 ,解决更新数据或保存项目导致弹窗消失的问题 |
| | | ## 1.9.7(2025-04-14) |
| | | - 修复 uni-popup-dialog 弹出框在vue3中双向绑定问题 |
| | | ## 1.9.6(2025-01-08) |
| | | - 修复 示例中过期图片地址 |
| | | ## 1.9.5(2024-10-15) |
| | | - 修复 微信小程序中的getSystemInfo警告 |
| | | ## 1.9.2(2024-09-21) |
| | | - 修复 uni-popup在android上的重复点击弹出位置不正确的bug |
| | | ## 1.9.1(2024-04-02) |
| | | - 修复 uni-popup-dialog vue3下使用value无法进行绑定的bug(双向绑定兼容旧写法) |
| | | ## 1.9.0(2024-03-28) |
| | | - 修复 uni-popup-dialog 双向绑定时初始化逻辑修正 |
| | | ## 1.8.9(2024-03-20) |
| | | - 修复 uni-popup-dialog 数据输入时修正为双向绑定 |
| | | ## 1.8.8(2024-02-20) |
| | | - 修复 uni-popup 在微信小程序下出现文字向上闪动的bug |
| | | ## 1.8.7(2024-02-02) |
| | | - 新增 uni-popup-dialog 新增属性focus:input模式下,是否自动自动聚焦 |
| | | ## 1.8.6(2024-01-30) |
| | | - 新增 uni-popup-dialog 新增属性maxLength:限制输入框字数 |
| | | ## 1.8.5(2024-01-26) |
| | | - 新增 uni-popup-dialog 新增属性showClose:控制关闭按钮的显示 |
| | | ## 1.8.4(2023-11-15) |
| | | - 新增 uni-popup 支持uni-app-x 注意暂时仅支持 `maskClick` `@open` `@close` |
| | | ## 1.8.3(2023-04-17) |
| | | - 修复 uni-popup 重复打开时的 bug |
| | | ## 1.8.2(2023-02-02) |
| | |
| | | </view> |
| | | <view v-else class="uni-dialog-content"> |
| | | <slot> |
| | | <input class="uni-dialog-input" v-model="val" :type="inputType" :placeholder="placeholderText" :focus="focus" > |
| | | <input class="uni-dialog-input" :maxlength="maxlength" v-model="val" :type="inputType" |
| | | :placeholder="placeholderText" :focus="focus"> |
| | | </slot> |
| | | </view> |
| | | <view class="uni-dialog-button-group"> |
| | | <view class="uni-dialog-button" @click="closeDialog"> |
| | | <view class="uni-dialog-button" v-if="showClose" @click="closeDialog"> |
| | | <text class="uni-dialog-button-text">{{closeText}}</text> |
| | | </view> |
| | | <view class="uni-dialog-button uni-border-left" @click="onOk"> |
| | | <view class="uni-dialog-button" :class="showClose?'uni-border-left':''" @click="onOk"> |
| | | <text class="uni-dialog-button-text uni-button-color">{{okText}}</text> |
| | | </view> |
| | | </view> |
| | |
| | | initVueI18n |
| | | } from '@dcloudio/uni-i18n' |
| | | import messages from '../uni-popup/i18n/index.js' |
| | | const { t } = initVueI18n(messages) |
| | | const { |
| | | t |
| | | } = initVueI18n(messages) |
| | | /** |
| | | * PopUp 弹出层-对话框样式 |
| | | * @description 弹出层-对话框样式 |
| | | * @tutorial https://ext.dcloud.net.cn/plugin?id=329 |
| | | * @property {String} value input 模式下的默认值 |
| | | * @property {String} placeholder input 模式下输入提示 |
| | | * @property {Boolean} focus input模式下是否自动聚焦,默认为true |
| | | * @property {String} type = [success|warning|info|error] 主题样式 |
| | | * @value success 成功 |
| | | * @value warning 提示 |
| | |
| | | * @property {String} mode = [base|input] 模式、 |
| | | * @value base 基础对话框 |
| | | * @value input 可输入对话框 |
| | | * @showClose {Boolean} 是否显示关闭按钮 |
| | | * @property {String} content 对话框内容 |
| | | * @property {Boolean} beforeClose 是否拦截取消事件 |
| | | * @property {Number} maxlength 输入 |
| | | * @event {Function} confirm 点击确认按钮触发 |
| | | * @event {Function} close 点击取消按钮触发 |
| | | */ |
| | |
| | | export default { |
| | | name: "uniPopupDialog", |
| | | mixins: [popup], |
| | | emits:['confirm','close'], |
| | | emits: ['confirm', 'close', 'update:modelValue', 'input'], |
| | | props: { |
| | | inputType:{ |
| | | type: String, |
| | | default: 'text' |
| | | }, |
| | | showClose: { |
| | | type: Boolean, |
| | | default: true |
| | | }, |
| | | // #ifdef VUE2 |
| | | value: { |
| | | type: [String, Number], |
| | | default: '' |
| | | }, |
| | | // #endif |
| | | // #ifdef VUE3 |
| | | modelValue: { |
| | | type: [Number, String], |
| | | default: '' |
| | | }, |
| | | // #endif |
| | | |
| | | |
| | | placeholder: { |
| | | type: [String, Number], |
| | | default: '' |
| | |
| | | confirmText:{ |
| | | type: String, |
| | | default: '' |
| | | }, |
| | | maxlength: { |
| | | type: Number, |
| | | default: -1, |
| | | }, |
| | | focus: { |
| | | type: Boolean, |
| | | default: true, |
| | | } |
| | | }, |
| | | data() { |
| | | return { |
| | | dialogType: 'error', |
| | | focus: false, |
| | | val: "" |
| | | } |
| | | }, |
| | |
| | | } |
| | | }, |
| | | value(val) { |
| | | this.val = val |
| | | this.setVal(val) |
| | | }, |
| | | // #ifdef VUE3 |
| | | modelValue(val) { |
| | | this.setVal(val) |
| | | }, |
| | | // #endif |
| | | val(val) { |
| | | // #ifdef VUE2 |
| | | // TODO 兼容 vue2 |
| | | this.$emit('input', val); |
| | | // #endif |
| | | // #ifdef VUE3 |
| | | // TODO 兼容 vue3 |
| | | this.$emit('update:modelValue', val); |
| | | // #endif |
| | | } |
| | | }, |
| | | created() { |
| | |
| | | // this.popup.closeMask() |
| | | if (this.mode === 'input') { |
| | | this.dialogType = 'info' |
| | | this.val = this.value |
| | | this.val = this.value; |
| | | // #ifdef VUE3 |
| | | this.val = this.modelValue; |
| | | // #endif |
| | | } else { |
| | | this.dialogType = this.type |
| | | } |
| | | }, |
| | | mounted() { |
| | | this.focus = true |
| | | }, |
| | | methods: { |
| | | /** |
| | | * 给val属性赋值 |
| | | */ |
| | | setVal(val) { |
| | | if (this.maxlength != -1 && this.mode === 'input') { |
| | | this.val = val.slice(0, this.maxlength); |
| | | } else { |
| | | this.val = val |
| | | } |
| | | }, |
| | | /** |
| | | * 点击确认按钮 |
| | | */ |
| | | onOk() { |
| | |
| | | }, |
| | | data() { |
| | | return { |
| | | // TODO 替换为自己的图标 |
| | | bottomData: [{ |
| | | text: '微信', |
| | | icon: 'https://vkceyugu.cdn.bspapp.com/VKCEYUGU-dc-site/c2b17470-50be-11eb-b680-7980c8a877b8.png', |
| | | icon: 'https://qiniu-web-assets.dcloud.net.cn/unidoc/zh/unicloudlogo.png', |
| | | name: 'wx' |
| | | }, |
| | | { |
| | | text: '支付宝', |
| | | icon: 'https://vkceyugu.cdn.bspapp.com/VKCEYUGU-dc-site/d684ae40-50be-11eb-8ff1-d5dcf8779628.png', |
| | | name: 'wx' |
| | | icon: 'https://qiniu-web-assets.dcloud.net.cn/unidoc/zh/unicloudlogo.png', |
| | | name: 'ali' |
| | | }, |
| | | { |
| | | text: 'QQ', |
| | | icon: 'https://vkceyugu.cdn.bspapp.com/VKCEYUGU-dc-site/e7a79520-50be-11eb-b997-9918a5dda011.png', |
| | | icon: 'https://qiniu-web-assets.dcloud.net.cn/unidoc/zh/unicloudlogo.png', |
| | | name: 'qq' |
| | | }, |
| | | { |
| | | text: '新浪', |
| | | icon: 'https://vkceyugu.cdn.bspapp.com/VKCEYUGU-dc-site/0dacdbe0-50bf-11eb-8ff1-d5dcf8779628.png', |
| | | icon: 'https://qiniu-web-assets.dcloud.net.cn/unidoc/zh/unicloudlogo.png', |
| | | name: 'sina' |
| | | }, |
| | | // { |
| New file |
| | |
| | | <template> |
| | | <view class="popup-root" v-if="isOpen" v-show="isShow" @click="clickMask"> |
| | | <view @click.stop> |
| | | <slot></slot> |
| | | </view> |
| | | </view> |
| | | </template> |
| | | |
| | | <script> |
| | | type CloseCallBack = ()=> void; |
| | | let closeCallBack:CloseCallBack = () :void => {}; |
| | | export default { |
| | | emits:["close","clickMask"], |
| | | data() { |
| | | return { |
| | | isShow:false, |
| | | isOpen:false |
| | | } |
| | | }, |
| | | props: { |
| | | maskClick: { |
| | | type: Boolean, |
| | | default: true |
| | | }, |
| | | }, |
| | | watch: { |
| | | // 设置show = true 时,如果没有 open 需要设置为 open |
| | | isShow:{ |
| | | handler(isShow) { |
| | | // console.log("isShow",isShow) |
| | | if(isShow && this.isOpen == false){ |
| | | this.isOpen = true |
| | | } |
| | | }, |
| | | immediate:true |
| | | }, |
| | | // 设置isOpen = true 时,如果没有 isShow 需要设置为 isShow |
| | | isOpen:{ |
| | | handler(isOpen) { |
| | | // console.log("isOpen",isOpen) |
| | | if(isOpen && this.isShow == false){ |
| | | this.isShow = true |
| | | } |
| | | }, |
| | | immediate:true |
| | | } |
| | | }, |
| | | methods:{ |
| | | open(){ |
| | | // ...funs : CloseCallBack[] |
| | | // if(funs.length > 0){ |
| | | // closeCallBack = funs[0] |
| | | // } |
| | | this.isOpen = true; |
| | | }, |
| | | clickMask(){ |
| | | if(this.maskClick == true){ |
| | | this.$emit('clickMask') |
| | | this.close() |
| | | } |
| | | }, |
| | | close(): void{ |
| | | this.isOpen = false; |
| | | this.$emit('close') |
| | | closeCallBack() |
| | | }, |
| | | hiden(){ |
| | | this.isShow = false |
| | | }, |
| | | show(){ |
| | | this.isShow = true |
| | | } |
| | | } |
| | | } |
| | | </script> |
| | | |
| | | <style> |
| | | .popup-root { |
| | | position: fixed; |
| | | top: 0; |
| | | left: 0; |
| | | width: 750rpx; |
| | | height: 100%; |
| | | flex: 1; |
| | | background-color: rgba(0, 0, 0, 0.3); |
| | | justify-content: center; |
| | | align-items: center; |
| | | z-index: 99; |
| | | } |
| | | </style> |
| | |
| | | :duration="duration" :show="showTrans" @click="onTap" /> |
| | | <uni-transition key="2" :mode-class="ani" name="content" :styles="transClass" :duration="duration" |
| | | :show="showTrans" @click="onTap"> |
| | | <view class="uni-popup__wrapper" :style="{ backgroundColor: bg }" :class="[popupstyle]" @click="clear"> |
| | | <view class="uni-popup__wrapper" :style="getStyles" :class="[popupstyle]" @click="clear"> |
| | | <slot /> |
| | | </view> |
| | | </uni-transition> |
| | |
| | | * @property {Boolean} isMaskClick = [true|false] 蒙版点击是否关闭弹窗 |
| | | * @property {String} backgroundColor 主窗口背景色 |
| | | * @property {String} maskBackgroundColor 蒙版颜色 |
| | | * @property {String} borderRadius 设置圆角(左上、右上、右下和左下) 示例:"10px 10px 10px 10px" |
| | | * @property {Boolean} safeArea 是否适配底部安全区 |
| | | * @event {Function} change 打开关闭弹窗触发,e={show: false} |
| | | * @event {Function} maskClick 点击遮罩触发 |
| | |
| | | type: String, |
| | | default: 'rgba(0, 0, 0, 0.4)' |
| | | }, |
| | | borderRadius:{ |
| | | type: String, |
| | | } |
| | | }, |
| | | |
| | | watch: { |
| | |
| | | backgroundColor: 'rgba(0, 0, 0, 0.4)' |
| | | }, |
| | | transClass: { |
| | | backgroundColor: 'transparent', |
| | | borderRadius: this.borderRadius || "0", |
| | | position: 'fixed', |
| | | left: 0, |
| | | right: 0 |
| | | }, |
| | | maskShow: true, |
| | | mkclick: true, |
| | | popupstyle: this.isDesktop ? 'fixforpc-top' : 'top' |
| | | popupstyle: 'top' |
| | | } |
| | | }, |
| | | computed: { |
| | | getStyles() { |
| | | let res = { backgroundColor: this.bg }; |
| | | if (this.borderRadius || "0") { |
| | | res = Object.assign(res, { borderRadius: this.borderRadius }) |
| | | } |
| | | return res; |
| | | }, |
| | | isDesktop() { |
| | | return this.popupWidth >= 500 && this.popupHeight >= 500 |
| | | }, |
| | |
| | | }, |
| | | mounted() { |
| | | const fixSize = () => { |
| | | // #ifdef MP-WEIXIN |
| | | const { |
| | | windowWidth, |
| | | windowHeight, |
| | | windowTop, |
| | | safeArea, |
| | | screenHeight, |
| | | safeAreaInsets |
| | | } = uni.getWindowInfo() |
| | | // #endif |
| | | // #ifndef MP-WEIXIN |
| | | const { |
| | | windowWidth, |
| | | windowHeight, |
| | |
| | | screenHeight, |
| | | safeAreaInsets |
| | | } = uni.getSystemInfoSync() |
| | | // #endif |
| | | this.popupWidth = windowWidth |
| | | this.popupHeight = windowHeight + (windowTop || 0) |
| | | // TODO fix by mehaotian 是否适配底部安全区 ,目前微信ios 、和 app ios 计算有差异,需要框架修复 |
| | |
| | | this.setH5Visible() |
| | | }, |
| | | // #endif |
| | | activated() { |
| | | this.setH5Visible(!this.showPopup); |
| | | }, |
| | | deactivated() { |
| | | this.setH5Visible(true); |
| | | }, |
| | | created() { |
| | | // this.mkclick = this.isMaskClick || this.maskClick |
| | | if (this.isMaskClick === null && this.maskClick === null) { |
| | |
| | | this.maskClass.backgroundColor = this.maskBackgroundColor |
| | | }, |
| | | methods: { |
| | | setH5Visible() { |
| | | setH5Visible(visible = true) { |
| | | // #ifdef H5 |
| | | // fix by mehaotian 处理 h5 滚动穿透的问题 |
| | | document.getElementsByTagName('body')[0].style.overflow = 'visible' |
| | | document.getElementsByTagName('body')[0].style.overflow = visible ? "visible" : "hidden"; |
| | | // #endif |
| | | }, |
| | | /** |
| | |
| | | position: 'fixed', |
| | | left: 0, |
| | | right: 0, |
| | | backgroundColor: this.bg |
| | | backgroundColor: this.bg, |
| | | borderRadius:this.borderRadius || "0" |
| | | } |
| | | // TODO 兼容 type 属性 ,后续会废弃 |
| | | if (type) return |
| | | this.showPopup = true |
| | | this.showTrans = true |
| | | this.$nextTick(() => { |
| | | this.showPoptrans() |
| | | if (this.messageChild && this.type === 'message') { |
| | | this.messageChild.timerClose() |
| | | } |
| | |
| | | left: 0, |
| | | right: 0, |
| | | bottom: 0, |
| | | //paddingBottom: 'constant(safe-area-inset-bottom)', ///兼容 IOS<11.2/ |
| | | //paddingBottom: 'env(safe-area-inset-bottom)', ///兼容 IOS>11.2/ |
| | | //paddingBottom: this.safeAreaInsets + 'px', |
| | | backgroundColor: this.bg |
| | | paddingBottom: this.safeAreaInsets + 'px', |
| | | backgroundColor: this.bg, |
| | | borderRadius:this.borderRadius || "0", |
| | | } |
| | | // TODO 兼容 type 属性 ,后续会废弃 |
| | | if (type) return |
| | | this.showPopup = true |
| | | this.showTrans = true |
| | | this.showPoptrans() |
| | | }, |
| | | /** |
| | | * 中间弹出样式处理 |
| | | */ |
| | | center(type) { |
| | | this.popupstyle = 'center' |
| | | //微信小程序下,组合动画会出现文字向上闪动问题,再此做特殊处理 |
| | | // #ifdef MP-WEIXIN |
| | | this.ani = ['fade'] |
| | | // #endif |
| | | // #ifndef MP-WEIXIN |
| | | this.ani = ['zoom-out', 'fade'] |
| | | // #endif |
| | | this.transClass = { |
| | | position: 'fixed', |
| | | /* #ifndef APP-NVUE */ |
| | |
| | | right: 0, |
| | | top: 0, |
| | | justifyContent: 'center', |
| | | alignItems: 'center' |
| | | alignItems: 'center', |
| | | borderRadius:this.borderRadius || "0" |
| | | } |
| | | // TODO 兼容 type 属性 ,后续会废弃 |
| | | if (type) return |
| | | this.showPopup = true |
| | | this.showTrans = true |
| | | this.showPoptrans() |
| | | }, |
| | | left(type) { |
| | | this.popupstyle = 'left' |
| | |
| | | bottom: 0, |
| | | top: 0, |
| | | backgroundColor: this.bg, |
| | | borderRadius:this.borderRadius || "0", |
| | | /* #ifndef APP-NVUE */ |
| | | display: 'flex', |
| | | flexDirection: 'column' |
| | |
| | | } |
| | | // TODO 兼容 type 属性 ,后续会废弃 |
| | | if (type) return |
| | | this.showPopup = true |
| | | this.showTrans = true |
| | | this.showPoptrans() |
| | | }, |
| | | right(type) { |
| | | this.popupstyle = 'right' |
| | |
| | | right: 0, |
| | | top: 0, |
| | | backgroundColor: this.bg, |
| | | borderRadius:this.borderRadius || "0", |
| | | /* #ifndef APP-NVUE */ |
| | | display: 'flex', |
| | | flexDirection: 'column' |
| | |
| | | } |
| | | // TODO 兼容 type 属性 ,后续会废弃 |
| | | if (type) return |
| | | this.showPoptrans() |
| | | }, |
| | | showPoptrans(){ |
| | | this.$nextTick(()=>{ |
| | | this.showPopup = true |
| | | this.showTrans = true |
| | | }) |
| | | } |
| | | } |
| | | } |
| | |
| | | { |
| | | "id": "uni-popup", |
| | | "displayName": "uni-popup 弹出层", |
| | | "version": "1.8.3", |
| | | "version": "1.9.10", |
| | | "description": " Popup 组件,提供常用的弹层", |
| | | "keywords": [ |
| | | "uni-ui", |
| | |
| | | ], |
| | | "repository": "https://github.com/dcloudio/uni-ui", |
| | | "engines": { |
| | | "HBuilderX": "" |
| | | "HBuilderX": "", |
| | | "uni-app": "^4.06", |
| | | "uni-app-x": "" |
| | | }, |
| | | "directories": { |
| | | "example": "../../temps/example_temps" |
| | |
| | | "permissions": "无" |
| | | }, |
| | | "npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui", |
| | | "type": "component-vue" |
| | | "type": "component-vue", |
| | | "darkmode": "x", |
| | | "i18n": "x", |
| | | "widescreen": "x" |
| | | }, |
| | | "uni_modules": { |
| | | "dependencies": [ |
| | |
| | | "encrypt": [], |
| | | "platforms": { |
| | | "cloud": { |
| | | "tcb": "y", |
| | | "aliyun": "y" |
| | | "tcb": "x", |
| | | "aliyun": "x", |
| | | "alipay": "x" |
| | | }, |
| | | "client": { |
| | | "App": { |
| | | "app-vue": "y", |
| | | "app-nvue": "y" |
| | | "uni-app": { |
| | | "vue": { |
| | | "vue2": "√", |
| | | "vue3": "√" |
| | | }, |
| | | "H5-mobile": { |
| | | "Safari": "y", |
| | | "Android Browser": "y", |
| | | "微信浏览器(Android)": "y", |
| | | "QQ浏览器(Android)": "y" |
| | | "web": { |
| | | "safari": "√", |
| | | "chrome": "√" |
| | | }, |
| | | "H5-pc": { |
| | | "Chrome": "y", |
| | | "IE": "y", |
| | | "Edge": "y", |
| | | "Firefox": "y", |
| | | "Safari": "y" |
| | | "app": { |
| | | "vue": "√", |
| | | "nvue": "√", |
| | | "android": "√", |
| | | "ios": "√", |
| | | "harmony": "√" |
| | | }, |
| | | "小程序": { |
| | | "微信": "y", |
| | | "阿里": "y", |
| | | "百度": "y", |
| | | "字节跳动": "y", |
| | | "QQ": "y" |
| | | "mp": { |
| | | "weixin": "√", |
| | | "alipay": "√", |
| | | "toutiao": "√", |
| | | "baidu": "√", |
| | | "kuaishou": "-", |
| | | "jd": "-", |
| | | "harmony": "-", |
| | | "qq": "√", |
| | | "lark": "-" |
| | | }, |
| | | "快应用": { |
| | | "华为": "u", |
| | | "联盟": "u" |
| | | "quickapp": { |
| | | "huawei": "-", |
| | | "union": "-" |
| | | } |
| | | }, |
| | | "Vue": { |
| | | "vue2": "y", |
| | | "vue3": "y" |
| | | "uni-app-x": { |
| | | "web": { |
| | | "safari": "√", |
| | | "chrome": "√" |
| | | }, |
| | | "app": { |
| | | "android": "√", |
| | | "ios": "√", |
| | | "harmony": "√" |
| | | }, |
| | | "mp": { |
| | | "weixin": "√" |
| | | } |
| | | } |
| | | } |
| | | } |
| | |
| | | ## 1.3.6(2025-07-18) |
| | | - 修复 nvue 页面,样式错误问题 |
| | | ## 1.3.5(2025-06-11) |
| | | - 修复 第一次执行不显示动画的问题 |
| | | ## 1.3.4(2025-04-16) |
| | | - 修复 页面数据更新到底动画复原的问题 |
| | | - 修复 示例页面打开报错的问题 |
| | | ## 1.3.3(2024-04-23) |
| | | - 修复 当元素会受变量影响自动隐藏的bug |
| | | ## 1.3.2(2023-05-04) |
| | | - 修复 NVUE 平台报错的问题 |
| | | ## 1.3.1(2021-11-23) |
| | | - 修复 init 方法初始化问题 |
| | | ## 1.3.0(2021-11-19) |
| | |
| | | class MPAnimation { |
| | | constructor(options, _this) { |
| | | this.options = options |
| | | this.animation = uni.createAnimation(options) |
| | | // 在iOS10+QQ小程序平台下,传给原生的对象一定是个普通对象而不是Proxy对象,否则会报parameter should be Object instead of ProxyObject的错误 |
| | | this.animation = uni.createAnimation({ |
| | | ...options |
| | | }) |
| | | this.currentStepAnimates = {} |
| | | this.next = 0 |
| | | this.$ = _this |
| | |
| | | <template> |
| | | <view v-if="isShow" ref="ani" :animation="animationData" :class="customClass" :style="transformStyles" @click="onClick"><slot></slot></view> |
| | | <!-- #ifndef APP-NVUE --> |
| | | <view v-show="isShow" ref="ani" :animation="animationData" :class="customClass" :style="transformStyles" @click="onClick"> |
| | | <slot></slot> |
| | | </view> |
| | | <!-- #endif --> |
| | | <!-- #ifdef APP-NVUE --> |
| | | <view v-if="isShow" ref="ani" :animation="animationData" :class="customClass" :style="transformStyles" @click="onClick"> |
| | | <slot></slot> |
| | | </view> |
| | | <!-- #endif --> |
| | | </template> |
| | | |
| | | <script> |
| | |
| | | customClass:{ |
| | | type: String, |
| | | default: '' |
| | | } |
| | | }, |
| | | onceRender: { |
| | | type: Boolean, |
| | | default: false |
| | | }, |
| | | }, |
| | | data() { |
| | | return { |
| | | isShow: false, |
| | | transform: '', |
| | | opacity: 1, |
| | | opacity: 0, |
| | | animationData: {}, |
| | | durationTime: 300, |
| | | config: {} |
| | |
| | | * @param {Object} obj |
| | | */ |
| | | step(obj, config = {}) { |
| | | if (!this.animation) return |
| | | for (let i in obj) { |
| | | try { |
| | | if(typeof obj[i] === 'object'){ |
| | | this.animation[i](...obj[i]) |
| | | }else{ |
| | | this.animation[i](obj[i]) |
| | | if (!this.animation) return this |
| | | Object.keys(obj).forEach(key => { |
| | | const value = obj[key] |
| | | if (typeof this.animation[key] === 'function') { |
| | | Array.isArray(value) ? |
| | | this.animation[key](...value) : |
| | | this.animation[key](value) |
| | | } |
| | | } catch (e) { |
| | | console.error(`方法 ${i} 不存在`) |
| | | } |
| | | } |
| | | }) |
| | | this.animation.step(config) |
| | | return this |
| | | }, |
| | |
| | | // 开始过度动画 |
| | | open() { |
| | | clearTimeout(this.timer) |
| | | this.transform = '' |
| | | this.isShow = true |
| | | let { opacity, transform } = this.styleInit(false) |
| | | if (typeof opacity !== 'undefined') { |
| | | this.opacity = opacity |
| | | } |
| | | this.transform = transform |
| | | // 新增初始状态重置逻辑(关键) |
| | | this.transform = this.styleInit(false).transform || '' |
| | | this.opacity = this.styleInit(false).opacity || 0 |
| | | |
| | | // 确保动态样式已经生效后,执行动画,如果不加 nextTick ,会导致 wx 动画执行异常 |
| | | this.$nextTick(() => { |
| | | // TODO 定时器保证动画完全执行,目前有些问题,后面会取消定时器 |
| | | this.timer = setTimeout(() => { |
| | | this.animation = createAnimation(this.config, this) |
| | | this.tranfromInit(false).step() |
| | | this.animation.run() |
| | | this.animation.run(() => { |
| | | // #ifdef APP-NVUE |
| | | this.transform = this.styleInit(false).transform || '' |
| | | this.opacity = this.styleInit(false).opacity || 1 |
| | | // #endif |
| | | // #ifndef APP-NVUE |
| | | this.transform = '' |
| | | this.opacity = this.styleInit(false).opacity || 1 |
| | | // #endif |
| | | this.$emit('change', { |
| | | detail: this.isShow |
| | | }) |
| | | }, 20) |
| | | }) |
| | | }, 80) |
| | | }) |
| | | }, |
| | | // 关闭过度动画 |
| | |
| | | }, |
| | | // 处理动画开始前的默认样式 |
| | | styleInit(type) { |
| | | let styles = { |
| | | transform: '' |
| | | } |
| | | let buildStyle = (type, mode) => { |
| | | if (mode === 'fade') { |
| | | styles.opacity = this.animationType(type)[mode] |
| | | let styles = { transform: '', opacity: 1 } |
| | | const buildStyle = (type, mode) => { |
| | | const value = this.animationType(type)[mode] // 直接使用 type 控制状态 |
| | | if (mode.startsWith('fade')) { |
| | | styles.opacity = value |
| | | } else { |
| | | styles.transform += this.animationType(type)[mode] + ' ' |
| | | styles.transform += value + ' ' |
| | | } |
| | | } |
| | | |
| | | if (typeof this.modeClass === 'string') { |
| | | buildStyle(type, this.modeClass) |
| | | } else { |
| | | this.modeClass.forEach(mode => { |
| | | buildStyle(type, mode) |
| | | }) |
| | | this.modeClass.forEach(mode => buildStyle(type, mode)) |
| | | } |
| | | return styles |
| | | }, |
| | |
| | | { |
| | | "id": "uni-transition", |
| | | "displayName": "uni-transition 过渡动画", |
| | | "version": "1.3.1", |
| | | "version": "1.3.6", |
| | | "description": "元素的简单过渡动画", |
| | | "keywords": [ |
| | | "uni-ui", |
| | |
| | | ], |
| | | "repository": "https://github.com/dcloudio/uni-ui", |
| | | "engines": { |
| | | "HBuilderX": "" |
| | | "HBuilderX": "", |
| | | "uni-app": "^4.12", |
| | | "uni-app-x": "" |
| | | }, |
| | | "directories": { |
| | | "example": "../../temps/example_temps" |
| | | }, |
| | | "dcloudext": { |
| | | "category": [ |
| | | "前端组件", |
| | | "通用组件" |
| | | ], |
| | | "sale": { |
| | | "regular": { |
| | | "price": "0.00" |
| | |
| | | "data": "无", |
| | | "permissions": "无" |
| | | }, |
| | | "npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui" |
| | | "npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui", |
| | | "type": "component-vue", |
| | | "darkmode": "x", |
| | | "i18n": "x", |
| | | "widescreen": "x" |
| | | }, |
| | | "uni_modules": { |
| | | "dependencies": ["uni-scss"], |
| | | "dependencies": [ |
| | | "uni-scss" |
| | | ], |
| | | "encrypt": [], |
| | | "platforms": { |
| | | "cloud": { |
| | | "tcb": "y", |
| | | "aliyun": "y" |
| | | "tcb": "x", |
| | | "aliyun": "x", |
| | | "alipay": "x" |
| | | }, |
| | | "client": { |
| | | "App": { |
| | | "app-vue": "y", |
| | | "app-nvue": "y" |
| | | "uni-app": { |
| | | "vue": { |
| | | "vue2": "√", |
| | | "vue3": "√" |
| | | }, |
| | | "H5-mobile": { |
| | | "Safari": "y", |
| | | "Android Browser": "y", |
| | | "微信浏览器(Android)": "y", |
| | | "QQ浏览器(Android)": "y" |
| | | "web": { |
| | | "safari": "√", |
| | | "chrome": "√" |
| | | }, |
| | | "H5-pc": { |
| | | "Chrome": "y", |
| | | "IE": "y", |
| | | "Edge": "y", |
| | | "Firefox": "y", |
| | | "Safari": "y" |
| | | "app": { |
| | | "vue": "√", |
| | | "nvue": "√", |
| | | "android": "√", |
| | | "ios": "√", |
| | | "harmony": "√" |
| | | }, |
| | | "小程序": { |
| | | "微信": "y", |
| | | "阿里": "y", |
| | | "百度": "y", |
| | | "字节跳动": "y", |
| | | "QQ": "y" |
| | | "mp": { |
| | | "weixin": { |
| | | }, |
| | | "快应用": { |
| | | "华为": "u", |
| | | "联盟": "u" |
| | | "alipay": { |
| | | }, |
| | | "Vue": { |
| | | "vue2": "y", |
| | | "vue3": "y" |
| | | "toutiao": { |
| | | }, |
| | | "baidu": { |
| | | }, |
| | | "kuaishou": { |
| | | }, |
| | | "jd": { |
| | | }, |
| | | "harmony": "-", |
| | | "qq": "√", |
| | | "lark": "-" |
| | | }, |
| | | "quickapp": { |
| | | "huawei": "√", |
| | | "union": "√" |
| | | } |
| | | }, |
| | | "uni-app-x": { |
| | | "web": { |
| | | "safari": "-", |
| | | "chrome": "-" |
| | | }, |
| | | "app": { |
| | | "android": "-", |
| | | "ios": "-", |
| | | "harmony": "-" |
| | | }, |
| | | "mp": { |
| | | "weixin": "-" |
| | | } |
| | | } |
| | | } |
| | | } |
| New file |
| | |
| | | ## 1.0.4(2023-12-06) |
| | | 1. 阻止事件冒泡处理 |
| | | ## 1.0.3(2023-10-23) |
| | | 1. 修复报错的BUG |
| | | ## 1.0.2(2023-10-23) |
| | | 1. 修复设置singleSize、multipleSize、space等值带单位,存在不显示的BUG |
| | | ## 1.0.1(2023-09-13) |
| | | 1. 添加依赖 |
| | | ## 1.0.0(2023-08-30) |
| | | 1. 新增uv-album相册组件 |
| New file |
| | |
| | | <template> |
| | | <view class="uv-album"> |
| | | <view |
| | | class="uv-album__row" |
| | | ref="uv-album__row" |
| | | v-for="(arr, index) in showUrls" |
| | | :forComputedUse="albumWidth" |
| | | :key="index" |
| | | > |
| | | <view |
| | | class="uv-album__row__wrapper" |
| | | v-for="(item, index1) in arr" |
| | | :key="index1" |
| | | :style="[imageStyle(index + 1, index1 + 1)]" |
| | | @tap.stop="previewFullImage ? onPreviewTap(getSrc(item)) : ''" |
| | | > |
| | | <image |
| | | :src="getSrc(item)" |
| | | :mode=" |
| | | urls.length === 1 |
| | | ? imageHeight > 0 |
| | | ? singleMode |
| | | : 'widthFix' |
| | | : multipleMode |
| | | " |
| | | :style="[ |
| | | { |
| | | width: imageWidth, |
| | | height: imageHeight |
| | | } |
| | | ]" |
| | | ></image> |
| | | <view |
| | | v-if=" |
| | | showMore && |
| | | urls.length > rowCount * showUrls.length && |
| | | index === showUrls.length - 1 && |
| | | index1 === showUrls[showUrls.length - 1].length - 1 |
| | | " |
| | | class="uv-album__row__wrapper__text" |
| | | > |
| | | <uv-text |
| | | :text="`+${urls.length - maxCount}`" |
| | | color="#fff" |
| | | :size="$uv.getPx(multipleSize) * 0.3" |
| | | align="center" |
| | | customStyle="justify-content: center" |
| | | ></uv-text> |
| | | </view> |
| | | </view> |
| | | </view> |
| | | </view> |
| | | </template> |
| | | <script> |
| | | import mpMixin from '@/uni_modules/uv-ui-tools/libs/mixin/mpMixin.js' |
| | | import mixin from '@/uni_modules/uv-ui-tools/libs/mixin/mixin.js' |
| | | // #ifdef APP-NVUE |
| | | // 由于weex为阿里的KPI业绩考核的产物,所以不支持百分比单位,这里需要通过dom查询组件的宽度 |
| | | const dom = uni.requireNativePlugin('dom') |
| | | // #endif |
| | | |
| | | /** |
| | | * Album 相册 |
| | | * @description 本组件提供一个类似相册的功能,让开发者开发起来更加得心应手。减少重复的模板代码 |
| | | * @tutorial https://www.uvui.cn/components/album.html |
| | | * @property {Array} urls 图片地址列表 Array<String>|Array<Object>形式 |
| | | * @property {String} keyName 指定从数组的对象元素中读取哪个属性作为图片地址 |
| | | * @property {String | Number} singleSize 单图时,图片长边的长度 (默认 180 ) |
| | | * @property {String | Number} multipleSize 多图时,图片边长 (默认 70 ) |
| | | * @property {String | Number} space 多图时,图片水平和垂直之间的间隔 (默认 6 ) |
| | | * @property {String} singleMode 单图时,图片缩放裁剪的模式 (默认 'scaleToFill' ) |
| | | * @property {String} multipleMode 多图时,图片缩放裁剪的模式 (默认 'aspectFill' ) |
| | | * @property {String | Number} maxCount 取消按钮的提示文字 (默认 9 ) |
| | | * @property {Boolean} previewFullImage 是否可以预览图片 (默认 true ) |
| | | * @property {String | Number} rowCount 每行展示图片数量,如设置,singleSize和multipleSize将会无效 (默认 3 ) |
| | | * @property {Boolean} showMore 超出maxCount时是否显示查看更多的提示 (默认 true ) |
| | | * |
| | | * @event {Function} albumWidth 某些特殊的情况下,需要让文字与相册的宽度相等,这里事件的形式对外发送 (回调参数 width ) |
| | | * @example <uv-album :urls="urls2" @albumWidth="width => albumWidth = width" multipleSize="68" ></uv-album> |
| | | */ |
| | | export default { |
| | | name: 'uv-album', |
| | | mixins: [mpMixin, mixin], |
| | | emits: ['albumWidth'], |
| | | props: { |
| | | // 图片地址,Array<String>|Array<Object>形式 |
| | | urls: { |
| | | type: Array, |
| | | default: () => [] |
| | | }, |
| | | // 指定从数组的对象元素中读取哪个属性作为图片地址 |
| | | keyName: { |
| | | type: String, |
| | | default: '' |
| | | }, |
| | | // 单图时,图片长边的长度 |
| | | singleSize: { |
| | | type: [String, Number], |
| | | default: 180 |
| | | }, |
| | | // 多图时,图片边长 |
| | | multipleSize: { |
| | | type: [String, Number], |
| | | default: 70 |
| | | }, |
| | | // 多图时,图片水平和垂直之间的间隔 |
| | | space: { |
| | | type: [String, Number], |
| | | default: 6 |
| | | }, |
| | | // 单图时,图片缩放裁剪的模式 |
| | | singleMode: { |
| | | type: String, |
| | | default: 'scaleToFill' |
| | | }, |
| | | // 多图时,图片缩放裁剪的模式 |
| | | multipleMode: { |
| | | type: String, |
| | | default: 'aspectFill' |
| | | }, |
| | | // 最多展示的图片数量,超出时最后一个位置将会显示剩余图片数量 |
| | | maxCount: { |
| | | type: [String, Number], |
| | | default: 9 |
| | | }, |
| | | // 是否可以预览图片 |
| | | previewFullImage: { |
| | | type: Boolean, |
| | | default: true |
| | | }, |
| | | // 每行展示图片数量,如设置,singleSize和multipleSize将会无效 |
| | | rowCount: { |
| | | type: [String, Number], |
| | | default: 3 |
| | | }, |
| | | // 超出maxCount时是否显示查看更多的提示 |
| | | showMore: { |
| | | type: Boolean, |
| | | default: true |
| | | }, |
| | | ...uni.$uv?.props?.album |
| | | }, |
| | | data() { |
| | | return { |
| | | // 单图的宽度 |
| | | singleWidth: 0, |
| | | // 单图的高度 |
| | | singleHeight: 0, |
| | | // 单图时,如果无法获取图片的尺寸信息,让图片宽度默认为容器的一定百分比 |
| | | singlePercent: 0.6 |
| | | } |
| | | }, |
| | | watch: { |
| | | urls: { |
| | | immediate: true, |
| | | handler(newVal) { |
| | | if (newVal.length === 1) { |
| | | this.getImageRect() |
| | | } |
| | | } |
| | | } |
| | | }, |
| | | computed: { |
| | | imageStyle() { |
| | | return (index1, index2) => { |
| | | const { space, rowCount, multipleSize, urls } = this; |
| | | const rowLen = this.showUrls.length; |
| | | const allLen = this.urls.length; |
| | | const style = { |
| | | marginRight: this.$uv.addUnit(space), |
| | | marginBottom: this.$uv.addUnit(space) |
| | | } |
| | | // 如果为最后一行,则每个图片都无需下边框 |
| | | if (index1 === rowLen) style.marginBottom = 0 |
| | | // 每行的最右边一张和总长度的最后一张无需右边框 |
| | | if ( |
| | | index2 === rowCount || |
| | | (index1 === rowLen && |
| | | index2 === this.showUrls[index1 - 1].length) |
| | | ) |
| | | style.marginRight = 0 |
| | | return style |
| | | } |
| | | }, |
| | | // 将数组划分为二维数组 |
| | | showUrls() { |
| | | const arr = [] |
| | | this.urls.map((item, index) => { |
| | | // 限制最大展示数量 |
| | | if (index + 1 <= this.maxCount) { |
| | | // 计算该元素为第几个素组内 |
| | | const itemIndex = Math.floor(index / this.rowCount) |
| | | // 判断对应的索引是否存在 |
| | | if (!arr[itemIndex]) { |
| | | arr[itemIndex] = [] |
| | | } |
| | | arr[itemIndex].push(item) |
| | | } |
| | | }) |
| | | return arr |
| | | }, |
| | | imageWidth() { |
| | | return this.$uv.addUnit( |
| | | this.urls.length === 1 ? this.singleWidth : this.multipleSize |
| | | ) |
| | | }, |
| | | imageHeight() { |
| | | return this.$uv.addUnit( |
| | | this.urls.length === 1 ? this.singleHeight : this.multipleSize |
| | | ) |
| | | }, |
| | | // 此变量无实际用途,仅仅是为了利用computed特性,让其在urls长度等变化时,重新计算图片的宽度 |
| | | // 因为用户在某些特殊的情况下,需要让文字与相册的宽度相等,所以这里事件的形式对外发送 |
| | | albumWidth() { |
| | | let width = 0 |
| | | if (this.urls.length === 1) { |
| | | width = this.singleWidth |
| | | } else { |
| | | width = |
| | | this.showUrls[0].length * this.$uv.getPx(this.multipleSize) + |
| | | this.$uv.getPx(this.space) * (this.showUrls[0].length - 1) |
| | | } |
| | | this.$emit('albumWidth', width) |
| | | return width |
| | | } |
| | | }, |
| | | methods: { |
| | | // 预览图片 |
| | | onPreviewTap(url) { |
| | | const urls = this.urls.map((item) => { |
| | | return this.getSrc(item) |
| | | }) |
| | | uni.previewImage({ |
| | | current: url, |
| | | urls |
| | | }) |
| | | }, |
| | | // 获取图片的路径 |
| | | getSrc(item) { |
| | | return this.$uv.test.object(item) ? |
| | | (this.keyName && item[this.keyName]) || item.src : |
| | | item |
| | | }, |
| | | // 单图时,获取图片的尺寸 |
| | | // 在小程序中,需要将网络图片的的域名添加到小程序的download域名才可能获取尺寸 |
| | | // 在没有添加的情况下,让单图宽度默认为盒子的一定宽度(singlePercent) |
| | | getImageRect() { |
| | | const src = this.getSrc(this.urls[0]) |
| | | uni.getImageInfo({ |
| | | src, |
| | | success: (res) => { |
| | | // 判断图片横向还是竖向展示方式 |
| | | const isHorizotal = res.width >= res.height |
| | | this.singleWidth = isHorizotal ? |
| | | this.singleSize : |
| | | (res.width / res.height) * this.$uv.getPx(this.singleSize) |
| | | this.singleHeight = !isHorizotal ? |
| | | this.singleSize : |
| | | (res.height / res.width) * this.singleWidth |
| | | }, |
| | | fail: () => { |
| | | this.getComponentWidth() |
| | | } |
| | | }) |
| | | }, |
| | | // 获取组件的宽度 |
| | | async getComponentWidth() { |
| | | // 延时一定时间,以获取dom尺寸 |
| | | await this.$uv.sleep(30) |
| | | // #ifndef APP-NVUE |
| | | this.$uGetRect('.uv-album__row').then((size) => { |
| | | this.singleWidth = size.width * this.singlePercent |
| | | }) |
| | | // #endif |
| | | |
| | | // #ifdef APP-NVUE |
| | | // 这里ref="uv-album__row"所在的标签为通过for循环出来,导致this.$refs['uv-album__row']是一个数组 |
| | | const ref = this.$refs['uv-album__row'][0] |
| | | ref && |
| | | dom.getComponentRect(ref, (res) => { |
| | | this.singleWidth = res.size.width * this.singlePercent |
| | | }) |
| | | // #endif |
| | | } |
| | | } |
| | | } |
| | | </script> |
| | | |
| | | <style lang="scss" scoped> |
| | | @import '@/uni_modules/uv-ui-tools/libs/css/components.scss'; |
| | | .uv-album { |
| | | @include flex(column); |
| | | &__row { |
| | | @include flex(row); |
| | | flex-wrap: wrap; |
| | | &__wrapper { |
| | | position: relative; |
| | | &__text { |
| | | position: absolute; |
| | | top: 0; |
| | | left: 0; |
| | | right: 0; |
| | | bottom: 0; |
| | | background-color: rgba(0, 0, 0, 0.3); |
| | | @include flex(row); |
| | | justify-content: center; |
| | | align-items: center; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | </style> |
| New file |
| | |
| | | { |
| | | "id": "uv-album", |
| | | "displayName": "uv-album 相册 全面兼容vue3+2、app、h5、小程序等多端", |
| | | "version": "1.0.4", |
| | | "description": "本组件提供一个类似相册的功能,让开发者开发起来更加得心应手,功能齐全,灵活配置可以,开箱即用。减少重复的模板代码", |
| | | "keywords": [ |
| | | "album", |
| | | "uv-ui", |
| | | "uvui", |
| | | "相册", |
| | | "图片" |
| | | ], |
| | | "repository": "", |
| | | "engines": { |
| | | "HBuilderX": "^3.1.0" |
| | | }, |
| | | "dcloudext": { |
| | | "type": "component-vue", |
| | | "sale": { |
| | | "regular": { |
| | | "price": "0.00" |
| | | }, |
| | | "sourcecode": { |
| | | "price": "0.00" |
| | | } |
| | | }, |
| | | "contact": { |
| | | "qq": "" |
| | | }, |
| | | "declaration": { |
| | | "ads": "无", |
| | | "data": "插件不采集任何数据", |
| | | "permissions": "无" |
| | | }, |
| | | "npmurl": "" |
| | | }, |
| | | "uni_modules": { |
| | | "dependencies": [ |
| | | "uv-ui-tools", |
| | | "uv-text" |
| | | ], |
| | | "encrypt": [], |
| | | "platforms": { |
| | | "cloud": { |
| | | "tcb": "y", |
| | | "aliyun": "y" |
| | | }, |
| | | "client": { |
| | | "Vue": { |
| | | "vue2": "y", |
| | | "vue3": "y" |
| | | }, |
| | | "App": { |
| | | "app-vue": "y", |
| | | "app-nvue": "y" |
| | | }, |
| | | "H5-mobile": { |
| | | "Safari": "y", |
| | | "Android Browser": "y", |
| | | "微信浏览器(Android)": "y", |
| | | "QQ浏览器(Android)": "y" |
| | | }, |
| | | "H5-pc": { |
| | | "Chrome": "y", |
| | | "IE": "y", |
| | | "Edge": "y", |
| | | "Firefox": "y", |
| | | "Safari": "y" |
| | | }, |
| | | "小程序": { |
| | | "微信": "y", |
| | | "阿里": "y", |
| | | "百度": "y", |
| | | "字节跳动": "y", |
| | | "QQ": "y", |
| | | "钉钉": "u", |
| | | "快手": "u", |
| | | "飞书": "u", |
| | | "京东": "u" |
| | | }, |
| | | "快应用": { |
| | | "华为": "u", |
| | | "联盟": "u" |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| New file |
| | |
| | | # Album 相册 |
| | | |
| | | > **组件名:uv-album** |
| | | |
| | | 本组件提供一个类似相册的功能,让开发者开发起来更加得心应手。 |
| | | |
| | | 功能齐全,灵活配置可以,开箱即用。减少重复的模板代码。 |
| | | |
| | | # <a href="https://www.uvui.cn/components/album.html" target="_blank">查看文档</a> |
| | | |
| | | ## [下载完整示例项目](https://ext.dcloud.net.cn/plugin?name=uv-ui) <small>(请不要 下载插件ZIP)</small> |
| | | |
| | | ### [更多插件,请关注uv-ui组件库](https://ext.dcloud.net.cn/plugin?name=uv-ui) |
| | | |
| | | <a href="https://ext.dcloud.net.cn/plugin?name=uv-ui" target="_blank"> |
| | | |
| | |  |
| | | |
| | | </a> |
| | | |
| | | #### 如使用过程中有任何问题反馈,或者您对uv-ui有一些好的建议,欢迎加入uv-ui官方交流群:<a href="https://www.uvui.cn/components/addQQGroup.html" target="_blank">官方QQ群</a> |
| New file |
| | |
| | | ## 1.0.2(2023-06-01) |
| | | 1. 修复点击触发两次实践的BUG |
| | | ## 1.0.1(2023-05-16) |
| | | 1. 优化组件依赖,修改后无需全局引入,组件导入即可使用 |
| | | 2. 优化部分功能 |
| | | ## 1.0.0(2023-05-10) |
| | | uv-alert 警告提示组件 |
| New file |
| | |
| | | export default { |
| | | props: { |
| | | // 显示文字 |
| | | title: { |
| | | type: String, |
| | | default: '' |
| | | }, |
| | | // 主题,success/warning/info/error |
| | | type: { |
| | | type: String, |
| | | default: 'warning' |
| | | }, |
| | | // 辅助性文字 |
| | | description: { |
| | | type: String, |
| | | default: '' |
| | | }, |
| | | // 是否可关闭 |
| | | closable: { |
| | | type: Boolean, |
| | | default: false |
| | | }, |
| | | // 是否显示图标 |
| | | showIcon: { |
| | | type: Boolean, |
| | | default: false |
| | | }, |
| | | // 浅或深色调,light-浅色,dark-深色 |
| | | effect: { |
| | | type: String, |
| | | default: 'light' |
| | | }, |
| | | // 文字是否居中 |
| | | center: { |
| | | type: Boolean, |
| | | default: false |
| | | }, |
| | | // 字体大小 |
| | | fontSize: { |
| | | type: [String, Number], |
| | | default: 14 |
| | | }, |
| | | ...uni.$uv?.props?.alert |
| | | } |
| | | } |
| New file |
| | |
| | | <template> |
| | | <uv-transition |
| | | mode="fade" |
| | | :show="show" |
| | | > |
| | | <view |
| | | class="uv-alert" |
| | | :class="[`uv-alert--${type}--${effect}`]" |
| | | @tap.stop="clickHandler" |
| | | :style="[$uv.addStyle(customStyle)]" |
| | | > |
| | | <view |
| | | class="uv-alert__icon" |
| | | v-if="showIcon" |
| | | > |
| | | <uv-icon |
| | | :name="iconName" |
| | | size="18" |
| | | :color="iconColor" |
| | | ></uv-icon> |
| | | </view> |
| | | <view |
| | | class="uv-alert__content" |
| | | :style="[{ |
| | | paddingRight: closable ? '20px' : 0 |
| | | }]" |
| | | > |
| | | <text |
| | | class="uv-alert__content__title" |
| | | v-if="title" |
| | | :style="[{ |
| | | fontSize: $uv.addUnit(fontSize), |
| | | textAlign: center ? 'center' : 'left' |
| | | }]" |
| | | :class="[effect === 'dark' ? 'uv-alert__text--dark' : `uv-alert__text--${type}--light`]" |
| | | >{{ title }}</text> |
| | | <text |
| | | class="uv-alert__content__desc" |
| | | v-if="description" |
| | | :style="[{ |
| | | fontSize: $uv.addUnit(fontSize), |
| | | textAlign: center ? 'center' : 'left' |
| | | }]" |
| | | :class="[effect === 'dark' ? 'uv-alert__text--dark' : `uv-alert__text--${type}--light`]" |
| | | >{{ description }}</text> |
| | | </view> |
| | | <view |
| | | class="uv-alert__close" |
| | | v-if="closable" |
| | | @tap.stop="closeHandler" |
| | | > |
| | | <uv-icon |
| | | name="close" |
| | | :color="iconColor" |
| | | size="15" |
| | | ></uv-icon> |
| | | </view> |
| | | </view> |
| | | </uv-transition> |
| | | </template> |
| | | |
| | | <script> |
| | | import mpMixin from '@/uni_modules/uv-ui-tools/libs/mixin/mpMixin.js' |
| | | import mixin from '@/uni_modules/uv-ui-tools/libs/mixin/mixin.js' |
| | | import props from './props.js'; |
| | | /** |
| | | * Alert 警告提示 |
| | | * @description 警告提示,展现需要关注的信息。 |
| | | * @tutorial https://www.uvui.cn/components/alertTips.html |
| | | * |
| | | * @property {String} title 显示的文字 |
| | | * @property {String} type 使用预设的颜色 (默认 'warning' ) |
| | | * @property {String} description 辅助性文字,颜色比title浅一点,字号也小一点,可选 |
| | | * @property {Boolean} closable 关闭按钮(默认为叉号icon图标) (默认 false ) |
| | | * @property {Boolean} showIcon 是否显示左边的辅助图标 ( 默认 false ) |
| | | * @property {String} effect 多图时,图片缩放裁剪的模式 (默认 'light' ) |
| | | * @property {Boolean} center 文字是否居中 (默认 false ) |
| | | * @property {String | Number} fontSize 字体大小 (默认 14 ) |
| | | * @property {Object} customStyle 定义需要用到的外部样式 |
| | | * @event {Function} click 点击组件时触发 |
| | | * @example <uv-alert :title="title" type = "warning" :closable="closable" :description = "description"></uv-alert> |
| | | */ |
| | | export default { |
| | | name: 'uv-alert', |
| | | mixins: [mpMixin, mixin, props], |
| | | emits: ['click'], |
| | | data() { |
| | | return { |
| | | show: true |
| | | } |
| | | }, |
| | | computed: { |
| | | iconColor() { |
| | | return this.effect === 'light' ? this.type : '#fff' |
| | | }, |
| | | // 不同主题对应不同的图标 |
| | | iconName() { |
| | | switch (this.type) { |
| | | case 'success': |
| | | return 'checkmark-circle-fill'; |
| | | break; |
| | | case 'error': |
| | | return 'close-circle-fill'; |
| | | break; |
| | | case 'warning': |
| | | return 'error-circle-fill'; |
| | | break; |
| | | case 'info': |
| | | return 'info-circle-fill'; |
| | | break; |
| | | case 'primary': |
| | | return 'more-circle-fill'; |
| | | break; |
| | | default: |
| | | return 'error-circle-fill'; |
| | | } |
| | | } |
| | | }, |
| | | methods: { |
| | | // 点击内容 |
| | | clickHandler() { |
| | | this.$emit('click') |
| | | }, |
| | | // 点击关闭按钮 |
| | | closeHandler() { |
| | | this.show = false |
| | | } |
| | | } |
| | | } |
| | | </script> |
| | | |
| | | <style lang="scss" scoped> |
| | | @import '@/uni_modules/uv-ui-tools/libs/css/components.scss'; |
| | | @import '@/uni_modules/uv-ui-tools/libs/css/color.scss'; |
| | | .uv-alert { |
| | | position: relative; |
| | | background-color: $uv-primary; |
| | | padding: 8px 10px; |
| | | @include flex(row); |
| | | align-items: center; |
| | | border-top-left-radius: 4px; |
| | | border-top-right-radius: 4px; |
| | | border-bottom-left-radius: 4px; |
| | | border-bottom-right-radius: 4px; |
| | | |
| | | &--primary--dark { |
| | | background-color: $uv-primary; |
| | | } |
| | | |
| | | &--primary--light { |
| | | background-color: #ecf5ff; |
| | | } |
| | | |
| | | &--error--dark { |
| | | background-color: $uv-error; |
| | | } |
| | | |
| | | &--error--light { |
| | | background-color: #FEF0F0; |
| | | } |
| | | |
| | | &--success--dark { |
| | | background-color: $uv-success; |
| | | } |
| | | |
| | | &--success--light { |
| | | background-color: #f5fff0; |
| | | } |
| | | |
| | | &--warning--dark { |
| | | background-color: $uv-warning; |
| | | } |
| | | |
| | | &--warning--light { |
| | | background-color: #FDF6EC; |
| | | } |
| | | |
| | | &--info--dark { |
| | | background-color: $uv-info; |
| | | } |
| | | |
| | | &--info--light { |
| | | background-color: #f4f4f5; |
| | | } |
| | | |
| | | &__icon { |
| | | margin-right: 5px; |
| | | } |
| | | |
| | | &__content { |
| | | @include flex(column); |
| | | flex: 1; |
| | | |
| | | &__title { |
| | | color: $uv-main-color; |
| | | font-size: 14px; |
| | | font-weight: bold; |
| | | color: #fff; |
| | | margin-bottom: 2px; |
| | | } |
| | | |
| | | &__desc { |
| | | color: $uv-main-color; |
| | | font-size: 14px; |
| | | flex-wrap: wrap; |
| | | color: #fff; |
| | | } |
| | | } |
| | | |
| | | &__title--dark, |
| | | &__desc--dark { |
| | | color: #FFFFFF; |
| | | } |
| | | |
| | | &__text--primary--light, |
| | | &__text--primary--light { |
| | | color: $uv-primary; |
| | | } |
| | | |
| | | &__text--success--light, |
| | | &__text--success--light { |
| | | color: $uv-success; |
| | | } |
| | | |
| | | &__text--warning--light, |
| | | &__text--warning--light { |
| | | color: $uv-warning; |
| | | } |
| | | |
| | | &__text--error--light, |
| | | &__text--error--light { |
| | | color: $uv-error; |
| | | } |
| | | |
| | | &__text--info--light, |
| | | &__text--info--light { |
| | | color: $uv-info; |
| | | } |
| | | |
| | | &__close { |
| | | position: absolute; |
| | | top: 11px; |
| | | right: 10px; |
| | | } |
| | | } |
| | | </style> |
| New file |
| | |
| | | { |
| | | "id": "uv-alert", |
| | | "displayName": "uv-alert 警告提示 全面兼容小程序、nvue、vue2、vue3等多端", |
| | | "version": "1.0.2", |
| | | "description": "uv-alert 警告提示,展现需要关注的信息。灵活配置,功能齐全,兼容全端", |
| | | "keywords": [ |
| | | "alert", |
| | | "uvui", |
| | | "uv-ui", |
| | | "警告提示" |
| | | ], |
| | | "repository": "", |
| | | "engines": { |
| | | "HBuilderX": "^3.1.0" |
| | | }, |
| | | "dcloudext": { |
| | | "type": "component-vue", |
| | | "sale": { |
| | | "regular": { |
| | | "price": "0.00" |
| | | }, |
| | | "sourcecode": { |
| | | "price": "0.00" |
| | | } |
| | | }, |
| | | "contact": { |
| | | "qq": "" |
| | | }, |
| | | "declaration": { |
| | | "ads": "无", |
| | | "data": "插件不采集任何数据", |
| | | "permissions": "无" |
| | | }, |
| | | "npmurl": "" |
| | | }, |
| | | "uni_modules": { |
| | | "dependencies": [ |
| | | "uv-ui-tools", |
| | | "uv-transition", |
| | | "uv-icon" |
| | | ], |
| | | "encrypt": [], |
| | | "platforms": { |
| | | "cloud": { |
| | | "tcb": "y", |
| | | "aliyun": "y" |
| | | }, |
| | | "client": { |
| | | "Vue": { |
| | | "vue2": "y", |
| | | "vue3": "y" |
| | | }, |
| | | "App": { |
| | | "app-vue": "y", |
| | | "app-nvue": "y" |
| | | }, |
| | | "H5-mobile": { |
| | | "Safari": "y", |
| | | "Android Browser": "y", |
| | | "微信浏览器(Android)": "y", |
| | | "QQ浏览器(Android)": "y" |
| | | }, |
| | | "H5-pc": { |
| | | "Chrome": "y", |
| | | "IE": "y", |
| | | "Edge": "y", |
| | | "Firefox": "y", |
| | | "Safari": "y" |
| | | }, |
| | | "小程序": { |
| | | "微信": "y", |
| | | "阿里": "y", |
| | | "百度": "y", |
| | | "字节跳动": "y", |
| | | "QQ": "y", |
| | | "钉钉": "u", |
| | | "快手": "u", |
| | | "飞书": "u", |
| | | "京东": "u" |
| | | }, |
| | | "快应用": { |
| | | "华为": "u", |
| | | "联盟": "u" |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| New file |
| | |
| | | ## Alert 警告提示 |
| | | |
| | | > **组件名:uv-alert** |
| | | |
| | | 警告提示,展现需要关注的信息。 |
| | | |
| | | 当某个页面需要向用户显示警告的信息时。 |
| | | |
| | | 非浮层的静态展现形式,始终展现,不会自动消失,用户可以点击关闭。 |
| | | |
| | | ### <a href="https://www.uvui.cn/components/alert.html" target="_blank">查看文档</a> |
| | | |
| | | ### [完整示例项目下载 | 关注更多组件](https://ext.dcloud.net.cn/plugin?name=uv-ui) |
| | | |
| | | #### 如使用过程中有任何问题,或者您对uv-ui有一些好的建议,欢迎加入 uv-ui 交流群:<a href="https://ext.dcloud.net.cn/plugin?id=12287" target="_blank">uv-ui</a>、<a href="https://www.uvui.cn/components/addQQGroup.html" target="_blank">官方QQ群</a> |
| New file |
| | |
| | | ## 1.0.5(2023-12-06) |
| | | 1. 优化 |
| | | ## 1.0.4(2023-12-06) |
| | | 1. 优化 |
| | | ## 1.0.3(2023-12-06) |
| | | 1. 阻止事件冒泡处理,单个头像模式 |
| | | ## 1.0.2(2023-12-06) |
| | | 1. 阻止事件冒泡处理 |
| | | ## 1.0.1(2023-05-16) |
| | | 1. 优化组件依赖,修改后无需全局引入,组件导入即可使用 |
| | | 2. 优化部分功能 |
| | | ## 1.0.0(2023-05-10) |
| | | uv-avatar 头像组件 |
| New file |
| | |
| | | export default { |
| | | props: { |
| | | // 头像图片组 |
| | | urls: { |
| | | type: Array, |
| | | default: () => [] |
| | | }, |
| | | // 最多展示的头像数量 |
| | | maxCount: { |
| | | type: [String, Number], |
| | | default: 5 |
| | | }, |
| | | // 头像形状 |
| | | shape: { |
| | | type: String, |
| | | default: 'circle' |
| | | }, |
| | | // 图片裁剪模式 |
| | | mode: { |
| | | type: String, |
| | | default: 'scaleToFill' |
| | | }, |
| | | // 超出maxCount时是否显示查看更多的提示 |
| | | showMore: { |
| | | type: Boolean, |
| | | default: true |
| | | }, |
| | | // 头像大小 |
| | | size: { |
| | | type: [String, Number], |
| | | default: 40 |
| | | }, |
| | | // 指定从数组的对象元素中读取哪个属性作为图片地址 |
| | | keyName: { |
| | | type: String, |
| | | default: '' |
| | | }, |
| | | // 头像之间的遮挡比例 |
| | | gap: { |
| | | type: [String, Number], |
| | | validator(value) { |
| | | return value >= 0 && value <= 1 |
| | | }, |
| | | default: 0.5 |
| | | }, |
| | | // 需额外显示的值 |
| | | extraValue: { |
| | | type: [Number, String], |
| | | default: 0 |
| | | }, |
| | | ...uni.$uv?.props?.avatarGroup |
| | | } |
| | | } |
| New file |
| | |
| | | <template> |
| | | <view class="uv-avatar-group"> |
| | | <view |
| | | class="uv-avatar-group__item" |
| | | v-for="(item, index) in showUrl" |
| | | :key="index" |
| | | :style="{ |
| | | marginLeft: index === 0 ? 0 : $uv.addUnit(-size * gap) |
| | | }" |
| | | > |
| | | <uv-avatar |
| | | :size="size" |
| | | :shape="shape" |
| | | :mode="mode" |
| | | :src="$uv.test.object(item) ? keyName && item[keyName] || item.url : item" |
| | | ></uv-avatar> |
| | | <view |
| | | class="uv-avatar-group__item__show-more" |
| | | v-if="showMore && index === showUrl.length - 1 && (urls.length > maxCount || extraValue > 0)" |
| | | @tap="clickHandler" |
| | | > |
| | | <uv-text |
| | | color="#ffffff" |
| | | :size="size * 0.4" |
| | | :text="`+${extraValue || urls.length - showUrl.length}`" |
| | | align="center" |
| | | customStyle="justify-content: center" |
| | | ></uv-text> |
| | | </view> |
| | | </view> |
| | | </view> |
| | | </template> |
| | | |
| | | <script> |
| | | import mpMixin from '@/uni_modules/uv-ui-tools/libs/mixin/mpMixin.js' |
| | | import mixin from '@/uni_modules/uv-ui-tools/libs/mixin/mixin.js' |
| | | import props from './props.js'; |
| | | /** |
| | | * AvatarGroup 头像组 |
| | | * @description 本组件一般用于展示头像的地方,如个人中心,或者评论列表页的用户头像展示等场所。 |
| | | * @tutorial https://www.uvui.cn/components/avatar.html |
| | | * |
| | | * @property {Array} urls 头像图片组 (默认 [] ) |
| | | * @property {String | Number} maxCount 最多展示的头像数量 ( 默认 5 ) |
| | | * @property {String} shape 头像形状( 'circle' (默认) | 'square' ) |
| | | * @property {String} mode 图片裁剪模式(默认 'scaleToFill' ) |
| | | * @property {Boolean} showMore 超出maxCount时是否显示查看更多的提示 (默认 true ) |
| | | * @property {String | Number} size 头像大小 (默认 40 ) |
| | | * @property {String} keyName 指定从数组的对象元素中读取哪个属性作为图片地址 |
| | | * @property {String | Number} gap 头像之间的遮挡比例(0.4代表遮挡40%) (默认 0.5 ) |
| | | * @property {String | Number} extraValue 需额外显示的值 |
| | | * @event {Function} showMore 头像组更多点击 |
| | | * @example <uv-avatar-group:urls="urls" size="35" gap="0.4" ></uv-avatar-group:urls=> |
| | | */ |
| | | export default { |
| | | name: 'uv-avatar-group', |
| | | mixins: [mpMixin, mixin, props], |
| | | data() { |
| | | return { |
| | | |
| | | } |
| | | }, |
| | | computed: { |
| | | showUrl() { |
| | | return this.urls.slice(0, this.maxCount) |
| | | } |
| | | }, |
| | | methods: { |
| | | clickHandler() { |
| | | this.$emit('showMore') |
| | | } |
| | | }, |
| | | } |
| | | </script> |
| | | |
| | | <style lang="scss" scoped> |
| | | @import '@/uni_modules/uv-ui-tools/libs/css/components.scss'; |
| | | @import '@/uni_modules/uv-ui-tools/libs/css/color.scss'; |
| | | |
| | | .uv-avatar-group { |
| | | @include flex; |
| | | |
| | | &__item { |
| | | margin-left: -10px; |
| | | position: relative; |
| | | |
| | | &--no-indent { |
| | | // 如果你想质疑作者不会使用:first-child,说明你太年轻,因为nvue不支持 |
| | | margin-left: 0; |
| | | } |
| | | |
| | | &__show-more { |
| | | position: absolute; |
| | | top: 0; |
| | | bottom: 0; |
| | | left: 0; |
| | | right: 0; |
| | | background-color: rgba(0, 0, 0, 0.3); |
| | | @include flex; |
| | | align-items: center; |
| | | justify-content: center; |
| | | border-radius: 100px; |
| | | } |
| | | } |
| | | } |
| | | </style> |
| New file |
| | |
| | | import { range } from '@/uni_modules/uv-ui-tools/libs/function/test.js' |
| | | export default { |
| | | props: { |
| | | // 头像图片路径(不能为相对路径) |
| | | src: { |
| | | type: String, |
| | | default: '' |
| | | }, |
| | | // 头像形状,circle-圆形,square-方形 |
| | | shape: { |
| | | type: String, |
| | | default: 'circle' |
| | | }, |
| | | // 头像尺寸 |
| | | size: { |
| | | type: [String, Number], |
| | | default: 40 |
| | | }, |
| | | // 裁剪模式 |
| | | mode: { |
| | | type: String, |
| | | default: 'scaleToFill' |
| | | }, |
| | | // 显示的文字 |
| | | text: { |
| | | type: String, |
| | | default: '' |
| | | }, |
| | | // 背景色 |
| | | bgColor: { |
| | | type: String, |
| | | default: '#c0c4cc' |
| | | }, |
| | | // 文字颜色 |
| | | color: { |
| | | type: String, |
| | | default: '#fff' |
| | | }, |
| | | // 文字大小 |
| | | fontSize: { |
| | | type: [String, Number], |
| | | default: 18 |
| | | }, |
| | | // 显示的图标 |
| | | icon: { |
| | | type: String, |
| | | default: '' |
| | | }, |
| | | // 显示小程序头像,只对百度,微信,QQ小程序有效 |
| | | mpAvatar: { |
| | | type: Boolean, |
| | | default: false |
| | | }, |
| | | // 是否使用随机背景色 |
| | | randomBgColor: { |
| | | type: Boolean, |
| | | default: false |
| | | }, |
| | | // 加载失败的默认头像(组件有内置默认图片) |
| | | defaultUrl: { |
| | | type: String, |
| | | default: '' |
| | | }, |
| | | // 如果配置了randomBgColor为true,且配置了此值,则从默认的背景色数组中取出对应索引的颜色值,取值0-19之间 |
| | | colorIndex: { |
| | | type: [String, Number], |
| | | // 校验参数规则,索引在0-19之间 |
| | | validator(n) { |
| | | return range(n, [0, 19]) || n === '' |
| | | }, |
| | | default: '' |
| | | }, |
| | | // 组件标识符 |
| | | name: { |
| | | type: String, |
| | | default: '' |
| | | }, |
| | | ...uni.$uv?.props?.avatar |
| | | } |
| | | } |
| New file |
| | |
| | | <template> |
| | | <view |
| | | class="uv-avatar" |
| | | :class="[`uv-avatar--${shape}`]" |
| | | :style="[{ |
| | | backgroundColor: (text || icon) ? (randomBgColor ? colors[colorIndex !== '' ? colorIndex : $uv.random(0, 19)] : bgColor) : 'transparent', |
| | | width: $uv.addUnit(size), |
| | | height: $uv.addUnit(size), |
| | | }, $uv.addStyle(customStyle)]" |
| | | @tap="clickHandler" |
| | | > |
| | | <slot> |
| | | <!-- #ifdef MP-WEIXIN || MP-QQ || MP-BAIDU --> |
| | | <open-data |
| | | v-if="mpAvatar && allowMp" |
| | | type="userAvatarUrl" |
| | | :style="[{ |
| | | width: $uv.addUnit(size), |
| | | height: $uv.addUnit(size) |
| | | }]" |
| | | /> |
| | | <!-- #endif --> |
| | | <!-- #ifndef MP-WEIXIN && MP-QQ && MP-BAIDU --> |
| | | <template v-if="mpAvatar && allowMp"></template> |
| | | <!-- #endif --> |
| | | <uv-icon |
| | | v-else-if="icon" |
| | | :name="icon" |
| | | :size="fontSize" |
| | | :color="color" |
| | | ></uv-icon> |
| | | <uv-text |
| | | v-else-if="text" |
| | | :text="text" |
| | | :size="fontSize" |
| | | :color="color" |
| | | align="center" |
| | | customStyle="justify-content: center" |
| | | ></uv-text> |
| | | <image |
| | | class="uv-avatar__image" |
| | | v-else |
| | | :class="[`uv-avatar__image--${shape}`]" |
| | | :src="avatarUrl || defaultUrl" |
| | | :mode="mode" |
| | | @error="errorHandler" |
| | | :style="[{ |
| | | width: $uv.addUnit(size), |
| | | height: $uv.addUnit(size) |
| | | }]" |
| | | ></image> |
| | | </slot> |
| | | </view> |
| | | </template> |
| | | |
| | | <script> |
| | | import mpMixin from '@/uni_modules/uv-ui-tools/libs/mixin/mpMixin.js' |
| | | import mixin from '@/uni_modules/uv-ui-tools/libs/mixin/mixin.js' |
| | | import props from './props.js'; |
| | | const base64Avatar = |
| | | "data:image/jpg;base64,/9j/4QAYRXhpZgAASUkqAAgAAAAAAAAAAAAAAP/sABFEdWNreQABAAQAAAA8AAD/4QMraHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLwA8P3hwYWNrZXQgYmVnaW49Iu+7vyIgaWQ9Ilc1TTBNcENlaGlIenJlU3pOVGN6a2M5ZCI/PiA8eDp4bXBtZXRhIHhtbG5zOng9ImFkb2JlOm5zOm1ldGEvIiB4OnhtcHRrPSJBZG9iZSBYTVAgQ29yZSA1LjMtYzAxMSA2Ni4xNDU2NjEsIDIwMTIvMDIvMDYtMTQ6NTY6MjcgICAgICAgICI+IDxyZGY6UkRGIHhtbG5zOnJkZj0iaHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zIyI+IDxyZGY6RGVzY3JpcHRpb24gcmRmOmFib3V0PSIiIHhtbG5zOnhtcD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLyIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bXA6Q3JlYXRvclRvb2w9IkFkb2JlIFBob3Rvc2hvcCBDUzYgKFdpbmRvd3MpIiB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOjREMEQwRkY0RjgwNDExRUE5OTY2RDgxODY3NkJFODMxIiB4bXBNTTpEb2N1bWVudElEPSJ4bXAuZGlkOjREMEQwRkY1RjgwNDExRUE5OTY2RDgxODY3NkJFODMxIj4gPHhtcE1NOkRlcml2ZWRGcm9tIHN0UmVmOmluc3RhbmNlSUQ9InhtcC5paWQ6NEQwRDBGRjJGODA0MTFFQTk5NjZEODE4Njc2QkU4MzEiIHN0UmVmOmRvY3VtZW50SUQ9InhtcC5kaWQ6NEQwRDBGRjNGODA0MTFFQTk5NjZEODE4Njc2QkU4MzEiLz4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+IDw/eHBhY2tldCBlbmQ9InIiPz7/7gAOQWRvYmUAZMAAAAAB/9sAhAAGBAQEBQQGBQUGCQYFBgkLCAYGCAsMCgoLCgoMEAwMDAwMDBAMDg8QDw4MExMUFBMTHBsbGxwfHx8fHx8fHx8fAQcHBw0MDRgQEBgaFREVGh8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx//wAARCADIAMgDAREAAhEBAxEB/8QAcQABAQEAAwEBAAAAAAAAAAAAAAUEAQMGAgcBAQAAAAAAAAAAAAAAAAAAAAAQAAIBAwICBgkDBQAAAAAAAAABAhEDBCEFMVFBYXGREiKBscHRMkJSEyOh4XLxYjNDFBEBAAAAAAAAAAAAAAAAAAAAAP/aAAwDAQACEQMRAD8A/fAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHbHFyZ/Dam+yLA+Z2L0Pjtyj2poD4AAAAAAAAAAAAAAAAAAAAAAAAKWFs9y6lcvvwQeqj8z9wFaziY1n/HbUX9XF97A7QAGXI23EvJ1goyfzR0YEfN269jeZ+a03pNe0DIAAAAAAAAAAAAAAAAAAAACvtO3RcVkXlWutuL9YFYAAAAAOJRjKLjJVi9GmB5/csH/mu1h/in8PU+QGMAAAAAAAAAAAAAAAAAAaMDG/6MmMH8C80+xAelSSVFolwQAAAAAAAHVlWI37ErUulaPk+hgeYnCUJuElSUXRrrQHAAAAAAAAAAAAAAAAABa2Oz4bM7r4zdF2ICmAAAAAAAAAg7zZ8GX41wuJP0rRgYAAAAAAAAAAAAAAAAAD0m2R8ODaXU33tsDSAAAAAAAAAlb9HyWZcnJd9PcBHAAAAAAAAAAAAAAAAAPS7e64Vn+KA0AAAAAAAAAJm+v8Ftf3ewCKAAAAAAAAAAAAAAAAAX9muqeGo9NttP06+0DcAAAAAAAAAjb7dTu2ra+VOT9P8AQCWAAAAAAAAAAAAAAAAAUNmyPt5Ltv4bui/kuAF0AAAAAAADiUlGLlJ0SVW+oDzOXfd/Ind6JPRdS0QHSAAAAAAAAAAAAAAAAAE2nVaNcGB6Lbs6OTao9LsF51z60BrAAAAAABJ3jOVHjW3r/sa9QEgAAAAAAAAAAAAAAAAAAAPu1duWriuW34ZR4MC9hbnZyEoy8l36XwfYBsAAADaSq9EuLAlZ+7xSdrGdW9Hc5dgEdtt1erfFgAAAAAAAAAAAAAAAAADVjbblX6NR8MH80tEBRs7HYivyzlN8lovaBPzduvY0m6eK10TXtAyAarO55lpJK54orolr+4GqO/Xaea1FvqbXvA+Z77kNeW3GPbV+4DJfzcm/pcm3H6Vou5AdAFLC2ed2Pjv1txa8sV8T6wOL+yZEKu1JXFy4MDBOE4ScZxcZLinoB8gAAAAAAAAAAAB242LeyJ+C3GvN9C7QLmJtePYpKS+5c+p8F2IDYAANJqj1T4oCfk7Nj3G5Wn9qXJax7gJ93Z82D8sVNc4v30A6Xg5i42Z+iLfqARwcyT0sz9MWvWBps7LlTf5Grce9/oBTxdtxseklHxT+uWr9AGoAB138ezfj4bsFJdD6V2MCPm7RdtJzs1uW1xXzL3gTgAAAAAAAAADRhYc8q74I6RWs5ckB6GxYtWLat21SK731sDsAAAAAAAAAAAAAAAASt021NO/YjrxuQXT1oCOAAAAAAABzGLlJRSq26JAelwsWONYjbXxcZvmwO8AAAAAAAAAAAAAAAAAAef3TEWPkVivx3NY9T6UBiAAAAAABo2+VmGXblddIJ8eivRUD0oAAAAAAAAAAAAAAAAAAAYt4tKeFKVNYNSXfRgefAAAAAAAAr7VuSSWPedKaW5v1MCsAAAAAAAAAAAAAAAAAAIe6bj96Ts2n+JPzSXzP3ATgAAAAAAAAFbbt1UUrOQ9FpC4/UwK6aaqtU+DAAAAAAAAAAAAAAA4lKMIuUmoxWrb4ARNx3R3q2rLpa4Sl0y/YCcAAAAAAAAAAANmFud7G8r89r6X0dgFvGzLGRGtuWvTF6NAdwAAAAAAAAAAAy5W442PVN+K59EePp5ARMvOv5MvO6QXCC4AZwAAAAAAAAAAAAAcxlKLUotprg1owN+PvORborq+7Hnwl3gUbO74VzRydt8pKn68ANcJwmqwkpLmnUDkAAAAfNy9atqtyagut0AxXt5xIV8Fbj6lRd7Am5G65V6qUvtwfyx94GMAAAAAAAAAAAAAAAAAAAOU2nVOj5gdsc3LiqRvTpyqwOxbnnrhdfpSfrQB7pnv/AGvuS9gHXPMy5/Fem1yq0v0A6W29XqwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAf//Z"; |
| | | /** |
| | | * Avatar 头像 |
| | | * @description 本组件一般用于展示头像的地方,如个人中心,或者评论列表页的用户头像展示等场所。 |
| | | * @tutorial https://www.uvui.cn/components/avatar.html |
| | | * |
| | | * @property {String} src 头像路径,如加载失败,将会显示默认头像(不能为相对路径) |
| | | * @property {String} shape 头像形状 ( circle (默认) | square) |
| | | * @property {String | Number} size 头像尺寸,可以为指定字符串(large, default, mini),或者数值 (默认 40 ) |
| | | * @property {String} mode 头像图片的裁剪类型,与uni的image组件的mode参数一致,如效果达不到需求,可尝试传widthFix值 (默认 'scaleToFill' ) |
| | | * @property {String} text 用文字替代图片,级别优先于src |
| | | * @property {String} bgColor 背景颜色,一般显示文字时用 (默认 '#c0c4cc' ) |
| | | * @property {String} color 文字颜色 (默认 '#ffffff' ) |
| | | * @property {String | Number} fontSize 文字大小 (默认 18 ) |
| | | * @property {String} icon 显示的图标 |
| | | * @property {Boolean} mpAvatar 显示小程序头像,只对百度,微信,QQ小程序有效 (默认 false ) |
| | | * @property {Boolean} randomBgColor 是否使用随机背景色 (默认 false ) |
| | | * @property {String} defaultUrl 加载失败的默认头像(组件有内置默认图片) |
| | | * @property {String | Number} colorIndex 如果配置了randomBgColor为true,且配置了此值,则从默认的背景色数组中取出对应索引的颜色值,取值0-19之间 |
| | | * @property {String} name 组件标识符 (默认 'level' ) |
| | | * @property {Object} customStyle 定义需要用到的外部样式 |
| | | * |
| | | * @event {Function} click 点击组件时触发 index: 用户传递的标识符 |
| | | * @example <uv-avatar :src="src" mode="square"></uv-avatar> |
| | | */ |
| | | export default { |
| | | name: 'uv-avatar', |
| | | emits: ['click'], |
| | | mixins: [mpMixin, mixin, props], |
| | | data() { |
| | | return { |
| | | // 如果配置randomBgColor参数为true,在图标或者文字的模式下,会随机从中取出一个颜色值当做背景色 |
| | | colors: ['#ffb34b', '#f2bba9', '#f7a196', '#f18080', '#88a867', '#bfbf39', '#89c152', '#94d554', '#f19ec2', |
| | | '#afaae4', '#e1b0df', '#c38cc1', '#72dcdc', '#9acdcb', '#77b1cc', '#448aca', '#86cefa', '#98d1ee', |
| | | '#73d1f1', |
| | | '#80a7dc' |
| | | ], |
| | | avatarUrl: this.src, |
| | | allowMp: false |
| | | } |
| | | }, |
| | | watch: { |
| | | // 监听头像src的变化,赋值给内部的avatarUrl变量,因为图片加载失败时,需要修改图片的src为默认值 |
| | | // 而组件内部不能直接修改props的值,所以需要一个中间变量 |
| | | src: { |
| | | immediate: true, |
| | | handler(newVal) { |
| | | this.avatarUrl = newVal |
| | | // 如果没有传src,则主动触发error事件,用于显示默认的头像,否则src为''空字符等的时候,会无内容展示 |
| | | if(!newVal) { |
| | | this.errorHandler() |
| | | } |
| | | } |
| | | } |
| | | }, |
| | | computed: { |
| | | imageStyle() { |
| | | const style = {} |
| | | return style |
| | | } |
| | | }, |
| | | created() { |
| | | this.init() |
| | | }, |
| | | methods: { |
| | | init() { |
| | | // 目前只有这几个小程序平台具有open-data标签 |
| | | // 其他平台可以通过uni.getUserInfo类似接口获取信息,但是需要弹窗授权(首次),不合符组件逻辑 |
| | | // 故目前自动获取小程序头像只支持这几个平台 |
| | | // #ifdef MP-WEIXIN || MP-QQ || MP-BAIDU |
| | | this.allowMp = true |
| | | // #endif |
| | | }, |
| | | // 判断传入的name属性,是否图片路径,只要带有"/"均认为是图片形式 |
| | | isImg() { |
| | | return this.src.indexOf('/') !== -1 |
| | | }, |
| | | // 图片加载时失败时触发 |
| | | errorHandler() { |
| | | this.avatarUrl = this.defaultUrl || base64Avatar |
| | | }, |
| | | clickHandler() { |
| | | this.$emit('click', this.name) |
| | | } |
| | | } |
| | | } |
| | | </script> |
| | | |
| | | <style lang="scss" scoped> |
| | | @import '@/uni_modules/uv-ui-tools/libs/css/components.scss'; |
| | | |
| | | .uv-avatar { |
| | | @include flex; |
| | | align-items: center; |
| | | justify-content: center; |
| | | |
| | | &--circle { |
| | | border-radius: 100px; |
| | | } |
| | | |
| | | &--square { |
| | | border-radius: 4px; |
| | | } |
| | | |
| | | &__image { |
| | | &--circle { |
| | | border-radius: 100px; |
| | | } |
| | | |
| | | &--square { |
| | | border-radius: 4px; |
| | | } |
| | | } |
| | | } |
| | | </style> |
| New file |
| | |
| | | { |
| | | "id": "uv-avatar", |
| | | "displayName": "uv-avatar 头像 全面兼容小程序、nvue、vue2、vue3等多端", |
| | | "version": "1.0.5", |
| | | "description": "uv-avatar 本组件一般用于展示头像的地方,如个人中心,或者评论列表页的用户头像展示等场所。", |
| | | "keywords": [ |
| | | "uv-avatar", |
| | | "uvui", |
| | | "uv-ui", |
| | | "avatar", |
| | | "头像" |
| | | ], |
| | | "repository": "", |
| | | "engines": { |
| | | "HBuilderX": "^3.1.0" |
| | | }, |
| | | "dcloudext": { |
| | | "type": "component-vue", |
| | | "sale": { |
| | | "regular": { |
| | | "price": "0.00" |
| | | }, |
| | | "sourcecode": { |
| | | "price": "0.00" |
| | | } |
| | | }, |
| | | "contact": { |
| | | "qq": "" |
| | | }, |
| | | "declaration": { |
| | | "ads": "无", |
| | | "data": "插件不采集任何数据", |
| | | "permissions": "无" |
| | | }, |
| | | "npmurl": "" |
| | | }, |
| | | "uni_modules": { |
| | | "dependencies": [ |
| | | "uv-ui-tools", |
| | | "uv-icon", |
| | | "uv-text" |
| | | ], |
| | | "encrypt": [], |
| | | "platforms": { |
| | | "cloud": { |
| | | "tcb": "y", |
| | | "aliyun": "y" |
| | | }, |
| | | "client": { |
| | | "Vue": { |
| | | "vue2": "y", |
| | | "vue3": "y" |
| | | }, |
| | | "App": { |
| | | "app-vue": "y", |
| | | "app-nvue": "y" |
| | | }, |
| | | "H5-mobile": { |
| | | "Safari": "y", |
| | | "Android Browser": "y", |
| | | "微信浏览器(Android)": "y", |
| | | "QQ浏览器(Android)": "y" |
| | | }, |
| | | "H5-pc": { |
| | | "Chrome": "y", |
| | | "IE": "y", |
| | | "Edge": "y", |
| | | "Firefox": "y", |
| | | "Safari": "y" |
| | | }, |
| | | "小程序": { |
| | | "微信": "y", |
| | | "阿里": "y", |
| | | "百度": "y", |
| | | "字节跳动": "y", |
| | | "QQ": "y", |
| | | "钉钉": "u", |
| | | "快手": "u", |
| | | "飞书": "u", |
| | | "京东": "u" |
| | | }, |
| | | "快应用": { |
| | | "华为": "u", |
| | | "联盟": "u" |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| New file |
| | |
| | | ## Avatar 头像 |
| | | |
| | | > **组件名:uv-avatar** |
| | | |
| | | 本组件一般用于展示头像的地方,如个人中心,或者评论列表页的用户头像展示等场所。 |
| | | |
| | | ### <a href="https://www.uvui.cn/components/avatar.html" target="_blank">查看文档</a> |
| | | |
| | | ### [完整示例项目下载 | 关注更多组件](https://ext.dcloud.net.cn/plugin?name=uv-ui) |
| | | |
| | | #### 如使用过程中有任何问题,或者您对uv-ui有一些好的建议,欢迎加入 uv-ui 交流群:<a href="https://ext.dcloud.net.cn/plugin?id=12287" target="_blank">uv-ui</a>、<a href="https://www.uvui.cn/components/addQQGroup.html" target="_blank">官方QQ群</a> |
| New file |
| | |
| | | ## 1.0.2(2023-07-03) |
| | | 1. 优化插槽自定义内容部分 |
| | | 2. 增加backToTop方法说明 |
| | | ## 1.0.1(2023-05-16) |
| | | 1. 优化组件依赖,修改后无需全局引入,组件导入即可使用 |
| | | 2. 优化部分功能 |
| | | ## 1.0.0(2023-05-10) |
| | | uv-back-top 返回顶部 |
| New file |
| | |
| | | export default { |
| | | props: { |
| | | // 返回顶部的形状,circle-圆形,square-方形 |
| | | mode: { |
| | | type: String, |
| | | default: 'circle' |
| | | }, |
| | | // 自定义图标 |
| | | icon: { |
| | | type: String, |
| | | default: 'arrow-upward' |
| | | }, |
| | | // 提示文字 |
| | | text: { |
| | | type: String, |
| | | default: '' |
| | | }, |
| | | // 返回顶部滚动时间 |
| | | duration: { |
| | | type: [String, Number], |
| | | default: 100 |
| | | }, |
| | | // 滚动距离 |
| | | scrollTop: { |
| | | type: [String, Number], |
| | | default: 0 |
| | | }, |
| | | // 距离顶部多少距离显示,单位px |
| | | top: { |
| | | type: [String, Number], |
| | | default: 400 |
| | | }, |
| | | // 返回顶部按钮到底部的距离,单位px |
| | | bottom: { |
| | | type: [String, Number], |
| | | default: 100 |
| | | }, |
| | | // 返回顶部按钮到右边的距离,单位px |
| | | right: { |
| | | type: [String, Number], |
| | | default: 20 |
| | | }, |
| | | // 层级 |
| | | zIndex: { |
| | | type: [String, Number], |
| | | default: 9 |
| | | }, |
| | | // 图标的样式,对象形式 |
| | | iconStyle: { |
| | | type: Object, |
| | | default: () => ({ |
| | | color: '#909399', |
| | | fontSize: '19px' |
| | | }) |
| | | }, |
| | | ...uni.$uv?.props?.backtop |
| | | } |
| | | } |
| New file |
| | |
| | | <template> |
| | | <uv-transition mode="fade" :customStyle="backTopStyle" :show="show"> |
| | | <slot> |
| | | <view class="uv-back-top" :style="[contentStyle]" @click="backToTop"> |
| | | <uv-icon :name="icon" :custom-style="iconStyle"></uv-icon> |
| | | <text v-if="text" class="uv-back-top__text">{{text}}</text> |
| | | </view> |
| | | </slot> |
| | | </uv-transition> |
| | | </template> |
| | | |
| | | <script> |
| | | import mpMixin from '@/uni_modules/uv-ui-tools/libs/mixin/mpMixin.js' |
| | | import mixin from '@/uni_modules/uv-ui-tools/libs/mixin/mixin.js' |
| | | import props from './props.js'; |
| | | // #ifdef APP-NVUE |
| | | const dom = weex.requireModule('dom') |
| | | // #endif |
| | | /** |
| | | * backTop 返回顶部 |
| | | * @description 本组件一个用于长页面,滑动一定距离后,出现返回顶部按钮,方便快速返回顶部的场景。 |
| | | * @tutorial https://www.uvui.cn/components/backTop.html |
| | | * @property {String} mode 返回顶部的形状,circle-圆形,square-方形 (默认 'circle' ) |
| | | * @property {String} icon 自定义图标 (默认 'arrow-upward' ) 见官方文档示例 |
| | | * @property {String} text 提示文字 |
| | | * @property {String | Number} duration 返回顶部滚动时间 (默认 100) |
| | | * @property {String | Number} scrollTop 滚动距离 (默认 0 ) |
| | | * @property {String | Number} top 距离顶部多少距离显示,单位px (默认 400 ) |
| | | * @property {String | Number} bottom 返回顶部按钮到底部的距离,单位px (默认 100 ) |
| | | * @property {String | Number} right 返回顶部按钮到右边的距离,单位px (默认 20 ) |
| | | * @property {String | Number} zIndex 层级 (默认 9 ) |
| | | * @property {Object<Object>} iconStyle 图标的样式,对象形式 (默认 {color: '#909399',fontSize: '19px'}) |
| | | * @property {Object} customStyle 定义需要用到的外部样式 |
| | | * |
| | | * @example <uv-back-top :scrollTop="scrollTop"></uv-back-top> |
| | | */ |
| | | export default { |
| | | name: 'uv-back-top', |
| | | emits: ['click'], |
| | | mixins: [mpMixin, mixin, props], |
| | | computed: { |
| | | backTopStyle() { |
| | | // 动画组件样式 |
| | | const style = { |
| | | bottom: this.$uv.addUnit(this.bottom), |
| | | right: this.$uv.addUnit(this.right), |
| | | width: '40px', |
| | | height: '40px', |
| | | position: 'fixed', |
| | | zIndex: 10, |
| | | } |
| | | return style |
| | | }, |
| | | show() { |
| | | return this.$uv.getPx(this.scrollTop) > this.$uv.getPx(this.top) |
| | | }, |
| | | contentStyle() { |
| | | const style = {} |
| | | let radius = 0 |
| | | // 是否圆形 |
| | | if (this.mode === 'circle') { |
| | | radius = '100px' |
| | | } else { |
| | | radius = '4px' |
| | | } |
| | | // 为了兼容安卓nvue,只能这么分开写 |
| | | style.borderTopLeftRadius = radius |
| | | style.borderTopRightRadius = radius |
| | | style.borderBottomLeftRadius = radius |
| | | style.borderBottomRightRadius = radius |
| | | return this.$uv.deepMerge(style, this.$uv.addStyle(this.customStyle)) |
| | | } |
| | | }, |
| | | methods: { |
| | | backToTop() { |
| | | // #ifdef APP-NVUE |
| | | if (!this.$parent.$refs['uv-back-top']) { |
| | | this.$uv.error(`nvue页面需要给页面最外层元素设置"ref='uv-back-top'`) |
| | | } |
| | | dom.scrollToElement(this.$parent.$refs['uv-back-top'], { |
| | | offset: 0 |
| | | }) |
| | | // #endif |
| | | |
| | | // #ifndef APP-NVUE |
| | | uni.pageScrollTo({ |
| | | scrollTop: 0, |
| | | duration: this.duration |
| | | }); |
| | | // #endif |
| | | this.$emit('click') |
| | | } |
| | | } |
| | | } |
| | | </script> |
| | | |
| | | <style lang="scss" scoped> |
| | | @import '@/uni_modules/uv-ui-tools/libs/css/components.scss'; |
| | | $uv-back-top-flex: 1 !default; |
| | | $uv-back-top-height: 100% !default; |
| | | $uv-back-top-background-color: #E1E1E1 !default; |
| | | $uv-back-top-tips-font-size: 12px !default; |
| | | .uv-back-top { |
| | | @include flex; |
| | | flex-direction: column; |
| | | align-items: center; |
| | | flex: $uv-back-top-flex; |
| | | height: $uv-back-top-height; |
| | | justify-content: center; |
| | | background-color: $uv-back-top-background-color; |
| | | &__tips { |
| | | font-size: $uv-back-top-tips-font-size; |
| | | transform: scale(0.8); |
| | | } |
| | | } |
| | | </style> |
| New file |
| | |
| | | { |
| | | "id": "uv-back-top", |
| | | "displayName": "uv-back-top 返回顶部 全面兼容小程序、nvue、vue2、vue3等多端", |
| | | "version": "1.0.2", |
| | | "description": "返回顶部 组件一个用于长页面,滑动一定距离后,出现返回顶部按钮,方便快速返回顶部的场景。", |
| | | "keywords": [ |
| | | "uv-back-top", |
| | | "uvui", |
| | | "uv-ui", |
| | | "avatar", |
| | | "返回顶部" |
| | | ], |
| | | "repository": "", |
| | | "engines": { |
| | | "HBuilderX": "^3.1.0" |
| | | }, |
| | | "dcloudext": { |
| | | "type": "component-vue", |
| | | "sale": { |
| | | "regular": { |
| | | "price": "0.00" |
| | | }, |
| | | "sourcecode": { |
| | | "price": "0.00" |
| | | } |
| | | }, |
| | | "contact": { |
| | | "qq": "" |
| | | }, |
| | | "declaration": { |
| | | "ads": "无", |
| | | "data": "插件不采集任何数据", |
| | | "permissions": "无" |
| | | }, |
| | | "npmurl": "" |
| | | }, |
| | | "uni_modules": { |
| | | "dependencies": [ |
| | | "uv-ui-tools", |
| | | "uv-icon", |
| | | "uv-transition" |
| | | ], |
| | | "encrypt": [], |
| | | "platforms": { |
| | | "cloud": { |
| | | "tcb": "y", |
| | | "aliyun": "y" |
| | | }, |
| | | "client": { |
| | | "Vue": { |
| | | "vue2": "y", |
| | | "vue3": "y" |
| | | }, |
| | | "App": { |
| | | "app-vue": "y", |
| | | "app-nvue": "y" |
| | | }, |
| | | "H5-mobile": { |
| | | "Safari": "y", |
| | | "Android Browser": "y", |
| | | "微信浏览器(Android)": "y", |
| | | "QQ浏览器(Android)": "y" |
| | | }, |
| | | "H5-pc": { |
| | | "Chrome": "y", |
| | | "IE": "y", |
| | | "Edge": "y", |
| | | "Firefox": "y", |
| | | "Safari": "y" |
| | | }, |
| | | "小程序": { |
| | | "微信": "y", |
| | | "阿里": "y", |
| | | "百度": "y", |
| | | "字节跳动": "y", |
| | | "QQ": "y", |
| | | "钉钉": "u", |
| | | "快手": "u", |
| | | "飞书": "u", |
| | | "京东": "u" |
| | | }, |
| | | "快应用": { |
| | | "华为": "u", |
| | | "联盟": "u" |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| New file |
| | |
| | | ## BackTop 返回顶部 |
| | | |
| | | > **组件名:uv-back-top** |
| | | |
| | | 该组件一个用于长页面,滑动一定距离后,出现返回顶部按钮,方便快速返回顶部的场景。 |
| | | |
| | | ### <a href="https://www.uvui.cn/components/backTop.html" target="_blank">查看文档</a> |
| | | |
| | | ### [完整示例项目下载 | 关注更多组件](https://ext.dcloud.net.cn/plugin?name=uv-ui) |
| | | |
| | | #### 如使用过程中有任何问题,或者您对uv-ui有一些好的建议,欢迎加入 uv-ui 交流群:<a href="https://ext.dcloud.net.cn/plugin?id=12287" target="_blank">uv-ui</a>、<a href="https://www.uvui.cn/components/addQQGroup.html" target="_blank">官方QQ群</a> |
| New file |
| | |
| | | ## 1.0.2(2023-06-04) |
| | | 1. 修复type等属性为null的时候不显示徽标的BUG |
| | | ## 1.0.1(2023-05-16) |
| | | 1. 优化组件依赖,修改后无需全局引入,组件导入即可使用 |
| | | 2. 优化部分功能 |
| | | ## 1.0.0(2023-05-10) |
| | | uv-badge 徽标数,数字角标 |
| New file |
| | |
| | | export default { |
| | | props: { |
| | | // 是否显示圆点 |
| | | isDot: { |
| | | type: Boolean, |
| | | default: false |
| | | }, |
| | | // 显示的内容 |
| | | value: { |
| | | type: [Number, String], |
| | | default: '' |
| | | }, |
| | | // 是否显示 |
| | | show: { |
| | | type: Boolean, |
| | | default: true |
| | | }, |
| | | // 最大值,超过最大值会显示 '{max}+' |
| | | max: { |
| | | type: [Number, String], |
| | | default: 999 |
| | | }, |
| | | // 主题类型,error|warning|success|primary |
| | | type: { |
| | | type: [String,undefined,null], |
| | | default: 'error' |
| | | }, |
| | | // 当数值为 0 时,是否展示 Badge |
| | | showZero: { |
| | | type: Boolean, |
| | | default: false |
| | | }, |
| | | // 背景颜色,优先级比type高,如设置,type参数会失效 |
| | | bgColor: { |
| | | type: [String, null], |
| | | default: null |
| | | }, |
| | | // 字体颜色 |
| | | color: { |
| | | type: [String, null], |
| | | default: null |
| | | }, |
| | | // 徽标形状,circle-四角均为圆角,horn-左下角为直角 |
| | | shape: { |
| | | type: [String,undefined,null], |
| | | default: 'circle' |
| | | }, |
| | | // 设置数字的显示方式,overflow|ellipsis|limit |
| | | // overflow会根据max字段判断,超出显示`${max}+` |
| | | // ellipsis会根据max判断,超出显示`${max}...` |
| | | // limit会依据1000作为判断条件,超出1000,显示`${value/1000}K`,比如2.2k、3.34w,最多保留2位小数 |
| | | numberType: { |
| | | type: [String,undefined,null], |
| | | default: 'overflow' |
| | | }, |
| | | // 设置badge的位置偏移,格式为 [x, y],也即设置的为top和right的值,absolute为true时有效 |
| | | offset: { |
| | | type: Array, |
| | | default: () => [] |
| | | }, |
| | | // 是否反转背景和字体颜色 |
| | | inverted: { |
| | | type: Boolean, |
| | | default: false |
| | | }, |
| | | // 是否绝对定位 |
| | | absolute: { |
| | | type: Boolean, |
| | | default: false |
| | | }, |
| | | ...uni.$uv?.props?.badge |
| | | } |
| | | } |
| New file |
| | |
| | | <template> |
| | | <text |
| | | v-if="show && ((Number(value) === 0 ? showZero : true) || isDot)" |
| | | :class="[isDot ? 'uv-badge--dot' : 'uv-badge--not-dot', inverted && 'uv-badge--inverted', shape === 'horn' && 'uv-badge--horn', `uv-badge--${propsType}${inverted ? '--inverted' : ''}`]" |
| | | :style="[$uv.addStyle(customStyle), badgeStyle]" |
| | | class="uv-badge" |
| | | >{{ isDot ? '' :showValue }}</text> |
| | | </template> |
| | | |
| | | <script> |
| | | import mpMixin from '@/uni_modules/uv-ui-tools/libs/mixin/mpMixin.js' |
| | | import mixin from '@/uni_modules/uv-ui-tools/libs/mixin/mixin.js' |
| | | import props from './props.js'; |
| | | /** |
| | | * badge 徽标数 |
| | | * @description 该组件一般用于图标右上角显示未读的消息数量,提示用户点击,有圆点和圆包含文字两种形式。 |
| | | * @tutorial https://www.uvui.cn/components/badge.html |
| | | * |
| | | * @property {Boolean} isDot 是否显示圆点 (默认 false ) |
| | | * @property {String | Number} value 显示的内容 |
| | | * @property {Boolean} show 是否显示 (默认 true ) |
| | | * @property {String | Number} max 最大值,超过最大值会显示 '{max}+' (默认999) |
| | | * @property {String} type 主题类型,error|warning|success|primary (默认 'error' ) |
| | | * @property {Boolean} showZero 当数值为 0 时,是否展示 Badge (默认 false ) |
| | | * @property {String} bgColor 背景颜色,优先级比type高,如设置,type参数会失效 |
| | | * @property {String} color 字体颜色 (默认 '#ffffff' ) |
| | | * @property {String} shape 徽标形状,circle-四角均为圆角,horn-左下角为直角 (默认 'circle' ) |
| | | * @property {String} numberType 设置数字的显示方式,overflow|ellipsis|limit (默认 'overflow' ) |
| | | * @property {Array}} offset 设置badge的位置偏移,格式为 [x, y],也即设置的为top和right的值,absolute为true时有效 |
| | | * @property {Boolean} inverted 是否反转背景和字体颜色(默认 false ) |
| | | * @property {Boolean} absolute 是否绝对定位(默认 false ) |
| | | * @property {Object} customStyle 定义需要用到的外部样式 |
| | | * @example <uv-badge :type="type" :count="count"></uv-badge> |
| | | */ |
| | | export default { |
| | | name: 'uv-badge', |
| | | mixins: [mpMixin, mixin, props], |
| | | computed: { |
| | | // 是否将badge中心与父组件右上角重合 |
| | | boxStyle() { |
| | | let style = {}; |
| | | return style; |
| | | }, |
| | | // 整个组件的样式 |
| | | badgeStyle() { |
| | | const style = {} |
| | | if(this.color) { |
| | | style.color = this.color |
| | | } |
| | | if (this.bgColor && !this.inverted) { |
| | | style.backgroundColor = this.bgColor |
| | | } |
| | | if (this.absolute) { |
| | | style.position = 'absolute' |
| | | // 如果有设置offset参数 |
| | | if(this.offset.length) { |
| | | // top和right分为为offset的第一个和第二个值,如果没有第二个值,则right等于top |
| | | const top = this.offset[0] |
| | | const right = this.offset[1] || top |
| | | style.top = this.$uv.addUnit(top) |
| | | style.right = this.$uv.addUnit(right) |
| | | } |
| | | } |
| | | return style |
| | | }, |
| | | showValue() { |
| | | switch (this.numberType) { |
| | | case "overflow": |
| | | return Number(this.value) > Number(this.max) ? this.max + "+" : this.value |
| | | break; |
| | | case "ellipsis": |
| | | return Number(this.value) > Number(this.max) ? "..." : this.value |
| | | break; |
| | | case "limit": |
| | | return Number(this.value) > 999 ? Number(this.value) >= 9999 ? |
| | | Math.floor(this.value / 1e4 * 100) / 100 + "w" : Math.floor(this.value / |
| | | 1e3 * 100) / 100 + "k" : this.value |
| | | break; |
| | | default: |
| | | return Number(this.value) |
| | | } |
| | | }, |
| | | propsType(){ |
| | | return this.type || 'error' |
| | | } |
| | | } |
| | | } |
| | | </script> |
| | | |
| | | <style lang="scss" scoped> |
| | | @import '@/uni_modules/uv-ui-tools/libs/css/components.scss'; |
| | | @import '@/uni_modules/uv-ui-tools/libs/css/color.scss'; |
| | | $uv-badge-primary: $uv-primary !default; |
| | | $uv-badge-error: $uv-error !default; |
| | | $uv-badge-success: $uv-success !default; |
| | | $uv-badge-info: $uv-info !default; |
| | | $uv-badge-warning: $uv-warning !default; |
| | | $uv-badge-dot-radius: 100px !default; |
| | | $uv-badge-dot-size: 8px !default; |
| | | $uv-badge-dot-right: 4px !default; |
| | | $uv-badge-dot-top: 0 !default; |
| | | $uv-badge-text-font-size: 11px !default; |
| | | $uv-badge-text-right: 10px !default; |
| | | $uv-badge-text-padding: 2px 5px !default; |
| | | $uv-badge-text-align: center !default; |
| | | $uv-badge-text-color: #FFFFFF !default; |
| | | |
| | | .uv-badge { |
| | | border-top-right-radius: $uv-badge-dot-radius; |
| | | border-top-left-radius: $uv-badge-dot-radius; |
| | | border-bottom-left-radius: $uv-badge-dot-radius; |
| | | border-bottom-right-radius: $uv-badge-dot-radius; |
| | | @include flex; |
| | | line-height: $uv-badge-text-font-size; |
| | | text-align: $uv-badge-text-align; |
| | | font-size: $uv-badge-text-font-size; |
| | | color: $uv-badge-text-color; |
| | | |
| | | &--dot { |
| | | height: $uv-badge-dot-size; |
| | | width: $uv-badge-dot-size; |
| | | } |
| | | |
| | | &--inverted { |
| | | font-size: 13px; |
| | | } |
| | | |
| | | &--not-dot { |
| | | padding: $uv-badge-text-padding; |
| | | } |
| | | |
| | | &--horn { |
| | | border-bottom-left-radius: 0; |
| | | } |
| | | |
| | | &--primary { |
| | | background-color: $uv-badge-primary; |
| | | } |
| | | |
| | | &--primary--inverted { |
| | | color: $uv-badge-primary; |
| | | } |
| | | |
| | | &--error { |
| | | background-color: $uv-badge-error; |
| | | } |
| | | |
| | | &--error--inverted { |
| | | color: $uv-badge-error; |
| | | } |
| | | |
| | | &--success { |
| | | background-color: $uv-badge-success; |
| | | } |
| | | |
| | | &--success--inverted { |
| | | color: $uv-badge-success; |
| | | } |
| | | |
| | | &--info { |
| | | background-color: $uv-badge-info; |
| | | } |
| | | |
| | | &--info--inverted { |
| | | color: $uv-badge-info; |
| | | } |
| | | |
| | | &--warning { |
| | | background-color: $uv-badge-warning; |
| | | } |
| | | |
| | | &--warning--inverted { |
| | | color: $uv-badge-warning; |
| | | } |
| | | } |
| | | </style> |
| New file |
| | |
| | | { |
| | | "id": "uv-badge", |
| | | "displayName": "uv-badge 徽标数,数字角标 全面兼容小程序、nvue、vue2、vue3等多端", |
| | | "version": "1.0.2", |
| | | "description": "徽标数一般用于图标右上角显示未读的消息数量,提示用户点击,有圆点和圆包含文字两种形式。", |
| | | "keywords": [ |
| | | "uv-badge", |
| | | "uvui", |
| | | "uv-ui", |
| | | "徽标数", |
| | | "数字角标" |
| | | ], |
| | | "repository": "", |
| | | "engines": { |
| | | "HBuilderX": "^3.1.0" |
| | | }, |
| | | "dcloudext": { |
| | | "type": "component-vue", |
| | | "sale": { |
| | | "regular": { |
| | | "price": "0.00" |
| | | }, |
| | | "sourcecode": { |
| | | "price": "0.00" |
| | | } |
| | | }, |
| | | "contact": { |
| | | "qq": "" |
| | | }, |
| | | "declaration": { |
| | | "ads": "无", |
| | | "data": "插件不采集任何数据", |
| | | "permissions": "无" |
| | | }, |
| | | "npmurl": "" |
| | | }, |
| | | "uni_modules": { |
| | | "dependencies": [ |
| | | "uv-ui-tools" |
| | | ], |
| | | "encrypt": [], |
| | | "platforms": { |
| | | "cloud": { |
| | | "tcb": "y", |
| | | "aliyun": "y" |
| | | }, |
| | | "client": { |
| | | "Vue": { |
| | | "vue2": "y", |
| | | "vue3": "y" |
| | | }, |
| | | "App": { |
| | | "app-vue": "y", |
| | | "app-nvue": "y" |
| | | }, |
| | | "H5-mobile": { |
| | | "Safari": "y", |
| | | "Android Browser": "y", |
| | | "微信浏览器(Android)": "y", |
| | | "QQ浏览器(Android)": "y" |
| | | }, |
| | | "H5-pc": { |
| | | "Chrome": "y", |
| | | "IE": "y", |
| | | "Edge": "y", |
| | | "Firefox": "y", |
| | | "Safari": "y" |
| | | }, |
| | | "小程序": { |
| | | "微信": "y", |
| | | "阿里": "y", |
| | | "百度": "y", |
| | | "字节跳动": "y", |
| | | "QQ": "y", |
| | | "钉钉": "u", |
| | | "快手": "u", |
| | | "飞书": "u", |
| | | "京东": "u" |
| | | }, |
| | | "快应用": { |
| | | "华为": "u", |
| | | "联盟": "u" |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| New file |
| | |
| | | ## Badge 徽标数 |
| | | |
| | | > **组件名:uv-badge** |
| | | |
| | | 该组件一般用于图标右上角显示未读的消息数量,提示用户点击,有圆点和圆包含文字两种形式。 |
| | | |
| | | ### <a href="https://www.uvui.cn/components/badge.html" target="_blank">查看文档</a> |
| | | |
| | | ### [完整示例项目下载 | 关注更多组件](https://ext.dcloud.net.cn/plugin?name=uv-ui) |
| | | |
| | | #### 如使用过程中有任何问题,或者您对uv-ui有一些好的建议,欢迎加入 uv-ui 交流群:<a href="https://ext.dcloud.net.cn/plugin?id=12287" target="_blank">uv-ui</a>、<a href="https://www.uvui.cn/components/addQQGroup.html" target="_blank">官方QQ群</a> |
| | |
| | | loadingColor() { |
| | | if (this.plain) { |
| | | // 如果有设置color值,则用color值,否则使用type主题颜色 |
| | | return this.color ? this.color : '#EE2626'; |
| | | return this.color ? this.color : '#3c9cff'; |
| | | } |
| | | if (this.type === "info") { |
| | | return "#c9c9c9"; |
| New file |
| | |
| | | ## 1.0.6(2023-11-03) |
| | | 1. **该版本不再维护**,推荐使用新版本[https://ext.dcloud.net.cn/plugin?name=uv-calendars](https://ext.dcloud.net.cn/plugin?name=uv-calendars) |
| | | ## 1.0.5(2023-07-02) |
| | | uv-calendar 由于弹出层uv-popup的修改,打开和关闭方法更改,详情参考文档:https://www.uvui.cn/components/calendar.html |
| | | ## 1.0.4(2023-06-15) |
| | | 1. formatter格式化中增加topInfo参数 |
| | | ## 1.0.3(2023-06-08) |
| | | 1. 增加点击日期change回调 |
| | | 2. 优化 |
| | | ## 1.0.2(2023-06-05) |
| | | 1. 修改多个时间选择的时候存在反选的BUG |
| | | ## 1.0.1(2023-05-16) |
| | | 1. 优化组件依赖,修改后无需全局引入,组件导入即可使用 |
| | | 2. 优化部分功能 |
| | | ## 1.0.0(2023-05-10) |
| | | uv-calendar 日历 |
| New file |
| | |
| | | /** |
| | | * @1900-2100区间内的公历、农历互转 |
| | | * @charset UTF-8 |
| | | * @github https://github.com/jjonline/calendar.js |
| | | * @Author Jea杨(JJonline@JJonline.Cn) |
| | | * @Time 2014-7-21 |
| | | * @Time 2016-8-13 Fixed 2033hex、Attribution Annals |
| | | * @Time 2016-9-25 Fixed lunar LeapMonth Param Bug |
| | | * @Time 2017-7-24 Fixed use getTerm Func Param Error.use solar year,NOT lunar year |
| | | * @Version 1.0.3 |
| | | * @公历转农历:calendar.solar2lunar(1987,11,01); //[you can ignore params of prefix 0] |
| | | * @农历转公历:calendar.lunar2solar(1987,09,10); //[you can ignore params of prefix 0] |
| | | */ |
| | | /* eslint-disable */ |
| | | var calendar = { |
| | | |
| | | /** |
| | | * 农历1900-2100的润大小信息表 |
| | | * @Array Of Property |
| | | * @return Hex |
| | | */ |
| | | lunarInfo: [0x04bd8, 0x04ae0, 0x0a570, 0x054d5, 0x0d260, 0x0d950, 0x16554, 0x056a0, 0x09ad0, 0x055d2, // 1900-1909 |
| | | 0x04ae0, 0x0a5b6, 0x0a4d0, 0x0d250, 0x1d255, 0x0b540, 0x0d6a0, 0x0ada2, 0x095b0, 0x14977, // 1910-1919 |
| | | 0x04970, 0x0a4b0, 0x0b4b5, 0x06a50, 0x06d40, 0x1ab54, 0x02b60, 0x09570, 0x052f2, 0x04970, // 1920-1929 |
| | | 0x06566, 0x0d4a0, 0x0ea50, 0x06e95, 0x05ad0, 0x02b60, 0x186e3, 0x092e0, 0x1c8d7, 0x0c950, // 1930-1939 |
| | | 0x0d4a0, 0x1d8a6, 0x0b550, 0x056a0, 0x1a5b4, 0x025d0, 0x092d0, 0x0d2b2, 0x0a950, 0x0b557, // 1940-1949 |
| | | 0x06ca0, 0x0b550, 0x15355, 0x04da0, 0x0a5b0, 0x14573, 0x052b0, 0x0a9a8, 0x0e950, 0x06aa0, // 1950-1959 |
| | | 0x0aea6, 0x0ab50, 0x04b60, 0x0aae4, 0x0a570, 0x05260, 0x0f263, 0x0d950, 0x05b57, 0x056a0, // 1960-1969 |
| | | 0x096d0, 0x04dd5, 0x04ad0, 0x0a4d0, 0x0d4d4, 0x0d250, 0x0d558, 0x0b540, 0x0b6a0, 0x195a6, // 1970-1979 |
| | | 0x095b0, 0x049b0, 0x0a974, 0x0a4b0, 0x0b27a, 0x06a50, 0x06d40, 0x0af46, 0x0ab60, 0x09570, // 1980-1989 |
| | | 0x04af5, 0x04970, 0x064b0, 0x074a3, 0x0ea50, 0x06b58, 0x05ac0, 0x0ab60, 0x096d5, 0x092e0, // 1990-1999 |
| | | 0x0c960, 0x0d954, 0x0d4a0, 0x0da50, 0x07552, 0x056a0, 0x0abb7, 0x025d0, 0x092d0, 0x0cab5, // 2000-2009 |
| | | 0x0a950, 0x0b4a0, 0x0baa4, 0x0ad50, 0x055d9, 0x04ba0, 0x0a5b0, 0x15176, 0x052b0, 0x0a930, // 2010-2019 |
| | | 0x07954, 0x06aa0, 0x0ad50, 0x05b52, 0x04b60, 0x0a6e6, 0x0a4e0, 0x0d260, 0x0ea65, 0x0d530, // 2020-2029 |
| | | 0x05aa0, 0x076a3, 0x096d0, 0x04afb, 0x04ad0, 0x0a4d0, 0x1d0b6, 0x0d250, 0x0d520, 0x0dd45, // 2030-2039 |
| | | 0x0b5a0, 0x056d0, 0x055b2, 0x049b0, 0x0a577, 0x0a4b0, 0x0aa50, 0x1b255, 0x06d20, 0x0ada0, // 2040-2049 |
| | | /** Add By JJonline@JJonline.Cn**/ |
| | | 0x14b63, 0x09370, 0x049f8, 0x04970, 0x064b0, 0x168a6, 0x0ea50, 0x06b20, 0x1a6c4, 0x0aae0, // 2050-2059 |
| | | 0x0a2e0, 0x0d2e3, 0x0c960, 0x0d557, 0x0d4a0, 0x0da50, 0x05d55, 0x056a0, 0x0a6d0, 0x055d4, // 2060-2069 |
| | | 0x052d0, 0x0a9b8, 0x0a950, 0x0b4a0, 0x0b6a6, 0x0ad50, 0x055a0, 0x0aba4, 0x0a5b0, 0x052b0, // 2070-2079 |
| | | 0x0b273, 0x06930, 0x07337, 0x06aa0, 0x0ad50, 0x14b55, 0x04b60, 0x0a570, 0x054e4, 0x0d160, // 2080-2089 |
| | | 0x0e968, 0x0d520, 0x0daa0, 0x16aa6, 0x056d0, 0x04ae0, 0x0a9d4, 0x0a2d0, 0x0d150, 0x0f252, // 2090-2099 |
| | | 0x0d520], // 2100 |
| | | |
| | | /** |
| | | * 公历每个月份的天数普通表 |
| | | * @Array Of Property |
| | | * @return Number |
| | | */ |
| | | solarMonth: [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31], |
| | | |
| | | /** |
| | | * 天干地支之天干速查表 |
| | | * @Array Of Property trans["甲","乙","丙","丁","戊","己","庚","辛","壬","癸"] |
| | | * @return Cn string |
| | | */ |
| | | Gan: ['\u7532', '\u4e59', '\u4e19', '\u4e01', '\u620a', '\u5df1', '\u5e9a', '\u8f9b', '\u58ec', '\u7678'], |
| | | |
| | | /** |
| | | * 天干地支之地支速查表 |
| | | * @Array Of Property |
| | | * @trans["子","丑","寅","卯","辰","巳","午","未","申","酉","戌","亥"] |
| | | * @return Cn string |
| | | */ |
| | | Zhi: ['\u5b50', '\u4e11', '\u5bc5', '\u536f', '\u8fb0', '\u5df3', '\u5348', '\u672a', '\u7533', '\u9149', '\u620c', '\u4ea5'], |
| | | |
| | | /** |
| | | * 天干地支之地支速查表<=>生肖 |
| | | * @Array Of Property |
| | | * @trans["鼠","牛","虎","兔","龙","蛇","马","羊","猴","鸡","狗","猪"] |
| | | * @return Cn string |
| | | */ |
| | | Animals: ['\u9f20', '\u725b', '\u864e', '\u5154', '\u9f99', '\u86c7', '\u9a6c', '\u7f8a', '\u7334', '\u9e21', '\u72d7', '\u732a'], |
| | | |
| | | /** |
| | | * 24节气速查表 |
| | | * @Array Of Property |
| | | * @trans["小寒","大寒","立春","雨水","惊蛰","春分","清明","谷雨","立夏","小满","芒种","夏至","小暑","大暑","立秋","处暑","白露","秋分","寒露","霜降","立冬","小雪","大雪","冬至"] |
| | | * @return Cn string |
| | | */ |
| | | solarTerm: ['\u5c0f\u5bd2', '\u5927\u5bd2', '\u7acb\u6625', '\u96e8\u6c34', '\u60ca\u86f0', '\u6625\u5206', '\u6e05\u660e', '\u8c37\u96e8', '\u7acb\u590f', '\u5c0f\u6ee1', '\u8292\u79cd', '\u590f\u81f3', '\u5c0f\u6691', '\u5927\u6691', '\u7acb\u79cb', '\u5904\u6691', '\u767d\u9732', '\u79cb\u5206', '\u5bd2\u9732', '\u971c\u964d', '\u7acb\u51ac', '\u5c0f\u96ea', '\u5927\u96ea', '\u51ac\u81f3'], |
| | | |
| | | /** |
| | | * 1900-2100各年的24节气日期速查表 |
| | | * @Array Of Property |
| | | * @return 0x string For splice |
| | | */ |
| | | sTermInfo: ['9778397bd097c36b0b6fc9274c91aa', '97b6b97bd19801ec9210c965cc920e', '97bcf97c3598082c95f8c965cc920f', |
| | | '97bd0b06bdb0722c965ce1cfcc920f', 'b027097bd097c36b0b6fc9274c91aa', '97b6b97bd19801ec9210c965cc920e', |
| | | '97bcf97c359801ec95f8c965cc920f', '97bd0b06bdb0722c965ce1cfcc920f', 'b027097bd097c36b0b6fc9274c91aa', |
| | | '97b6b97bd19801ec9210c965cc920e', '97bcf97c359801ec95f8c965cc920f', '97bd0b06bdb0722c965ce1cfcc920f', |
| | | 'b027097bd097c36b0b6fc9274c91aa', '9778397bd19801ec9210c965cc920e', '97b6b97bd19801ec95f8c965cc920f', |
| | | '97bd09801d98082c95f8e1cfcc920f', '97bd097bd097c36b0b6fc9210c8dc2', '9778397bd197c36c9210c9274c91aa', |
| | | '97b6b97bd19801ec95f8c965cc920e', '97bd09801d98082c95f8e1cfcc920f', '97bd097bd097c36b0b6fc9210c8dc2', |
| | | '9778397bd097c36c9210c9274c91aa', '97b6b97bd19801ec95f8c965cc920e', '97bcf97c3598082c95f8e1cfcc920f', |
| | | '97bd097bd097c36b0b6fc9210c8dc2', '9778397bd097c36c9210c9274c91aa', '97b6b97bd19801ec9210c965cc920e', |
| | | '97bcf97c3598082c95f8c965cc920f', '97bd097bd097c35b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa', |
| | | '97b6b97bd19801ec9210c965cc920e', '97bcf97c3598082c95f8c965cc920f', '97bd097bd097c35b0b6fc920fb0722', |
| | | '9778397bd097c36b0b6fc9274c91aa', '97b6b97bd19801ec9210c965cc920e', '97bcf97c359801ec95f8c965cc920f', |
| | | '97bd097bd097c35b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa', '97b6b97bd19801ec9210c965cc920e', |
| | | '97bcf97c359801ec95f8c965cc920f', '97bd097bd097c35b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa', |
| | | '97b6b97bd19801ec9210c965cc920e', '97bcf97c359801ec95f8c965cc920f', '97bd097bd07f595b0b6fc920fb0722', |
| | | '9778397bd097c36b0b6fc9210c8dc2', '9778397bd19801ec9210c9274c920e', '97b6b97bd19801ec95f8c965cc920f', |
| | | '97bd07f5307f595b0b0bc920fb0722', '7f0e397bd097c36b0b6fc9210c8dc2', '9778397bd097c36c9210c9274c920e', |
| | | '97b6b97bd19801ec95f8c965cc920f', '97bd07f5307f595b0b0bc920fb0722', '7f0e397bd097c36b0b6fc9210c8dc2', |
| | | '9778397bd097c36c9210c9274c91aa', '97b6b97bd19801ec9210c965cc920e', '97bd07f1487f595b0b0bc920fb0722', |
| | | '7f0e397bd097c36b0b6fc9210c8dc2', '9778397bd097c36b0b6fc9274c91aa', '97b6b97bd19801ec9210c965cc920e', |
| | | '97bcf7f1487f595b0b0bb0b6fb0722', '7f0e397bd097c35b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa', |
| | | '97b6b97bd19801ec9210c965cc920e', '97bcf7f1487f595b0b0bb0b6fb0722', '7f0e397bd097c35b0b6fc920fb0722', |
| | | '9778397bd097c36b0b6fc9274c91aa', '97b6b97bd19801ec9210c965cc920e', '97bcf7f1487f531b0b0bb0b6fb0722', |
| | | '7f0e397bd097c35b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa', '97b6b97bd19801ec9210c965cc920e', |
| | | '97bcf7f1487f531b0b0bb0b6fb0722', '7f0e397bd07f595b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa', |
| | | '97b6b97bd19801ec9210c9274c920e', '97bcf7f0e47f531b0b0bb0b6fb0722', '7f0e397bd07f595b0b0bc920fb0722', |
| | | '9778397bd097c36b0b6fc9210c91aa', '97b6b97bd197c36c9210c9274c920e', '97bcf7f0e47f531b0b0bb0b6fb0722', |
| | | '7f0e397bd07f595b0b0bc920fb0722', '9778397bd097c36b0b6fc9210c8dc2', '9778397bd097c36c9210c9274c920e', |
| | | '97b6b7f0e47f531b0723b0b6fb0722', '7f0e37f5307f595b0b0bc920fb0722', '7f0e397bd097c36b0b6fc9210c8dc2', |
| | | '9778397bd097c36b0b70c9274c91aa', '97b6b7f0e47f531b0723b0b6fb0721', '7f0e37f1487f595b0b0bb0b6fb0722', |
| | | '7f0e397bd097c35b0b6fc9210c8dc2', '9778397bd097c36b0b6fc9274c91aa', '97b6b7f0e47f531b0723b0b6fb0721', |
| | | '7f0e27f1487f595b0b0bb0b6fb0722', '7f0e397bd097c35b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa', |
| | | '97b6b7f0e47f531b0723b0b6fb0721', '7f0e27f1487f531b0b0bb0b6fb0722', '7f0e397bd097c35b0b6fc920fb0722', |
| | | '9778397bd097c36b0b6fc9274c91aa', '97b6b7f0e47f531b0723b0b6fb0721', '7f0e27f1487f531b0b0bb0b6fb0722', |
| | | '7f0e397bd097c35b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa', '97b6b7f0e47f531b0723b0b6fb0721', |
| | | '7f0e27f1487f531b0b0bb0b6fb0722', '7f0e397bd07f595b0b0bc920fb0722', '9778397bd097c36b0b6fc9274c91aa', |
| | | '97b6b7f0e47f531b0723b0787b0721', '7f0e27f0e47f531b0b0bb0b6fb0722', '7f0e397bd07f595b0b0bc920fb0722', |
| | | '9778397bd097c36b0b6fc9210c91aa', '97b6b7f0e47f149b0723b0787b0721', '7f0e27f0e47f531b0723b0b6fb0722', |
| | | '7f0e397bd07f595b0b0bc920fb0722', '9778397bd097c36b0b6fc9210c8dc2', '977837f0e37f149b0723b0787b0721', |
| | | '7f07e7f0e47f531b0723b0b6fb0722', '7f0e37f5307f595b0b0bc920fb0722', '7f0e397bd097c35b0b6fc9210c8dc2', |
| | | '977837f0e37f14998082b0787b0721', '7f07e7f0e47f531b0723b0b6fb0721', '7f0e37f1487f595b0b0bb0b6fb0722', |
| | | '7f0e397bd097c35b0b6fc9210c8dc2', '977837f0e37f14998082b0787b06bd', '7f07e7f0e47f531b0723b0b6fb0721', |
| | | '7f0e27f1487f531b0b0bb0b6fb0722', '7f0e397bd097c35b0b6fc920fb0722', '977837f0e37f14998082b0787b06bd', |
| | | '7f07e7f0e47f531b0723b0b6fb0721', '7f0e27f1487f531b0b0bb0b6fb0722', '7f0e397bd097c35b0b6fc920fb0722', |
| | | '977837f0e37f14998082b0787b06bd', '7f07e7f0e47f531b0723b0b6fb0721', '7f0e27f1487f531b0b0bb0b6fb0722', |
| | | '7f0e397bd07f595b0b0bc920fb0722', '977837f0e37f14998082b0787b06bd', '7f07e7f0e47f531b0723b0b6fb0721', |
| | | '7f0e27f1487f531b0b0bb0b6fb0722', '7f0e397bd07f595b0b0bc920fb0722', '977837f0e37f14998082b0787b06bd', |
| | | '7f07e7f0e47f149b0723b0787b0721', '7f0e27f0e47f531b0b0bb0b6fb0722', '7f0e397bd07f595b0b0bc920fb0722', |
| | | '977837f0e37f14998082b0723b06bd', '7f07e7f0e37f149b0723b0787b0721', '7f0e27f0e47f531b0723b0b6fb0722', |
| | | '7f0e397bd07f595b0b0bc920fb0722', '977837f0e37f14898082b0723b02d5', '7ec967f0e37f14998082b0787b0721', |
| | | '7f07e7f0e47f531b0723b0b6fb0722', '7f0e37f1487f595b0b0bb0b6fb0722', '7f0e37f0e37f14898082b0723b02d5', |
| | | '7ec967f0e37f14998082b0787b0721', '7f07e7f0e47f531b0723b0b6fb0722', '7f0e37f1487f531b0b0bb0b6fb0722', |
| | | '7f0e37f0e37f14898082b0723b02d5', '7ec967f0e37f14998082b0787b06bd', '7f07e7f0e47f531b0723b0b6fb0721', |
| | | '7f0e37f1487f531b0b0bb0b6fb0722', '7f0e37f0e37f14898082b072297c35', '7ec967f0e37f14998082b0787b06bd', |
| | | '7f07e7f0e47f531b0723b0b6fb0721', '7f0e27f1487f531b0b0bb0b6fb0722', '7f0e37f0e37f14898082b072297c35', |
| | | '7ec967f0e37f14998082b0787b06bd', '7f07e7f0e47f531b0723b0b6fb0721', '7f0e27f1487f531b0b0bb0b6fb0722', |
| | | '7f0e37f0e366aa89801eb072297c35', '7ec967f0e37f14998082b0787b06bd', '7f07e7f0e47f149b0723b0787b0721', |
| | | '7f0e27f1487f531b0b0bb0b6fb0722', '7f0e37f0e366aa89801eb072297c35', '7ec967f0e37f14998082b0723b06bd', |
| | | '7f07e7f0e47f149b0723b0787b0721', '7f0e27f0e47f531b0723b0b6fb0722', '7f0e37f0e366aa89801eb072297c35', |
| | | '7ec967f0e37f14998082b0723b06bd', '7f07e7f0e37f14998083b0787b0721', '7f0e27f0e47f531b0723b0b6fb0722', |
| | | '7f0e37f0e366aa89801eb072297c35', '7ec967f0e37f14898082b0723b02d5', '7f07e7f0e37f14998082b0787b0721', |
| | | '7f07e7f0e47f531b0723b0b6fb0722', '7f0e36665b66aa89801e9808297c35', '665f67f0e37f14898082b0723b02d5', |
| | | '7ec967f0e37f14998082b0787b0721', '7f07e7f0e47f531b0723b0b6fb0722', '7f0e36665b66a449801e9808297c35', |
| | | '665f67f0e37f14898082b0723b02d5', '7ec967f0e37f14998082b0787b06bd', '7f07e7f0e47f531b0723b0b6fb0721', |
| | | '7f0e36665b66a449801e9808297c35', '665f67f0e37f14898082b072297c35', '7ec967f0e37f14998082b0787b06bd', |
| | | '7f07e7f0e47f531b0723b0b6fb0721', '7f0e26665b66a449801e9808297c35', '665f67f0e37f1489801eb072297c35', |
| | | '7ec967f0e37f14998082b0787b06bd', '7f07e7f0e47f531b0723b0b6fb0721', '7f0e27f1487f531b0b0bb0b6fb0722'], |
| | | |
| | | /** |
| | | * 数字转中文速查表 |
| | | * @Array Of Property |
| | | * @trans ['日','一','二','三','四','五','六','七','八','九','十'] |
| | | * @return Cn string |
| | | */ |
| | | nStr1: ['\u65e5', '\u4e00', '\u4e8c', '\u4e09', '\u56db', '\u4e94', '\u516d', '\u4e03', '\u516b', '\u4e5d', '\u5341'], |
| | | |
| | | /** |
| | | * 日期转农历称呼速查表 |
| | | * @Array Of Property |
| | | * @trans ['初','十','廿','卅'] |
| | | * @return Cn string |
| | | */ |
| | | nStr2: ['\u521d', '\u5341', '\u5eff', '\u5345'], |
| | | |
| | | /** |
| | | * 月份转农历称呼速查表 |
| | | * @Array Of Property |
| | | * @trans ['正','一','二','三','四','五','六','七','八','九','十','冬','腊'] |
| | | * @return Cn string |
| | | */ |
| | | nStr3: ['\u6b63', '\u4e8c', '\u4e09', '\u56db', '\u4e94', '\u516d', '\u4e03', '\u516b', '\u4e5d', '\u5341', '\u51ac', '\u814a'], |
| | | |
| | | /** |
| | | * 返回农历y年一整年的总天数 |
| | | * @param lunar Year |
| | | * @return Number |
| | | * @eg:var count = calendar.lYearDays(1987) ;//count=387 |
| | | */ |
| | | lYearDays: function (y) { |
| | | var i; var sum = 348 |
| | | for (i = 0x8000; i > 0x8; i >>= 1) { sum += (this.lunarInfo[y - 1900] & i) ? 1 : 0 } |
| | | return (sum + this.leapDays(y)) |
| | | }, |
| | | |
| | | /** |
| | | * 返回农历y年闰月是哪个月;若y年没有闰月 则返回0 |
| | | * @param lunar Year |
| | | * @return Number (0-12) |
| | | * @eg:var leapMonth = calendar.leapMonth(1987) ;//leapMonth=6 |
| | | */ |
| | | leapMonth: function (y) { // 闰字编码 \u95f0 |
| | | return (this.lunarInfo[y - 1900] & 0xf) |
| | | }, |
| | | |
| | | /** |
| | | * 返回农历y年闰月的天数 若该年没有闰月则返回0 |
| | | * @param lunar Year |
| | | * @return Number (0、29、30) |
| | | * @eg:var leapMonthDay = calendar.leapDays(1987) ;//leapMonthDay=29 |
| | | */ |
| | | leapDays: function (y) { |
| | | if (this.leapMonth(y)) { |
| | | return ((this.lunarInfo[y - 1900] & 0x10000) ? 30 : 29) |
| | | } |
| | | return (0) |
| | | }, |
| | | |
| | | /** |
| | | * 返回农历y年m月(非闰月)的总天数,计算m为闰月时的天数请使用leapDays方法 |
| | | * @param lunar Year |
| | | * @return Number (-1、29、30) |
| | | * @eg:var MonthDay = calendar.monthDays(1987,9) ;//MonthDay=29 |
| | | */ |
| | | monthDays: function (y, m) { |
| | | if (m > 12 || m < 1) { return -1 }// 月份参数从1至12,参数错误返回-1 |
| | | return ((this.lunarInfo[y - 1900] & (0x10000 >> m)) ? 30 : 29) |
| | | }, |
| | | |
| | | /** |
| | | * 返回公历(!)y年m月的天数 |
| | | * @param solar Year |
| | | * @return Number (-1、28、29、30、31) |
| | | * @eg:var solarMonthDay = calendar.leapDays(1987) ;//solarMonthDay=30 |
| | | */ |
| | | solarDays: function (y, m) { |
| | | if (m > 12 || m < 1) { return -1 } // 若参数错误 返回-1 |
| | | var ms = m - 1 |
| | | if (ms == 1) { // 2月份的闰平规律测算后确认返回28或29 |
| | | return (((y % 4 == 0) && (y % 100 != 0) || (y % 400 == 0)) ? 29 : 28) |
| | | } else { |
| | | return (this.solarMonth[ms]) |
| | | } |
| | | }, |
| | | |
| | | /** |
| | | * 农历年份转换为干支纪年 |
| | | * @param lYear 农历年的年份数 |
| | | * @return Cn string |
| | | */ |
| | | toGanZhiYear: function (lYear) { |
| | | var ganKey = (lYear - 3) % 10 |
| | | var zhiKey = (lYear - 3) % 12 |
| | | if (ganKey == 0) ganKey = 10// 如果余数为0则为最后一个天干 |
| | | if (zhiKey == 0) zhiKey = 12// 如果余数为0则为最后一个地支 |
| | | return this.Gan[ganKey - 1] + this.Zhi[zhiKey - 1] |
| | | }, |
| | | |
| | | /** |
| | | * 公历月、日判断所属星座 |
| | | * @param cMonth [description] |
| | | * @param cDay [description] |
| | | * @return Cn string |
| | | */ |
| | | toAstro: function (cMonth, cDay) { |
| | | var s = '\u9b54\u7faf\u6c34\u74f6\u53cc\u9c7c\u767d\u7f8a\u91d1\u725b\u53cc\u5b50\u5de8\u87f9\u72ee\u5b50\u5904\u5973\u5929\u79e4\u5929\u874e\u5c04\u624b\u9b54\u7faf' |
| | | var arr = [20, 19, 21, 21, 21, 22, 23, 23, 23, 23, 22, 22] |
| | | return s.substr(cMonth * 2 - (cDay < arr[cMonth - 1] ? 2 : 0), 2) + '\u5ea7'// 座 |
| | | }, |
| | | |
| | | /** |
| | | * 传入offset偏移量返回干支 |
| | | * @param offset 相对甲子的偏移量 |
| | | * @return Cn string |
| | | */ |
| | | toGanZhi: function (offset) { |
| | | return this.Gan[offset % 10] + this.Zhi[offset % 12] |
| | | }, |
| | | |
| | | /** |
| | | * 传入公历(!)y年获得该年第n个节气的公历日期 |
| | | * @param y公历年(1900-2100);n二十四节气中的第几个节气(1~24);从n=1(小寒)算起 |
| | | * @return day Number |
| | | * @eg:var _24 = calendar.getTerm(1987,3) ;//_24=4;意即1987年2月4日立春 |
| | | */ |
| | | getTerm: function (y, n) { |
| | | if (y < 1900 || y > 2100) { return -1 } |
| | | if (n < 1 || n > 24) { return -1 } |
| | | var _table = this.sTermInfo[y - 1900] |
| | | var _info = [ |
| | | parseInt('0x' + _table.substr(0, 5)).toString(), |
| | | parseInt('0x' + _table.substr(5, 5)).toString(), |
| | | parseInt('0x' + _table.substr(10, 5)).toString(), |
| | | parseInt('0x' + _table.substr(15, 5)).toString(), |
| | | parseInt('0x' + _table.substr(20, 5)).toString(), |
| | | parseInt('0x' + _table.substr(25, 5)).toString() |
| | | ] |
| | | var _calday = [ |
| | | _info[0].substr(0, 1), |
| | | _info[0].substr(1, 2), |
| | | _info[0].substr(3, 1), |
| | | _info[0].substr(4, 2), |
| | | |
| | | _info[1].substr(0, 1), |
| | | _info[1].substr(1, 2), |
| | | _info[1].substr(3, 1), |
| | | _info[1].substr(4, 2), |
| | | |
| | | _info[2].substr(0, 1), |
| | | _info[2].substr(1, 2), |
| | | _info[2].substr(3, 1), |
| | | _info[2].substr(4, 2), |
| | | |
| | | _info[3].substr(0, 1), |
| | | _info[3].substr(1, 2), |
| | | _info[3].substr(3, 1), |
| | | _info[3].substr(4, 2), |
| | | |
| | | _info[4].substr(0, 1), |
| | | _info[4].substr(1, 2), |
| | | _info[4].substr(3, 1), |
| | | _info[4].substr(4, 2), |
| | | |
| | | _info[5].substr(0, 1), |
| | | _info[5].substr(1, 2), |
| | | _info[5].substr(3, 1), |
| | | _info[5].substr(4, 2) |
| | | ] |
| | | return parseInt(_calday[n - 1]) |
| | | }, |
| | | |
| | | /** |
| | | * 传入农历数字月份返回汉语通俗表示法 |
| | | * @param lunar month |
| | | * @return Cn string |
| | | * @eg:var cnMonth = calendar.toChinaMonth(12) ;//cnMonth='腊月' |
| | | */ |
| | | toChinaMonth: function (m) { // 月 => \u6708 |
| | | if (m > 12 || m < 1) { return -1 } // 若参数错误 返回-1 |
| | | var s = this.nStr3[m - 1] |
| | | s += '\u6708'// 加上月字 |
| | | return s |
| | | }, |
| | | |
| | | /** |
| | | * 传入农历日期数字返回汉字表示法 |
| | | * @param lunar day |
| | | * @return Cn string |
| | | * @eg:var cnDay = calendar.toChinaDay(21) ;//cnMonth='廿一' |
| | | */ |
| | | toChinaDay: function (d) { // 日 => \u65e5 |
| | | var s |
| | | switch (d) { |
| | | case 10: |
| | | s = '\u521d\u5341'; break |
| | | case 20: |
| | | s = '\u4e8c\u5341'; break |
| | | break |
| | | case 30: |
| | | s = '\u4e09\u5341'; break |
| | | break |
| | | default: |
| | | s = this.nStr2[Math.floor(d / 10)] |
| | | s += this.nStr1[d % 10] |
| | | } |
| | | return (s) |
| | | }, |
| | | |
| | | /** |
| | | * 年份转生肖[!仅能大致转换] => 精确划分生肖分界线是“立春” |
| | | * @param y year |
| | | * @return Cn string |
| | | * @eg:var animal = calendar.getAnimal(1987) ;//animal='兔' |
| | | */ |
| | | getAnimal: function (y) { |
| | | return this.Animals[(y - 4) % 12] |
| | | }, |
| | | |
| | | /** |
| | | * 传入阳历年月日获得详细的公历、农历object信息 <=>JSON |
| | | * @param y solar year |
| | | * @param m solar month |
| | | * @param d solar day |
| | | * @return JSON object |
| | | * @eg:console.log(calendar.solar2lunar(1987,11,01)); |
| | | */ |
| | | solar2lunar: function (y, m, d) { // 参数区间1900.1.31~2100.12.31 |
| | | // 年份限定、上限 |
| | | if (y < 1900 || y > 2100) { |
| | | return -1// undefined转换为数字变为NaN |
| | | } |
| | | // 公历传参最下限 |
| | | if (y == 1900 && m == 1 && d < 31) { |
| | | return -1 |
| | | } |
| | | // 未传参 获得当天 |
| | | if (!y) { |
| | | var objDate = new Date() |
| | | } else { |
| | | var objDate = new Date(y, parseInt(m) - 1, d) |
| | | } |
| | | var i; var leap = 0; var temp = 0 |
| | | // 修正ymd参数 |
| | | var y = objDate.getFullYear() |
| | | var m = objDate.getMonth() + 1 |
| | | var d = objDate.getDate() |
| | | var offset = (Date.UTC(objDate.getFullYear(), objDate.getMonth(), objDate.getDate()) - Date.UTC(1900, 0, 31)) / 86400000 |
| | | for (i = 1900; i < 2101 && offset > 0; i++) { |
| | | temp = this.lYearDays(i) |
| | | offset -= temp |
| | | } |
| | | if (offset < 0) { |
| | | offset += temp; i-- |
| | | } |
| | | |
| | | // 是否今天 |
| | | var isTodayObj = new Date() |
| | | var isToday = false |
| | | if (isTodayObj.getFullYear() == y && isTodayObj.getMonth() + 1 == m && isTodayObj.getDate() == d) { |
| | | isToday = true |
| | | } |
| | | // 星期几 |
| | | var nWeek = objDate.getDay() |
| | | var cWeek = this.nStr1[nWeek] |
| | | // 数字表示周几顺应天朝周一开始的惯例 |
| | | if (nWeek == 0) { |
| | | nWeek = 7 |
| | | } |
| | | // 农历年 |
| | | var year = i |
| | | var leap = this.leapMonth(i) // 闰哪个月 |
| | | var isLeap = false |
| | | |
| | | // 效验闰月 |
| | | for (i = 1; i < 13 && offset > 0; i++) { |
| | | // 闰月 |
| | | if (leap > 0 && i == (leap + 1) && isLeap == false) { |
| | | --i |
| | | isLeap = true; temp = this.leapDays(year) // 计算农历闰月天数 |
| | | } else { |
| | | temp = this.monthDays(year, i)// 计算农历普通月天数 |
| | | } |
| | | // 解除闰月 |
| | | if (isLeap == true && i == (leap + 1)) { isLeap = false } |
| | | offset -= temp |
| | | } |
| | | // 闰月导致数组下标重叠取反 |
| | | if (offset == 0 && leap > 0 && i == leap + 1) { |
| | | if (isLeap) { |
| | | isLeap = false |
| | | } else { |
| | | isLeap = true; --i |
| | | } |
| | | } |
| | | if (offset < 0) { |
| | | offset += temp; --i |
| | | } |
| | | // 农历月 |
| | | var month = i |
| | | // 农历日 |
| | | var day = offset + 1 |
| | | // 天干地支处理 |
| | | var sm = m - 1 |
| | | var gzY = this.toGanZhiYear(year) |
| | | |
| | | // 当月的两个节气 |
| | | // bugfix-2017-7-24 11:03:38 use lunar Year Param `y` Not `year` |
| | | var firstNode = this.getTerm(y, (m * 2 - 1))// 返回当月「节」为几日开始 |
| | | var secondNode = this.getTerm(y, (m * 2))// 返回当月「节」为几日开始 |
| | | |
| | | // 依据12节气修正干支月 |
| | | var gzM = this.toGanZhi((y - 1900) * 12 + m + 11) |
| | | if (d >= firstNode) { |
| | | gzM = this.toGanZhi((y - 1900) * 12 + m + 12) |
| | | } |
| | | |
| | | // 传入的日期的节气与否 |
| | | var isTerm = false |
| | | var Term = null |
| | | if (firstNode == d) { |
| | | isTerm = true |
| | | Term = this.solarTerm[m * 2 - 2] |
| | | } |
| | | if (secondNode == d) { |
| | | isTerm = true |
| | | Term = this.solarTerm[m * 2 - 1] |
| | | } |
| | | // 日柱 当月一日与 1900/1/1 相差天数 |
| | | var dayCyclical = Date.UTC(y, sm, 1, 0, 0, 0, 0) / 86400000 + 25567 + 10 |
| | | var gzD = this.toGanZhi(dayCyclical + d - 1) |
| | | // 该日期所属的星座 |
| | | var astro = this.toAstro(m, d) |
| | | |
| | | return { 'lYear': year, 'lMonth': month, 'lDay': day, 'Animal': this.getAnimal(year), 'IMonthCn': (isLeap ? '\u95f0' : '') + this.toChinaMonth(month), 'IDayCn': this.toChinaDay(day), 'cYear': y, 'cMonth': m, 'cDay': d, 'gzYear': gzY, 'gzMonth': gzM, 'gzDay': gzD, 'isToday': isToday, 'isLeap': isLeap, 'nWeek': nWeek, 'ncWeek': '\u661f\u671f' + cWeek, 'isTerm': isTerm, 'Term': Term, 'astro': astro } |
| | | }, |
| | | |
| | | /** |
| | | * 传入农历年月日以及传入的月份是否闰月获得详细的公历、农历object信息 <=>JSON |
| | | * @param y lunar year |
| | | * @param m lunar month |
| | | * @param d lunar day |
| | | * @param isLeapMonth lunar month is leap or not.[如果是农历闰月第四个参数赋值true即可] |
| | | * @return JSON object |
| | | * @eg:console.log(calendar.lunar2solar(1987,9,10)); |
| | | */ |
| | | lunar2solar: function (y, m, d, isLeapMonth) { // 参数区间1900.1.31~2100.12.1 |
| | | var isLeapMonth = !!isLeapMonth |
| | | var leapOffset = 0 |
| | | var leapMonth = this.leapMonth(y) |
| | | var leapDay = this.leapDays(y) |
| | | if (isLeapMonth && (leapMonth != m)) { return -1 }// 传参要求计算该闰月公历 但该年得出的闰月与传参的月份并不同 |
| | | if (y == 2100 && m == 12 && d > 1 || y == 1900 && m == 1 && d < 31) { return -1 }// 超出了最大极限值 |
| | | var day = this.monthDays(y, m) |
| | | var _day = day |
| | | // bugFix 2016-9-25 |
| | | // if month is leap, _day use leapDays method |
| | | if (isLeapMonth) { |
| | | _day = this.leapDays(y, m) |
| | | } |
| | | if (y < 1900 || y > 2100 || d > _day) { return -1 }// 参数合法性效验 |
| | | |
| | | // 计算农历的时间差 |
| | | var offset = 0 |
| | | for (var i = 1900; i < y; i++) { |
| | | offset += this.lYearDays(i) |
| | | } |
| | | var leap = 0; var isAdd = false |
| | | for (var i = 1; i < m; i++) { |
| | | leap = this.leapMonth(y) |
| | | if (!isAdd) { // 处理闰月 |
| | | if (leap <= i && leap > 0) { |
| | | offset += this.leapDays(y); isAdd = true |
| | | } |
| | | } |
| | | offset += this.monthDays(y, i) |
| | | } |
| | | // 转换闰月农历 需补充该年闰月的前一个月的时差 |
| | | if (isLeapMonth) { offset += day } |
| | | // 1900年农历正月一日的公历时间为1900年1月30日0时0分0秒(该时间也是本农历的最开始起始点) |
| | | var stmap = Date.UTC(1900, 1, 30, 0, 0, 0) |
| | | var calObj = new Date((offset + d - 31) * 86400000 + stmap) |
| | | var cY = calObj.getUTCFullYear() |
| | | var cM = calObj.getUTCMonth() + 1 |
| | | var cD = calObj.getUTCDate() |
| | | |
| | | return this.solar2lunar(cY, cM, cD) |
| | | } |
| | | } |
| | | |
| | | export default calendar |
| New file |
| | |
| | | <template> |
| | | <view class="uv-calendar-header uv-border-bottom"> |
| | | <text |
| | | class="uv-calendar-header__title" |
| | | v-if="showTitle" |
| | | >{{ title }}</text> |
| | | <text |
| | | class="uv-calendar-header__subtitle" |
| | | v-if="showSubtitle" |
| | | >{{ subtitle }}</text> |
| | | <view class="uv-calendar-header__weekdays"> |
| | | <text class="uv-calendar-header__weekdays__weekday">一</text> |
| | | <text class="uv-calendar-header__weekdays__weekday">二</text> |
| | | <text class="uv-calendar-header__weekdays__weekday">三</text> |
| | | <text class="uv-calendar-header__weekdays__weekday">四</text> |
| | | <text class="uv-calendar-header__weekdays__weekday">五</text> |
| | | <text class="uv-calendar-header__weekdays__weekday">六</text> |
| | | <text class="uv-calendar-header__weekdays__weekday">日</text> |
| | | </view> |
| | | </view> |
| | | </template> |
| | | |
| | | <script> |
| | | import mpMixin from '@/uni_modules/uv-ui-tools/libs/mixin/mpMixin.js' |
| | | import mixin from '@/uni_modules/uv-ui-tools/libs/mixin/mixin.js' |
| | | export default { |
| | | name: 'uv-calendar-header', |
| | | mixins: [mpMixin, mixin], |
| | | props: { |
| | | // 标题 |
| | | title: { |
| | | type: String, |
| | | default: '' |
| | | }, |
| | | // 副标题 |
| | | subtitle: { |
| | | type: [String,null], |
| | | default: '' |
| | | }, |
| | | // 是否显示标题 |
| | | showTitle: { |
| | | type: Boolean, |
| | | default: true |
| | | }, |
| | | // 是否显示副标题 |
| | | showSubtitle: { |
| | | type: Boolean, |
| | | default: true |
| | | }, |
| | | }, |
| | | data() { |
| | | return { |
| | | |
| | | } |
| | | }, |
| | | methods: { |
| | | name() { |
| | | |
| | | } |
| | | }, |
| | | } |
| | | </script> |
| | | |
| | | <style lang="scss" scoped> |
| | | $show-border: 1; |
| | | $show-border-bottom: 1; |
| | | @import '@/uni_modules/uv-ui-tools/libs/css/variable.scss'; |
| | | @import '@/uni_modules/uv-ui-tools/libs/css/components.scss'; |
| | | @import '@/uni_modules/uv-ui-tools/libs/css/color.scss'; |
| | | .uv-calendar-header { |
| | | padding-bottom: 4px; |
| | | |
| | | &__title { |
| | | font-size: 16px; |
| | | color: $uv-main-color; |
| | | text-align: center; |
| | | height: 42px; |
| | | line-height: 42px; |
| | | font-weight: bold; |
| | | } |
| | | |
| | | &__subtitle { |
| | | font-size: 14px; |
| | | color: $uv-main-color; |
| | | height: 40px; |
| | | text-align: center; |
| | | line-height: 40px; |
| | | font-weight: bold; |
| | | } |
| | | |
| | | &__weekdays { |
| | | @include flex; |
| | | justify-content: space-between; |
| | | |
| | | &__weekday { |
| | | font-size: 13px; |
| | | color: $uv-main-color; |
| | | line-height: 30px; |
| | | flex: 1; |
| | | text-align: center; |
| | | } |
| | | } |
| | | } |
| | | </style> |
| New file |
| | |
| | | <template> |
| | | <view class="uv-calendar-month-wrapper" ref="uv-calendar-month-wrapper"> |
| | | <view v-for="(item, index) in months" :key="index" :class="[`uv-calendar-month-${index}`]" |
| | | :ref="`uv-calendar-month-${index}`" :id="`month-${index}`"> |
| | | <text v-if="index !== 0" class="uv-calendar-month__title">{{ item.year }}年{{ item.month }}月</text> |
| | | <view class="uv-calendar-month__days"> |
| | | <view v-if="showMark" class="uv-calendar-month__days__month-mark-wrapper"> |
| | | <text class="uv-calendar-month__days__month-mark-wrapper__text">{{ item.month }}</text> |
| | | </view> |
| | | <view class="uv-calendar-month__days__day" v-for="(item1, index1) in item.date" :key="index1" |
| | | :style="[dayStyle(index, index1, item1)]" @tap="clickHandler(index, index1, item1)" |
| | | :class="[item1.selected && 'uv-calendar-month__days__day__select--selected']"> |
| | | <view class="uv-calendar-month__days__day__select" :style="[daySelectStyle(index, index1, item1)]"> |
| | | <text v-if="getTopInfo(index, index1, item1)" |
| | | class="uv-calendar-month__days__day__select__top-info" |
| | | :class="[item1.disabled && 'uv-calendar-month__days__day__select__top-info--disabled']" |
| | | :style="[textStyle(item1)]" |
| | | >{{ getTopInfo(index, index1, item1) }}</text> |
| | | <text class="uv-calendar-month__days__day__select__info" |
| | | :class="[item1.disabled && 'uv-calendar-month__days__day__select__info--disabled']" |
| | | :style="[textStyle(item1)]">{{ item1.day }}</text> |
| | | <text v-if="getBottomInfo(index, index1, item1)" |
| | | class="uv-calendar-month__days__day__select__buttom-info" |
| | | :class="[item1.disabled && 'uv-calendar-month__days__day__select__buttom-info--disabled']" |
| | | :style="[textStyle(item1)]">{{ getBottomInfo(index, index1, item1) }}</text> |
| | | <text v-if="item1.dot" class="uv-calendar-month__days__day__select__dot"></text> |
| | | </view> |
| | | </view> |
| | | </view> |
| | | </view> |
| | | </view> |
| | | </template> |
| | | |
| | | <script> |
| | | // #ifdef APP-NVUE |
| | | // 由于nvue不支持百分比单位,需要查询宽度来计算每个日期的宽度 |
| | | const dom = uni.requireNativePlugin('dom') |
| | | // #endif |
| | | import { colorGradient } from '@/uni_modules/uv-ui-tools/libs/function/colorGradient.js'; |
| | | import mpMixin from '@/uni_modules/uv-ui-tools/libs/mixin/mpMixin.js' |
| | | import mixin from '@/uni_modules/uv-ui-tools/libs/mixin/mixin.js' |
| | | import dayjs from '@/uni_modules/uv-ui-tools/libs/util/dayjs.js' |
| | | export default { |
| | | name: 'uv-calendar-month', |
| | | emits:['monthSelected','updateMonthTop','change'], |
| | | mixins: [mpMixin, mixin], |
| | | props: { |
| | | // 是否显示月份背景色 |
| | | showMark: { |
| | | type: Boolean, |
| | | default: true |
| | | }, |
| | | // 主题色,对底部按钮和选中日期有效 |
| | | color: { |
| | | type: String, |
| | | default: '#3c9cff' |
| | | }, |
| | | // 月份数据 |
| | | months: { |
| | | type: Array, |
| | | default: () => [] |
| | | }, |
| | | // 日期选择类型 |
| | | mode: { |
| | | type: String, |
| | | default: 'single' |
| | | }, |
| | | // 日期行高 |
| | | rowHeight: { |
| | | type: [String, Number], |
| | | default: 58 |
| | | }, |
| | | // mode=multiple时,最多可选多少个日期 |
| | | maxCount: { |
| | | type: [String, Number], |
| | | default: Infinity |
| | | }, |
| | | // mode=range时,第一个日期底部的提示文字 |
| | | startText: { |
| | | type: String, |
| | | default: '开始' |
| | | }, |
| | | // mode=range时,最后一个日期底部的提示文字 |
| | | endText: { |
| | | type: String, |
| | | default: '结束' |
| | | }, |
| | | // 默认选中的日期,mode为multiple或range是必须为数组格式 |
| | | defaultDate: { |
| | | type: [Array, String, Date], |
| | | default: null |
| | | }, |
| | | // 最小的可选日期 |
| | | minDate: { |
| | | type: [String, Number], |
| | | default: 0 |
| | | }, |
| | | // 最大可选日期 |
| | | maxDate: { |
| | | type: [String, Number], |
| | | default: 0 |
| | | }, |
| | | // 如果没有设置maxDate,则往后推多少个月 |
| | | maxMonth: { |
| | | type: [String, Number], |
| | | default: 2 |
| | | }, |
| | | // 是否为只读状态,只读状态下禁止选择日期 |
| | | readonly: { |
| | | type: Boolean, |
| | | default: false |
| | | }, |
| | | // 日期区间最多可选天数,默认无限制,mode = range时有效 |
| | | maxRange: { |
| | | type: [Number, String], |
| | | default: Infinity |
| | | }, |
| | | // 范围选择超过最多可选天数时的提示文案,mode = range时有效 |
| | | rangePrompt: { |
| | | type: String, |
| | | default: '' |
| | | }, |
| | | // 范围选择超过最多可选天数时,是否展示提示文案,mode = range时有效 |
| | | showRangePrompt: { |
| | | type: Boolean, |
| | | default: true |
| | | }, |
| | | // 是否允许日期范围的起止时间为同一天,mode = range时有效 |
| | | allowSameDay: { |
| | | type: Boolean, |
| | | default: false |
| | | } |
| | | }, |
| | | data() { |
| | | return { |
| | | // 每个日期的宽度 |
| | | width: 0, |
| | | // 当前选中的日期item |
| | | item: {}, |
| | | selected: [] |
| | | } |
| | | }, |
| | | watch: { |
| | | selectedChange: { |
| | | immediate: true, |
| | | handler(n) { |
| | | this.setDefaultDate() |
| | | } |
| | | } |
| | | }, |
| | | computed: { |
| | | // 多个条件的变化,会引起选中日期的变化,这里统一管理监听 |
| | | selectedChange() { |
| | | return [this.minDate, this.maxDate, this.defaultDate] |
| | | }, |
| | | dayStyle(index1, index2, item) { |
| | | return (index1, index2, item) => { |
| | | const style = {} |
| | | let week = item.week |
| | | // 不进行四舍五入的形式保留2位小数 |
| | | const dayWidth = Number(parseFloat(this.width / 7).toFixed(3).slice(0, -1)) |
| | | // 得出每个日期的宽度 |
| | | // #ifdef APP-NVUE |
| | | style.width = this.$uv.addUnit(dayWidth) |
| | | // #endif |
| | | style.height = this.$uv.addUnit(this.rowHeight) |
| | | if (index2 === 0) { |
| | | // 获取当前为星期几,如果为0,则为星期天,减一为每月第一天时,需要向左偏移的item个数 |
| | | week = (week === 0 ? 7 : week) - 1 |
| | | style.marginLeft = this.$uv.addUnit(week * dayWidth) |
| | | } |
| | | if (this.mode === 'range') { |
| | | // 之所以需要这么写,是因为DCloud公司的iOS客户端的开发者能力有限导致的bug |
| | | style.paddingLeft = 0 |
| | | style.paddingRight = 0 |
| | | style.paddingBottom = 0 |
| | | style.paddingTop = 0 |
| | | } |
| | | return style |
| | | } |
| | | }, |
| | | daySelectStyle() { |
| | | return (index1, index2, item) => { |
| | | let date = dayjs(item.date).format("YYYY-MM-DD"), |
| | | style = {} |
| | | // 判断date是否在selected数组中,因为月份可能会需要补0,所以使用dateSame判断,而不用数组的includes判断 |
| | | if (this.selected.some(item => this.dateSame(item, date))) { |
| | | style.backgroundColor = this.color |
| | | } |
| | | if (this.mode === 'single') { |
| | | if (date === this.selected[0]) { |
| | | // 因为需要对nvue的兼容,只能这么写,无法缩写,也无法通过类名控制等等 |
| | | style.borderTopLeftRadius = '3px' |
| | | style.borderBottomLeftRadius = '3px' |
| | | style.borderTopRightRadius = '3px' |
| | | style.borderBottomRightRadius = '3px' |
| | | } |
| | | } else if (this.mode === 'range') { |
| | | if (this.selected.length >= 2) { |
| | | const len = this.selected.length - 1 |
| | | // 第一个日期设置左上角和左下角的圆角 |
| | | if (this.dateSame(date, this.selected[0])) { |
| | | style.borderTopLeftRadius = '3px' |
| | | style.borderBottomLeftRadius = '3px' |
| | | } |
| | | // 最后一个日期设置右上角和右下角的圆角 |
| | | if (this.dateSame(date, this.selected[len])) { |
| | | style.borderTopRightRadius = '3px' |
| | | style.borderBottomRightRadius = '3px' |
| | | } |
| | | // 处于第一和最后一个之间的日期,背景色设置为浅色,通过将对应颜色进行等分,再取其尾部的颜色值 |
| | | if (dayjs(date).isAfter(dayjs(this.selected[0])) && dayjs(date).isBefore(dayjs(this |
| | | .selected[len]))) { |
| | | style.backgroundColor = colorGradient(this.color, '#ffffff', 100)[90] |
| | | // 增加一个透明度,让范围区间的背景色也能看到底部的mark水印字符 |
| | | style.opacity = 0.7 |
| | | } |
| | | } else if (this.selected.length === 1) { |
| | | // 之所以需要这么写,是因为DCloud公司的iOS客户端的开发者能力有限导致的bug |
| | | // 进行还原操作,否则在nvue的iOS,uni-app有bug,会导致诡异的表现 |
| | | style.borderTopLeftRadius = '3px' |
| | | style.borderBottomLeftRadius = '3px' |
| | | } |
| | | } else { |
| | | if (this.selected.some(item => this.dateSame(item, date))) { |
| | | style.borderTopLeftRadius = '3px' |
| | | style.borderBottomLeftRadius = '3px' |
| | | style.borderTopRightRadius = '3px' |
| | | style.borderBottomRightRadius = '3px' |
| | | } |
| | | } |
| | | return style |
| | | } |
| | | }, |
| | | // 某个日期是否被选中 |
| | | textStyle() { |
| | | return (item) => { |
| | | const date = dayjs(item.date).format("YYYY-MM-DD"), |
| | | style = {} |
| | | // 选中的日期,提示文字设置白色 |
| | | if (this.selected.some(item => this.dateSame(item, date))) { |
| | | style.color = '#ffffff' |
| | | } |
| | | if (this.mode === 'range') { |
| | | const len = this.selected.length - 1 |
| | | // 如果是范围选择模式,第一个和最后一个之间的日期,文字颜色设置为高亮的主题色 |
| | | if (dayjs(date).isAfter(dayjs(this.selected[0])) && dayjs(date).isBefore(dayjs(this |
| | | .selected[len]))) { |
| | | style.color = this.color |
| | | } |
| | | } |
| | | return style |
| | | } |
| | | }, |
| | | // 获取顶部的提示文字 |
| | | getTopInfo() { |
| | | return (index1, index2, item) => { |
| | | return item.topInfo; |
| | | } |
| | | }, |
| | | // 获取底部的提示文字 |
| | | getBottomInfo() { |
| | | return (index1, index2, item) => { |
| | | const date = dayjs(item.date).format("YYYY-MM-DD") |
| | | const bottomInfo = item.bottomInfo |
| | | // 当为日期范围模式时,且选择的日期个数大于0时 |
| | | if (this.mode === 'range' && this.selected.length > 0) { |
| | | if (this.selected.length === 1) { |
| | | // 选择了一个日期时,如果当前日期为数组中的第一个日期,则显示底部文字为“开始” |
| | | if (this.dateSame(date, this.selected[0])) return this.startText |
| | | else return bottomInfo |
| | | } else { |
| | | const len = this.selected.length - 1 |
| | | // 如果数组中的日期大于2个时,第一个和最后一个显示为开始和结束日期 |
| | | if (this.dateSame(date, this.selected[0]) && this.dateSame(date, this.selected[1]) && |
| | | len === 1) { |
| | | // 如果长度为2,且第一个等于第二个日期,则提示语放在同一个item中 |
| | | return `${this.startText}/${this.endText}` |
| | | } else if (this.dateSame(date, this.selected[0])) { |
| | | return this.startText |
| | | } else if (this.dateSame(date, this.selected[len])) { |
| | | return this.endText |
| | | } else { |
| | | return bottomInfo |
| | | } |
| | | } |
| | | } else { |
| | | return bottomInfo |
| | | } |
| | | } |
| | | } |
| | | }, |
| | | mounted() { |
| | | this.init() |
| | | }, |
| | | methods: { |
| | | init() { |
| | | // 初始化默认选中 |
| | | this.$emit('monthSelected', this.selected) |
| | | this.$nextTick(() => { |
| | | // 这里需要另一个延时,因为获取宽度后,会进行月份数据渲染,只有渲染完成之后,才有真正的高度 |
| | | // 因为nvue下,$nextTick并不是100%可靠的 |
| | | this.$uv.sleep(10).then(() => { |
| | | this.getWrapperWidth() |
| | | this.getMonthRect() |
| | | }) |
| | | }) |
| | | }, |
| | | // 判断两个日期是否相等 |
| | | dateSame(date1, date2) { |
| | | return dayjs(date1).isSame(dayjs(date2)) |
| | | }, |
| | | // 获取月份数据区域的宽度,因为nvue不支持百分比,所以无法通过css设置每个日期item的宽度 |
| | | getWrapperWidth() { |
| | | // #ifdef APP-NVUE |
| | | dom.getComponentRect(this.$refs['uv-calendar-month-wrapper'], res => { |
| | | this.width = res.size.width |
| | | }) |
| | | // #endif |
| | | // #ifndef APP-NVUE |
| | | this.$uvGetRect('.uv-calendar-month-wrapper').then(size => { |
| | | this.width = size.width |
| | | }) |
| | | // #endif |
| | | }, |
| | | getMonthRect() { |
| | | // 获取每个月份数据的尺寸,用于父组件在scroll-view滚动事件中,监听当前滚动到了第几个月份 |
| | | const promiseAllArr = this.months.map((item, index) => this.getMonthRectByPromise( |
| | | `uv-calendar-month-${index}`)) |
| | | // 一次性返回 |
| | | Promise.all(promiseAllArr).then( |
| | | sizes => { |
| | | let height = 1 |
| | | const topArr = [] |
| | | for (let i = 0; i < this.months.length; i++) { |
| | | // 添加到months数组中,供scroll-view滚动事件中,判断当前滚动到哪个月份 |
| | | topArr[i] = height |
| | | height += sizes[i].height |
| | | } |
| | | // 由于微信下,无法通过this.months[i].top的形式(引用类型)去修改父组件的month的top值,所以使用事件形式对外发出 |
| | | this.$emit('updateMonthTop', topArr) |
| | | }) |
| | | }, |
| | | // 获取每个月份区域的尺寸 |
| | | getMonthRectByPromise(el) { |
| | | // #ifndef APP-NVUE |
| | | // $uvGetRect为uvui自带的节点查询简化方法,详见文档介绍:https://www.uvui.cn/js/getRect.html |
| | | // 组件内部一般用this.$uvGetRect,对外的为getRect,二者功能一致,名称不同 |
| | | return new Promise(resolve => { |
| | | this.$uvGetRect(`.${el}`).then(size => { |
| | | resolve(size) |
| | | }) |
| | | }) |
| | | // #endif |
| | | |
| | | // #ifdef APP-NVUE |
| | | // nvue下,使用dom模块查询元素高度 |
| | | // 返回一个promise,让调用此方法的主体能使用then回调 |
| | | return new Promise(resolve => { |
| | | dom.getComponentRect(this.$refs[el][0], res => { |
| | | resolve(res.size) |
| | | }) |
| | | }) |
| | | // #endif |
| | | }, |
| | | // 点击某一个日期 |
| | | clickHandler(index1, index2, item) { |
| | | if (this.readonly) { |
| | | return; |
| | | } |
| | | this.item = item |
| | | const date = dayjs(item.date).format("YYYY-MM-DD") |
| | | if (item.disabled) return |
| | | // 对上一次选择的日期数组进行深度克隆 |
| | | let selected = this.$uv.deepClone(this.selected) |
| | | if (this.mode === 'single') { |
| | | // 单选情况下,让数组中的元素为当前点击的日期 |
| | | selected = [date] |
| | | } else if (this.mode === 'multiple') { |
| | | if (selected.some(item => this.dateSame(item, date))) { |
| | | // 如果点击的日期已在数组中,则进行移除操作,也就是达到反选的效果 |
| | | const itemIndex = selected.findIndex(item => dayjs(item).format("YYYY-MM-DD") === dayjs(date).format("YYYY-MM-DD")) |
| | | selected.splice(itemIndex, 1) |
| | | } else { |
| | | // 如果点击的日期不在数组中,且已有的长度小于总可选长度时,则添加到数组中去 |
| | | if (selected.length < this.maxCount) selected.push(date) |
| | | } |
| | | } else { |
| | | // 选择区间形式 |
| | | if (selected.length === 0 || selected.length >= 2) { |
| | | // 如果原来就为0或者大于2的长度,则当前点击的日期,就是开始日期 |
| | | selected = [date] |
| | | } else if (selected.length === 1) { |
| | | // 如果已经选择了开始日期 |
| | | const existsDate = selected[0] |
| | | // 如果当前选择的日期小于上一次选择的日期,则当前的日期定为开始日期 |
| | | if (dayjs(date).isBefore(existsDate)) { |
| | | selected = [date] |
| | | } else if (dayjs(date).isAfter(existsDate)) { |
| | | // 当前日期减去最大可选的日期天数,如果大于起始时间,则进行提示 |
| | | if(dayjs(dayjs(date).subtract(this.maxRange, 'day')).isAfter(dayjs(selected[0])) && this.showRangePrompt) { |
| | | if(this.rangePrompt) { |
| | | this.$uv.toast(this.rangePrompt) |
| | | } else { |
| | | this.$uv.toast(`选择天数不能超过 ${this.maxRange} 天`) |
| | | } |
| | | return |
| | | } |
| | | // 如果当前日期大于已有日期,将当前的添加到数组尾部 |
| | | selected.push(date) |
| | | const startDate = selected[0] |
| | | const endDate = selected[1] |
| | | const arr = [] |
| | | let i = 0 |
| | | do { |
| | | // 将开始和结束日期之间的日期添加到数组中 |
| | | arr.push(dayjs(startDate).add(i, 'day').format("YYYY-MM-DD")) |
| | | i++ |
| | | // 累加的日期小于结束日期时,继续下一次的循环 |
| | | } while (dayjs(startDate).add(i, 'day').isBefore(dayjs(endDate))) |
| | | // 为了一次性修改数组,避免computed中多次触发,这里才用arr变量一次性赋值的方式,同时将最后一个日期添加近来 |
| | | arr.push(endDate) |
| | | selected = arr |
| | | } else { |
| | | // 选择区间时,只有一个日期的情况下,且不允许选择起止为同一天的话,不允许选择自己 |
| | | if (selected[0] === date && !this.allowSameDay) return |
| | | selected.push(date) |
| | | } |
| | | } |
| | | } |
| | | this.setSelected(selected) |
| | | this.$emit('change',{ |
| | | day: date, |
| | | selected: selected |
| | | }); |
| | | }, |
| | | // 设置默认日期 |
| | | setDefaultDate() { |
| | | if (!this.defaultDate) { |
| | | // 如果没有设置默认日期,则将当天日期设置为默认选中的日期 |
| | | const selected = [dayjs().format("YYYY-MM-DD")] |
| | | return this.setSelected(selected, false) |
| | | } |
| | | let defaultDate = [] |
| | | const minDate = this.minDate || dayjs().format("YYYY-MM-DD") |
| | | const maxDate = this.maxDate || dayjs(minDate).add(this.maxMonth - 1, 'month').format("YYYY-MM-DD") |
| | | if (this.mode === 'single') { |
| | | // 单选模式,可以是字符串或数组,Date对象等 |
| | | if (!this.$uv.test.array(this.defaultDate)) { |
| | | defaultDate = [dayjs(this.defaultDate).format("YYYY-MM-DD")] |
| | | } else { |
| | | defaultDate = [this.defaultDate[0]] |
| | | } |
| | | } else { |
| | | // 如果为非数组,则不执行 |
| | | if (!this.$uv.test.array(this.defaultDate)) return |
| | | defaultDate = this.defaultDate |
| | | } |
| | | // 过滤用户传递的默认数组,取出只在可允许最大值与最小值之间的元素 |
| | | defaultDate = defaultDate.filter(item => { |
| | | return dayjs(item).isAfter(dayjs(minDate).subtract(1, 'day')) && dayjs(item).isBefore(dayjs( |
| | | maxDate).add(1, 'day')) |
| | | }) |
| | | this.setSelected(defaultDate, false) |
| | | }, |
| | | setSelected(selected, event = true) { |
| | | this.selected = selected |
| | | event && this.$emit('monthSelected', this.selected) |
| | | } |
| | | } |
| | | } |
| | | </script> |
| | | |
| | | <style lang="scss" scoped> |
| | | @import '@/uni_modules/uv-ui-tools/libs/css/components.scss'; |
| | | @import '@/uni_modules/uv-ui-tools/libs/css/color.scss'; |
| | | .uv-calendar-month-wrapper { |
| | | margin-top: 4px; |
| | | } |
| | | |
| | | .uv-calendar-month { |
| | | |
| | | &__title { |
| | | font-size: 14px; |
| | | line-height: 42px; |
| | | height: 42px; |
| | | color: $uv-main-color; |
| | | text-align: center; |
| | | font-weight: bold; |
| | | } |
| | | |
| | | &__days { |
| | | position: relative; |
| | | @include flex; |
| | | flex-wrap: wrap; |
| | | |
| | | &__month-mark-wrapper { |
| | | position: absolute; |
| | | top: 0; |
| | | bottom: 0; |
| | | left: 0; |
| | | right: 0; |
| | | @include flex; |
| | | justify-content: center; |
| | | align-items: center; |
| | | |
| | | &__text { |
| | | font-size: 155px; |
| | | color: rgba(231, 232, 234, 0.83); |
| | | } |
| | | } |
| | | |
| | | &__day { |
| | | @include flex; |
| | | padding: 2px; |
| | | /* #ifndef APP-NVUE */ |
| | | // vue下使用css进行宽度计算,因为某些安卓机会无法进行js获取父元素宽度进行计算得出,会有偏移 |
| | | width: calc(100% / 7); |
| | | box-sizing: border-box; |
| | | /* #endif */ |
| | | |
| | | &__select { |
| | | flex: 1; |
| | | @include flex; |
| | | align-items: center; |
| | | justify-content: center; |
| | | position: relative; |
| | | |
| | | &__dot { |
| | | width: 7px; |
| | | height: 7px; |
| | | border-radius: 100px; |
| | | background-color: $uv-error; |
| | | position: absolute; |
| | | top: 12px; |
| | | right: 7px; |
| | | } |
| | | |
| | | &__top-info { |
| | | color: $uv-content-color; |
| | | text-align: center; |
| | | position: absolute; |
| | | top: 2px; |
| | | font-size: 10px; |
| | | text-align: center; |
| | | left: 0; |
| | | right: 0; |
| | | &--selected { |
| | | color: #ffffff; |
| | | } |
| | | |
| | | &--disabled { |
| | | color: #cacbcd; |
| | | } |
| | | } |
| | | |
| | | &__buttom-info { |
| | | color: $uv-content-color; |
| | | text-align: center; |
| | | position: absolute; |
| | | bottom: 5px; |
| | | font-size: 10px; |
| | | text-align: center; |
| | | left: 0; |
| | | right: 0; |
| | | |
| | | &--selected { |
| | | color: #ffffff; |
| | | } |
| | | |
| | | &--disabled { |
| | | color: #cacbcd; |
| | | } |
| | | } |
| | | |
| | | &__info { |
| | | text-align: center; |
| | | font-size: 16px; |
| | | |
| | | &--selected { |
| | | color: #ffffff; |
| | | } |
| | | |
| | | &--disabled { |
| | | color: #cacbcd; |
| | | } |
| | | } |
| | | |
| | | &--selected { |
| | | background-color: $uv-primary; |
| | | @include flex; |
| | | justify-content: center; |
| | | align-items: center; |
| | | flex: 1; |
| | | border-radius: 3px; |
| | | } |
| | | |
| | | &--range-selected { |
| | | opacity: 0.3; |
| | | border-radius: 0; |
| | | } |
| | | |
| | | &--range-start-selected { |
| | | border-top-right-radius: 0; |
| | | border-bottom-right-radius: 0; |
| | | } |
| | | |
| | | &--range-end-selected { |
| | | border-top-left-radius: 0; |
| | | border-bottom-left-radius: 0; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | </style> |
| New file |
| | |
| | | export default { |
| | | props: { |
| | | // 日历顶部标题 |
| | | title: { |
| | | type: String, |
| | | default: '日期选择' |
| | | }, |
| | | // 是否显示标题 |
| | | showTitle: { |
| | | type: Boolean, |
| | | default: true |
| | | }, |
| | | // 是否显示副标题 |
| | | showSubtitle: { |
| | | type: Boolean, |
| | | default: true |
| | | }, |
| | | // 日期类型选择,single-选择单个日期,multiple-可以选择多个日期,range-选择日期范围 |
| | | mode: { |
| | | type: String, |
| | | default: 'single' |
| | | }, |
| | | // mode=range时,第一个日期底部的提示文字 |
| | | startText: { |
| | | type: String, |
| | | default: '开始' |
| | | }, |
| | | // mode=range时,最后一个日期底部的提示文字 |
| | | endText: { |
| | | type: String, |
| | | default: '结束' |
| | | }, |
| | | // 自定义列表 |
| | | customList: { |
| | | type: Array, |
| | | default: () => [] |
| | | }, |
| | | // 主题色,对底部按钮和选中日期有效 |
| | | color: { |
| | | type: String, |
| | | default: '#3c9cff' |
| | | }, |
| | | // 最小的可选日期 |
| | | minDate: { |
| | | type: [String, Number], |
| | | default: 0 |
| | | }, |
| | | // 最大可选日期 |
| | | maxDate: { |
| | | type: [String, Number], |
| | | default: 0 |
| | | }, |
| | | // 默认选中的日期,mode为multiple或range是必须为数组格式 |
| | | defaultDate: { |
| | | type: [Array, String, Date, null], |
| | | default: null |
| | | }, |
| | | // mode=multiple时,最多可选多少个日期 |
| | | maxCount: { |
| | | type: [String, Number], |
| | | default: Number.MAX_SAFE_INTEGER |
| | | }, |
| | | // 日期行高 |
| | | rowHeight: { |
| | | type: [String, Number], |
| | | default: 56 |
| | | }, |
| | | // 日期格式化函数 |
| | | formatter: { |
| | | type: [Function, null], |
| | | default: null |
| | | }, |
| | | // 是否显示农历 |
| | | showLunar: { |
| | | type: Boolean, |
| | | default: false |
| | | }, |
| | | // 是否显示月份背景色 |
| | | showMark: { |
| | | type: Boolean, |
| | | default: true |
| | | }, |
| | | // 确定按钮的文字 |
| | | confirmText: { |
| | | type: String, |
| | | default: '确定' |
| | | }, |
| | | // 确认按钮处于禁用状态时的文字 |
| | | confirmDisabledText: { |
| | | type: String, |
| | | default: '确定' |
| | | }, |
| | | // 是否允许点击遮罩关闭日历 |
| | | closeOnClickOverlay: { |
| | | type: Boolean, |
| | | default: false |
| | | }, |
| | | // 是否允许点击确认按钮关闭日历 |
| | | closeOnClickConfirm: { |
| | | type: Boolean, |
| | | default: true |
| | | }, |
| | | // 是否为只读状态,只读状态下禁止选择日期 |
| | | readonly: { |
| | | type: Boolean, |
| | | default: false |
| | | }, |
| | | // 是否展示确认按钮 |
| | | showConfirm: { |
| | | type: Boolean, |
| | | default: true |
| | | }, |
| | | // 日期区间最多可选天数,默认无限制,mode = range时有效 Infinity |
| | | maxRange: { |
| | | type: [Number, String], |
| | | default: Number.MAX_SAFE_INTEGER |
| | | }, |
| | | // 范围选择超过最多可选天数时的提示文案,mode = range时有效 |
| | | rangePrompt: { |
| | | type: String, |
| | | default: '' |
| | | }, |
| | | // 范围选择超过最多可选天数时,是否展示提示文案,mode = range时有效 |
| | | showRangePrompt: { |
| | | type: Boolean, |
| | | default: true |
| | | }, |
| | | // 是否允许日期范围的起止时间为同一天,mode = range时有效 |
| | | allowSameDay: { |
| | | type: Boolean, |
| | | default: false |
| | | }, |
| | | // 圆角值 |
| | | round: { |
| | | type: [Boolean, String, Number], |
| | | default: 0 |
| | | }, |
| | | // 最多展示月份数量 |
| | | monthNum: { |
| | | type: [Number, String], |
| | | default: 3 |
| | | }, |
| | | ...uni.$uv?.props?.calendar |
| | | } |
| | | } |
| New file |
| | |
| | | <template> |
| | | <uv-popup |
| | | ref="calendarPopup" |
| | | mode="bottom" |
| | | closeable |
| | | :round="round" |
| | | :closeOnClickOverlay="closeOnClickOverlay" |
| | | @change="popupChange" |
| | | > |
| | | <view class="uv-calendar"> |
| | | <uvHeader |
| | | :title="title" |
| | | :subtitle="subtitle" |
| | | :showSubtitle="showSubtitle" |
| | | :showTitle="showTitle" |
| | | ></uvHeader> |
| | | <scroll-view |
| | | :style="{ height: $uv.addUnit(listHeight) }" |
| | | scroll-y |
| | | @scroll="onScroll" |
| | | :scroll-top="scrollTop" |
| | | :scrollIntoView="scrollIntoView" |
| | | > |
| | | <uvMonth |
| | | :color="color" |
| | | :rowHeight="rowHeight" |
| | | :showMark="showMark" |
| | | :months="months" |
| | | :mode="mode" |
| | | :maxCount="maxCount" |
| | | :startText="startText" |
| | | :endText="endText" |
| | | :defaultDate="defaultDate" |
| | | :minDate="innerMinDate" |
| | | :maxDate="innerMaxDate" |
| | | :maxMonth="monthNum" |
| | | :readonly="readonly" |
| | | :maxRange="maxRange" |
| | | :rangePrompt="rangePrompt" |
| | | :showRangePrompt="showRangePrompt" |
| | | :allowSameDay="allowSameDay" |
| | | ref="month" |
| | | @monthSelected="monthSelected" |
| | | @updateMonthTop="updateMonthTop" |
| | | @change="changeDay" |
| | | ></uvMonth> |
| | | </scroll-view> |
| | | <slot name="footer" v-if="showConfirm"> |
| | | <view class="uv-calendar__confirm"> |
| | | <uv-button |
| | | shape="circle" |
| | | :text="buttonDisabled ? confirmDisabledText : confirmText" |
| | | :color="color" |
| | | @click="confirm" |
| | | :disabled="buttonDisabled" |
| | | ></uv-button> |
| | | </view> |
| | | </slot> |
| | | </view> |
| | | </uv-popup> |
| | | </template> |
| | | |
| | | <script> |
| | | import mpMixin from '@/uni_modules/uv-ui-tools/libs/mixin/mpMixin.js' |
| | | import mixin from '@/uni_modules/uv-ui-tools/libs/mixin/mixin.js' |
| | | import uvHeader from './header.vue' |
| | | import uvMonth from './month.vue' |
| | | import props from './props.js' |
| | | import dayjs from '@/uni_modules/uv-ui-tools/libs/util/dayjs.js' |
| | | import Calendar from './calendar.js' |
| | | /** |
| | | * Calendar 日历 |
| | | * @description 此组件用于单个选择日期,范围选择日期等,日历被包裹在底部弹起的容器中. |
| | | * @tutorial https://www.uvui.cn/components/calendar.html |
| | | * |
| | | * @property {String} title 标题内容 (默认 日期选择 ) |
| | | * @property {Boolean} showTitle 是否显示标题 (默认 true ) |
| | | * @property {Boolean} showSubtitle 是否显示副标题 (默认 true ) |
| | | * @property {String} mode 日期类型选择 single-选择单个日期,multiple-可以选择多个日期,range-选择日期范围 ( 默认 'single' ) |
| | | * @property {String} startText mode=range时,第一个日期底部的提示文字 (默认 '开始' ) |
| | | * @property {String} endText mode=range时,最后一个日期底部的提示文字 (默认 '结束' ) |
| | | * @property {Array} customList 自定义列表 |
| | | * @property {String} color 主题色,对底部按钮和选中日期有效 (默认 ‘#3c9cff' ) |
| | | * @property {String | Number} minDate 最小的可选日期 (默认 0 ) |
| | | * @property {String | Number} maxDate 最大可选日期 (默认 0 ) |
| | | * @property {Array | String| Date} defaultDate 默认选中的日期,mode为multiple或range是必须为数组格式 |
| | | * @property {String | Number} maxCount mode=multiple时,最多可选多少个日期 (默认 Number.MAX_SAFE_INTEGER ) |
| | | * @property {String | Number} rowHeight 日期行高 (默认 56 ) |
| | | * @property {Function} formatter 日期格式化函数 |
| | | * @property {Boolean} showLunar 是否显示农历 (默认 false ) |
| | | * @property {Boolean} showMark 是否显示月份背景色 (默认 true ) |
| | | * @property {String} confirmText 确定按钮的文字 (默认 '确定' ) |
| | | * @property {String} confirmDisabledText 确认按钮处于禁用状态时的文字 (默认 '确定' ) |
| | | * @property {Boolean} show 是否显示日历弹窗 (默认 false ) |
| | | * @property {Boolean} closeOnClickOverlay 是否允许点击遮罩关闭日历 (默认 false ) |
| | | * @property {Boolean} closeOnClickConfirm 是否允许点击确认按钮关闭日历,设置为false不影响confirm事件返回 (默认 true ) |
| | | * @property {Boolean} readonly 是否为只读状态,只读状态下禁止选择日期 (默认 false ) |
| | | * @property {String | Number} maxRange 日期区间最多可选天数,默认无限制,mode = range时有效 |
| | | * @property {String} rangePrompt 范围选择超过最多可选天数时的提示文案,mode = range时有效 |
| | | * @property {Boolean} showRangePrompt 范围选择超过最多可选天数时,是否展示提示文案,mode = range时有效 (默认 true ) |
| | | * @property {Boolean} allowSameDay 是否允许日期范围的起止时间为同一天,mode = range时有效 (默认 false ) |
| | | * @property {Number|String} round 圆角值,默认无圆角 (默认 0 ) |
| | | * @property {Number|String} monthNum 最多展示的月份数量 (默认 3 ) |
| | | * |
| | | * @event {Function()} confirm 点击确定按钮时触发 选择日期相关的返回参数 |
| | | * @event {Function()} close 日历关闭时触发 可定义页面关闭时的回调事件 |
| | | * @example <uv-calendar ref="calendar" :defaultDate="defaultDateMultiple" mode="multiple" @confirm="confirm"> |
| | | </uv-calendar> |
| | | * */ |
| | | export default { |
| | | name: 'uv-calendar', |
| | | emits:['confirm','close','change'], |
| | | mixins: [mpMixin, mixin, props], |
| | | components: { |
| | | uvHeader, |
| | | uvMonth |
| | | }, |
| | | data() { |
| | | return { |
| | | // 需要显示的月份的数组 |
| | | months: [], |
| | | // 在月份滚动区域中,当前视图中月份的index索引 |
| | | monthIndex: 0, |
| | | // 月份滚动区域的高度 |
| | | listHeight: 0, |
| | | // month组件中选择的日期数组 |
| | | selected: [], |
| | | scrollIntoView: '', |
| | | scrollTop:0, |
| | | // 过滤处理方法 |
| | | innerFormatter: (value) => value |
| | | } |
| | | }, |
| | | watch: { |
| | | selectedChange: { |
| | | immediate: true, |
| | | handler(n) { |
| | | this.setMonth() |
| | | } |
| | | } |
| | | }, |
| | | computed: { |
| | | // 由于maxDate和minDate可以为字符串(2021-10-10),或者数值(时间戳),但是dayjs如果接受字符串形式的时间戳会有问题,这里进行处理 |
| | | innerMaxDate() { |
| | | return this.$uv.test.number(this.maxDate) |
| | | ? Number(this.maxDate) |
| | | : this.maxDate |
| | | }, |
| | | innerMinDate() { |
| | | return this.$uv.test.number(this.minDate) |
| | | ? Number(this.minDate) |
| | | : this.minDate |
| | | }, |
| | | // 多个条件的变化,会引起选中日期的变化,这里统一管理监听 |
| | | selectedChange() { |
| | | return [this.innerMinDate, this.innerMaxDate, this.defaultDate] |
| | | }, |
| | | subtitle() { |
| | | // 初始化时,this.months为空数组,所以需要特别判断处理 |
| | | if (this.months.length) { |
| | | return `${this.months[this.monthIndex].year}年${ |
| | | this.months[this.monthIndex].month |
| | | }月` |
| | | } else { |
| | | return '' |
| | | } |
| | | }, |
| | | buttonDisabled() { |
| | | // 如果为range类型,且选择的日期个数不足1个时,让底部的按钮出于disabled状态 |
| | | if (this.mode === 'range') { |
| | | if (this.selected.length <= 1) { |
| | | return true |
| | | } else { |
| | | return false |
| | | } |
| | | } else { |
| | | return false |
| | | } |
| | | } |
| | | }, |
| | | mounted() { |
| | | this.start = Date.now() |
| | | this.init() |
| | | }, |
| | | methods: { |
| | | // 在微信小程序中,不支持将函数当做props参数,故只能通过ref形式调用 |
| | | setFormatter(e) { |
| | | this.innerFormatter = e |
| | | }, |
| | | // 点击日期框触发 |
| | | changeDay(e) { |
| | | this.$emit('change',e); |
| | | }, |
| | | // month组件内部选择日期后,通过事件通知给父组件 |
| | | monthSelected(e) { |
| | | this.selected = e |
| | | if (!this.showConfirm) { |
| | | // 在不需要确认按钮的情况下,如果为单选,或者范围多选且已选长度大于2,则直接进行返还 |
| | | if ( |
| | | this.mode === 'multiple' || |
| | | this.mode === 'single' || |
| | | (this.mode === 'range' && this.selected.length >= 2) |
| | | ) { |
| | | this.$emit('confirm', this.selected) |
| | | } |
| | | } |
| | | }, |
| | | init() { |
| | | // 校验maxDate,不能小于minDate |
| | | if ( |
| | | this.innerMaxDate && |
| | | this.innerMinDate && |
| | | new Date(this.innerMaxDate).getTime() < new Date(this.innerMinDate).getTime() |
| | | ) { |
| | | return this.$uv.error('maxDate不能小于minDate') |
| | | } |
| | | // 滚动区域的高度 |
| | | this.listHeight = this.rowHeight * 5 + 30 |
| | | this.setMonth() |
| | | }, |
| | | open() { |
| | | this.setMonth() |
| | | this.$refs.calendarPopup.open(); |
| | | }, |
| | | popupChange(e) { |
| | | if(!e.show) { |
| | | this.$emit('close'); |
| | | } |
| | | }, |
| | | // 点击确定按钮 |
| | | confirm() { |
| | | if (!this.buttonDisabled) { |
| | | this.$emit('confirm', this.selected) |
| | | } |
| | | if (this.closeOnClickConfirm) { |
| | | this.$refs.calendarPopup.close(); |
| | | } |
| | | }, |
| | | // 获得两个日期之间的月份数 |
| | | getMonths(minDate, maxDate) { |
| | | const minYear = dayjs(minDate).year() |
| | | const minMonth = dayjs(minDate).month() + 1 |
| | | const maxYear = dayjs(maxDate).year() |
| | | const maxMonth = dayjs(maxDate).month() + 1 |
| | | return (maxYear - minYear) * 12 + (maxMonth - minMonth) + 1 |
| | | }, |
| | | // 设置月份数据 |
| | | setMonth() { |
| | | // 最小日期的毫秒数 |
| | | const minDate = this.innerMinDate || dayjs().valueOf() |
| | | // 如果没有指定最大日期,则往后推3个月 |
| | | const maxDate = |
| | | this.innerMaxDate || |
| | | dayjs(minDate) |
| | | .add(this.monthNum - 1, 'month') |
| | | .valueOf() |
| | | // 最大最小月份之间的共有多少个月份, |
| | | const months = this.$uv.range( |
| | | 1, |
| | | this.monthNum, |
| | | this.getMonths(minDate, maxDate) |
| | | ) |
| | | // 先清空数组 |
| | | this.months = [] |
| | | for (let i = 0; i < months; i++) { |
| | | this.months.push({ |
| | | date: new Array( |
| | | dayjs(minDate).add(i, 'month').daysInMonth() |
| | | ) |
| | | .fill(1) |
| | | .map((item, index) => { |
| | | // 日期,取值1-31 |
| | | let day = index + 1 |
| | | // 星期,0-6,0为周日 |
| | | const week = dayjs(minDate) |
| | | .add(i, 'month') |
| | | .date(day) |
| | | .day() |
| | | const date = dayjs(minDate) |
| | | .add(i, 'month') |
| | | .date(day) |
| | | .format('YYYY-MM-DD') |
| | | let topInfo = '' |
| | | let bottomInfo = '' |
| | | if (this.showLunar) { |
| | | // 将日期转为农历格式 |
| | | const lunar = Calendar.solar2lunar( |
| | | dayjs(date).year(), |
| | | dayjs(date).month() + 1, |
| | | dayjs(date).date() |
| | | ) |
| | | bottomInfo = lunar.IDayCn |
| | | } |
| | | let config = { |
| | | day, |
| | | week, |
| | | // 小于最小允许的日期,或者大于最大的日期,则设置为disabled状态 |
| | | disabled: |
| | | dayjs(date).isBefore( |
| | | dayjs(minDate).format('YYYY-MM-DD') |
| | | ) || |
| | | dayjs(date).isAfter( |
| | | dayjs(maxDate).format('YYYY-MM-DD') |
| | | ), |
| | | // 返回一个日期对象,供外部的formatter获取当前日期的年月日等信息,进行加工处理 |
| | | date: new Date(date), |
| | | topInfo, |
| | | bottomInfo, |
| | | dot: false, |
| | | month: |
| | | dayjs(minDate).add(i, 'month').month() + 1 |
| | | } |
| | | const formatter = |
| | | this.formatter || this.innerFormatter |
| | | return formatter(config) |
| | | }), |
| | | // 当前所属的月份 |
| | | month: dayjs(minDate).add(i, 'month').month() + 1, |
| | | // 当前年份 |
| | | year: dayjs(minDate).add(i, 'month').year() |
| | | }) |
| | | } |
| | | |
| | | }, |
| | | // 滚动到默认设置的月份 |
| | | scrollIntoDefaultMonth(selected) { |
| | | // 查询默认日期在可选列表的下标 |
| | | const _index = this.months.findIndex(({ |
| | | year, |
| | | month |
| | | }) => { |
| | | month = this.$uv.padZero(month) |
| | | return `${year}-${month}` === selected |
| | | }) |
| | | if (_index !== -1) { |
| | | // #ifndef MP-WEIXIN |
| | | this.$nextTick(() => { |
| | | this.scrollIntoView = `month-${_index}` |
| | | }) |
| | | // #endif |
| | | // #ifdef MP-WEIXIN |
| | | this.scrollTop = this.months[_index].top || 0; |
| | | // #endif |
| | | } |
| | | }, |
| | | // scroll-view滚动监听 |
| | | onScroll(event) { |
| | | // 不允许小于0的滚动值,如果scroll-view到顶了,继续下拉,会出现负数值 |
| | | const scrollTop = Math.max(0, event.detail.scrollTop) |
| | | // 将当前滚动条数值,除以滚动区域的高度,可以得出当前滚动到了哪一个月份的索引 |
| | | for (let i = 0; i < this.months.length; i++) { |
| | | if (scrollTop >= (this.months[i].top || this.listHeight)) { |
| | | this.monthIndex = i |
| | | } |
| | | } |
| | | }, |
| | | // 更新月份的top值 |
| | | updateMonthTop(topArr = []) { |
| | | // 设置对应月份的top值,用于onScroll方法更新月份 |
| | | topArr.map((item, index) => { |
| | | this.months[index].top = item |
| | | }) |
| | | |
| | | // 获取默认日期的下标 |
| | | if (!this.defaultDate) { |
| | | // 如果没有设置默认日期,则将当天日期设置为默认选中的日期 |
| | | const selected = dayjs().format("YYYY-MM") |
| | | this.scrollIntoDefaultMonth(selected) |
| | | return |
| | | } |
| | | let selected = dayjs().format("YYYY-MM"); |
| | | // 单选模式,可以是字符串或数组,Date对象等 |
| | | if (!this.$uv.test.array(this.defaultDate)) { |
| | | selected = dayjs(this.defaultDate).format("YYYY-MM") |
| | | } else { |
| | | selected = dayjs(this.defaultDate[0]).format("YYYY-MM"); |
| | | } |
| | | this.scrollIntoDefaultMonth(selected) |
| | | } |
| | | } |
| | | } |
| | | </script> |
| | | |
| | | <style lang="scss" scoped> |
| | | .uv-calendar { |
| | | &__confirm { |
| | | padding: 7px 18px; |
| | | } |
| | | } |
| | | </style> |
| New file |
| | |
| | | { |
| | | "id": "uv-calendar", |
| | | "displayName": "uv-calendar 日历 全面兼容vue3+2、app、h5、小程序等多端", |
| | | "version": "1.0.6", |
| | | "description": "日历组件用于单个选择日期,范围选择日期等,日历被包裹在底部弹起的容器中,灵活配置,功能齐全,兼容全端。强烈推荐使用最新版日历组件,在下方跳入。", |
| | | "keywords": [ |
| | | "uv-calendar", |
| | | "uvui", |
| | | "uv-ui", |
| | | "calendar", |
| | | "日历" |
| | | ], |
| | | "repository": "", |
| | | "engines": { |
| | | "HBuilderX": "^3.1.0" |
| | | }, |
| | | "dcloudext": { |
| | | "type": "component-vue", |
| | | "sale": { |
| | | "regular": { |
| | | "price": "0.00" |
| | | }, |
| | | "sourcecode": { |
| | | "price": "0.00" |
| | | } |
| | | }, |
| | | "contact": { |
| | | "qq": "" |
| | | }, |
| | | "declaration": { |
| | | "ads": "无", |
| | | "data": "插件不采集任何数据", |
| | | "permissions": "无" |
| | | }, |
| | | "npmurl": "" |
| | | }, |
| | | "uni_modules": { |
| | | "dependencies": [ |
| | | "uv-ui-tools", |
| | | "uv-button", |
| | | "uv-popup" |
| | | ], |
| | | "encrypt": [], |
| | | "platforms": { |
| | | "cloud": { |
| | | "tcb": "y", |
| | | "aliyun": "y" |
| | | }, |
| | | "client": { |
| | | "Vue": { |
| | | "vue2": "y", |
| | | "vue3": "y" |
| | | }, |
| | | "App": { |
| | | "app-vue": "y", |
| | | "app-nvue": "y" |
| | | }, |
| | | "H5-mobile": { |
| | | "Safari": "y", |
| | | "Android Browser": "y", |
| | | "微信浏览器(Android)": "y", |
| | | "QQ浏览器(Android)": "y" |
| | | }, |
| | | "H5-pc": { |
| | | "Chrome": "y", |
| | | "IE": "y", |
| | | "Edge": "y", |
| | | "Firefox": "y", |
| | | "Safari": "y" |
| | | }, |
| | | "小程序": { |
| | | "微信": "y", |
| | | "阿里": "y", |
| | | "百度": "y", |
| | | "字节跳动": "y", |
| | | "QQ": "y", |
| | | "钉钉": "u", |
| | | "快手": "u", |
| | | "飞书": "u", |
| | | "京东": "u" |
| | | }, |
| | | "快应用": { |
| | | "华为": "u", |
| | | "联盟": "u" |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| New file |
| | |
| | | ## Calendar 日历 |
| | | |
| | | > **组件名:uv-calendar** |
| | | |
| | | 此组件用于单个选择日期,范围选择日期等,日历被包裹在底部弹起的容器中。灵活配置,功能齐全,兼容全端。 |
| | | |
| | | ## 温馨提示:该组件不再更新,强烈推荐使用最新版日历组件:[https://www.uvui.cn/components/calendars.html](https://www.uvui.cn/components/calendars.html)。基于 `uv-ui` 插件市场首款多功能日历组件,不仅可以查看、选择日期,还可以选择任意范围内的日期、打点操作、自定义主题颜色、自定义文案、农历显示等。追求的就是完美。 |
| | | |
| | | # <a href="https://www.uvui.cn/components/calendar.html" target="_blank">查看文档</a> |
| | | |
| | | ## [下载完整示例项目](https://ext.dcloud.net.cn/plugin?name=uv-ui) <small>(请不要 下载插件ZIP)</small> |
| | | |
| | | ### [更多插件,请关注uv-ui组件库](https://ext.dcloud.net.cn/plugin?name=uv-ui) |
| | | |
| | | <a href="https://ext.dcloud.net.cn/plugin?name=uv-ui" target="_blank"> |
| | | |
| | |  |
| | | |
| | | </a> |
| | | |
| | | #### 如使用过程中有任何问题反馈,或者您对uv-ui有一些好的建议,欢迎加入uv-ui官方交流群:<a href="https://www.uvui.cn/components/addQQGroup.html" target="_blank">官方QQ群</a> |
| New file |
| | |
| | | ## 1.0.15(2023-11-08) |
| | | 1. 增加readonly属性,是否为只读状态,只读状态下禁止选择日期 |
| | | ## 1.0.14(2023-10-12) |
| | | 1. 修复selected没有设置了info或者info设置为空字符串后,文本则无法恢复BUG |
| | | ## 1.0.13(2023-09-19) |
| | | 1. 修复range模式下,selected设置了info后选中后,导致文本不恢复的问题 |
| | | 2. 修复multiple模式下,selected自定义信息的颜色没变,依然是白色 |
| | | ## 1.0.12(2023-09-14) |
| | | 1. 优化 |
| | | ## 1.0.11(2023-09-14) |
| | | 1. 增加allowSameDay参数,是否允许日期范围的起止时间为同一天,mode = range时有效 |
| | | 2. 修复在vue2+小程序渲染时闪烁的问题 |
| | | ## 1.0.10(2023-09-07) |
| | | 1. 修复国际化失效的BUG |
| | | ## 1.0.9(2023-09-01) |
| | | 1. 修复在pages.json中设置easycom会报错的BUG |
| | | ## 1.0.8(2023-08-29) |
| | | 1. 修复mainjs中设置setConfig修改属性不生效的问题,出自评论区:https://ext.dcloud.net.cn/plugin?id=12287 |
| | | ## 1.0.7(2023-08-26) |
| | | 1. 去除range参数,由mode="range"替换 |
| | | 2. 新增mode参数,不传 / multiple / range,分别为单日期, 多个日期,选择日期范围 |
| | | 3. 与uv-calendar选择日期的功能保持一致 |
| | | ## 1.0.6(2023-08-25) |
| | | 1. 修复点击返回今天按钮时,monthSwitch方法回调参数返回月份不是当天对应月份:https://github.com/climblee/uv-ui/issues/7 |
| | | ## 1.0.5(2023-08-13) |
| | | 1. 修复选择月份弹窗层级的问题 |
| | | ## 1.0.4(2023-08-06) |
| | | 1. 优化 |
| | | ## 1.0.3(2023-08-06) |
| | | 1. 修复高度不对的BUG |
| | | 2. 修复文案在小屏幕的BUG |
| | | ## 1.0.2(2023-08-05) |
| | | 1. 增加startText参数 |
| | | 2. 增加endText参数 |
| | | 3. 增加selected中的参数 |
| | | 4. 优化日历范围选择 |
| | | ## 1.0.1(2023-08-04) |
| | | 1. 修复 自定义主题时 颜色错误的BUG |
| | | ## 1.0.0(2023-08-03) |
| | | 1. 新增 uv-calendars 新版日历发布 |
| New file |
| | |
| | | <template> |
| | | <view class="uv-calendar-body"> |
| | | <view class="uv-calendar__header"> |
| | | <view class="uv-calendar__header-btn-box" @click.stop="pre"> |
| | | <view class="uv-calendar__header-btn uv-calendar--left"></view> |
| | | </view> |
| | | <picker mode="date" :value="getDate" fields="month" @change="bindDateChange"> |
| | | <text class="uv-calendar__header-text">{{ (nowDate.year||'') +' / '+( nowDate.month||'')}}</text> |
| | | </picker> |
| | | <view class="uv-calendar__header-btn-box" @click.stop="next"> |
| | | <view class="uv-calendar__header-btn uv-calendar--right"></view> |
| | | </view> |
| | | <text class="uv-calendar__backtoday" @click="backToday">{{todayText}}</text> |
| | | </view> |
| | | <view class="uv-calendar__box"> |
| | | <view v-if="showMonth" class="uv-calendar__box-bg"> |
| | | <text class="uv-calendar__box-bg-text">{{nowDate.month}}</text> |
| | | </view> |
| | | <view class="uv-calendar__weeks uv-calendar__weeks-week"> |
| | | <view class="uv-calendar__weeks-day"> |
| | | <text class="uv-calendar__weeks-day-text">{{SUNText}}</text> |
| | | </view> |
| | | <view class="uv-calendar__weeks-day"> |
| | | <text class="uv-calendar__weeks-day-text">{{monText}}</text> |
| | | </view> |
| | | <view class="uv-calendar__weeks-day"> |
| | | <text class="uv-calendar__weeks-day-text">{{TUEText}}</text> |
| | | </view> |
| | | <view class="uv-calendar__weeks-day"> |
| | | <text class="uv-calendar__weeks-day-text">{{WEDText}}</text> |
| | | </view> |
| | | <view class="uv-calendar__weeks-day"> |
| | | <text class="uv-calendar__weeks-day-text">{{THUText}}</text> |
| | | </view> |
| | | <view class="uv-calendar__weeks-day"> |
| | | <text class="uv-calendar__weeks-day-text">{{FRIText}}</text> |
| | | </view> |
| | | <view class="uv-calendar__weeks-day"> |
| | | <text class="uv-calendar__weeks-day-text">{{SATText}}</text> |
| | | </view> |
| | | </view> |
| | | <view class="uv-calendar__weeks" v-for="(item,weekIndex) in weeks" :key="weekIndex"> |
| | | <view class="uv-calendar__weeks-item" v-for="(weeks,weeksIndex) in item" :key="weeksIndex"> |
| | | <calendar-item class="uv-calendar-item--hook" :weeks="weeks" :rangeInfoText="rangeInfoText(weeks)" :multiple="multiple" :range="range" :calendar="calendar" :selected="selected" :lunar="lunar" :color="color" @change="choiceDate"></calendar-item> |
| | | </view> |
| | | </view> |
| | | </view> |
| | | </view> |
| | | </template> |
| | | |
| | | <script> |
| | | import mpMixin from '@/uni_modules/uv-ui-tools/libs/mixin/mpMixin.js'; |
| | | import mixin from '@/uni_modules/uv-ui-tools/libs/mixin/mixin.js'; |
| | | |
| | | import CalendarItem from './calendar-item.vue'; |
| | | |
| | | import { initVueI18n } from '@dcloudio/uni-i18n'; |
| | | import i18nMessages from './i18n/index.js'; |
| | | const { t } = initVueI18n(i18nMessages); |
| | | export default { |
| | | mixins: [mpMixin, mixin], |
| | | components: { |
| | | CalendarItem |
| | | }, |
| | | props: { |
| | | date: { |
| | | type: [String,Array], |
| | | default: '' |
| | | }, |
| | | nowDate: { |
| | | type: [String, Object], |
| | | default: '' |
| | | }, |
| | | weeks: { |
| | | type: [Array, Object], |
| | | default () { |
| | | return [] |
| | | } |
| | | }, |
| | | calendar: { |
| | | type: Object, |
| | | default () { |
| | | return {} |
| | | } |
| | | }, |
| | | selected: { |
| | | type: Array, |
| | | default () { |
| | | return [] |
| | | } |
| | | }, |
| | | lunar: { |
| | | type: Boolean, |
| | | default: false |
| | | }, |
| | | showMonth: { |
| | | type: Boolean, |
| | | default: true |
| | | }, |
| | | color: { |
| | | type: String, |
| | | default: '#3c9cff' |
| | | }, |
| | | startText: { |
| | | type: String, |
| | | default: '开始' |
| | | }, |
| | | endText: { |
| | | type: String, |
| | | default: '结束' |
| | | }, |
| | | range: { |
| | | type: Boolean, |
| | | default: false |
| | | }, |
| | | multiple: { |
| | | type: Boolean, |
| | | default: false |
| | | }, |
| | | // 是否允许日期范围的起止时间为同一天,mode = range时有效 |
| | | allowSameDay: { |
| | | type: Boolean, |
| | | default: false |
| | | } |
| | | }, |
| | | computed: { |
| | | getDate() { |
| | | return Array.isArray(this.date) ? this.date[0] : this.date; |
| | | }, |
| | | /** |
| | | * for i18n |
| | | */ |
| | | todayText() { |
| | | return t("uv-calender.today") |
| | | }, |
| | | monText() { |
| | | return t("uv-calender.MON") |
| | | }, |
| | | TUEText() { |
| | | return t("uv-calender.TUE") |
| | | }, |
| | | WEDText() { |
| | | return t("uv-calender.WED") |
| | | }, |
| | | THUText() { |
| | | return t("uv-calender.THU") |
| | | }, |
| | | FRIText() { |
| | | return t("uv-calender.FRI") |
| | | }, |
| | | SATText() { |
| | | return t("uv-calender.SAT") |
| | | }, |
| | | SUNText() { |
| | | return t("uv-calender.SUN") |
| | | }, |
| | | rangeInfoText(weeks) { |
| | | return weeks=> { |
| | | if(this.allowSameDay && weeks.beforeRange && weeks.afterRange && weeks.dateEqual) { |
| | | return this.setInfo(weeks,`${this.startText}/${this.endText}`); |
| | | } |
| | | if(weeks.beforeRange) { |
| | | return this.setInfo(weeks,this.startText); |
| | | } |
| | | if(weeks.afterRange) { |
| | | return this.setInfo(weeks,this.endText); |
| | | } |
| | | if(weeks.extraInfo?.info_old == ' ') { |
| | | weeks.extraInfo.info = null; |
| | | }else if(weeks.extraInfo?.info_old) { |
| | | weeks.extraInfo.info = weeks.extraInfo.info_old; |
| | | } |
| | | } |
| | | } |
| | | }, |
| | | methods: { |
| | | setInfo(weeks,text) { |
| | | this.setInfoOld(weeks); |
| | | if(weeks.extraInfo) { |
| | | weeks.extraInfo.info = text; |
| | | }else { |
| | | weeks.extraInfo = { |
| | | info: text |
| | | } |
| | | } |
| | | }, |
| | | setInfoOld(weeks) { |
| | | if(weeks.extraInfo) { |
| | | weeks.extraInfo.info_old = weeks.extraInfo.info ? weeks.extraInfo.info_old || weeks.extraInfo.info : ' '; |
| | | } |
| | | }, |
| | | bindDateChange(e) { |
| | | this.$emit('bindDateChange', e); |
| | | }, |
| | | backToday() { |
| | | this.$emit('backToday'); |
| | | }, |
| | | pre() { |
| | | this.$emit('pre'); |
| | | }, |
| | | next() { |
| | | this.$emit('next'); |
| | | }, |
| | | choiceDate(e) { |
| | | this.$emit('choiceDate', e); |
| | | } |
| | | } |
| | | } |
| | | </script> |
| | | |
| | | <style scoped lang="scss"> |
| | | @mixin flex($direction: row) { |
| | | /* #ifndef APP-NVUE */ |
| | | display: flex; |
| | | /* #endif */ |
| | | flex-direction: $direction; |
| | | } |
| | | $uv-bg-color-mask: rgba($color: #000000, $alpha: 0.4); |
| | | $uv-border-color: #EDEDED !default; |
| | | $uv-text-color: #333; |
| | | $uv-bg-color-hover: #f1f1f1; |
| | | $uv-font-size-base: 14px; |
| | | $uv-text-color-placeholder: #808080; |
| | | $uv-color-subtitle: #555555; |
| | | $uv-text-color-grey: #999; |
| | | .uv-calendar { |
| | | @include flex(column); |
| | | } |
| | | .uv-calendar__mask { |
| | | position: fixed; |
| | | bottom: 0; |
| | | top: 0; |
| | | left: 0; |
| | | right: 0; |
| | | background-color: $uv-bg-color-mask; |
| | | transition-property: opacity; |
| | | transition-duration: 0.3s; |
| | | opacity: 0; |
| | | /* #ifndef APP-NVUE */ |
| | | z-index: 99; |
| | | /* #endif */ |
| | | } |
| | | .uv-calendar--mask-show { |
| | | opacity: 1 |
| | | } |
| | | .uv-calendar--fixed { |
| | | position: fixed; |
| | | /* #ifdef APP-NVUE */ |
| | | bottom: 0; |
| | | /* #endif */ |
| | | left: 0; |
| | | right: 0; |
| | | transition-property: transform; |
| | | transition-duration: 0.3s; |
| | | transform: translateY(460px); |
| | | /* #ifndef APP-NVUE */ |
| | | bottom: calc(var(--window-bottom)); |
| | | z-index: 99; |
| | | /* #endif */ |
| | | } |
| | | .uv-calendar--ani-show { |
| | | transform: translateY(0); |
| | | } |
| | | .uv-calendar__content { |
| | | background-color: #fff; |
| | | } |
| | | .uv-calendar__header { |
| | | position: relative; |
| | | @include flex; |
| | | justify-content: center; |
| | | align-items: center; |
| | | height: 50px; |
| | | border-bottom-color: $uv-border-color; |
| | | border-bottom-style: solid; |
| | | border-bottom-width: 1px; |
| | | } |
| | | .uv-calendar--fixed-top { |
| | | @include flex; |
| | | justify-content: space-between; |
| | | border-top-color: $uv-border-color; |
| | | border-top-style: solid; |
| | | border-top-width: 1px; |
| | | } |
| | | .uv-calendar--fixed-width { |
| | | width: 50px; |
| | | } |
| | | .uv-calendar__backtoday { |
| | | position: absolute; |
| | | right: 0; |
| | | top: 25rpx; |
| | | padding: 0 5px; |
| | | padding-left: 10px; |
| | | height: 25px; |
| | | line-height: 25px; |
| | | font-size: 12px; |
| | | border-top-left-radius: 25px; |
| | | border-bottom-left-radius: 25px; |
| | | color: $uv-text-color; |
| | | background-color: $uv-bg-color-hover; |
| | | } |
| | | .uv-calendar__header-text { |
| | | text-align: center; |
| | | width: 100px; |
| | | font-size: $uv-font-size-base; |
| | | color: $uv-text-color; |
| | | } |
| | | .uv-calendar__header-btn-box { |
| | | @include flex; |
| | | align-items: center; |
| | | justify-content: center; |
| | | width: 50px; |
| | | height: 50px; |
| | | } |
| | | .uv-calendar__header-btn { |
| | | width: 10px; |
| | | height: 10px; |
| | | border-left-color: $uv-text-color-placeholder; |
| | | border-left-style: solid; |
| | | border-left-width: 2px; |
| | | border-top-color: $uv-color-subtitle; |
| | | border-top-style: solid; |
| | | border-top-width: 2px; |
| | | } |
| | | .uv-calendar--left { |
| | | transform: rotate(-45deg); |
| | | } |
| | | .uv-calendar--right { |
| | | transform: rotate(135deg); |
| | | } |
| | | .uv-calendar__weeks { |
| | | position: relative; |
| | | @include flex; |
| | | } |
| | | .uv-calendar__weeks-week { |
| | | padding: 0 0 2rpx; |
| | | } |
| | | .uv-calendar__weeks-item { |
| | | flex: 1; |
| | | } |
| | | .uv-calendar__weeks-day { |
| | | flex: 1; |
| | | @include flex(column); |
| | | justify-content: center; |
| | | align-items: center; |
| | | height: 45px; |
| | | border-bottom-color: #F5F5F5; |
| | | border-bottom-style: solid; |
| | | border-bottom-width: 1px; |
| | | } |
| | | .uv-calendar__weeks-day-text { |
| | | font-size: 14px; |
| | | } |
| | | .uv-calendar__box { |
| | | position: relative; |
| | | } |
| | | .uv-calendar__box-bg { |
| | | @include flex(column); |
| | | justify-content: center; |
| | | align-items: center; |
| | | position: absolute; |
| | | top: 0; |
| | | left: 0; |
| | | right: 0; |
| | | bottom: 0; |
| | | } |
| | | .uv-calendar__box-bg-text { |
| | | font-size: 200px; |
| | | font-weight: bold; |
| | | color: $uv-text-color-grey; |
| | | opacity: 0.1; |
| | | text-align: center; |
| | | /* #ifndef APP-NVUE */ |
| | | line-height: 1; |
| | | /* #endif */ |
| | | } |
| | | </style> |
| New file |
| | |
| | | <template> |
| | | <view class="uv-calendar-item__weeks-box" :class="{ |
| | | 'uv-calendar-item--disable':weeks.disable || (weeks.extraInfo&&weeks.extraInfo.disable), |
| | | 'uv-calendar-item--isDay':calendar.fullDate === weeks.fullDate && weeks.isDay && !multiple, |
| | | 'uv-calendar-item--checked':(calendar.fullDate === weeks.fullDate && !weeks.isDay && !multiple) , |
| | | 'uv-calendar-item--before-checked':weeks.beforeRange, |
| | | 'uv-calendar-item--range': weeks.range, |
| | | 'uv-calendar-item--after-checked':weeks.afterRange, |
| | | 'uv-calendar-item--multiple':weeks.multiple |
| | | }" :style="[itemBoxStyle]" @click="choiceDate(weeks)"> |
| | | <view class="uv-calendar-item__weeks-box-item"> |
| | | <text v-if="selected&&weeks.extraInfo&&weeks.extraInfo.badge" class="uv-calendar-item__weeks-box-circle"></text> |
| | | <text class="uv-calendar-item__weeks-top-text" v-if="weeks.extraInfo&&weeks.extraInfo.topinfo" :style="[infoStyle('top')]">{{weeks.extraInfo&&weeks.extraInfo.topinfo}}</text> |
| | | <text class="uv-calendar-item__weeks-box-text" :class="{ |
| | | 'uv-calendar-item--isDay-text': weeks.isDay, |
| | | 'uv-calendar-item--isDay':calendar.fullDate === weeks.fullDate && weeks.isDay && !multiple, |
| | | 'uv-calendar-item--checked':calendar.fullDate === weeks.fullDate && !weeks.isDay && !multiple, |
| | | 'uv-calendar-item--before-checked':weeks.beforeRange, |
| | | 'uv-calendar-item--range': weeks.range, |
| | | 'uv-calendar-item--after-checked':weeks.afterRange, |
| | | 'uv-calendar-item--multiple':weeks.multiple, |
| | | 'uv-calendar-item--disable':weeks.disable || (weeks.extraInfo&&weeks.extraInfo.disable) |
| | | }" :style="[itemBoxStyle]">{{weeks.date}}</text> |
| | | <text v-if="!lunar&&!weeks.extraInfo && weeks.isDay" class="uv-calendar-item__weeks-lunar-text" :class="{ |
| | | 'uv-calendar-item--isDay-text':weeks.isDay, |
| | | 'uv-calendar-item--isDay':calendar.fullDate === weeks.fullDate && weeks.isDay && !multiple, |
| | | 'uv-calendar-item--checked':calendar.fullDate === weeks.fullDate && !weeks.isDay && !multiple, |
| | | 'uv-calendar-item--before-checked':weeks.beforeRange, |
| | | 'uv-calendar-item--range': weeks.range, |
| | | 'uv-calendar-item--after-checked':weeks.afterRange, |
| | | 'uv-calendar-item--multiple':weeks.multiple |
| | | }" :style="[itemBoxStyle]">{{todayText}}</text> |
| | | <text v-if="lunar&&!weeks.extraInfo" class="uv-calendar-item__weeks-lunar-text" :class="{ |
| | | 'uv-calendar-item--isDay-text':weeks.isDay, |
| | | 'uv-calendar-item--isDay':calendar.fullDate === weeks.fullDate && weeks.isDay && !multiple, |
| | | 'uv-calendar-item--checked':calendar.fullDate === weeks.fullDate && !weeks.isDay && !multiple, |
| | | 'uv-calendar-item--before-checked':weeks.beforeRange, |
| | | 'uv-calendar-item--range': weeks.range, |
| | | 'uv-calendar-item--after-checked':weeks.afterRange, |
| | | 'uv-calendar-item--multiple':weeks.multiple, |
| | | 'uv-calendar-item--disable':weeks.disable || (weeks.extraInfo&&weeks.extraInfo.disable) |
| | | }" :style="[itemBoxStyle]">{{weeks.isDay ? todayText : (weeks.lunar.IDayCn === '初一'?weeks.lunar.IMonthCn:weeks.lunar.IDayCn)}}</text> |
| | | <text v-if="weeks.extraInfo&&weeks.extraInfo.info" class="uv-calendar-item__weeks-lunar-text" :class="{ |
| | | 'uv-calendar-item__weeks-lunar-text--equal': weeks.dateEqual |
| | | }" :style="[infoStyle('bottom')]">{{weeks.extraInfo.info}}</text> |
| | | </view> |
| | | </view> |
| | | </template> |
| | | <script> |
| | | import { colorGradient } from '@/uni_modules/uv-ui-tools/libs/function/colorGradient.js'; |
| | | import { initVueI18n } from '@dcloudio/uni-i18n' |
| | | import i18nMessages from './i18n/index.js' |
| | | const { t } = initVueI18n(i18nMessages) |
| | | export default { |
| | | emits: ['change'], |
| | | props: { |
| | | weeks: { |
| | | type: Object, |
| | | default () { |
| | | return {} |
| | | } |
| | | }, |
| | | calendar: { |
| | | type: Object, |
| | | default: () => { |
| | | return {} |
| | | } |
| | | }, |
| | | selected: { |
| | | type: Array, |
| | | default: () => { |
| | | return [] |
| | | } |
| | | }, |
| | | lunar: { |
| | | type: Boolean, |
| | | default: false |
| | | }, |
| | | color: { |
| | | type: String, |
| | | default: '#3c9cff' |
| | | }, |
| | | range: { |
| | | type: Boolean, |
| | | default: false |
| | | }, |
| | | multiple: { |
| | | type: Boolean, |
| | | default: false |
| | | } |
| | | }, |
| | | computed: { |
| | | todayText() { |
| | | return t("uv-calender.today") |
| | | }, |
| | | itemBoxStyle() { |
| | | const style = {}; |
| | | if (this.multiple) { // 多选状态 |
| | | if (this.weeks.multiple) { |
| | | style.backgroundColor = this.color; |
| | | style.color = '#fff'; |
| | | } else if (this.weeks.isDay) { |
| | | style.color = this.color; |
| | | } |
| | | } else if (this.range) { // 范围选择 |
| | | if (this.weeks.beforeRange || this.weeks.afterRange) { |
| | | style.backgroundColor = this.color; |
| | | } else if (this.weeks.range) { |
| | | style.backgroundColor = colorGradient(this.color, '#ffffff', 100)[90] |
| | | style.color = this.color; |
| | | style.opacity = 0.8; |
| | | style.borderRadius = 0; |
| | | } |
| | | } else { |
| | | if (this.weeks.isDay) { |
| | | style.color = this.color; |
| | | } |
| | | if (this.calendar.fullDate === this.weeks.fullDate) { |
| | | style.backgroundColor = this.color; |
| | | style.color = '#fff'; |
| | | } |
| | | } |
| | | return style; |
| | | }, |
| | | infoStyle(val) { |
| | | return val => { |
| | | const style = {}; |
| | | if (!this.weeks.multiple) { |
| | | if (val == 'top') { |
| | | style.color = this.weeks.extraInfo.topinfoColor ? this.weeks.extraInfo.topinfoColor : '#606266'; |
| | | } else if (val == 'bottom') { |
| | | style.color = this.weeks.extraInfo.infoColor ? this.weeks.extraInfo.infoColor : '#f56c6c'; |
| | | } |
| | | if (this.weeks.range) { |
| | | style.color = this.color; |
| | | } |
| | | if (this.calendar.fullDate === this.weeks.fullDate || this.weeks.beforeRange || this.weeks.afterRange) { |
| | | style.color = this.multiple ? style.color : '#fff'; |
| | | } |
| | | } else { |
| | | style.color = '#fff'; |
| | | } |
| | | return style; |
| | | } |
| | | } |
| | | }, |
| | | methods: { |
| | | choiceDate(weeks) { |
| | | if (this.weeks.extraInfo && this.weeks.extraInfo.disable) return; |
| | | this.$emit('change', weeks) |
| | | } |
| | | } |
| | | } |
| | | </script> |
| | | <style lang="scss" scoped> |
| | | @mixin flex($direction: row) { |
| | | /* #ifndef APP-NVUE */ |
| | | display: flex; |
| | | /* #endif */ |
| | | flex-direction: $direction; |
| | | } |
| | | $uv-font-size-base: 14px; |
| | | $uv-text-color: #333; |
| | | $uv-font-size-sm: 24rpx; |
| | | $uv-error: #f56c6c !default; |
| | | $uv-opacity-disabled: 0.3; |
| | | $uv-text-color-disable: #c0c0c0; |
| | | $uv-primary: #3c9cff !default; |
| | | $info-height: 32rpx; |
| | | .uv-calendar-item__weeks-box { |
| | | flex: 1; |
| | | @include flex(column); |
| | | justify-content: center; |
| | | align-items: center; |
| | | border-radius: 4px; |
| | | } |
| | | .uv-calendar-item__weeks-top-text { |
| | | height: $info-height; |
| | | line-height: $info-height; |
| | | font-size: $uv-font-size-sm; |
| | | } |
| | | .uv-calendar-item__weeks-box-text { |
| | | font-size: $uv-font-size-base; |
| | | color: $uv-text-color; |
| | | } |
| | | .uv-calendar-item__weeks-lunar-text { |
| | | height: $info-height; |
| | | line-height: $info-height; |
| | | font-size: $uv-font-size-sm; |
| | | color: $uv-text-color; |
| | | } |
| | | .uv-calendar-item__weeks-lunar-text--equal { |
| | | /* #ifdef H5 */ |
| | | white-space: nowrap; |
| | | transform: scale(.8); |
| | | /* #endif */ |
| | | /* #ifndef H5 */ |
| | | font-size: 20rpx; |
| | | /* #endif */ |
| | | } |
| | | .uv-calendar-item__weeks-box-item { |
| | | position: relative; |
| | | @include flex(column); |
| | | justify-content: center; |
| | | align-items: center; |
| | | width: 106rpx; |
| | | height: 56px; |
| | | } |
| | | .uv-calendar-item__weeks-box-circle { |
| | | position: absolute; |
| | | top: 5px; |
| | | right: 5px; |
| | | width: 8px; |
| | | height: 8px; |
| | | border-radius: 8px; |
| | | background-color: $uv-error; |
| | | } |
| | | .uv-calendar-item--disable { |
| | | background-color: rgba(249, 249, 249, $uv-opacity-disabled); |
| | | color: $uv-text-color-disable; |
| | | } |
| | | .uv-calendar-item--isDay-text { |
| | | color: $uv-primary; |
| | | } |
| | | .uv-calendar-item--isDay { |
| | | background-color: $uv-primary; |
| | | color: #fff; |
| | | } |
| | | .uv-calendar-item--checked { |
| | | background-color: $uv-primary; |
| | | color: #fff; |
| | | border-radius: 4px; |
| | | } |
| | | // .uv-calendar-item--range { |
| | | // background-color: $uv-primary; |
| | | // color: #fff; |
| | | // } |
| | | .uv-calendar-item--before-checked { |
| | | color: #fff; |
| | | } |
| | | .uv-calendar-item--after-checked { |
| | | color: #fff; |
| | | } |
| | | .uv-calendar-item--multiple { |
| | | background-color: $uv-primary; |
| | | color: #fff; |
| | | } |
| | | </style> |
| New file |
| | |
| | | /** |
| | | * @1900-2100区间内的公历、农历互转 |
| | | * @charset UTF-8 |
| | | * @github https://github.com/jjonline/calendar.js |
| | | * @Author Jea杨(JJonline@JJonline.Cn) |
| | | * @Time 2014-7-21 |
| | | * @Time 2016-8-13 Fixed 2033hex、Attribution Annals |
| | | * @Time 2016-9-25 Fixed lunar LeapMonth Param Bug |
| | | * @Time 2017-7-24 Fixed use getTerm Func Param Error.use solar year,NOT lunar year |
| | | * @Version 1.0.3 |
| | | * @公历转农历:calendar.solar2lunar(1987,11,01); //[you can ignore params of prefix 0] |
| | | * @农历转公历:calendar.lunar2solar(1987,09,10); //[you can ignore params of prefix 0] |
| | | */ |
| | | /* eslint-disable */ |
| | | var calendar = { |
| | | |
| | | /** |
| | | * 农历1900-2100的润大小信息表 |
| | | * @Array Of Property |
| | | * @return Hex |
| | | */ |
| | | lunarInfo: [0x04bd8, 0x04ae0, 0x0a570, 0x054d5, 0x0d260, 0x0d950, 0x16554, 0x056a0, 0x09ad0, 0x055d2, // 1900-1909 |
| | | 0x04ae0, 0x0a5b6, 0x0a4d0, 0x0d250, 0x1d255, 0x0b540, 0x0d6a0, 0x0ada2, 0x095b0, 0x14977, // 1910-1919 |
| | | 0x04970, 0x0a4b0, 0x0b4b5, 0x06a50, 0x06d40, 0x1ab54, 0x02b60, 0x09570, 0x052f2, 0x04970, // 1920-1929 |
| | | 0x06566, 0x0d4a0, 0x0ea50, 0x06e95, 0x05ad0, 0x02b60, 0x186e3, 0x092e0, 0x1c8d7, 0x0c950, // 1930-1939 |
| | | 0x0d4a0, 0x1d8a6, 0x0b550, 0x056a0, 0x1a5b4, 0x025d0, 0x092d0, 0x0d2b2, 0x0a950, 0x0b557, // 1940-1949 |
| | | 0x06ca0, 0x0b550, 0x15355, 0x04da0, 0x0a5b0, 0x14573, 0x052b0, 0x0a9a8, 0x0e950, 0x06aa0, // 1950-1959 |
| | | 0x0aea6, 0x0ab50, 0x04b60, 0x0aae4, 0x0a570, 0x05260, 0x0f263, 0x0d950, 0x05b57, 0x056a0, // 1960-1969 |
| | | 0x096d0, 0x04dd5, 0x04ad0, 0x0a4d0, 0x0d4d4, 0x0d250, 0x0d558, 0x0b540, 0x0b6a0, 0x195a6, // 1970-1979 |
| | | 0x095b0, 0x049b0, 0x0a974, 0x0a4b0, 0x0b27a, 0x06a50, 0x06d40, 0x0af46, 0x0ab60, 0x09570, // 1980-1989 |
| | | 0x04af5, 0x04970, 0x064b0, 0x074a3, 0x0ea50, 0x06b58, 0x05ac0, 0x0ab60, 0x096d5, 0x092e0, // 1990-1999 |
| | | 0x0c960, 0x0d954, 0x0d4a0, 0x0da50, 0x07552, 0x056a0, 0x0abb7, 0x025d0, 0x092d0, 0x0cab5, // 2000-2009 |
| | | 0x0a950, 0x0b4a0, 0x0baa4, 0x0ad50, 0x055d9, 0x04ba0, 0x0a5b0, 0x15176, 0x052b0, 0x0a930, // 2010-2019 |
| | | 0x07954, 0x06aa0, 0x0ad50, 0x05b52, 0x04b60, 0x0a6e6, 0x0a4e0, 0x0d260, 0x0ea65, 0x0d530, // 2020-2029 |
| | | 0x05aa0, 0x076a3, 0x096d0, 0x04afb, 0x04ad0, 0x0a4d0, 0x1d0b6, 0x0d250, 0x0d520, 0x0dd45, // 2030-2039 |
| | | 0x0b5a0, 0x056d0, 0x055b2, 0x049b0, 0x0a577, 0x0a4b0, 0x0aa50, 0x1b255, 0x06d20, 0x0ada0, // 2040-2049 |
| | | /** Add By JJonline@JJonline.Cn**/ |
| | | 0x14b63, 0x09370, 0x049f8, 0x04970, 0x064b0, 0x168a6, 0x0ea50, 0x06b20, 0x1a6c4, 0x0aae0, // 2050-2059 |
| | | 0x0a2e0, 0x0d2e3, 0x0c960, 0x0d557, 0x0d4a0, 0x0da50, 0x05d55, 0x056a0, 0x0a6d0, 0x055d4, // 2060-2069 |
| | | 0x052d0, 0x0a9b8, 0x0a950, 0x0b4a0, 0x0b6a6, 0x0ad50, 0x055a0, 0x0aba4, 0x0a5b0, 0x052b0, // 2070-2079 |
| | | 0x0b273, 0x06930, 0x07337, 0x06aa0, 0x0ad50, 0x14b55, 0x04b60, 0x0a570, 0x054e4, 0x0d160, // 2080-2089 |
| | | 0x0e968, 0x0d520, 0x0daa0, 0x16aa6, 0x056d0, 0x04ae0, 0x0a9d4, 0x0a2d0, 0x0d150, 0x0f252, // 2090-2099 |
| | | 0x0d520], // 2100 |
| | | |
| | | /** |
| | | * 公历每个月份的天数普通表 |
| | | * @Array Of Property |
| | | * @return Number |
| | | */ |
| | | solarMonth: [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31], |
| | | |
| | | /** |
| | | * 天干地支之天干速查表 |
| | | * @Array Of Property trans["甲","乙","丙","丁","戊","己","庚","辛","壬","癸"] |
| | | * @return Cn string |
| | | */ |
| | | Gan: ['\u7532', '\u4e59', '\u4e19', '\u4e01', '\u620a', '\u5df1', '\u5e9a', '\u8f9b', '\u58ec', '\u7678'], |
| | | |
| | | /** |
| | | * 天干地支之地支速查表 |
| | | * @Array Of Property |
| | | * @trans["子","丑","寅","卯","辰","巳","午","未","申","酉","戌","亥"] |
| | | * @return Cn string |
| | | */ |
| | | Zhi: ['\u5b50', '\u4e11', '\u5bc5', '\u536f', '\u8fb0', '\u5df3', '\u5348', '\u672a', '\u7533', '\u9149', '\u620c', '\u4ea5'], |
| | | |
| | | /** |
| | | * 天干地支之地支速查表<=>生肖 |
| | | * @Array Of Property |
| | | * @trans["鼠","牛","虎","兔","龙","蛇","马","羊","猴","鸡","狗","猪"] |
| | | * @return Cn string |
| | | */ |
| | | Animals: ['\u9f20', '\u725b', '\u864e', '\u5154', '\u9f99', '\u86c7', '\u9a6c', '\u7f8a', '\u7334', '\u9e21', '\u72d7', '\u732a'], |
| | | |
| | | /** |
| | | * 24节气速查表 |
| | | * @Array Of Property |
| | | * @trans["小寒","大寒","立春","雨水","惊蛰","春分","清明","谷雨","立夏","小满","芒种","夏至","小暑","大暑","立秋","处暑","白露","秋分","寒露","霜降","立冬","小雪","大雪","冬至"] |
| | | * @return Cn string |
| | | */ |
| | | solarTerm: ['\u5c0f\u5bd2', '\u5927\u5bd2', '\u7acb\u6625', '\u96e8\u6c34', '\u60ca\u86f0', '\u6625\u5206', '\u6e05\u660e', '\u8c37\u96e8', '\u7acb\u590f', '\u5c0f\u6ee1', '\u8292\u79cd', '\u590f\u81f3', '\u5c0f\u6691', '\u5927\u6691', '\u7acb\u79cb', '\u5904\u6691', '\u767d\u9732', '\u79cb\u5206', '\u5bd2\u9732', '\u971c\u964d', '\u7acb\u51ac', '\u5c0f\u96ea', '\u5927\u96ea', '\u51ac\u81f3'], |
| | | |
| | | /** |
| | | * 1900-2100各年的24节气日期速查表 |
| | | * @Array Of Property |
| | | * @return 0x string For splice |
| | | */ |
| | | sTermInfo: ['9778397bd097c36b0b6fc9274c91aa', '97b6b97bd19801ec9210c965cc920e', '97bcf97c3598082c95f8c965cc920f', |
| | | '97bd0b06bdb0722c965ce1cfcc920f', 'b027097bd097c36b0b6fc9274c91aa', '97b6b97bd19801ec9210c965cc920e', |
| | | '97bcf97c359801ec95f8c965cc920f', '97bd0b06bdb0722c965ce1cfcc920f', 'b027097bd097c36b0b6fc9274c91aa', |
| | | '97b6b97bd19801ec9210c965cc920e', '97bcf97c359801ec95f8c965cc920f', '97bd0b06bdb0722c965ce1cfcc920f', |
| | | 'b027097bd097c36b0b6fc9274c91aa', '9778397bd19801ec9210c965cc920e', '97b6b97bd19801ec95f8c965cc920f', |
| | | '97bd09801d98082c95f8e1cfcc920f', '97bd097bd097c36b0b6fc9210c8dc2', '9778397bd197c36c9210c9274c91aa', |
| | | '97b6b97bd19801ec95f8c965cc920e', '97bd09801d98082c95f8e1cfcc920f', '97bd097bd097c36b0b6fc9210c8dc2', |
| | | '9778397bd097c36c9210c9274c91aa', '97b6b97bd19801ec95f8c965cc920e', '97bcf97c3598082c95f8e1cfcc920f', |
| | | '97bd097bd097c36b0b6fc9210c8dc2', '9778397bd097c36c9210c9274c91aa', '97b6b97bd19801ec9210c965cc920e', |
| | | '97bcf97c3598082c95f8c965cc920f', '97bd097bd097c35b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa', |
| | | '97b6b97bd19801ec9210c965cc920e', '97bcf97c3598082c95f8c965cc920f', '97bd097bd097c35b0b6fc920fb0722', |
| | | '9778397bd097c36b0b6fc9274c91aa', '97b6b97bd19801ec9210c965cc920e', '97bcf97c359801ec95f8c965cc920f', |
| | | '97bd097bd097c35b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa', '97b6b97bd19801ec9210c965cc920e', |
| | | '97bcf97c359801ec95f8c965cc920f', '97bd097bd097c35b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa', |
| | | '97b6b97bd19801ec9210c965cc920e', '97bcf97c359801ec95f8c965cc920f', '97bd097bd07f595b0b6fc920fb0722', |
| | | '9778397bd097c36b0b6fc9210c8dc2', '9778397bd19801ec9210c9274c920e', '97b6b97bd19801ec95f8c965cc920f', |
| | | '97bd07f5307f595b0b0bc920fb0722', '7f0e397bd097c36b0b6fc9210c8dc2', '9778397bd097c36c9210c9274c920e', |
| | | '97b6b97bd19801ec95f8c965cc920f', '97bd07f5307f595b0b0bc920fb0722', '7f0e397bd097c36b0b6fc9210c8dc2', |
| | | '9778397bd097c36c9210c9274c91aa', '97b6b97bd19801ec9210c965cc920e', '97bd07f1487f595b0b0bc920fb0722', |
| | | '7f0e397bd097c36b0b6fc9210c8dc2', '9778397bd097c36b0b6fc9274c91aa', '97b6b97bd19801ec9210c965cc920e', |
| | | '97bcf7f1487f595b0b0bb0b6fb0722', '7f0e397bd097c35b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa', |
| | | '97b6b97bd19801ec9210c965cc920e', '97bcf7f1487f595b0b0bb0b6fb0722', '7f0e397bd097c35b0b6fc920fb0722', |
| | | '9778397bd097c36b0b6fc9274c91aa', '97b6b97bd19801ec9210c965cc920e', '97bcf7f1487f531b0b0bb0b6fb0722', |
| | | '7f0e397bd097c35b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa', '97b6b97bd19801ec9210c965cc920e', |
| | | '97bcf7f1487f531b0b0bb0b6fb0722', '7f0e397bd07f595b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa', |
| | | '97b6b97bd19801ec9210c9274c920e', '97bcf7f0e47f531b0b0bb0b6fb0722', '7f0e397bd07f595b0b0bc920fb0722', |
| | | '9778397bd097c36b0b6fc9210c91aa', '97b6b97bd197c36c9210c9274c920e', '97bcf7f0e47f531b0b0bb0b6fb0722', |
| | | '7f0e397bd07f595b0b0bc920fb0722', '9778397bd097c36b0b6fc9210c8dc2', '9778397bd097c36c9210c9274c920e', |
| | | '97b6b7f0e47f531b0723b0b6fb0722', '7f0e37f5307f595b0b0bc920fb0722', '7f0e397bd097c36b0b6fc9210c8dc2', |
| | | '9778397bd097c36b0b70c9274c91aa', '97b6b7f0e47f531b0723b0b6fb0721', '7f0e37f1487f595b0b0bb0b6fb0722', |
| | | '7f0e397bd097c35b0b6fc9210c8dc2', '9778397bd097c36b0b6fc9274c91aa', '97b6b7f0e47f531b0723b0b6fb0721', |
| | | '7f0e27f1487f595b0b0bb0b6fb0722', '7f0e397bd097c35b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa', |
| | | '97b6b7f0e47f531b0723b0b6fb0721', '7f0e27f1487f531b0b0bb0b6fb0722', '7f0e397bd097c35b0b6fc920fb0722', |
| | | '9778397bd097c36b0b6fc9274c91aa', '97b6b7f0e47f531b0723b0b6fb0721', '7f0e27f1487f531b0b0bb0b6fb0722', |
| | | '7f0e397bd097c35b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa', '97b6b7f0e47f531b0723b0b6fb0721', |
| | | '7f0e27f1487f531b0b0bb0b6fb0722', '7f0e397bd07f595b0b0bc920fb0722', '9778397bd097c36b0b6fc9274c91aa', |
| | | '97b6b7f0e47f531b0723b0787b0721', '7f0e27f0e47f531b0b0bb0b6fb0722', '7f0e397bd07f595b0b0bc920fb0722', |
| | | '9778397bd097c36b0b6fc9210c91aa', '97b6b7f0e47f149b0723b0787b0721', '7f0e27f0e47f531b0723b0b6fb0722', |
| | | '7f0e397bd07f595b0b0bc920fb0722', '9778397bd097c36b0b6fc9210c8dc2', '977837f0e37f149b0723b0787b0721', |
| | | '7f07e7f0e47f531b0723b0b6fb0722', '7f0e37f5307f595b0b0bc920fb0722', '7f0e397bd097c35b0b6fc9210c8dc2', |
| | | '977837f0e37f14998082b0787b0721', '7f07e7f0e47f531b0723b0b6fb0721', '7f0e37f1487f595b0b0bb0b6fb0722', |
| | | '7f0e397bd097c35b0b6fc9210c8dc2', '977837f0e37f14998082b0787b06bd', '7f07e7f0e47f531b0723b0b6fb0721', |
| | | '7f0e27f1487f531b0b0bb0b6fb0722', '7f0e397bd097c35b0b6fc920fb0722', '977837f0e37f14998082b0787b06bd', |
| | | '7f07e7f0e47f531b0723b0b6fb0721', '7f0e27f1487f531b0b0bb0b6fb0722', '7f0e397bd097c35b0b6fc920fb0722', |
| | | '977837f0e37f14998082b0787b06bd', '7f07e7f0e47f531b0723b0b6fb0721', '7f0e27f1487f531b0b0bb0b6fb0722', |
| | | '7f0e397bd07f595b0b0bc920fb0722', '977837f0e37f14998082b0787b06bd', '7f07e7f0e47f531b0723b0b6fb0721', |
| | | '7f0e27f1487f531b0b0bb0b6fb0722', '7f0e397bd07f595b0b0bc920fb0722', '977837f0e37f14998082b0787b06bd', |
| | | '7f07e7f0e47f149b0723b0787b0721', '7f0e27f0e47f531b0b0bb0b6fb0722', '7f0e397bd07f595b0b0bc920fb0722', |
| | | '977837f0e37f14998082b0723b06bd', '7f07e7f0e37f149b0723b0787b0721', '7f0e27f0e47f531b0723b0b6fb0722', |
| | | '7f0e397bd07f595b0b0bc920fb0722', '977837f0e37f14898082b0723b02d5', '7ec967f0e37f14998082b0787b0721', |
| | | '7f07e7f0e47f531b0723b0b6fb0722', '7f0e37f1487f595b0b0bb0b6fb0722', '7f0e37f0e37f14898082b0723b02d5', |
| | | '7ec967f0e37f14998082b0787b0721', '7f07e7f0e47f531b0723b0b6fb0722', '7f0e37f1487f531b0b0bb0b6fb0722', |
| | | '7f0e37f0e37f14898082b0723b02d5', '7ec967f0e37f14998082b0787b06bd', '7f07e7f0e47f531b0723b0b6fb0721', |
| | | '7f0e37f1487f531b0b0bb0b6fb0722', '7f0e37f0e37f14898082b072297c35', '7ec967f0e37f14998082b0787b06bd', |
| | | '7f07e7f0e47f531b0723b0b6fb0721', '7f0e27f1487f531b0b0bb0b6fb0722', '7f0e37f0e37f14898082b072297c35', |
| | | '7ec967f0e37f14998082b0787b06bd', '7f07e7f0e47f531b0723b0b6fb0721', '7f0e27f1487f531b0b0bb0b6fb0722', |
| | | '7f0e37f0e366aa89801eb072297c35', '7ec967f0e37f14998082b0787b06bd', '7f07e7f0e47f149b0723b0787b0721', |
| | | '7f0e27f1487f531b0b0bb0b6fb0722', '7f0e37f0e366aa89801eb072297c35', '7ec967f0e37f14998082b0723b06bd', |
| | | '7f07e7f0e47f149b0723b0787b0721', '7f0e27f0e47f531b0723b0b6fb0722', '7f0e37f0e366aa89801eb072297c35', |
| | | '7ec967f0e37f14998082b0723b06bd', '7f07e7f0e37f14998083b0787b0721', '7f0e27f0e47f531b0723b0b6fb0722', |
| | | '7f0e37f0e366aa89801eb072297c35', '7ec967f0e37f14898082b0723b02d5', '7f07e7f0e37f14998082b0787b0721', |
| | | '7f07e7f0e47f531b0723b0b6fb0722', '7f0e36665b66aa89801e9808297c35', '665f67f0e37f14898082b0723b02d5', |
| | | '7ec967f0e37f14998082b0787b0721', '7f07e7f0e47f531b0723b0b6fb0722', '7f0e36665b66a449801e9808297c35', |
| | | '665f67f0e37f14898082b0723b02d5', '7ec967f0e37f14998082b0787b06bd', '7f07e7f0e47f531b0723b0b6fb0721', |
| | | '7f0e36665b66a449801e9808297c35', '665f67f0e37f14898082b072297c35', '7ec967f0e37f14998082b0787b06bd', |
| | | '7f07e7f0e47f531b0723b0b6fb0721', '7f0e26665b66a449801e9808297c35', '665f67f0e37f1489801eb072297c35', |
| | | '7ec967f0e37f14998082b0787b06bd', '7f07e7f0e47f531b0723b0b6fb0721', '7f0e27f1487f531b0b0bb0b6fb0722'], |
| | | |
| | | /** |
| | | * 数字转中文速查表 |
| | | * @Array Of Property |
| | | * @trans ['日','一','二','三','四','五','六','七','八','九','十'] |
| | | * @return Cn string |
| | | */ |
| | | nStr1: ['\u65e5', '\u4e00', '\u4e8c', '\u4e09', '\u56db', '\u4e94', '\u516d', '\u4e03', '\u516b', '\u4e5d', '\u5341'], |
| | | |
| | | /** |
| | | * 日期转农历称呼速查表 |
| | | * @Array Of Property |
| | | * @trans ['初','十','廿','卅'] |
| | | * @return Cn string |
| | | */ |
| | | nStr2: ['\u521d', '\u5341', '\u5eff', '\u5345'], |
| | | |
| | | /** |
| | | * 月份转农历称呼速查表 |
| | | * @Array Of Property |
| | | * @trans ['正','一','二','三','四','五','六','七','八','九','十','冬','腊'] |
| | | * @return Cn string |
| | | */ |
| | | nStr3: ['\u6b63', '\u4e8c', '\u4e09', '\u56db', '\u4e94', '\u516d', '\u4e03', '\u516b', '\u4e5d', '\u5341', '\u51ac', '\u814a'], |
| | | |
| | | /** |
| | | * 返回农历y年一整年的总天数 |
| | | * @param lunar Year |
| | | * @return Number |
| | | * @eg:var count = calendar.lYearDays(1987) ;//count=387 |
| | | */ |
| | | lYearDays: function (y) { |
| | | var i; var sum = 348 |
| | | for (i = 0x8000; i > 0x8; i >>= 1) { sum += (this.lunarInfo[y - 1900] & i) ? 1 : 0 } |
| | | return (sum + this.leapDays(y)) |
| | | }, |
| | | |
| | | /** |
| | | * 返回农历y年闰月是哪个月;若y年没有闰月 则返回0 |
| | | * @param lunar Year |
| | | * @return Number (0-12) |
| | | * @eg:var leapMonth = calendar.leapMonth(1987) ;//leapMonth=6 |
| | | */ |
| | | leapMonth: function (y) { // 闰字编码 \u95f0 |
| | | return (this.lunarInfo[y - 1900] & 0xf) |
| | | }, |
| | | |
| | | /** |
| | | * 返回农历y年闰月的天数 若该年没有闰月则返回0 |
| | | * @param lunar Year |
| | | * @return Number (0、29、30) |
| | | * @eg:var leapMonthDay = calendar.leapDays(1987) ;//leapMonthDay=29 |
| | | */ |
| | | leapDays: function (y) { |
| | | if (this.leapMonth(y)) { |
| | | return ((this.lunarInfo[y - 1900] & 0x10000) ? 30 : 29) |
| | | } |
| | | return (0) |
| | | }, |
| | | |
| | | /** |
| | | * 返回农历y年m月(非闰月)的总天数,计算m为闰月时的天数请使用leapDays方法 |
| | | * @param lunar Year |
| | | * @return Number (-1、29、30) |
| | | * @eg:var MonthDay = calendar.monthDays(1987,9) ;//MonthDay=29 |
| | | */ |
| | | monthDays: function (y, m) { |
| | | if (m > 12 || m < 1) { return -1 }// 月份参数从1至12,参数错误返回-1 |
| | | return ((this.lunarInfo[y - 1900] & (0x10000 >> m)) ? 30 : 29) |
| | | }, |
| | | |
| | | /** |
| | | * 返回公历(!)y年m月的天数 |
| | | * @param solar Year |
| | | * @return Number (-1、28、29、30、31) |
| | | * @eg:var solarMonthDay = calendar.leapDays(1987) ;//solarMonthDay=30 |
| | | */ |
| | | solarDays: function (y, m) { |
| | | if (m > 12 || m < 1) { return -1 } // 若参数错误 返回-1 |
| | | var ms = m - 1 |
| | | if (ms == 1) { // 2月份的闰平规律测算后确认返回28或29 |
| | | return (((y % 4 == 0) && (y % 100 != 0) || (y % 400 == 0)) ? 29 : 28) |
| | | } else { |
| | | return (this.solarMonth[ms]) |
| | | } |
| | | }, |
| | | |
| | | /** |
| | | * 农历年份转换为干支纪年 |
| | | * @param lYear 农历年的年份数 |
| | | * @return Cn string |
| | | */ |
| | | toGanZhiYear: function (lYear) { |
| | | var ganKey = (lYear - 3) % 10 |
| | | var zhiKey = (lYear - 3) % 12 |
| | | if (ganKey == 0) ganKey = 10// 如果余数为0则为最后一个天干 |
| | | if (zhiKey == 0) zhiKey = 12// 如果余数为0则为最后一个地支 |
| | | return this.Gan[ganKey - 1] + this.Zhi[zhiKey - 1] |
| | | }, |
| | | |
| | | /** |
| | | * 公历月、日判断所属星座 |
| | | * @param cMonth [description] |
| | | * @param cDay [description] |
| | | * @return Cn string |
| | | */ |
| | | toAstro: function (cMonth, cDay) { |
| | | var s = '\u9b54\u7faf\u6c34\u74f6\u53cc\u9c7c\u767d\u7f8a\u91d1\u725b\u53cc\u5b50\u5de8\u87f9\u72ee\u5b50\u5904\u5973\u5929\u79e4\u5929\u874e\u5c04\u624b\u9b54\u7faf' |
| | | var arr = [20, 19, 21, 21, 21, 22, 23, 23, 23, 23, 22, 22] |
| | | return s.substr(cMonth * 2 - (cDay < arr[cMonth - 1] ? 2 : 0), 2) + '\u5ea7'// 座 |
| | | }, |
| | | |
| | | /** |
| | | * 传入offset偏移量返回干支 |
| | | * @param offset 相对甲子的偏移量 |
| | | * @return Cn string |
| | | */ |
| | | toGanZhi: function (offset) { |
| | | return this.Gan[offset % 10] + this.Zhi[offset % 12] |
| | | }, |
| | | |
| | | /** |
| | | * 传入公历(!)y年获得该年第n个节气的公历日期 |
| | | * @param y公历年(1900-2100);n二十四节气中的第几个节气(1~24);从n=1(小寒)算起 |
| | | * @return day Number |
| | | * @eg:var _24 = calendar.getTerm(1987,3) ;//_24=4;意即1987年2月4日立春 |
| | | */ |
| | | getTerm: function (y, n) { |
| | | if (y < 1900 || y > 2100) { return -1 } |
| | | if (n < 1 || n > 24) { return -1 } |
| | | var _table = this.sTermInfo[y - 1900] |
| | | var _info = [ |
| | | parseInt('0x' + _table.substr(0, 5)).toString(), |
| | | parseInt('0x' + _table.substr(5, 5)).toString(), |
| | | parseInt('0x' + _table.substr(10, 5)).toString(), |
| | | parseInt('0x' + _table.substr(15, 5)).toString(), |
| | | parseInt('0x' + _table.substr(20, 5)).toString(), |
| | | parseInt('0x' + _table.substr(25, 5)).toString() |
| | | ] |
| | | var _calday = [ |
| | | _info[0].substr(0, 1), |
| | | _info[0].substr(1, 2), |
| | | _info[0].substr(3, 1), |
| | | _info[0].substr(4, 2), |
| | | |
| | | _info[1].substr(0, 1), |
| | | _info[1].substr(1, 2), |
| | | _info[1].substr(3, 1), |
| | | _info[1].substr(4, 2), |
| | | |
| | | _info[2].substr(0, 1), |
| | | _info[2].substr(1, 2), |
| | | _info[2].substr(3, 1), |
| | | _info[2].substr(4, 2), |
| | | |
| | | _info[3].substr(0, 1), |
| | | _info[3].substr(1, 2), |
| | | _info[3].substr(3, 1), |
| | | _info[3].substr(4, 2), |
| | | |
| | | _info[4].substr(0, 1), |
| | | _info[4].substr(1, 2), |
| | | _info[4].substr(3, 1), |
| | | _info[4].substr(4, 2), |
| | | |
| | | _info[5].substr(0, 1), |
| | | _info[5].substr(1, 2), |
| | | _info[5].substr(3, 1), |
| | | _info[5].substr(4, 2) |
| | | ] |
| | | return parseInt(_calday[n - 1]) |
| | | }, |
| | | |
| | | /** |
| | | * 传入农历数字月份返回汉语通俗表示法 |
| | | * @param lunar month |
| | | * @return Cn string |
| | | * @eg:var cnMonth = calendar.toChinaMonth(12) ;//cnMonth='腊月' |
| | | */ |
| | | toChinaMonth: function (m) { // 月 => \u6708 |
| | | if (m > 12 || m < 1) { return -1 } // 若参数错误 返回-1 |
| | | var s = this.nStr3[m - 1] |
| | | s += '\u6708'// 加上月字 |
| | | return s |
| | | }, |
| | | |
| | | /** |
| | | * 传入农历日期数字返回汉字表示法 |
| | | * @param lunar day |
| | | * @return Cn string |
| | | * @eg:var cnDay = calendar.toChinaDay(21) ;//cnMonth='廿一' |
| | | */ |
| | | toChinaDay: function (d) { // 日 => \u65e5 |
| | | var s |
| | | switch (d) { |
| | | case 10: |
| | | s = '\u521d\u5341'; break |
| | | case 20: |
| | | s = '\u4e8c\u5341'; break |
| | | break |
| | | case 30: |
| | | s = '\u4e09\u5341'; break |
| | | break |
| | | default : |
| | | s = this.nStr2[Math.floor(d / 10)] |
| | | s += this.nStr1[d % 10] |
| | | } |
| | | return (s) |
| | | }, |
| | | |
| | | /** |
| | | * 年份转生肖[!仅能大致转换] => 精确划分生肖分界线是“立春” |
| | | * @param y year |
| | | * @return Cn string |
| | | * @eg:var animal = calendar.getAnimal(1987) ;//animal='兔' |
| | | */ |
| | | getAnimal: function (y) { |
| | | return this.Animals[(y - 4) % 12] |
| | | }, |
| | | |
| | | /** |
| | | * 传入阳历年月日获得详细的公历、农历object信息 <=>JSON |
| | | * @param y solar year |
| | | * @param m solar month |
| | | * @param d solar day |
| | | * @return JSON object |
| | | * @eg:console.log(calendar.solar2lunar(1987,11,01)); |
| | | */ |
| | | solar2lunar: function (y, m, d) { // 参数区间1900.1.31~2100.12.31 |
| | | // 年份限定、上限 |
| | | if (y < 1900 || y > 2100) { |
| | | return -1// undefined转换为数字变为NaN |
| | | } |
| | | // 公历传参最下限 |
| | | if (y == 1900 && m == 1 && d < 31) { |
| | | return -1 |
| | | } |
| | | // 未传参 获得当天 |
| | | if (!y) { |
| | | var objDate = new Date() |
| | | } else { |
| | | var objDate = new Date(y, parseInt(m) - 1, d) |
| | | } |
| | | var i; var leap = 0; var temp = 0 |
| | | // 修正ymd参数 |
| | | var y = objDate.getFullYear() |
| | | var m = objDate.getMonth() + 1 |
| | | var d = objDate.getDate() |
| | | var offset = (Date.UTC(objDate.getFullYear(), objDate.getMonth(), objDate.getDate()) - Date.UTC(1900, 0, 31)) / 86400000 |
| | | for (i = 1900; i < 2101 && offset > 0; i++) { |
| | | temp = this.lYearDays(i) |
| | | offset -= temp |
| | | } |
| | | if (offset < 0) { |
| | | offset += temp; i-- |
| | | } |
| | | |
| | | // 是否今天 |
| | | var isTodayObj = new Date() |
| | | var isToday = false |
| | | if (isTodayObj.getFullYear() == y && isTodayObj.getMonth() + 1 == m && isTodayObj.getDate() == d) { |
| | | isToday = true |
| | | } |
| | | // 星期几 |
| | | var nWeek = objDate.getDay() |
| | | var cWeek = this.nStr1[nWeek] |
| | | // 数字表示周几顺应天朝周一开始的惯例 |
| | | if (nWeek == 0) { |
| | | nWeek = 7 |
| | | } |
| | | // 农历年 |
| | | var year = i |
| | | var leap = this.leapMonth(i) // 闰哪个月 |
| | | var isLeap = false |
| | | |
| | | // 效验闰月 |
| | | for (i = 1; i < 13 && offset > 0; i++) { |
| | | // 闰月 |
| | | if (leap > 0 && i == (leap + 1) && isLeap == false) { |
| | | --i |
| | | isLeap = true; temp = this.leapDays(year) // 计算农历闰月天数 |
| | | } else { |
| | | temp = this.monthDays(year, i)// 计算农历普通月天数 |
| | | } |
| | | // 解除闰月 |
| | | if (isLeap == true && i == (leap + 1)) { isLeap = false } |
| | | offset -= temp |
| | | } |
| | | // 闰月导致数组下标重叠取反 |
| | | if (offset == 0 && leap > 0 && i == leap + 1) { |
| | | if (isLeap) { |
| | | isLeap = false |
| | | } else { |
| | | isLeap = true; --i |
| | | } |
| | | } |
| | | if (offset < 0) { |
| | | offset += temp; --i |
| | | } |
| | | // 农历月 |
| | | var month = i |
| | | // 农历日 |
| | | var day = offset + 1 |
| | | // 天干地支处理 |
| | | var sm = m - 1 |
| | | var gzY = this.toGanZhiYear(year) |
| | | |
| | | // 当月的两个节气 |
| | | // bugfix-2017-7-24 11:03:38 use lunar Year Param `y` Not `year` |
| | | var firstNode = this.getTerm(y, (m * 2 - 1))// 返回当月「节」为几日开始 |
| | | var secondNode = this.getTerm(y, (m * 2))// 返回当月「节」为几日开始 |
| | | |
| | | // 依据12节气修正干支月 |
| | | var gzM = this.toGanZhi((y - 1900) * 12 + m + 11) |
| | | if (d >= firstNode) { |
| | | gzM = this.toGanZhi((y - 1900) * 12 + m + 12) |
| | | } |
| | | |
| | | // 传入的日期的节气与否 |
| | | var isTerm = false |
| | | var Term = null |
| | | if (firstNode == d) { |
| | | isTerm = true |
| | | Term = this.solarTerm[m * 2 - 2] |
| | | } |
| | | if (secondNode == d) { |
| | | isTerm = true |
| | | Term = this.solarTerm[m * 2 - 1] |
| | | } |
| | | // 日柱 当月一日与 1900/1/1 相差天数 |
| | | var dayCyclical = Date.UTC(y, sm, 1, 0, 0, 0, 0) / 86400000 + 25567 + 10 |
| | | var gzD = this.toGanZhi(dayCyclical + d - 1) |
| | | // 该日期所属的星座 |
| | | var astro = this.toAstro(m, d) |
| | | |
| | | return { 'lYear': year, 'lMonth': month, 'lDay': day, 'Animal': this.getAnimal(year), 'IMonthCn': (isLeap ? '\u95f0' : '') + this.toChinaMonth(month), 'IDayCn': this.toChinaDay(day), 'cYear': y, 'cMonth': m, 'cDay': d, 'gzYear': gzY, 'gzMonth': gzM, 'gzDay': gzD, 'isToday': isToday, 'isLeap': isLeap, 'nWeek': nWeek, 'ncWeek': '\u661f\u671f' + cWeek, 'isTerm': isTerm, 'Term': Term, 'astro': astro } |
| | | }, |
| | | |
| | | /** |
| | | * 传入农历年月日以及传入的月份是否闰月获得详细的公历、农历object信息 <=>JSON |
| | | * @param y lunar year |
| | | * @param m lunar month |
| | | * @param d lunar day |
| | | * @param isLeapMonth lunar month is leap or not.[如果是农历闰月第四个参数赋值true即可] |
| | | * @return JSON object |
| | | * @eg:console.log(calendar.lunar2solar(1987,9,10)); |
| | | */ |
| | | lunar2solar: function (y, m, d, isLeapMonth) { // 参数区间1900.1.31~2100.12.1 |
| | | var isLeapMonth = !!isLeapMonth |
| | | var leapOffset = 0 |
| | | var leapMonth = this.leapMonth(y) |
| | | var leapDay = this.leapDays(y) |
| | | if (isLeapMonth && (leapMonth != m)) { return -1 }// 传参要求计算该闰月公历 但该年得出的闰月与传参的月份并不同 |
| | | if (y == 2100 && m == 12 && d > 1 || y == 1900 && m == 1 && d < 31) { return -1 }// 超出了最大极限值 |
| | | var day = this.monthDays(y, m) |
| | | var _day = day |
| | | // bugFix 2016-9-25 |
| | | // if month is leap, _day use leapDays method |
| | | if (isLeapMonth) { |
| | | _day = this.leapDays(y, m) |
| | | } |
| | | if (y < 1900 || y > 2100 || d > _day) { return -1 }// 参数合法性效验 |
| | | |
| | | // 计算农历的时间差 |
| | | var offset = 0 |
| | | for (var i = 1900; i < y; i++) { |
| | | offset += this.lYearDays(i) |
| | | } |
| | | var leap = 0; var isAdd = false |
| | | for (var i = 1; i < m; i++) { |
| | | leap = this.leapMonth(y) |
| | | if (!isAdd) { // 处理闰月 |
| | | if (leap <= i && leap > 0) { |
| | | offset += this.leapDays(y); isAdd = true |
| | | } |
| | | } |
| | | offset += this.monthDays(y, i) |
| | | } |
| | | // 转换闰月农历 需补充该年闰月的前一个月的时差 |
| | | if (isLeapMonth) { offset += day } |
| | | // 1900年农历正月一日的公历时间为1900年1月30日0时0分0秒(该时间也是本农历的最开始起始点) |
| | | var stmap = Date.UTC(1900, 1, 30, 0, 0, 0) |
| | | var calObj = new Date((offset + d - 31) * 86400000 + stmap) |
| | | var cY = calObj.getUTCFullYear() |
| | | var cM = calObj.getUTCMonth() + 1 |
| | | var cD = calObj.getUTCDate() |
| | | |
| | | return this.solar2lunar(cY, cM, cD) |
| | | } |
| | | } |
| | | |
| | | export default calendar |
| New file |
| | |
| | | { |
| | | "uv-calender.ok": "ok", |
| | | "uv-calender.cancel": "cancel", |
| | | "uv-calender.today": "today", |
| | | "uv-calender.MON": "MON", |
| | | "uv-calender.TUE": "TUE", |
| | | "uv-calender.WED": "WED", |
| | | "uv-calender.THU": "THU", |
| | | "uv-calender.FRI": "FRI", |
| | | "uv-calender.SAT": "SAT", |
| | | "uv-calender.SUN": "SUN" |
| | | } |
| New file |
| | |
| | | import en from './en.json' |
| | | import zhHans from './zh-Hans.json' |
| | | import zhHant from './zh-Hant.json' |
| | | export default { |
| | | en, |
| | | 'zh-Hans': zhHans, |
| | | 'zh-Hant': zhHant |
| | | } |
| New file |
| | |
| | | { |
| | | "uv-calender.ok": "确定", |
| | | "uv-calender.cancel": "取消", |
| | | "uv-calender.today": "今日", |
| | | "uv-calender.SUN": "日", |
| | | "uv-calender.MON": "一", |
| | | "uv-calender.TUE": "二", |
| | | "uv-calender.WED": "三", |
| | | "uv-calender.THU": "四", |
| | | "uv-calender.FRI": "五", |
| | | "uv-calender.SAT": "六" |
| | | } |
| New file |
| | |
| | | { |
| | | "uv-calender.ok": "確定", |
| | | "uv-calender.cancel": "取消", |
| | | "uv-calender.today": "今日", |
| | | "uv-calender.SUN": "日", |
| | | "uv-calender.MON": "一", |
| | | "uv-calender.TUE": "二", |
| | | "uv-calender.WED": "三", |
| | | "uv-calender.THU": "四", |
| | | "uv-calender.FRI": "五", |
| | | "uv-calender.SAT": "六" |
| | | } |
| New file |
| | |
| | | import CALENDAR from './calendar.js' |
| | | class Calendar { |
| | | constructor({ |
| | | date, |
| | | selected, |
| | | startDate, |
| | | endDate, |
| | | range, |
| | | multiple, |
| | | allowSameDay |
| | | } = {}) { |
| | | // 当前日期 |
| | | this.date = this.getDate(new Date()) // 当前初入日期 |
| | | // 打点信息 |
| | | this.selected = selected || []; |
| | | // 范围开始 |
| | | this.startDate = startDate |
| | | // 范围结束 |
| | | this.endDate = endDate |
| | | this.range = range |
| | | this.multiple = multiple |
| | | this.allowSameDay = allowSameDay |
| | | // 多选状态 |
| | | this.cleanRangeStatus() |
| | | // 范围状态 |
| | | this.cleanMultipleStatus() |
| | | // 每周日期 |
| | | this.weeks = {} |
| | | // this._getWeek(this.date.fullDate) |
| | | } |
| | | /** |
| | | * 设置日期 |
| | | * @param {Object} date |
| | | */ |
| | | setDate(date, status) { |
| | | if (this.range && status == 'init') { |
| | | this.cleanRangeStatus(); |
| | | if (Array.isArray(date)) { |
| | | this.rangeStatus.before = date[0]; |
| | | this.rangeStatus.after = date.length > 1 ? date[date.length - 1] : ''; |
| | | if (this.rangeStatus.after && this.dateCompare(this.rangeStatus.before, this.rangeStatus.after)) { |
| | | this.rangeStatus.data = this.geDateAll(this.rangeStatus.before, this.rangeStatus.after) |
| | | } |
| | | this.selectDate = this.getDate(date[0]) |
| | | this._getWeek(this.selectDate.fullDate) |
| | | } else { |
| | | this.selectDate = this.getDate(date) |
| | | this.rangeStatus.before = this.selectDate.fullDate; |
| | | this._getWeek(this.selectDate.fullDate) |
| | | } |
| | | } else if (this.multiple && status == 'init') { |
| | | this.cleanMultipleStatus(); |
| | | if (Array.isArray(date)) { |
| | | this.multipleStatus.data = date; |
| | | this.selectDate = this.getDate(date[0]) |
| | | this._getWeek(this.selectDate.fullDate) |
| | | } else { |
| | | this.selectDate = this.getDate(date) |
| | | this.multipleStatus.data = [this.selectDate.fullDate]; |
| | | this._getWeek(this.selectDate.fullDate) |
| | | } |
| | | } else { |
| | | if (Array.isArray(date)) { |
| | | this.selectDate = this.getDate(date[0]) |
| | | this._getWeek(this.selectDate.fullDate) |
| | | } else { |
| | | this.selectDate = this.getDate(date) |
| | | this._getWeek(this.selectDate.fullDate) |
| | | } |
| | | } |
| | | } |
| | | /** |
| | | * 清理多选状态 |
| | | */ |
| | | cleanRangeStatus() { |
| | | this.rangeStatus = { |
| | | before: '', |
| | | after: '', |
| | | data: [] |
| | | } |
| | | } |
| | | /** |
| | | * 清理多选状态 |
| | | */ |
| | | cleanMultipleStatus() { |
| | | this.multipleStatus = { |
| | | data: [] |
| | | } |
| | | } |
| | | /** |
| | | * 重置开始日期 |
| | | */ |
| | | resetSatrtDate(startDate) { |
| | | // 范围开始 |
| | | this.startDate = startDate |
| | | } |
| | | /** |
| | | * 重置结束日期 |
| | | */ |
| | | resetEndDate(endDate) { |
| | | // 范围结束 |
| | | this.endDate = endDate |
| | | } |
| | | /** |
| | | * 获取任意时间 |
| | | */ |
| | | getDate(date, AddDayCount = 0, str = 'day') { |
| | | if (!date) { |
| | | date = new Date() |
| | | } |
| | | if (typeof date !== 'object') { |
| | | date = date.replace(/-/g, '/') |
| | | } |
| | | const dd = new Date(date) |
| | | switch (str) { |
| | | case 'day': |
| | | dd.setDate(dd.getDate() + AddDayCount) // 获取AddDayCount天后的日期 |
| | | break |
| | | case 'month': |
| | | if (dd.getDate() === 31 && AddDayCount > 0) { |
| | | dd.setDate(dd.getDate() + AddDayCount) |
| | | } else { |
| | | const preMonth = dd.getMonth() |
| | | dd.setMonth(preMonth + AddDayCount) // 获取AddDayCount天后的日期 |
| | | const nextMonth = dd.getMonth() |
| | | // 处理 pre 切换月份目标月份为2月没有当前日(30 31) 切换错误问题 |
| | | if (AddDayCount < 0 && preMonth !== 0 && nextMonth - preMonth > AddDayCount) { |
| | | dd.setMonth(nextMonth + (nextMonth - preMonth + AddDayCount)) |
| | | } |
| | | // 处理 next 切换月份目标月份为2月没有当前日(30 31) 切换错误问题 |
| | | if (AddDayCount > 0 && nextMonth - preMonth > AddDayCount) { |
| | | dd.setMonth(nextMonth - (nextMonth - preMonth - AddDayCount)) |
| | | } |
| | | } |
| | | break |
| | | case 'year': |
| | | dd.setFullYear(dd.getFullYear() + AddDayCount) // 获取AddDayCount天后的日期 |
| | | break |
| | | } |
| | | const y = dd.getFullYear() |
| | | const m = dd.getMonth() + 1 < 10 ? '0' + (dd.getMonth() + 1) : dd.getMonth() + 1 // 获取当前月份的日期,不足10补0 |
| | | const d = dd.getDate() < 10 ? '0' + dd.getDate() : dd.getDate() // 获取当前几号,不足10补0 |
| | | return { |
| | | fullDate: y + '-' + m + '-' + d, |
| | | year: y, |
| | | month: m, |
| | | date: d, |
| | | day: dd.getDay() |
| | | } |
| | | } |
| | | /** |
| | | * 获取上月剩余天数 |
| | | */ |
| | | _getLastMonthDays(firstDay, full) { |
| | | let dateArr = [] |
| | | for (let i = firstDay; i > 0; i--) { |
| | | const beforeDate = new Date(full.year, full.month - 1, -i + 1).getDate() |
| | | dateArr.push({ |
| | | date: beforeDate, |
| | | month: full.month - 1, |
| | | lunar: this.getlunar(full.year, full.month - 1, beforeDate), |
| | | disable: true |
| | | }) |
| | | } |
| | | return dateArr |
| | | } |
| | | /** |
| | | * 获取本月天数 |
| | | */ |
| | | _currentMonthDys(dateData, full) { |
| | | let dateArr = [] |
| | | let fullDate = this.date.fullDate |
| | | for (let i = 1; i <= dateData; i++) { |
| | | let nowDate = full.year + '-' + (full.month < 10 ? full.month : full.month) + '-' + (i < 10 ? '0' + i : i) |
| | | // 是否今天 |
| | | let isDay = fullDate === nowDate |
| | | // 获取打点信息 |
| | | let info = this.selected && this.selected.find((item) => { |
| | | if (this.dateEqual(nowDate, item.date)) { |
| | | return item |
| | | } |
| | | }) |
| | | // 日期禁用 |
| | | let disableBefore = true |
| | | let disableAfter = true |
| | | if (this.startDate) { |
| | | // let dateCompBefore = this.dateCompare(this.startDate, fullDate) |
| | | // disableBefore = this.dateCompare(dateCompBefore ? this.startDate : fullDate, nowDate) |
| | | disableBefore = this.dateCompare(this.startDate, nowDate) |
| | | } |
| | | if (this.endDate) { |
| | | // let dateCompAfter = this.dateCompare(fullDate, this.endDate) |
| | | // disableAfter = this.dateCompare(nowDate, dateCompAfter ? this.endDate : fullDate) |
| | | disableAfter = this.dateCompare(nowDate, this.endDate) |
| | | } |
| | | let ranges = this.rangeStatus.data |
| | | let checked = false |
| | | let rangesStatus = -1 |
| | | if (this.range) { |
| | | if (ranges) { |
| | | rangesStatus = ranges.findIndex((item) => { |
| | | return this.dateEqual(item, nowDate) |
| | | }) |
| | | } |
| | | if (rangesStatus !== -1) { |
| | | checked = true |
| | | } |
| | | } |
| | | let multiples = this.multipleStatus.data |
| | | let checked_multiple = false |
| | | let multiplesStatus = -1 |
| | | if (this.multiple) { |
| | | if (multiples) { |
| | | multiplesStatus = multiples.findIndex((item) => { |
| | | return this.dateEqual(item, nowDate) |
| | | }) |
| | | } |
| | | if (multiplesStatus !== -1) { |
| | | checked_multiple = true |
| | | } |
| | | } |
| | | let data = { |
| | | fullDate: nowDate, |
| | | year: full.year, |
| | | date: i, |
| | | range: this.range ? checked : false, |
| | | multiple: this.multiple ? checked_multiple : false, |
| | | beforeRange: this.dateEqual(this.rangeStatus.before, nowDate), |
| | | afterRange: this.dateEqual(this.rangeStatus.after, nowDate), |
| | | dateEqual: this.range && checked && this.dateEqual(this.rangeStatus.before, this.rangeStatus.after), |
| | | month: full.month, |
| | | lunar: this.getlunar(full.year, full.month, i), |
| | | disable: !(disableBefore && disableAfter), |
| | | isDay |
| | | } |
| | | if (info) { |
| | | data.extraInfo = info |
| | | } |
| | | dateArr.push(data) |
| | | } |
| | | return dateArr |
| | | } |
| | | /** |
| | | * 获取下月天数 |
| | | */ |
| | | _getNextMonthDays(surplus, full) { |
| | | let dateArr = [] |
| | | for (let i = 1; i < surplus + 1; i++) { |
| | | dateArr.push({ |
| | | date: i, |
| | | month: Number(full.month) + 1, |
| | | lunar: this.getlunar(full.year, Number(full.month) + 1, i), |
| | | disable: true |
| | | }) |
| | | } |
| | | return dateArr |
| | | } |
| | | /** |
| | | * 获取当前日期详情 |
| | | * @param {Object} date |
| | | */ |
| | | getInfo(date) { |
| | | if (!date) { |
| | | date = new Date() |
| | | } else if (Array.isArray(date)) { |
| | | date = date[0] |
| | | } |
| | | const dateInfo = this.canlender.find(item => item.fullDate === this.getDate(date).fullDate) |
| | | return dateInfo |
| | | } |
| | | /** |
| | | * 比较时间大小 |
| | | */ |
| | | dateCompare(startDate, endDate) { |
| | | // 计算截止时间 |
| | | startDate = new Date(startDate.replace('-', '/').replace('-', '/')) |
| | | // 计算详细项的截止时间 |
| | | endDate = new Date(endDate.replace('-', '/').replace('-', '/')) |
| | | if (startDate <= endDate) { |
| | | return true |
| | | } else { |
| | | return false |
| | | } |
| | | } |
| | | /** |
| | | * 比较时间是否相等 |
| | | */ |
| | | dateEqual(before, after) { |
| | | // 计算截止时间 |
| | | before = new Date(before.replace('-', '/').replace('-', '/')) |
| | | // 计算详细项的截止时间 |
| | | after = new Date(after.replace('-', '/').replace('-', '/')) |
| | | if (before.getTime() - after.getTime() === 0) { |
| | | return true |
| | | } else { |
| | | return false |
| | | } |
| | | } |
| | | /** |
| | | * 比较after时间是否大于before时间 |
| | | */ |
| | | dateAfterLgBefore(before, after) { |
| | | // 计算截止时间 |
| | | before = new Date(before.replace('-', '/').replace('-', '/')) |
| | | // 计算详细项的截止时间 |
| | | after = new Date(after.replace('-', '/').replace('-', '/')) |
| | | if (after.getTime() - before.getTime() > 0) { |
| | | return true |
| | | } else { |
| | | return false |
| | | } |
| | | } |
| | | /** |
| | | * 获取日期范围内所有日期 |
| | | * @param {Object} begin |
| | | * @param {Object} end |
| | | */ |
| | | geDateAll(begin, end) { |
| | | var arr = [] |
| | | var ab = begin.split('-') |
| | | var ae = end.split('-') |
| | | var db = new Date() |
| | | db.setFullYear(ab[0], ab[1] - 1, ab[2]) |
| | | var de = new Date() |
| | | de.setFullYear(ae[0], ae[1] - 1, ae[2]) |
| | | var unixDb = db.getTime() - 24 * 60 * 60 * 1000 |
| | | var unixDe = de.getTime() - 24 * 60 * 60 * 1000 |
| | | for (var k = unixDb; k <= unixDe;) { |
| | | k = k + 24 * 60 * 60 * 1000 |
| | | arr.push(this.getDate(new Date(parseInt(k))).fullDate) |
| | | } |
| | | return arr |
| | | } |
| | | /** |
| | | * 计算阴历日期显示 |
| | | */ |
| | | getlunar(year, month, date) { |
| | | return CALENDAR.solar2lunar(year, month, date) |
| | | } |
| | | /** |
| | | * 设置打点 |
| | | */ |
| | | setSelectInfo(data, value) { |
| | | this.selected = value |
| | | this._getWeek(data) |
| | | } |
| | | /** |
| | | * 获取多选状态 |
| | | */ |
| | | setMultiple(fullDate) { |
| | | if (!this.multiple) return |
| | | let multiples = this.multipleStatus.data; |
| | | const findIndex = multiples.findIndex(item => this.dateEqual(fullDate, item)); |
| | | if (findIndex < 0) { |
| | | this.multipleStatus.data = this.multipleStatus.data.concat([fullDate]); |
| | | } else { |
| | | this.multipleStatus.data.splice(findIndex, 1); |
| | | } |
| | | this._getWeek(fullDate) |
| | | } |
| | | /** |
| | | * 获取范围状态 |
| | | */ |
| | | setRange(fullDate) { |
| | | let { |
| | | before, |
| | | after |
| | | } = this.rangeStatus |
| | | if (!this.range) return |
| | | if (before && after) { |
| | | this.cleanRangeStatus(); |
| | | this.rangeStatus.before = fullDate |
| | | } else { |
| | | if (!before) { |
| | | this.rangeStatus.before = fullDate |
| | | } else { |
| | | if (this.allowSameDay && this.dateEqual(before, fullDate)) { |
| | | this.rangeStatus.after = fullDate |
| | | } else if (!this.dateAfterLgBefore(this.rangeStatus.before, fullDate)) { |
| | | this.cleanRangeStatus(); |
| | | this.rangeStatus.before = fullDate |
| | | this._getWeek(fullDate) |
| | | return; |
| | | } |
| | | this.rangeStatus.after = fullDate |
| | | if (this.dateCompare(this.rangeStatus.before, this.rangeStatus.after)) { |
| | | this.rangeStatus.data = this.geDateAll(this.rangeStatus.before, this.rangeStatus.after); |
| | | } else { |
| | | this.rangeStatus.data = this.geDateAll(this.rangeStatus.after, this.rangeStatus.before); |
| | | } |
| | | } |
| | | } |
| | | this._getWeek(fullDate) |
| | | } |
| | | /** |
| | | * 获取每周数据 |
| | | * @param {Object} dateData |
| | | */ |
| | | _getWeek(dateData) { |
| | | const { |
| | | year, |
| | | month |
| | | } = this.getDate(dateData) |
| | | let firstDay = new Date(year, month - 1, 1).getDay() |
| | | let currentDay = new Date(year, month, 0).getDate() |
| | | let dates = { |
| | | lastMonthDays: this._getLastMonthDays(firstDay, this.getDate(dateData)), // 上个月末尾几天 |
| | | currentMonthDys: this._currentMonthDys(currentDay, this.getDate(dateData)), // 本月天数 |
| | | nextMonthDays: [], // 下个月开始几天 |
| | | weeks: [] |
| | | } |
| | | let canlender = [] |
| | | const surplus = 42 - (dates.lastMonthDays.length + dates.currentMonthDys.length) |
| | | dates.nextMonthDays = this._getNextMonthDays(surplus, this.getDate(dateData)) |
| | | canlender = canlender.concat(dates.lastMonthDays, dates.currentMonthDys, dates.nextMonthDays) |
| | | let weeks = {} |
| | | // 拼接数组 上个月开始几天 + 本月天数+ 下个月开始几天 |
| | | for (let i = 0; i < canlender.length; i++) { |
| | | if (i % 7 === 0) { |
| | | weeks[parseInt(i / 7)] = new Array(7) |
| | | } |
| | | weeks[parseInt(i / 7)][i % 7] = canlender[i] |
| | | } |
| | | this.canlender = canlender |
| | | this.weeks = weeks |
| | | } |
| | | //静态方法 |
| | | // static init(date) { |
| | | // if (!this.instance) { |
| | | // this.instance = new Calendar(date); |
| | | // } |
| | | // return this.instance; |
| | | // } |
| | | } |
| | | export default Calendar |
| New file |
| | |
| | | <template> |
| | | <view class="uv-calendar"> |
| | | <view class="uv-calendar__content" v-if="insert"> |
| | | <calendar-body |
| | | :date="date" |
| | | :nowDate="nowDate" |
| | | :weeks="weeks" |
| | | :calendar="calendar" |
| | | :selected="selected" |
| | | :lunar="lunar" |
| | | :showMonth="showMonth" |
| | | :color="color" |
| | | :startText="startText" |
| | | :endText="endText" |
| | | :range="range" |
| | | :multiple="multiple" |
| | | :allowSameDay="allowSameDay" |
| | | @bindDateChange="bindDateChange" |
| | | @pre="pre" |
| | | @next="next" |
| | | @backToday="backToday" |
| | | @choiceDate="choiceDate" |
| | | ></calendar-body> |
| | | </view> |
| | | <uv-popup ref="popup" mode="bottom" v-else :round="round" z-index="998" :close-on-click-overlay="closeOnClickOverlay" @maskClick="maskClick"> |
| | | <view style="min-height: 100px;"> |
| | | <uv-toolbar |
| | | :show="true" |
| | | :cancelColor="cancelColor" |
| | | :confirmColor="getConfirmColor" |
| | | :cancelText="cancelText" |
| | | :confirmText="confirmText" |
| | | :title="title" |
| | | @cancel="close" |
| | | @confirm="confirm"></uv-toolbar> |
| | | <view class="line"></view> |
| | | <calendar-body |
| | | :nowDate="nowDate" |
| | | :weeks="weeks" |
| | | :calendar="calendar" |
| | | :selected="selected" |
| | | :lunar="lunar" |
| | | :showMonth="showMonth" |
| | | :color="color" |
| | | :startText="startText" |
| | | :endText="endText" |
| | | :range="range" |
| | | :multiple="multiple" |
| | | :allowSameDay="allowSameDay" |
| | | @bindDateChange="bindDateChange" |
| | | @pre="pre" |
| | | @next="next" |
| | | @backToday="backToday" |
| | | @choiceDate="choiceDate" |
| | | ></calendar-body> |
| | | </view> |
| | | </uv-popup> |
| | | </view> |
| | | </template> |
| | | <script> |
| | | /** |
| | | * Calendar 日历 |
| | | * @description 日历组件可以查看日期,选择任意范围内的日期,打点操作。常用场景如:酒店日期预订、火车机票选择购买日期、上下班打卡等 |
| | | * @tutorial https://ext.dcloud.net.cn/plugin?name=uv-calendar |
| | | * @property {String} date 自定义当前时间,默认为今天 |
| | | * @property {Boolean} lunar 显示农历 |
| | | * @property {String} startDate 日期选择范围-开始日期 |
| | | * @property {String} endDate 日期选择范围-结束日期 |
| | | * @property {String} mode = [不传 | multiple | range ] 多个日期 | 选择日期范围 默认单日期 |
| | | * @property {Boolean} insert = [true|false] 插入模式,默认为false |
| | | * @value true 弹窗模式 |
| | | * @value false 插入模式 |
| | | * @property {Boolean} clearDate = [true|false] 弹窗模式是否清空上次选择内容 |
| | | * @property {Array} selected 打点,期待格式[{date: '2019-06-27', info: '签到', data: { custom: '自定义信息', name: '自定义消息头',xxx:xxx... }}] |
| | | * @property {String} cancelColor 取消按钮颜色 |
| | | * @property {String} confirmColor 确认按钮颜色,默认#3c9cff |
| | | * @property {String} title 头部工具条中间的标题文字 |
| | | * @property {String} color 主题色,默认#3c9cff |
| | | * @property {Number} round :insert="false"时的圆角 |
| | | * @property {Boolean} closeOnClickOverlay 点击遮罩是否关闭 |
| | | * @property {String} startText range为true时,第一个日期底部的提示文字 |
| | | * @property {String} endText range为true时,最后一个日期底部的提示文字 |
| | | * @property {String} readonly 是否为只读状态,只读状态下禁止选择日期,默认false |
| | | * |
| | | * @event {Function} change 日期改变,`insert :ture` 时生效 |
| | | * @event {Function} confirm 确认选择`insert :false` 时生效 |
| | | * @event {Function} monthSwitch 切换月份时触发 |
| | | * |
| | | * @example <uv-calendar :insert="true":lunar="true" :start-date="'2019-3-2'":end-date="'2019-5-20'"@change="change" /> |
| | | */ |
| | | import mpMixin from '@/uni_modules/uv-ui-tools/libs/mixin/mpMixin.js'; |
| | | import mixin from '@/uni_modules/uv-ui-tools/libs/mixin/mixin.js'; |
| | | import Calendar from './util.js'; |
| | | import calendarBody from './calendar-body.vue'; |
| | | import { initVueI18n } from '@dcloudio/uni-i18n'; |
| | | import i18nMessages from './i18n/index.js'; |
| | | const { t } = initVueI18n(i18nMessages); |
| | | export default { |
| | | components: { |
| | | calendarBody |
| | | }, |
| | | mixins: [mpMixin, mixin], |
| | | emits: ['close', 'confirm', 'change', 'monthSwitch'], |
| | | props: { |
| | | // 取消按钮颜色 |
| | | cancelColor: { |
| | | type: String, |
| | | default: '' |
| | | }, |
| | | // 确认按钮颜色,range模式下未选全显示灰色 |
| | | confirmColor: { |
| | | type: String, |
| | | default: '#3c9cff' |
| | | }, |
| | | // 标题 |
| | | title: { |
| | | type: String, |
| | | default: '' |
| | | }, |
| | | // 主题色 |
| | | color: { |
| | | type: String, |
| | | default: '#3c9cff' |
| | | }, |
| | | // 默认显示日期 |
| | | date: { |
| | | type: [String,Array], |
| | | default: '' |
| | | }, |
| | | // 打点等设置 |
| | | selected: { |
| | | type: Array, |
| | | default () { |
| | | return [] |
| | | } |
| | | }, |
| | | // 是否显示农历 |
| | | lunar: { |
| | | type: Boolean, |
| | | default: false |
| | | }, |
| | | // 可选择的起始日期 |
| | | startDate: { |
| | | type: String, |
| | | default: '' |
| | | }, |
| | | // 可选择的结束日期 |
| | | endDate: { |
| | | type: String, |
| | | default: '' |
| | | }, |
| | | // multiple - 选择多日期 range - 选择日期范围 |
| | | mode: { |
| | | type: String, |
| | | default: '' |
| | | }, |
| | | // 是否插入模式 |
| | | insert: { |
| | | type: Boolean, |
| | | default: false |
| | | }, |
| | | // 是否显示月份为背景 |
| | | showMonth: { |
| | | type: Boolean, |
| | | default: true |
| | | }, |
| | | // 弹窗模式是否清空上次选择内容 |
| | | clearDate: { |
| | | type: Boolean, |
| | | default: true |
| | | }, |
| | | // 弹窗圆角 |
| | | round: { |
| | | type: [Number,String], |
| | | default: 8 |
| | | }, |
| | | // 点击遮罩是否关闭弹窗 |
| | | closeOnClickOverlay: { |
| | | type: Boolean, |
| | | default: true |
| | | }, |
| | | // range为true时,第一个日期底部的提示文字 |
| | | startText: { |
| | | type: String, |
| | | default: '开始' |
| | | }, |
| | | // range为true时,最后一个日期底部的提示文字 |
| | | endText: { |
| | | type: String, |
| | | default: '结束' |
| | | }, |
| | | // 是否允许日期范围的起止时间为同一天,mode = range时有效 |
| | | allowSameDay: { |
| | | type: Boolean, |
| | | default: false |
| | | }, |
| | | // 是否禁用 |
| | | readonly: { |
| | | type: Boolean, |
| | | default: false |
| | | }, |
| | | ...uni.$uv?.props?.calendars |
| | | }, |
| | | data(){ |
| | | return { |
| | | weeks: [], |
| | | calendar: {}, |
| | | nowDate: '', |
| | | allowConfirm: false, |
| | | multiple: false, |
| | | range: false |
| | | } |
| | | }, |
| | | computed:{ |
| | | /** |
| | | * for i18n |
| | | */ |
| | | confirmText() { |
| | | return t("uv-calender.ok") |
| | | }, |
| | | cancelText() { |
| | | return t("uv-calender.cancel") |
| | | }, |
| | | getConfirmColor() { |
| | | if(this.range || this.multiple || this.readonly) { |
| | | return this.allowConfirm? this.confirmColor: '#999' |
| | | }else { |
| | | return this.confirmColor; |
| | | } |
| | | } |
| | | }, |
| | | watch: { |
| | | date(newVal) { |
| | | this.init(newVal) |
| | | }, |
| | | startDate(val) { |
| | | this.cale.resetSatrtDate(val) |
| | | this.cale.setDate(this.nowDate.fullDate) |
| | | this.weeks = this.cale.weeks |
| | | }, |
| | | endDate(val) { |
| | | this.cale.resetEndDate(val) |
| | | this.cale.setDate(this.nowDate.fullDate) |
| | | this.weeks = this.cale.weeks |
| | | }, |
| | | selected(newVal) { |
| | | this.cale.setSelectInfo(this.nowDate.fullDate, newVal) |
| | | this.weeks = this.cale.weeks |
| | | } |
| | | }, |
| | | created() { |
| | | this.setMode(); |
| | | this.cale = new Calendar({ |
| | | selected: this.selected, |
| | | startDate: this.startDate, |
| | | endDate: this.endDate, |
| | | range: this.range, |
| | | multiple: this.multiple, |
| | | allowSameDay: this.allowSameDay |
| | | }) |
| | | this.init(this.date) |
| | | }, |
| | | methods: { |
| | | setMode() { |
| | | switch (this.mode){ |
| | | case 'range': |
| | | this.range = true; |
| | | break; |
| | | case 'multiple': |
| | | this.multiple = true; |
| | | default: |
| | | break; |
| | | } |
| | | }, |
| | | async open() { |
| | | if (this.clearDate && !this.insert) { |
| | | this.cale.cleanRangeStatus() |
| | | this.init(this.date) |
| | | } |
| | | if(!this.insert){ |
| | | this.$refs.popup.open(); |
| | | } |
| | | }, |
| | | close() { |
| | | this.$refs.popup.close(); |
| | | this.$emit('close'); |
| | | }, |
| | | confirm() { |
| | | if(this.readonly) { |
| | | return; |
| | | } else if(this.range && !this.cale.rangeStatus.after) { |
| | | return; |
| | | } else if(this.multiple && this.cale.multipleStatus.data.length == 0){ |
| | | return; |
| | | } |
| | | this.setEmit('confirm'); |
| | | this.close() |
| | | }, |
| | | maskClick() { |
| | | if(this.closeOnClickOverlay) { |
| | | this.$emit('close'); |
| | | } |
| | | }, |
| | | bindDateChange(e) { |
| | | const value = e.detail.value + '-1' |
| | | this.setDate(value) |
| | | |
| | | const { year, month } = this.cale.getDate(value) |
| | | this.$emit('monthSwitch', { |
| | | year, |
| | | month |
| | | }) |
| | | }, |
| | | /** |
| | | * 初始化日期显示 |
| | | * @param {Object} date |
| | | */ |
| | | init(date) { |
| | | if(this.range) { |
| | | // 重置范围选择状态 |
| | | this.cale.cleanRangeStatus(); |
| | | }else if(this.multiple){ |
| | | // 重置多选状态 |
| | | this.cale.cleanMultipleStatus(); |
| | | } |
| | | this.cale.setDate(date,'init') |
| | | this.weeks = this.cale.weeks |
| | | this.nowDate = this.calendar = this.cale.getInfo(date) |
| | | this.changeConfirmStatus(); |
| | | }, |
| | | /** |
| | | * 变化触发 |
| | | */ |
| | | change() { |
| | | this.changeConfirmStatus(); |
| | | if (!this.insert) return |
| | | this.setEmit('change') |
| | | }, |
| | | changeConfirmStatus() { |
| | | if(this.readonly) { |
| | | this.allowConfirm = false; |
| | | } else if (this.range) { |
| | | this.allowConfirm = this.cale.rangeStatus.after ? true : false; |
| | | } else if(this.multiple) { |
| | | this.allowConfirm = this.cale.multipleStatus.data.length > 0 ? true : false; |
| | | } |
| | | }, |
| | | /** |
| | | * 选择月份触发 |
| | | */ |
| | | monthSwitch() { |
| | | let { |
| | | year, |
| | | month |
| | | } = this.nowDate |
| | | this.$emit('monthSwitch', { |
| | | year, |
| | | month: Number(month) |
| | | }) |
| | | }, |
| | | /** |
| | | * 派发事件 |
| | | * @param {Object} name |
| | | */ |
| | | setEmit(name) { |
| | | let { |
| | | year, |
| | | month, |
| | | date, |
| | | fullDate, |
| | | lunar, |
| | | extraInfo |
| | | } = this.calendar |
| | | this.$emit(name, { |
| | | range: this.cale.rangeStatus, |
| | | multiple: this.cale.multipleStatus, |
| | | year, |
| | | month, |
| | | date, |
| | | fulldate: fullDate, |
| | | lunar, |
| | | extraInfo: extraInfo || {} |
| | | }) |
| | | }, |
| | | /** |
| | | * 选择天触发 |
| | | * @param {Object} weeks |
| | | */ |
| | | choiceDate(weeks) { |
| | | if (weeks.disable || this.readonly) return |
| | | this.calendar = weeks |
| | | // 设置范围选择 |
| | | this.cale.setRange(this.calendar.fullDate) |
| | | // 设置多选 |
| | | this.cale.setMultiple(this.calendar.fullDate); |
| | | this.weeks = this.cale.weeks |
| | | this.change() |
| | | }, |
| | | /** |
| | | * 回到今天 |
| | | */ |
| | | backToday() { |
| | | const nowYearMonth = `${this.nowDate.year}-${this.nowDate.month}` |
| | | const date = this.cale.getDate(new Date()) |
| | | const todayYearMonth = `${date.year}-${date.month}` |
| | | this.init(date.fullDate) |
| | | if (nowYearMonth !== todayYearMonth) { |
| | | this.monthSwitch() |
| | | } |
| | | this.change() |
| | | }, |
| | | /** |
| | | * 上个月 |
| | | */ |
| | | pre() { |
| | | const preDate = this.cale.getDate(this.nowDate.fullDate, -1, 'month').fullDate |
| | | this.setDate(preDate) |
| | | this.monthSwitch() |
| | | }, |
| | | /** |
| | | * 下个月 |
| | | */ |
| | | next() { |
| | | const nextDate = this.cale.getDate(this.nowDate.fullDate, +1, 'month').fullDate |
| | | this.setDate(nextDate) |
| | | this.monthSwitch() |
| | | }, |
| | | /** |
| | | * 设置日期 |
| | | * @param {Object} date |
| | | */ |
| | | setDate(date) { |
| | | this.cale.setDate(date) |
| | | this.weeks = this.cale.weeks |
| | | this.nowDate = this.cale.getInfo(date) |
| | | } |
| | | } |
| | | } |
| | | </script> |
| | | <style scoped lang="scss"> |
| | | $uv-border-color: #EDEDED !default; |
| | | .uv-calendar__content { |
| | | background-color: #fff; |
| | | } |
| | | .line { |
| | | width: 750rpx; |
| | | height: 1px; |
| | | border-bottom-color: $uv-border-color; |
| | | border-bottom-style: solid; |
| | | border-bottom-width: 1px; |
| | | } |
| | | </style> |
| New file |
| | |
| | | { |
| | | "id": "uv-calendars", |
| | | "displayName": "uv-calendars 最新日历 全面兼容vue3+2、app、h5、小程序等多端", |
| | | "version": "1.0.15", |
| | | "description": "新版本uv-calendars,不仅拥有老版本的所有功能,还增加了更加适用的插入页面等强大功能,且更加简洁。查看日期、选择单个或多个或任意范围日期,打点操作,自定义文案,自定义主题等强大功能。", |
| | | "keywords": [ |
| | | "uv-ui", |
| | | "uvui", |
| | | "日历", |
| | | "打卡", |
| | | "日历选择" |
| | | ], |
| | | "repository": "", |
| | | "engines": { |
| | | "HBuilderX": "^3.1.0" |
| | | }, |
| | | "dcloudext": { |
| | | "type": "component-vue", |
| | | "sale": { |
| | | "regular": { |
| | | "price": "0.00" |
| | | }, |
| | | "sourcecode": { |
| | | "price": "0.00" |
| | | } |
| | | }, |
| | | "contact": { |
| | | "qq": "" |
| | | }, |
| | | "declaration":{ |
| | | "ads": "无", |
| | | "data": "插件不采集任何数据", |
| | | "permissions": "无" |
| | | }, |
| | | "npmurl": "" |
| | | }, |
| | | "uni_modules": { |
| | | "dependencies": [ |
| | | "uv-ui-tools", |
| | | "uv-popup", |
| | | "uv-toolbar" |
| | | ], |
| | | "encrypt": [], |
| | | "platforms": { |
| | | "cloud": { |
| | | "tcb": "y", |
| | | "aliyun": "y" |
| | | }, |
| | | "client": { |
| | | "Vue": { |
| | | "vue2": "y", |
| | | "vue3": "y" |
| | | }, |
| | | "App": { |
| | | "app-vue": "y", |
| | | "app-nvue": "y" |
| | | }, |
| | | "H5-mobile": { |
| | | "Safari": "y", |
| | | "Android Browser": "y", |
| | | "微信浏览器(Android)": "y", |
| | | "QQ浏览器(Android)": "y" |
| | | }, |
| | | "H5-pc": { |
| | | "Chrome": "y", |
| | | "IE": "y", |
| | | "Edge": "y", |
| | | "Firefox": "y", |
| | | "Safari": "y" |
| | | }, |
| | | "小程序": { |
| | | "微信": "y", |
| | | "阿里": "y", |
| | | "百度": "y", |
| | | "字节跳动": "y", |
| | | "QQ": "y", |
| | | "钉钉": "u", |
| | | "快手": "u", |
| | | "飞书": "u", |
| | | "京东": "u" |
| | | }, |
| | | "快应用": { |
| | | "华为": "u", |
| | | "联盟": "u" |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| New file |
| | |
| | | ## Calendars 全新日历 |
| | | |
| | | > **组件名:uv-calendars** |
| | | |
| | | 为了解决老版本`uv-calendar`性能问题,特别是对日期选择范围有很大限制,体验不友好等缺点。于是有了新版日历组件。 |
| | | |
| | | 新版本`uv-calendars`,不仅拥有老版本的所有功能,还增加了更加适用的插入页面等强大功能,且更加简洁。查看日期、选择单个或多个或任意范围日期,打点操作,自定义文案,自定义主题等强大功能。 |
| | | |
| | | 常用场景:酒店日期预订、火车机票选择购买日期、上下班打卡等。 |
| | | |
| | | # <a href="https://www.uvui.cn/components/calendars.html" target="_blank">查看文档</a> |
| | | |
| | | ## [下载完整示例项目](https://ext.dcloud.net.cn/plugin?name=uv-ui) <small>(请不要 下载插件ZIP)</small> |
| | | |
| | | ### [更多插件,请关注uv-ui组件库](https://ext.dcloud.net.cn/plugin?name=uv-ui) |
| | | |
| | | <a href="https://ext.dcloud.net.cn/plugin?name=uv-ui" target="_blank"> |
| | | |
| | |  |
| | | |
| | | </a> |
| | | |
| | | #### 如使用过程中有任何问题反馈,或者您对uv-ui有一些好的建议,欢迎加入uv-ui官方交流群:<a href="https://www.uvui.cn/components/addQQGroup.html" target="_blank">官方QQ群</a> |
| New file |
| | |
| | | ## 1.0.5(2023-08-05) |
| | | 在vue2模式下,v-model设置为0时不生效的BUG |
| | | ## 1.0.4(2023-07-13) |
| | | 1. 修复value/v-model更改不生效的BUG |
| | | ## 1.0.3(2023-06-28) |
| | | 修复:使用:disabledKeyboard="true"属性,事件全部失效的BUG |
| | | ## 1.0.2(2023-06-23) |
| | | 优化下边框 |
| | | ## 1.0.1(2023-05-16) |
| | | 1. 优化组件依赖,修改后无需全局引入,组件导入即可使用 |
| | | 2. 优化部分功能 |
| | | ## 1.0.0(2023-05-10) |
| | | uv-code-input 验证码输入 |
| New file |
| | |
| | | export default { |
| | | props: { |
| | | value: { |
| | | type: [String, Number], |
| | | default: '' |
| | | }, |
| | | modelValue: { |
| | | type: [String, Number], |
| | | default: '' |
| | | }, |
| | | // 键盘弹起时,是否自动上推页面 |
| | | adjustPosition: { |
| | | type: Boolean, |
| | | default: true |
| | | }, |
| | | // 最大输入长度 |
| | | maxlength: { |
| | | type: [String, Number], |
| | | default: 6 |
| | | }, |
| | | // 是否用圆点填充 |
| | | dot: { |
| | | type: Boolean, |
| | | default: false |
| | | }, |
| | | // 显示模式,box-盒子模式,line-底部横线模式 |
| | | mode: { |
| | | type: String, |
| | | default: 'box' |
| | | }, |
| | | // 是否细边框 |
| | | hairline: { |
| | | type: Boolean, |
| | | default: false |
| | | }, |
| | | // 字符间的距离 |
| | | space: { |
| | | type: [String, Number], |
| | | default: 10 |
| | | }, |
| | | // 是否自动获取焦点 |
| | | focus: { |
| | | type: Boolean, |
| | | default: false |
| | | }, |
| | | // 字体是否加粗 |
| | | bold: { |
| | | type: Boolean, |
| | | default: false |
| | | }, |
| | | // 字体颜色 |
| | | color: { |
| | | type: String, |
| | | default: '#606266' |
| | | }, |
| | | // 字体大小 |
| | | fontSize: { |
| | | type: [String, Number], |
| | | default: 18 |
| | | }, |
| | | // 输入框的大小,宽等于高 |
| | | size: { |
| | | type: [String, Number], |
| | | default: 35 |
| | | }, |
| | | // 是否隐藏原生键盘,如果想用自定义键盘的话,需设置此参数为true |
| | | disabledKeyboard: { |
| | | type: Boolean, |
| | | default: false |
| | | }, |
| | | // 边框和线条颜色 |
| | | borderColor: { |
| | | type: String, |
| | | default: '#c9cacc' |
| | | }, |
| | | // 是否禁止输入"."符号 |
| | | disabledDot: { |
| | | type: Boolean, |
| | | default: true |
| | | }, |
| | | ...uni.$uv?.props?.codeInput |
| | | } |
| | | } |
| New file |
| | |
| | | <template> |
| | | <view class="uv-code-input"> |
| | | <view |
| | | class="uv-code-input__item" |
| | | :style="[itemStyle(index)]" |
| | | v-for="(item, index) in codeLength" |
| | | :key="index" |
| | | > |
| | | <view |
| | | class="uv-code-input__item__dot" |
| | | v-if="dot && codeArray.length > index" |
| | | ></view> |
| | | <text |
| | | v-else |
| | | :style="{ |
| | | fontSize: $uv.addUnit(fontSize), |
| | | fontWeight: bold ? 'bold' : 'normal', |
| | | color: color |
| | | }" |
| | | >{{codeArray[index]}}</text> |
| | | <view |
| | | class="uv-code-input__item__line" |
| | | v-if="mode === 'line'" |
| | | :style="[lineStyle]" |
| | | ></view> |
| | | <!-- #ifndef APP-PLUS --> |
| | | <view v-if="isFocus && codeArray.length === index" :style="{backgroundColor: color}" class="uv-code-input__item__cursor"></view> |
| | | <!-- #endif --> |
| | | </view> |
| | | <input |
| | | :disabled="disabledKeyboard" |
| | | type="number" |
| | | :focus="focus" |
| | | :value="inputValue" |
| | | :maxlength="maxlength" |
| | | :adjustPosition="adjustPosition" |
| | | class="uv-code-input__input" |
| | | @input="inputHandler" |
| | | :style="{ |
| | | height: $uv.addUnit(size) |
| | | }" |
| | | @focus="isFocus = true" |
| | | @blur="isFocus = false" |
| | | /> |
| | | </view> |
| | | </template> |
| | | |
| | | <script> |
| | | import mpMixin from '@/uni_modules/uv-ui-tools/libs/mixin/mpMixin.js' |
| | | import mixin from '@/uni_modules/uv-ui-tools/libs/mixin/mixin.js' |
| | | import props from './props.js'; |
| | | /** |
| | | * CodeInput 验证码输入 |
| | | * @description 该组件一般用于验证用户短信验证码的场景,也可以结合uvui的键盘组件使用 |
| | | * @tutorial https://www.uvui.cn/components/codeInput.html |
| | | * @property {String | Number} value / v-model 预置值 |
| | | * @property {String | Number} maxlength 最大输入长度 (默认 6 ) |
| | | * @property {Boolean} dot 是否用圆点填充 (默认 false ) |
| | | * @property {String} mode 显示模式,box-盒子模式,line-底部横线模式 (默认 'box' ) |
| | | * @property {Boolean} hairline 是否细边框 (默认 false ) |
| | | * @property {String | Number} space 字符间的距离 (默认 10 ) |
| | | * @property {Boolean} focus 是否自动获取焦点 (默认 false ) |
| | | * @property {Boolean} bold 字体和输入横线是否加粗 (默认 false ) |
| | | * @property {String} color 字体颜色 (默认 '#606266' ) |
| | | * @property {String | Number} fontSize 字体大小,单位px (默认 18 ) |
| | | * @property {String | Number} size 输入框的大小,宽等于高 (默认 35 ) |
| | | * @property {Boolean} disabledKeyboard 是否隐藏原生键盘,如果想用自定义键盘的话,需设置此参数为true (默认 false ) |
| | | * @property {String} borderColor 边框和线条颜色 (默认 '#c9cacc' ) |
| | | * @property {Boolean} disabledDot 是否禁止输入"."符号 (默认 true ) |
| | | * |
| | | * @event {Function} change 输入内容发生改变时触发,具体见上方说明 value:当前输入的值 |
| | | * @event {Function} finish 输入字符个数达maxlength值时触发,见上方说明 value:当前输入的值 |
| | | * @example <uv-code-input v-model="value4" :focus="true"></uv-code-input> |
| | | */ |
| | | export default { |
| | | name: 'uv-code-input', |
| | | mixins: [mpMixin, mixin, props], |
| | | data() { |
| | | return { |
| | | inputValue: '', |
| | | isFocus: this.focus |
| | | } |
| | | }, |
| | | created() { |
| | | const value = String(this.value) || String(this.modelValue); |
| | | this.inputValue = String(value).substring(0, this.maxlength); |
| | | }, |
| | | watch: { |
| | | value(newVal) { |
| | | // 转为字符串,超出部分截掉 |
| | | this.inputValue = String(newVal).substring(0, this.maxlength); |
| | | if (this.disabledKeyboard) { |
| | | this.customInput(); |
| | | } |
| | | }, |
| | | modelValue(newVal) { |
| | | // 转为字符串,超出部分截掉 |
| | | this.inputValue = String(newVal).substring(0, this.maxlength); |
| | | if (this.disabledKeyboard) { |
| | | this.customInput(); |
| | | } |
| | | } |
| | | }, |
| | | computed: { |
| | | // 根据长度,循环输入框的个数,因为头条小程序数值不能用于v-for |
| | | codeLength() { |
| | | return new Array(Number(this.maxlength)) |
| | | }, |
| | | // 循环item的样式 |
| | | itemStyle() { |
| | | return index => { |
| | | const addUnit = this.$uv.addUnit |
| | | const style = { |
| | | width: addUnit(this.size), |
| | | height: addUnit(this.size) |
| | | } |
| | | // 盒子模式下,需要额外进行处理 |
| | | if (this.mode === 'box') { |
| | | // 设置盒子的边框,如果是细边框,则设置为0.5px宽度 |
| | | style.border = `${this.hairline ? 0.5 : 1}px solid ${this.borderColor}` |
| | | // 如果盒子间距为0的话 |
| | | if (this.$uv.getPx(this.space) === 0) { |
| | | // 给第一和最后一个盒子设置圆角 |
| | | if (index === 0) { |
| | | style.borderTopLeftRadius = '3px' |
| | | style.borderBottomLeftRadius = '3px' |
| | | } |
| | | if (index === this.codeLength.length - 1) { |
| | | style.borderTopRightRadius = '3px' |
| | | style.borderBottomRightRadius = '3px' |
| | | } |
| | | // 最后一个盒子的右边框需要保留 |
| | | if (index !== this.codeLength.length - 1) { |
| | | style.borderRight = 'none' |
| | | } |
| | | } |
| | | } |
| | | if (index !== this.codeLength.length - 1) { |
| | | // 设置验证码字符之间的距离,通过margin-right设置,最后一个字符,无需右边框 |
| | | style.marginRight = addUnit(this.space) |
| | | } else { |
| | | // 最后一个盒子的有边框需要保留 |
| | | style.marginRight = 0 |
| | | } |
| | | return style |
| | | } |
| | | }, |
| | | // 将输入的值,转为数组,给item历遍时,根据当前的索引显示数组的元素 |
| | | codeArray() { |
| | | return String(this.inputValue).split('') |
| | | }, |
| | | // 下划线模式下,横线的样式 |
| | | lineStyle() { |
| | | const style = {} |
| | | style.height = this.hairline ? '1px' : '4px' |
| | | style.width = this.$uv.addUnit(this.size) |
| | | // 线条模式下,背景色即为边框颜色 |
| | | style.backgroundColor = this.borderColor |
| | | return style |
| | | } |
| | | }, |
| | | methods: { |
| | | // 监听输入框的值发生变化 |
| | | inputHandler(e) { |
| | | const value = e.detail.value |
| | | this.inputValue = value |
| | | // 是否允许输入“.”符号 |
| | | if (this.disabledDot) { |
| | | this.$nextTick(() => { |
| | | this.inputValue = value.replace('.', '') |
| | | }) |
| | | } |
| | | // 未达到maxlength之前,发送change事件,达到后发送finish事件 |
| | | this.$emit('change', value) |
| | | // 修改通过v-model双向绑定的值 |
| | | this.$emit('input', value) |
| | | this.$emit('update:modelValue', value) |
| | | // 达到用户指定输入长度时,发出完成事件 |
| | | if (String(value).length >= Number(this.maxlength)) { |
| | | this.$emit('finish', value) |
| | | } |
| | | }, |
| | | // 自定义键盘输入值监听 |
| | | customInput() { |
| | | const value = this.inputValue; |
| | | // 是否允许输入“.”符号 |
| | | if (this.disabledDot) { |
| | | this.$nextTick(() => { |
| | | this.inputValue = value.replace('.', '') |
| | | }) |
| | | } |
| | | // 未达到maxlength之前,发送change事件,达到后发送finish事件 |
| | | this.$emit('change', value) |
| | | // 达到用户指定输入长度时,发出完成事件 |
| | | if (String(value).length >= Number(this.maxlength)) { |
| | | this.$emit('finish', value) |
| | | } |
| | | } |
| | | } |
| | | } |
| | | </script> |
| | | <style lang="scss" scoped> |
| | | @import '@/uni_modules/uv-ui-tools/libs/css/components.scss'; |
| | | @import '@/uni_modules/uv-ui-tools/libs/css/color.scss'; |
| | | $uv-code-input-cursor-width: 1px; |
| | | $uv-code-input-cursor-height: 40%; |
| | | $uv-code-input-cursor-animation-duration: 1s; |
| | | $uv-code-input-cursor-animation-name: uv-cursor-flicker; |
| | | .uv-code-input { |
| | | @include flex; |
| | | position: relative; |
| | | overflow: hidden; |
| | | &__item { |
| | | @include flex; |
| | | justify-content: center; |
| | | align-items: center; |
| | | position: relative; |
| | | &__text { |
| | | font-size: 15px; |
| | | color: $uv-content-color; |
| | | } |
| | | &__dot { |
| | | width: 7px; |
| | | height: 7px; |
| | | border-radius: 100px; |
| | | background-color: $uv-content-color; |
| | | } |
| | | &__line { |
| | | position: absolute; |
| | | bottom: 0; |
| | | height: 4px; |
| | | border-radius: 100px; |
| | | width: 40px; |
| | | background-color: $uv-content-color; |
| | | } |
| | | /* #ifndef APP-PLUS */ |
| | | &__cursor { |
| | | position: absolute; |
| | | top: 50%; |
| | | left: 50%; |
| | | transform: translate(-50%, -50%); |
| | | width: $uv-code-input-cursor-width; |
| | | height: $uv-code-input-cursor-height; |
| | | animation: $uv-code-input-cursor-animation-duration uv-cursor-flicker infinite; |
| | | } |
| | | /* #endif */ |
| | | } |
| | | &__input { |
| | | // 之所以需要input输入框,是因为有它才能唤起键盘 |
| | | // 这里将它设置为两倍的屏幕宽度,再将左边的一半移出屏幕,为了不让用户看到输入的内容 |
| | | position: absolute; |
| | | left: -750rpx; |
| | | width: 1500rpx; |
| | | top: 0; |
| | | background-color: transparent; |
| | | text-align: left; |
| | | } |
| | | } |
| | | /* #ifndef APP-PLUS */ |
| | | @keyframes uv-cursor-flicker { |
| | | 0% { |
| | | opacity: 0; |
| | | } |
| | | 50% { |
| | | opacity: 1; |
| | | } |
| | | 100% { |
| | | opacity: 0; |
| | | } |
| | | } |
| | | /* #endif */ |
| | | </style> |
| New file |
| | |
| | | { |
| | | "id": "uv-code-input", |
| | | "displayName": "uv-code-input 验证码输入 全面兼容vue3+2、app、h5、小程序等多端", |
| | | "version": "1.0.5", |
| | | "description": "验证码输入组件一般用于验证用户短信验证码的场景,输入框或横线多种模式可选。", |
| | | "keywords": [ |
| | | "uv-code-input", |
| | | "uvui", |
| | | "uv-ui", |
| | | "code", |
| | | "验证码输入" |
| | | ], |
| | | "repository": "", |
| | | "engines": { |
| | | "HBuilderX": "^3.1.0" |
| | | }, |
| | | "dcloudext": { |
| | | "type": "component-vue", |
| | | "sale": { |
| | | "regular": { |
| | | "price": "0.00" |
| | | }, |
| | | "sourcecode": { |
| | | "price": "0.00" |
| | | } |
| | | }, |
| | | "contact": { |
| | | "qq": "" |
| | | }, |
| | | "declaration": { |
| | | "ads": "无", |
| | | "data": "插件不采集任何数据", |
| | | "permissions": "无" |
| | | }, |
| | | "npmurl": "" |
| | | }, |
| | | "uni_modules": { |
| | | "dependencies": [ |
| | | "uv-ui-tools" |
| | | ], |
| | | "encrypt": [], |
| | | "platforms": { |
| | | "cloud": { |
| | | "tcb": "y", |
| | | "aliyun": "y" |
| | | }, |
| | | "client": { |
| | | "Vue": { |
| | | "vue2": "y", |
| | | "vue3": "y" |
| | | }, |
| | | "App": { |
| | | "app-vue": "y", |
| | | "app-nvue": "y" |
| | | }, |
| | | "H5-mobile": { |
| | | "Safari": "y", |
| | | "Android Browser": "y", |
| | | "微信浏览器(Android)": "y", |
| | | "QQ浏览器(Android)": "y" |
| | | }, |
| | | "H5-pc": { |
| | | "Chrome": "y", |
| | | "IE": "y", |
| | | "Edge": "y", |
| | | "Firefox": "y", |
| | | "Safari": "y" |
| | | }, |
| | | "小程序": { |
| | | "微信": "y", |
| | | "阿里": "y", |
| | | "百度": "y", |
| | | "字节跳动": "y", |
| | | "QQ": "y", |
| | | "钉钉": "u", |
| | | "快手": "u", |
| | | "飞书": "u", |
| | | "京东": "u" |
| | | }, |
| | | "快应用": { |
| | | "华为": "u", |
| | | "联盟": "u" |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| New file |
| | |
| | | ## CodeInput 验证码输入框 |
| | | |
| | | > **组件名:uv-code-input** |
| | | |
| | | 该组件一般用于验证用户短信验证码的场景,输入框或横线多种模式可选。 |
| | | |
| | | # <a href="https://www.uvui.cn/components/codeInput.html" target="_blank">查看文档</a> |
| | | |
| | | ## [下载完整示例项目](https://ext.dcloud.net.cn/plugin?name=uv-ui) <small>(请不要 下载插件ZIP)</small> |
| | | |
| | | ### [更多插件,请关注uv-ui组件库](https://ext.dcloud.net.cn/plugin?name=uv-ui) |
| | | |
| | | <a href="https://ext.dcloud.net.cn/plugin?name=uv-ui" target="_blank"> |
| | | |
| | |  |
| | | |
| | | </a> |
| | | |
| | | #### 如使用过程中有任何问题反馈,或者您对uv-ui有一些好的建议,欢迎加入uv-ui官方交流群:<a href="https://www.uvui.cn/components/addQQGroup.html" target="_blank">官方QQ群</a> |
| New file |
| | |
| | | ## 1.0.3(2023-10-13) |
| | | 1. 优化 |
| | | ## 1.0.2(2023-10-13) |
| | | 1. unmounted兼容vue3 |
| | | ## 1.0.1(2023-05-16) |
| | | 1. 优化组件依赖,修改后无需全局引入,组件导入即可使用 |
| | | 2. 优化部分功能 |
| | | ## 1.0.0(2023-05-10) |
| | | uv-code 验证码倒计时 |
| New file |
| | |
| | | export default { |
| | | props: { |
| | | // 倒计时总秒数 |
| | | seconds: { |
| | | type: [String, Number], |
| | | default: 60 |
| | | }, |
| | | // 尚未开始时提示 |
| | | startText: { |
| | | type: String, |
| | | default: '获取验证码' |
| | | }, |
| | | // 正在倒计时中的提示 |
| | | changeText: { |
| | | type: String, |
| | | default: 'X秒重新获取' |
| | | }, |
| | | // 倒计时结束时的提示 |
| | | endText: { |
| | | type: String, |
| | | default: '重新获取' |
| | | }, |
| | | // 是否在H5刷新或各端返回再进入时继续倒计时 |
| | | keepRunning: { |
| | | type: Boolean, |
| | | default: false |
| | | }, |
| | | // 为了区分多个页面,或者一个页面多个倒计时组件本地存储的继续倒计时变了 |
| | | uniqueKey: { |
| | | type: String, |
| | | default: '' |
| | | }, |
| | | ...uni.$uv?.props?.code |
| | | } |
| | | } |
| New file |
| | |
| | | <template> |
| | | <view class="uv-code"> |
| | | <!-- 此组件功能由js完成,无需写html逻辑 --> |
| | | </view> |
| | | </template> |
| | | <script> |
| | | import mpMixin from '@/uni_modules/uv-ui-tools/libs/mixin/mpMixin.js' |
| | | import mixin from '@/uni_modules/uv-ui-tools/libs/mixin/mixin.js' |
| | | import props from './props.js'; |
| | | /** |
| | | * Code 验证码倒计时 |
| | | * @description 考虑到用户实际发送验证码的场景,可能是一个按钮,也可能是一段文字,提示语各有不同,所以本组件不提供界面显示,只提供倒计时文本,由用户将文本嵌入到具体的场景 |
| | | * @tutorial https://www.uvui.cn/components/code.html |
| | | * @property {String | Number} seconds 倒计时所需的秒数(默认 60 ) |
| | | * @property {String} startText 开始前的提示语,见官网说明(默认 '获取验证码' ) |
| | | * @property {String} changeText 倒计时期间的提示语,必须带有字母"x",见官网说明(默认 'X秒重新获取' ) |
| | | * @property {String} endText 倒计结束的提示语,见官网说明(默认 '重新获取' ) |
| | | * @property {Boolean} keepRunning 是否在H5刷新或各端返回再进入时继续倒计时( 默认false ) |
| | | * @property {String} uniqueKey 为了区分多个页面,或者一个页面多个倒计时组件本地存储的继续倒计时变了 |
| | | * |
| | | * @event {Function} change 倒计时期间,每秒触发一次 |
| | | * @event {Function} start 开始倒计时触发 |
| | | * @event {Function} end 结束倒计时触发 |
| | | * @example <uv-code ref="uCode" @change="codeChange" seconds="20"></uv-code> |
| | | */ |
| | | export default { |
| | | name: "uv-code", |
| | | mixins: [mpMixin, mixin, props], |
| | | data() { |
| | | return { |
| | | secNum: this.seconds, |
| | | timer: null, |
| | | canGetCode: true, // 是否可以执行验证码操作 |
| | | } |
| | | }, |
| | | mounted() { |
| | | this.checkKeepRunning() |
| | | }, |
| | | watch: { |
| | | seconds: { |
| | | immediate: true, |
| | | handler(n) { |
| | | this.secNum = n |
| | | } |
| | | } |
| | | }, |
| | | methods: { |
| | | checkKeepRunning() { |
| | | // 获取上一次退出页面(H5还包括刷新)时的时间戳,如果没有上次的保存,此值可能为空 |
| | | let lastTimestamp = Number(uni.getStorageSync(this.uniqueKey + '_$uCountDownTimestamp')) |
| | | if (!lastTimestamp) return this.changeEvent(this.startText) |
| | | // 当前秒的时间戳 |
| | | let nowTimestamp = Math.floor((+new Date()) / 1000) |
| | | // 判断当前的时间戳,是否小于上一次的本该按设定结束,却提前结束的时间戳 |
| | | if (this.keepRunning && lastTimestamp && lastTimestamp > nowTimestamp) { |
| | | // 剩余尚未执行完的倒计秒数 |
| | | this.secNum = lastTimestamp - nowTimestamp |
| | | // 清除本地保存的变量 |
| | | uni.removeStorageSync(this.uniqueKey + '_$uCountDownTimestamp') |
| | | // 开始倒计时 |
| | | this.start() |
| | | } else { |
| | | // 如果不存在需要继续上一次的倒计时,执行正常的逻辑 |
| | | this.changeEvent(this.startText) |
| | | } |
| | | }, |
| | | // 开始倒计时 |
| | | start() { |
| | | // 防止快速点击获取验证码的按钮而导致内部产生多个定时器导致混乱 |
| | | if (this.timer) { |
| | | clearInterval(this.timer) |
| | | this.timer = null |
| | | } |
| | | this.$emit('start') |
| | | this.canGetCode = false |
| | | // 这里放这句,是为了一开始时就提示,否则要等setInterval的1秒后才会有提示 |
| | | this.changeEvent(this.changeText.replace(/x|X/, this.secNum)) |
| | | this.timer = setInterval(() => { |
| | | if (--this.secNum) { |
| | | // 用当前倒计时的秒数替换提示字符串中的"x"字母 |
| | | this.changeEvent(this.changeText.replace(/x|X/, this.secNum)) |
| | | } else { |
| | | clearInterval(this.timer) |
| | | this.timer = null |
| | | this.changeEvent(this.endText) |
| | | this.secNum = this.seconds |
| | | this.$emit('end') |
| | | this.canGetCode = true |
| | | } |
| | | }, 1000) |
| | | this.setTimeToStorage() |
| | | }, |
| | | // 重置,可以让用户再次获取验证码 |
| | | reset() { |
| | | this.canGetCode = true |
| | | clearInterval(this.timer) |
| | | this.secNum = this.seconds |
| | | this.changeEvent(this.endText) |
| | | }, |
| | | changeEvent(text) { |
| | | this.$emit('change', text) |
| | | }, |
| | | // 保存时间戳,为了防止倒计时尚未结束,H5刷新或者各端的右上角返回上一页再进来 |
| | | setTimeToStorage() { |
| | | if (!this.keepRunning || !this.timer) return |
| | | // 记录当前的时间戳,为了下次进入页面,如果还在倒计时内的话,继续倒计时 |
| | | // 倒计时尚未结束,结果大于0;倒计时已经开始,就会小于初始值,如果等于初始值,说明没有开始倒计时,无需处理 |
| | | if (this.secNum > 0 && this.secNum <= this.seconds) { |
| | | // 获取当前时间戳(+ new Date()为特殊写法),除以1000变成秒,再去除小数部分 |
| | | let nowTimestamp = Math.floor((+new Date()) / 1000) |
| | | // 将本该结束时候的时间戳保存起来 => 当前时间戳 + 剩余的秒数 |
| | | uni.setStorage({ |
| | | key: this.uniqueKey + '_$uCountDownTimestamp', |
| | | data: nowTimestamp + Number(this.secNum) |
| | | }) |
| | | } |
| | | } |
| | | }, |
| | | // #ifdef VUE2 |
| | | // 组件销毁的时候,清除定时器,否则定时器会继续存在,系统不会自动清除 |
| | | beforeDestroy() { |
| | | this.setTimeToStorage() |
| | | clearTimeout(this.timer) |
| | | this.timer = null |
| | | }, |
| | | // #endif |
| | | // #ifdef VUE3 |
| | | // 组件销毁,兼容vue3 |
| | | unmounted() { |
| | | this.setTimeToStorage() |
| | | clearTimeout(this.timer) |
| | | this.timer = null |
| | | } |
| | | // #endif |
| | | } |
| | | </script> |
| New file |
| | |
| | | { |
| | | "id": "uv-code", |
| | | "displayName": "uv-code 验证码倒计时 全面兼容小程序、nvue、vue2、vue3等多端", |
| | | "version": "1.0.3", |
| | | "description": "考虑到用户实际发送验证码的场景,可能是一个按钮,也可能是一段文字,提示语各有不同,所以本组件不提供界面显示,只提供倒计时文本,由用户将文本嵌入到具体的场景。", |
| | | "keywords": [ |
| | | "uv-code", |
| | | "uvui", |
| | | "uv-ui", |
| | | "code", |
| | | "验证码倒计时" |
| | | ], |
| | | "repository": "", |
| | | "engines": { |
| | | "HBuilderX": "^3.1.0" |
| | | }, |
| | | "dcloudext": { |
| | | "type": "component-vue", |
| | | "sale": { |
| | | "regular": { |
| | | "price": "0.00" |
| | | }, |
| | | "sourcecode": { |
| | | "price": "0.00" |
| | | } |
| | | }, |
| | | "contact": { |
| | | "qq": "" |
| | | }, |
| | | "declaration": { |
| | | "ads": "无", |
| | | "data": "插件不采集任何数据", |
| | | "permissions": "无" |
| | | }, |
| | | "npmurl": "" |
| | | }, |
| | | "uni_modules": { |
| | | "dependencies": [ |
| | | "uv-ui-tools" |
| | | ], |
| | | "encrypt": [], |
| | | "platforms": { |
| | | "cloud": { |
| | | "tcb": "y", |
| | | "aliyun": "y" |
| | | }, |
| | | "client": { |
| | | "Vue": { |
| | | "vue2": "y", |
| | | "vue3": "y" |
| | | }, |
| | | "App": { |
| | | "app-vue": "y", |
| | | "app-nvue": "y" |
| | | }, |
| | | "H5-mobile": { |
| | | "Safari": "y", |
| | | "Android Browser": "y", |
| | | "微信浏览器(Android)": "y", |
| | | "QQ浏览器(Android)": "y" |
| | | }, |
| | | "H5-pc": { |
| | | "Chrome": "y", |
| | | "IE": "y", |
| | | "Edge": "y", |
| | | "Firefox": "y", |
| | | "Safari": "y" |
| | | }, |
| | | "小程序": { |
| | | "微信": "y", |
| | | "阿里": "y", |
| | | "百度": "y", |
| | | "字节跳动": "y", |
| | | "QQ": "y", |
| | | "钉钉": "u", |
| | | "快手": "u", |
| | | "飞书": "u", |
| | | "京东": "u" |
| | | }, |
| | | "快应用": { |
| | | "华为": "u", |
| | | "联盟": "u" |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| New file |
| | |
| | | ## Code 验证码输入框 |
| | | |
| | | > **组件名:uv-code** |
| | | |
| | | 考虑到用户实际发送验证码的场景,可能是一个按钮,也可能是一段文字,提示语各有不同,所以本组件不提供界面显示,只提供倒计时文本,由用户将文本嵌入到具体的场景。 |
| | | |
| | | ### <a href="https://www.uvui.cn/components/code.html" target="_blank">查看文档</a> |
| | | |
| | | ### [完整示例项目下载 | 关注更多组件](https://ext.dcloud.net.cn/plugin?name=uv-ui) |
| | | |
| | | #### 如使用过程中有任何问题,或者您对uv-ui有一些好的建议,欢迎加入 uv-ui 交流群:<a href="https://ext.dcloud.net.cn/plugin?id=12287" target="_blank">uv-ui</a>、<a href="https://www.uvui.cn/components/addQQGroup.html" target="_blank">官方QQ群</a> |
| New file |
| | |
| | | ## 1.0.1(2023-05-16) |
| | | 1. 优化组件依赖,修改后无需全局引入,组件导入即可使用 |
| | | 2. 优化部分功能 |
| | | ## 1.0.0(2023-05-10) |
| | | uv-collapse 折叠面板 |
| New file |
| | |
| | | export default { |
| | | props: { |
| | | // 标题 |
| | | title: { |
| | | type: String, |
| | | default: '' |
| | | }, |
| | | // 标题右侧内容 |
| | | value: { |
| | | type: String, |
| | | default: '' |
| | | }, |
| | | // 标题下方的描述信息 |
| | | label: { |
| | | type: String, |
| | | default: '' |
| | | }, |
| | | // 是否禁用折叠面板 |
| | | disabled: { |
| | | type: Boolean, |
| | | default: false |
| | | }, |
| | | // 是否展示右侧箭头并开启点击反馈 |
| | | isLink: { |
| | | type: Boolean, |
| | | default: true |
| | | }, |
| | | // 是否开启点击反馈 |
| | | clickable: { |
| | | type: Boolean, |
| | | default: true |
| | | }, |
| | | // 是否显示内边框 |
| | | border: { |
| | | type: Boolean, |
| | | default: true |
| | | }, |
| | | // 标题的对齐方式 |
| | | align: { |
| | | type: String, |
| | | default: 'left' |
| | | }, |
| | | // 唯一标识符 |
| | | name: { |
| | | type: [String, Number], |
| | | default: '' |
| | | }, |
| | | // 标题左侧图片,可为绝对路径的图片或内置图标 |
| | | icon: { |
| | | type: String, |
| | | default: '' |
| | | }, |
| | | // 面板展开收起的过渡时间,单位ms |
| | | duration: { |
| | | type: Number, |
| | | default: 300 |
| | | }, |
| | | ...uni.$uv?.props?.collapseItem |
| | | } |
| | | } |
| New file |
| | |
| | | <template> |
| | | <view class="uv-collapse-item"> |
| | | <uv-cell |
| | | :title="title" |
| | | :value="value" |
| | | :label="label" |
| | | :icon="icon" |
| | | :isLink="isLink" |
| | | :clickable="clickable" |
| | | :border="parentData.border && showBorder" |
| | | @click="clickHandler" |
| | | :arrowDirection="expanded ? 'up' : 'down'" |
| | | :disabled="disabled" |
| | | > |
| | | <!-- #ifndef MP-WEIXIN --> |
| | | <!-- 微信小程序不支持,因为微信中不支持 <slot name="title" slot="title" />的写法 --> |
| | | <template slot="title"> |
| | | <slot name="title"></slot> |
| | | </template> |
| | | <template slot="icon"> |
| | | <slot name="icon"></slot> |
| | | </template> |
| | | <template slot="value"> |
| | | <slot name="value"></slot> |
| | | </template> |
| | | <template slot="right-icon"> |
| | | <slot name="right-icon"></slot> |
| | | </template> |
| | | <!-- #endif --> |
| | | </uv-cell> |
| | | <view |
| | | class="uv-collapse-item__content" |
| | | :animation="animationData" |
| | | ref="animation" |
| | | > |
| | | <view |
| | | class="uv-collapse-item__content__text content-class" |
| | | :id="elId" |
| | | :ref="elId" |
| | | ><slot /></view> |
| | | </view> |
| | | <uv-line v-if="parentData.border"></uv-line> |
| | | </view> |
| | | </template> |
| | | |
| | | <script> |
| | | import mpMixin from '@/uni_modules/uv-ui-tools/libs/mixin/mpMixin.js' |
| | | import mixin from '@/uni_modules/uv-ui-tools/libs/mixin/mixin.js' |
| | | import props from './props.js'; |
| | | // #ifdef APP-NVUE |
| | | const animation = uni.requireNativePlugin('animation') |
| | | const dom = uni.requireNativePlugin('dom') |
| | | // #endif |
| | | /** |
| | | * collapseItem 折叠面板Item |
| | | * @description 通过折叠面板收纳内容区域(搭配uv-collapse使用) |
| | | * @tutorial https://www.uvui.cn/components/collapse.html |
| | | * @property {String} title 标题 |
| | | * @property {String} value 标题右侧内容 |
| | | * @property {String} label 标题下方的描述信息 |
| | | * @property {Boolean} disbled 是否禁用折叠面板 ( 默认 false ) |
| | | * @property {Boolean} isLink 是否展示右侧箭头并开启点击反馈 ( 默认 true ) |
| | | * @property {Boolean} clickable 是否开启点击反馈 ( 默认 true ) |
| | | * @property {Boolean} border 是否显示内边框 ( 默认 true ) |
| | | * @property {String} align 标题的对齐方式 ( 默认 'left' ) |
| | | * @property {String | Number} name 唯一标识符 |
| | | * @property {String} icon 标题左侧图片,可为绝对路径的图片或内置图标 |
| | | * @event {Function} change 某个item被打开或者收起时触发 |
| | | * @example <uv-collapse-item :title="item.head" v-for="(item, index) in itemList" :key="index">{{item.body}}</uv-collapse-item> |
| | | */ |
| | | export default { |
| | | name: "uv-collapse-item", |
| | | mixins: [mpMixin, mixin, props], |
| | | data() { |
| | | return { |
| | | elId: '', |
| | | // uni.createAnimation的导出数据 |
| | | animationData: {}, |
| | | // 是否展开状态 |
| | | expanded: false, |
| | | // 根据expanded确定是否显示border,为了控制展开时,cell的下划线更好的显示效果,进行一定时间的延时 |
| | | showBorder: false, |
| | | // 是否动画中,如果是则不允许继续触发点击 |
| | | animating: false, |
| | | // 父组件uv-collapse的参数 |
| | | parentData: { |
| | | accordion: false, |
| | | border: false |
| | | } |
| | | }; |
| | | }, |
| | | watch: { |
| | | expanded(n) { |
| | | clearTimeout(this.timer) |
| | | this.timer = null |
| | | // 这里根据expanded的值来进行一定的延时,是为了cell的下划线更好的显示效果 |
| | | this.timer = setTimeout(() => { |
| | | this.showBorder = n |
| | | }, n ? 10 : 290) |
| | | } |
| | | }, |
| | | created() { |
| | | this.elId = this.$uv.guid(); |
| | | }, |
| | | mounted() { |
| | | this.init() |
| | | }, |
| | | methods: { |
| | | // 异步获取内容,或者动态修改了内容时,需要重新初始化 |
| | | init() { |
| | | // 初始化数据 |
| | | this.updateParentData() |
| | | if (!this.parent) { |
| | | return this.$uv.error('uv-collapse-item必须要搭配uv-collapse组件使用') |
| | | } |
| | | const { |
| | | value, |
| | | accordion, |
| | | children = [] |
| | | } = this.parent |
| | | |
| | | if (accordion) { |
| | | if (this.$uv.test.array(value)) { |
| | | return this.$uv.error('手风琴模式下,uv-collapse组件的value参数不能为数组') |
| | | } |
| | | this.expanded = this.name == value |
| | | } else { |
| | | if (!this.$uv.test.array(value) && value !== null) { |
| | | return this.$uv.error('非手风琴模式下,uv-collapse组件的value参数必须为数组') |
| | | } |
| | | this.expanded = (value || []).some(item => item == this.name) |
| | | } |
| | | // 设置组件的展开或收起状态 |
| | | this.$nextTick(function() { |
| | | this.setContentAnimate() |
| | | }) |
| | | }, |
| | | updateParentData() { |
| | | // 此方法在mixin中 |
| | | this.getParentData('uv-collapse') |
| | | }, |
| | | async setContentAnimate() { |
| | | // 每次面板打开或者收起时,都查询元素尺寸 |
| | | // 好处是,父组件从服务端获取内容后,变更折叠面板后可以获得最新的高度 |
| | | const rect = await this.queryRect() |
| | | const height = this.expanded ? rect.height : 0 |
| | | this.animating = true |
| | | // #ifdef APP-NVUE |
| | | const ref = this.$refs['animation'].ref |
| | | animation.transition(ref, { |
| | | styles: { |
| | | height: height + 'px' |
| | | }, |
| | | duration: this.duration, |
| | | // 必须设置为true,否则会到面板收起或展开时,页面其他元素不会随之调整它们的布局 |
| | | needLayout: true, |
| | | timingFunction: 'ease-in-out', |
| | | }, () => { |
| | | this.animating = false |
| | | }) |
| | | // #endif |
| | | |
| | | // #ifndef APP-NVUE |
| | | const animation = uni.createAnimation({ |
| | | timingFunction: 'ease-in-out', |
| | | }); |
| | | animation |
| | | .height(height) |
| | | .step({ |
| | | duration: this.duration, |
| | | }) |
| | | .step() |
| | | // 导出动画数据给面板的animationData值 |
| | | this.animationData = animation.export() |
| | | // 标识动画结束 |
| | | this.$uv.sleep(this.duration).then(() => { |
| | | this.animating = false |
| | | }) |
| | | // #endif |
| | | }, |
| | | // 点击collapsehead头部 |
| | | clickHandler() { |
| | | if (this.disabled && this.animating) return |
| | | // 设置本组件为相反的状态 |
| | | this.parent && this.parent.onChange(this) |
| | | }, |
| | | // 查询内容高度 |
| | | queryRect() { |
| | | // #ifndef APP-NVUE |
| | | // 组件内部一般用this.$uvGetRect,对外的为getRect,二者功能一致,名称不同 |
| | | return new Promise(resolve => { |
| | | this.$uvGetRect(`#${this.elId}`).then(size => { |
| | | resolve(size) |
| | | }) |
| | | }) |
| | | // #endif |
| | | |
| | | // #ifdef APP-NVUE |
| | | // nvue下,使用dom模块查询元素高度 |
| | | // 返回一个promise,让调用此方法的主体能使用then回调 |
| | | return new Promise(resolve => { |
| | | dom.getComponentRect(this.$refs[this.elId], res => { |
| | | resolve(res.size) |
| | | }) |
| | | }) |
| | | // #endif |
| | | } |
| | | }, |
| | | }; |
| | | </script> |
| | | |
| | | <style lang="scss" scoped> |
| | | @import '@/uni_modules/uv-ui-tools/libs/css/components.scss'; |
| | | @import '@/uni_modules/uv-ui-tools/libs/css/color.scss'; |
| | | .uv-collapse-item { |
| | | |
| | | &__content { |
| | | overflow: hidden; |
| | | height: 0; |
| | | |
| | | &__text { |
| | | padding: 12px 15px; |
| | | color: $uv-content-color; |
| | | font-size: 14px; |
| | | line-height: 18px; |
| | | } |
| | | } |
| | | } |
| | | </style> |
| New file |
| | |
| | | export default { |
| | | props: { |
| | | // 当前展开面板的name,非手风琴模式:[<string | number>],手风琴模式:string | number |
| | | value: { |
| | | type: [String, Number, Array, null], |
| | | default: null |
| | | }, |
| | | // 是否手风琴模式 |
| | | accordion: { |
| | | type: Boolean, |
| | | default: false |
| | | }, |
| | | // 是否显示外边框 |
| | | border: { |
| | | type: Boolean, |
| | | default: true |
| | | }, |
| | | ...uni.$uv?.props?.collapse |
| | | } |
| | | } |
| New file |
| | |
| | | <template> |
| | | <view class="uv-collapse"> |
| | | <uv-line v-if="border"></uv-line> |
| | | <slot /> |
| | | </view> |
| | | </template> |
| | | |
| | | <script> |
| | | import mpMixin from '@/uni_modules/uv-ui-tools/libs/mixin/mpMixin.js' |
| | | import mixin from '@/uni_modules/uv-ui-tools/libs/mixin/mixin.js' |
| | | import props from './props.js'; |
| | | /** |
| | | * collapse 折叠面板 |
| | | * @description 通过折叠面板收纳内容区域 |
| | | * @tutorial https://www.uvui.cn/components/collapse.html |
| | | * @property {String | Number | Array} value 当前展开面板的name,非手风琴模式:[<string | number>],手风琴模式:string | number |
| | | * @property {Boolean} accordion 是否手风琴模式( 默认 false ) |
| | | * @property {Boolean} border 是否显示外边框 ( 默认 true ) |
| | | * @event {Function} change 当前激活面板展开时触发(如果是手风琴模式,参数activeNames类型为String,否则为Array) |
| | | * @example <uv-collapse></uv-collapse> |
| | | */ |
| | | export default { |
| | | name: "uv-collapse", |
| | | mixins: [mpMixin, mixin, props], |
| | | watch: { |
| | | needInit() { |
| | | this.init() |
| | | }, |
| | | // 当父组件需要子组件需要共享的参数发生了变化,手动通知子组件 |
| | | parentData() { |
| | | if (this.children.length) { |
| | | this.children.map(child => { |
| | | // 判断子组件(uv-checkbox)如果有updateParentData方法的话,就就执行(执行的结果是子组件重新从父组件拉取了最新的值) |
| | | typeof(child.updateParentData) === 'function' && child.updateParentData() |
| | | }) |
| | | } |
| | | } |
| | | }, |
| | | created() { |
| | | this.children = [] |
| | | }, |
| | | computed: { |
| | | needInit() { |
| | | // 通过computed,同时监听accordion和value值的变化 |
| | | // 再通过watch去执行init()方法,进行再一次的初始化 |
| | | return [this.accordion, this.value] |
| | | } |
| | | }, |
| | | methods: { |
| | | // 重新初始化一次内部的所有子元素 |
| | | init() { |
| | | this.children.map(child => { |
| | | child.init() |
| | | }) |
| | | }, |
| | | /** |
| | | * collapse-item被点击时触发,由collapse统一处理各子组件的状态 |
| | | * @param {Object} target 被操作的面板的实例 |
| | | */ |
| | | onChange(target) { |
| | | let changeArr = [] |
| | | this.children.map((child, index) => { |
| | | // 如果是手风琴模式,将其他的折叠面板收起来 |
| | | if (this.accordion) { |
| | | child.expanded = child === target ? !target.expanded : false |
| | | child.setContentAnimate() |
| | | } else { |
| | | if(child === target) { |
| | | child.expanded = !child.expanded |
| | | child.setContentAnimate() |
| | | } |
| | | } |
| | | // 拼接change事件中,数组元素的状态 |
| | | changeArr.push({ |
| | | // 如果没有定义name属性,则默认返回组件的index索引 |
| | | name: child.name || index, |
| | | status: child.expanded ? 'open' : 'close' |
| | | }) |
| | | }) |
| | | |
| | | this.$emit('change', changeArr) |
| | | this.$emit(target.expanded ? 'open' : 'close', target.name) |
| | | } |
| | | } |
| | | } |
| | | </script> |
| New file |
| | |
| | | { |
| | | "id": "uv-collapse", |
| | | "displayName": "uv-collapse 折叠面板 全面兼容小程序、nvue、vue2、vue3等多端", |
| | | "version": "1.0.1", |
| | | "description": "折叠面板组件,通过折叠面板收纳内容区域,点击可展开收起,多功能参数可配置。", |
| | | "keywords": [ |
| | | "uv-collapse", |
| | | "uvui", |
| | | "uv-ui", |
| | | "collapse", |
| | | "折叠面板" |
| | | ], |
| | | "repository": "", |
| | | "engines": { |
| | | "HBuilderX": "^3.1.0" |
| | | }, |
| | | "dcloudext": { |
| | | "type": "component-vue", |
| | | "sale": { |
| | | "regular": { |
| | | "price": "0.00" |
| | | }, |
| | | "sourcecode": { |
| | | "price": "0.00" |
| | | } |
| | | }, |
| | | "contact": { |
| | | "qq": "" |
| | | }, |
| | | "declaration": { |
| | | "ads": "无", |
| | | "data": "插件不采集任何数据", |
| | | "permissions": "无" |
| | | }, |
| | | "npmurl": "" |
| | | }, |
| | | "uni_modules": { |
| | | "dependencies": [ |
| | | "uv-ui-tools", |
| | | "uv-line", |
| | | "uv-cell" |
| | | ], |
| | | "encrypt": [], |
| | | "platforms": { |
| | | "cloud": { |
| | | "tcb": "y", |
| | | "aliyun": "y" |
| | | }, |
| | | "client": { |
| | | "Vue": { |
| | | "vue2": "y", |
| | | "vue3": "y" |
| | | }, |
| | | "App": { |
| | | "app-vue": "y", |
| | | "app-nvue": "y" |
| | | }, |
| | | "H5-mobile": { |
| | | "Safari": "y", |
| | | "Android Browser": "y", |
| | | "微信浏览器(Android)": "y", |
| | | "QQ浏览器(Android)": "y" |
| | | }, |
| | | "H5-pc": { |
| | | "Chrome": "y", |
| | | "IE": "y", |
| | | "Edge": "y", |
| | | "Firefox": "y", |
| | | "Safari": "y" |
| | | }, |
| | | "小程序": { |
| | | "微信": "y", |
| | | "阿里": "y", |
| | | "百度": "y", |
| | | "字节跳动": "y", |
| | | "QQ": "y", |
| | | "钉钉": "u", |
| | | "快手": "u", |
| | | "飞书": "u", |
| | | "京东": "u" |
| | | }, |
| | | "快应用": { |
| | | "华为": "u", |
| | | "联盟": "u" |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| New file |
| | |
| | | ## Collapse 折叠面板 |
| | | |
| | | > **组件名:uv-collapse** |
| | | |
| | | 通过折叠面板收纳内容区域,点击可展开收起,多功能参数可配置。 |
| | | |
| | | ### <a href="https://www.uvui.cn/components/collapse.html" target="_blank">查看文档</a> |
| | | |
| | | ### [完整示例项目下载 | 关注更多组件](https://ext.dcloud.net.cn/plugin?name=uv-ui) |
| | | |
| | | #### 如使用过程中有任何问题,或者您对uv-ui有一些好的建议,欢迎加入 uv-ui 交流群:<a href="https://ext.dcloud.net.cn/plugin?id=12287" target="_blank">uv-ui</a>、<a href="https://www.uvui.cn/components/addQQGroup.html" target="_blank">官方QQ群</a> |
| New file |
| | |
| | | ## 1.0.3(2023-10-13) |
| | | 1. unmounted兼容vue3 |
| | | ## 1.0.2(2023-06-20) |
| | | 1. 增加外部样式customStyle参数 |
| | | ## 1.0.1(2023-05-16) |
| | | 1. 优化组件依赖,修改后无需全局引入,组件导入即可使用 |
| | | 2. 优化部分功能 |
| | | ## 1.0.0(2023-05-10) |
| | | uv-count-down 倒计时 |
| New file |
| | |
| | | export default { |
| | | props: { |
| | | // 倒计时时长,单位ms |
| | | time: { |
| | | type: [String, Number], |
| | | default: 0 |
| | | }, |
| | | // 时间格式,DD-日,HH-时,mm-分,ss-秒,SSS-毫秒 |
| | | format: { |
| | | type: String, |
| | | default: 'HH:mm:ss' |
| | | }, |
| | | // 是否自动开始倒计时 |
| | | autoStart: { |
| | | type: Boolean, |
| | | default: true |
| | | }, |
| | | // 是否展示毫秒倒计时 |
| | | millisecond: { |
| | | type: Boolean, |
| | | default: false |
| | | }, |
| | | ...uni.$uv?.props?.countDown |
| | | } |
| | | } |
| New file |
| | |
| | | // 补0,如1 -> 01 |
| | | function padZero(num, targetLength = 2) { |
| | | let str = `${num}` |
| | | while (str.length < targetLength) { |
| | | str = `0${str}` |
| | | } |
| | | return str |
| | | } |
| | | const SECOND = 1000 |
| | | const MINUTE = 60 * SECOND |
| | | const HOUR = 60 * MINUTE |
| | | const DAY = 24 * HOUR |
| | | export function parseTimeData(time) { |
| | | const days = Math.floor(time / DAY) |
| | | const hours = Math.floor((time % DAY) / HOUR) |
| | | const minutes = Math.floor((time % HOUR) / MINUTE) |
| | | const seconds = Math.floor((time % MINUTE) / SECOND) |
| | | const milliseconds = Math.floor(time % SECOND) |
| | | return { |
| | | days, |
| | | hours, |
| | | minutes, |
| | | seconds, |
| | | milliseconds |
| | | } |
| | | } |
| | | export function parseFormat(format, timeData) { |
| | | let { |
| | | days, |
| | | hours, |
| | | minutes, |
| | | seconds, |
| | | milliseconds |
| | | } = timeData |
| | | // 如果格式化字符串中不存在DD(天),则将天的时间转为小时中去 |
| | | if (format.indexOf('DD') === -1) { |
| | | hours += days * 24 |
| | | } else { |
| | | // 对天补0 |
| | | format = format.replace('DD', padZero(days)) |
| | | } |
| | | // 其他同理于DD的格式化处理方式 |
| | | if (format.indexOf('HH') === -1) { |
| | | minutes += hours * 60 |
| | | } else { |
| | | format = format.replace('HH', padZero(hours)) |
| | | } |
| | | if (format.indexOf('mm') === -1) { |
| | | seconds += minutes * 60 |
| | | } else { |
| | | format = format.replace('mm', padZero(minutes)) |
| | | } |
| | | if (format.indexOf('ss') === -1) { |
| | | milliseconds += seconds * 1000 |
| | | } else { |
| | | format = format.replace('ss', padZero(seconds)) |
| | | } |
| | | return format.replace('SSS', padZero(milliseconds, 3)) |
| | | } |
| | | export function isSameSecond(time1, time2) { |
| | | return Math.floor(time1 / 1000) === Math.floor(time2 / 1000) |
| | | } |
| New file |
| | |
| | | <template> |
| | | <view |
| | | class="uv-count-down" |
| | | :style="[$uv.addStyle(customStyle)]"> |
| | | <slot> |
| | | <text class="uv-count-down__text">{{ formattedTime }}</text> |
| | | </slot> |
| | | </view> |
| | | </template> |
| | | <script> |
| | | import mpMixin from '@/uni_modules/uv-ui-tools/libs/mixin/mpMixin.js' |
| | | import mixin from '@/uni_modules/uv-ui-tools/libs/mixin/mixin.js' |
| | | import props from './props.js'; |
| | | import { |
| | | isSameSecond, |
| | | parseFormat, |
| | | parseTimeData |
| | | } from './utils'; |
| | | /** |
| | | * uv-count-down 倒计时 |
| | | * @description 该组件一般使用于某个活动的截止时间上,通过数字的变化,给用户明确的时间感受,提示用户进行某一个行为操作。 |
| | | * @tutorial https://www.uvui.cn/components/countDown.html |
| | | * @property {String | Number} time 倒计时时长,单位ms (默认 0 ) |
| | | * @property {String} format 时间格式,DD-日,HH-时,mm-分,ss-秒,SSS-毫秒 (默认 'HH:mm:ss' ) |
| | | * @property {Boolean} autoStart 是否自动开始倒计时 (默认 true ) |
| | | * @property {Boolean} millisecond 是否展示毫秒倒计时 (默认 false ) |
| | | * @event {Function} finish 倒计时结束时触发 |
| | | * @event {Function} change 倒计时变化时触发 |
| | | * @event {Function} start 开始倒计时 |
| | | * @event {Function} pause 暂停倒计时 |
| | | * @event {Function} reset 重设倒计时,若 auto-start 为 true,重设后会自动开始倒计时 |
| | | * @example <uv-count-down :time="time"></uv-count-down> |
| | | */ |
| | | export default { |
| | | name: 'uv-count-down', |
| | | mixins: [mpMixin, mixin, props], |
| | | data() { |
| | | return { |
| | | timer: null, |
| | | // 各单位(天,时,分等)剩余时间 |
| | | timeData: parseTimeData(0), |
| | | // 格式化后的时间,如"03:23:21" |
| | | formattedTime: '0', |
| | | // 倒计时是否正在进行中 |
| | | runing: false, |
| | | endTime: 0, // 结束的毫秒时间戳 |
| | | remainTime: 0, // 剩余的毫秒时间 |
| | | } |
| | | }, |
| | | watch: { |
| | | time(n) { |
| | | this.reset() |
| | | } |
| | | }, |
| | | mounted() { |
| | | this.init() |
| | | }, |
| | | methods: { |
| | | init() { |
| | | this.reset() |
| | | }, |
| | | // 开始倒计时 |
| | | start() { |
| | | if (this.runing) return |
| | | // 标识为进行中 |
| | | this.runing = true |
| | | // 结束时间戳 = 此刻时间戳 + 剩余的时间 |
| | | this.endTime = Date.now() + this.remainTime |
| | | this.toTick() |
| | | }, |
| | | // 根据是否展示毫秒,执行不同操作函数 |
| | | toTick() { |
| | | if (this.millisecond) { |
| | | this.microTick() |
| | | } else { |
| | | this.macroTick() |
| | | } |
| | | }, |
| | | macroTick() { |
| | | this.clearTimeout() |
| | | // 每隔一定时间,更新一遍定时器的值 |
| | | // 同时此定时器的作用也能带来毫秒级的更新 |
| | | this.timer = setTimeout(() => { |
| | | // 获取剩余时间 |
| | | const remain = this.getRemainTime() |
| | | // 重设剩余时间 |
| | | if (!isSameSecond(remain, this.remainTime) || remain === 0) { |
| | | this.setRemainTime(remain) |
| | | } |
| | | // 如果剩余时间不为0,则继续检查更新倒计时 |
| | | if (this.remainTime !== 0) { |
| | | this.macroTick() |
| | | } |
| | | }, 30) |
| | | }, |
| | | microTick() { |
| | | this.clearTimeout() |
| | | this.timer = setTimeout(() => { |
| | | this.setRemainTime(this.getRemainTime()) |
| | | if (this.remainTime !== 0) { |
| | | this.microTick() |
| | | } |
| | | }, 50) |
| | | }, |
| | | // 获取剩余的时间 |
| | | getRemainTime() { |
| | | // 取最大值,防止出现小于0的剩余时间值 |
| | | return Math.max(this.endTime - Date.now(), 0) |
| | | }, |
| | | // 设置剩余的时间 |
| | | setRemainTime(remain) { |
| | | this.remainTime = remain |
| | | // 根据剩余的毫秒时间,得出该有天,小时,分钟等的值,返回一个对象 |
| | | const timeData = parseTimeData(remain) |
| | | this.$emit('change', timeData) |
| | | // 得出格式化后的时间 |
| | | this.formattedTime = parseFormat(this.format, timeData) |
| | | // 如果时间已到,停止倒计时 |
| | | if (remain <= 0) { |
| | | this.pause() |
| | | this.$emit('finish') |
| | | } |
| | | }, |
| | | // 重置倒计时 |
| | | reset() { |
| | | this.pause() |
| | | this.remainTime = this.time |
| | | this.setRemainTime(this.remainTime) |
| | | if (this.autoStart) { |
| | | this.start() |
| | | } |
| | | }, |
| | | // 暂停倒计时 |
| | | pause() { |
| | | this.runing = false; |
| | | this.clearTimeout() |
| | | }, |
| | | // 清空定时器 |
| | | clearTimeout() { |
| | | clearTimeout(this.timer) |
| | | this.timer = null |
| | | } |
| | | }, |
| | | // #ifdef VUE2 |
| | | beforeDestroy() { |
| | | this.clearTimeout() |
| | | }, |
| | | // #endif |
| | | // #ifdef VUE3 |
| | | unmounted() { |
| | | this.clearTimeout() |
| | | } |
| | | // #endif |
| | | } |
| | | </script> |
| | | <style lang="scss" scoped> |
| | | @import '@/uni_modules/uv-ui-tools/libs/css/components.scss'; |
| | | @import '@/uni_modules/uv-ui-tools/libs/css/color.scss'; |
| | | $uv-count-down-text-color: $uv-content-color !default; |
| | | $uv-count-down-text-font-size: 15px !default; |
| | | $uv-count-down-text-line-height: 22px !default; |
| | | .uv-count-down { |
| | | &__text { |
| | | color: $uv-count-down-text-color; |
| | | font-size: $uv-count-down-text-font-size; |
| | | line-height: $uv-count-down-text-line-height; |
| | | } |
| | | } |
| | | </style> |
| New file |
| | |
| | | { |
| | | "id": "uv-count-down", |
| | | "displayName": "uv-count-down 倒计时 全面兼容小程序、nvue、vue2、vue3等多端", |
| | | "version": "1.0.3", |
| | | "description": "该倒计时组件一般使用于某个活动的截止时间上,通过数字的变化,给用户明确的时间感受,提示用户进行某一个行为操作。", |
| | | "keywords": [ |
| | | "uv-count-down", |
| | | "uvui", |
| | | "uv-ui", |
| | | "countDown", |
| | | "倒计时" |
| | | ], |
| | | "repository": "", |
| | | "engines": { |
| | | "HBuilderX": "^3.1.0" |
| | | }, |
| | | "dcloudext": { |
| | | "type": "component-vue", |
| | | "sale": { |
| | | "regular": { |
| | | "price": "0.00" |
| | | }, |
| | | "sourcecode": { |
| | | "price": "0.00" |
| | | } |
| | | }, |
| | | "contact": { |
| | | "qq": "" |
| | | }, |
| | | "declaration": { |
| | | "ads": "无", |
| | | "data": "插件不采集任何数据", |
| | | "permissions": "无" |
| | | }, |
| | | "npmurl": "" |
| | | }, |
| | | "uni_modules": { |
| | | "dependencies": [ |
| | | "uv-ui-tools" |
| | | ], |
| | | "encrypt": [], |
| | | "platforms": { |
| | | "cloud": { |
| | | "tcb": "y", |
| | | "aliyun": "y" |
| | | }, |
| | | "client": { |
| | | "Vue": { |
| | | "vue2": "y", |
| | | "vue3": "y" |
| | | }, |
| | | "App": { |
| | | "app-vue": "y", |
| | | "app-nvue": "y" |
| | | }, |
| | | "H5-mobile": { |
| | | "Safari": "y", |
| | | "Android Browser": "y", |
| | | "微信浏览器(Android)": "y", |
| | | "QQ浏览器(Android)": "y" |
| | | }, |
| | | "H5-pc": { |
| | | "Chrome": "y", |
| | | "IE": "y", |
| | | "Edge": "y", |
| | | "Firefox": "y", |
| | | "Safari": "y" |
| | | }, |
| | | "小程序": { |
| | | "微信": "y", |
| | | "阿里": "y", |
| | | "百度": "y", |
| | | "字节跳动": "y", |
| | | "QQ": "y", |
| | | "钉钉": "u", |
| | | "快手": "u", |
| | | "飞书": "u", |
| | | "京东": "u" |
| | | }, |
| | | "快应用": { |
| | | "华为": "u", |
| | | "联盟": "u" |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| New file |
| | |
| | | ## CountDown 倒计时 |
| | | |
| | | > **组件名:uv-count-down** |
| | | |
| | | 该组件一般使用于某个活动的截止时间上,通过数字的变化,给用户明确的时间感受,提示用户进行某一个行为操作。 |
| | | |
| | | ### <a href="https://www.uvui.cn/components/countDown.html" target="_blank">查看文档</a> |
| | | |
| | | ### [完整示例项目下载 | 关注更多组件](https://ext.dcloud.net.cn/plugin?name=uv-ui) |
| | | |
| | | #### 如使用过程中有任何问题,或者您对uv-ui有一些好的建议,欢迎加入 uv-ui 交流群:<a href="https://ext.dcloud.net.cn/plugin?id=12287" target="_blank">uv-ui</a>、<a href="https://www.uvui.cn/components/addQQGroup.html" target="_blank">官方QQ群</a> |
| New file |
| | |
| | | ## 1.0.4(2023-06-20) |
| | | 1. 优化 |
| | | ## 1.0.3(2023-06-20) |
| | | 1. 修复继续滚动的函数 |
| | | 2. 修复其他 |
| | | ## 1.0.2(2023-06-20) |
| | | 1. 适配px和rpx的单位 |
| | | 2. 适配customStyle参数 |
| | | ## 1.0.1(2023-05-16) |
| | | 1. 优化组件依赖,修改后无需全局引入,组件导入即可使用 |
| | | 2. 优化部分功能 |
| | | ## 1.0.0(2023-05-10) |
| | | uv-count-to 数字滚动 |
| New file |
| | |
| | | export default { |
| | | props: { |
| | | // 开始的数值,默认从0增长到某一个数 |
| | | startVal: { |
| | | type: [String, Number], |
| | | default: 0 |
| | | }, |
| | | // 要滚动的目标数值,必须 |
| | | endVal: { |
| | | type: [String, Number], |
| | | default: 0 |
| | | }, |
| | | // 滚动到目标数值的动画持续时间,单位为毫秒(ms) |
| | | duration: { |
| | | type: [String, Number], |
| | | default: 2000 |
| | | }, |
| | | // 设置数值后是否自动开始滚动 |
| | | autoplay: { |
| | | type: Boolean, |
| | | default: true |
| | | }, |
| | | // 要显示的小数位数 |
| | | decimals: { |
| | | type: [String, Number], |
| | | default: 0 |
| | | }, |
| | | // 是否在即将到达目标数值的时候,使用缓慢滚动的效果 |
| | | useEasing: { |
| | | type: Boolean, |
| | | default: true |
| | | }, |
| | | // 十进制分割 |
| | | decimal: { |
| | | type: [String, Number], |
| | | default: '.' |
| | | }, |
| | | // 字体颜色 |
| | | color: { |
| | | type: String, |
| | | default: '#606266' |
| | | }, |
| | | // 字体大小 |
| | | fontSize: { |
| | | type: [String, Number], |
| | | default: 22 |
| | | }, |
| | | // 是否加粗字体 |
| | | bold: { |
| | | type: Boolean, |
| | | default: false |
| | | }, |
| | | // 千位分隔符,类似金额的分割(¥23,321.05中的",") |
| | | separator: { |
| | | type: String, |
| | | default: '' |
| | | }, |
| | | ...uni.$uv?.props?.countTo |
| | | } |
| | | } |
| New file |
| | |
| | | <template> |
| | | <text |
| | | class="uv-count-num" |
| | | :style="[{ |
| | | fontSize: $uv.addUnit(fontSize), |
| | | fontWeight: bold ? 'bold' : 'normal', |
| | | color: color |
| | | },$uv.addStyle(customStyle)]" |
| | | >{{ displayValue }}</text> |
| | | </template> |
| | | |
| | | <script> |
| | | import mpMixin from '@/uni_modules/uv-ui-tools/libs/mixin/mpMixin.js' |
| | | import mixin from '@/uni_modules/uv-ui-tools/libs/mixin/mixin.js' |
| | | import props from './props.js'; |
| | | /** |
| | | * countTo 数字滚动 |
| | | * @description 该组件一般用于需要滚动数字到某一个值的场景,目标要求是一个递增的值。 |
| | | * @tutorial https://www.uvui.cn/components/countTo.html |
| | | * @property {String | Number} startVal 开始的数值,默认从0增长到某一个数(默认 0 ) |
| | | * @property {String | Number} endVal 要滚动的目标数值,必须 (默认 0 ) |
| | | * @property {String | Number} duration 滚动到目标数值的动画持续时间,单位为毫秒(ms) (默认 2000 ) |
| | | * @property {Boolean} autoplay 设置数值后是否自动开始滚动 (默认 true ) |
| | | * @property {String | Number} decimals 要显示的小数位数,见官网说明(默认 0 ) |
| | | * @property {Boolean} useEasing 滚动结束时,是否缓动结尾,见官网说明(默认 true ) |
| | | * @property {String} decimal 十进制分割 ( 默认 "." ) |
| | | * @property {String} color 字体颜色( 默认 '#606266' ) |
| | | * @property {String | Number} fontSize 字体大小,单位px( 默认 22 ) |
| | | * @property {Boolean} bold 字体是否加粗(默认 false ) |
| | | * @property {String} separator 千位分隔符,见官网说明 |
| | | * @event {Function} end 数值滚动到目标值时触发 |
| | | * @example <uv-count-to ref="uCountTo" :end-val="endVal" :autoplay="autoplay"></uv-count-to> |
| | | */ |
| | | export default { |
| | | name: 'uv-count-to', |
| | | data() { |
| | | return { |
| | | localStartVal: this.startVal, |
| | | displayValue: this.formatNumber(this.startVal), |
| | | printVal: null, |
| | | paused: false, // 是否暂停 |
| | | localDuration: Number(this.duration), |
| | | startTime: null, // 开始的时间 |
| | | timestamp: null, // 时间戳 |
| | | remaining: null, // 停留的时间 |
| | | rAF: null, |
| | | lastTime: 0 // 上一次的时间 |
| | | }; |
| | | }, |
| | | mixins: [mpMixin, mixin, props], |
| | | computed: { |
| | | countDown() { |
| | | return this.startVal > this.endVal; |
| | | } |
| | | }, |
| | | watch: { |
| | | startVal() { |
| | | this.autoplay && this.start(); |
| | | }, |
| | | endVal() { |
| | | this.autoplay && this.start(); |
| | | } |
| | | }, |
| | | mounted() { |
| | | this.autoplay && this.start(); |
| | | }, |
| | | methods: { |
| | | easingFn(t, b, c, d) { |
| | | return (c * (-Math.pow(2, (-10 * t) / d) + 1) * 1024) / 1023 + b; |
| | | }, |
| | | requestAnimationFrame(callback) { |
| | | const currTime = new Date().getTime(); |
| | | // 为了使setTimteout的尽可能的接近每秒60帧的效果 |
| | | const timeToCall = Math.max(0, 16 - (currTime - this.lastTime)); |
| | | const id = setTimeout(() => { |
| | | callback(currTime + timeToCall); |
| | | }, timeToCall); |
| | | this.lastTime = currTime + timeToCall; |
| | | return id; |
| | | }, |
| | | cancelAnimationFrame(id) { |
| | | clearTimeout(id); |
| | | }, |
| | | // 开始滚动数字 |
| | | start() { |
| | | this.localStartVal = this.startVal; |
| | | this.startTime = null; |
| | | this.localDuration = this.duration; |
| | | this.paused = false; |
| | | this.rAF = this.requestAnimationFrame(this.count); |
| | | }, |
| | | // 暂定状态,从暂停状态开始滚动;或者滚动状态下,暂停 |
| | | restart() { |
| | | if (this.paused) { |
| | | this.resume(); |
| | | this.paused = false; |
| | | } else { |
| | | this.stop(); |
| | | this.paused = true; |
| | | } |
| | | }, |
| | | // 暂停 |
| | | stop() { |
| | | this.cancelAnimationFrame(this.rAF); |
| | | this.paused = true; |
| | | }, |
| | | // 重新开始(暂停的情况下) |
| | | resume() { |
| | | if (!this.remaining) return; |
| | | this.startTime = 0; |
| | | this.localDuration = this.remaining; |
| | | this.localStartVal = this.printVal; |
| | | this.requestAnimationFrame(this.count); |
| | | }, |
| | | // 重置 |
| | | reset() { |
| | | this.startTime = null; |
| | | this.cancelAnimationFrame(this.rAF); |
| | | this.displayValue = this.formatNumber(this.startVal); |
| | | }, |
| | | count(timestamp) { |
| | | if (!this.startTime) this.startTime = timestamp; |
| | | this.timestamp = timestamp; |
| | | const progress = timestamp - this.startTime; |
| | | this.remaining = this.localDuration - progress; |
| | | if (this.useEasing) { |
| | | if (this.countDown) { |
| | | this.printVal = this.localStartVal - this.easingFn(progress, 0, this.localStartVal - this.endVal, this.localDuration); |
| | | } else { |
| | | this.printVal = this.easingFn(progress, this.localStartVal, this.endVal - this.localStartVal, this.localDuration); |
| | | } |
| | | } else { |
| | | if (this.countDown) { |
| | | this.printVal = this.localStartVal - (this.localStartVal - this.endVal) * (progress / this.localDuration); |
| | | } else { |
| | | this.printVal = this.localStartVal + (this.endVal - this.localStartVal) * (progress / this.localDuration); |
| | | } |
| | | } |
| | | if (this.countDown) { |
| | | this.printVal = this.printVal < this.endVal ? this.endVal : this.printVal; |
| | | } else { |
| | | this.printVal = this.printVal > this.endVal ? this.endVal : this.printVal; |
| | | } |
| | | this.displayValue = this.formatNumber(this.printVal) || 0; |
| | | if (progress < this.localDuration) { |
| | | this.rAF = this.requestAnimationFrame(this.count); |
| | | } else { |
| | | this.$emit('end'); |
| | | } |
| | | }, |
| | | // 判断是否数字 |
| | | isNumber(val) { |
| | | return !isNaN(parseFloat(val)); |
| | | }, |
| | | formatNumber(num) { |
| | | // 将num转为Number类型,因为其值可能为字符串数值,调用toFixed会报错 |
| | | num = Number(num); |
| | | num = num.toFixed(Number(this.decimals)); |
| | | num += ''; |
| | | const x = num.split('.'); |
| | | let x1 = x[0]; |
| | | const x2 = x.length > 1 ? `${this.decimal}${x[1]}` : ''; |
| | | const rgx = /(\d+)(\d{3})/; |
| | | if (this.separator && !this.isNumber(this.separator)) { |
| | | while (rgx.test(x1)) { |
| | | x1 = x1.replace(rgx, '$1' + this.separator + '$2'); |
| | | } |
| | | } |
| | | return x1 + x2; |
| | | }, |
| | | destroyed() { |
| | | this.cancelAnimationFrame(this.rAF); |
| | | } |
| | | } |
| | | }; |
| | | </script> |
| | | |
| | | <style lang="scss" scoped> |
| | | @import '@/uni_modules/uv-ui-tools/libs/css/components.scss'; |
| | | |
| | | .uv-count-num { |
| | | /* #ifndef APP-NVUE */ |
| | | display: inline-flex; |
| | | /* #endif */ |
| | | text-align: center; |
| | | } |
| | | </style> |
| New file |
| | |
| | | { |
| | | "id": "uv-count-to", |
| | | "displayName": "uv-count-to 数字滚动 全面兼容小程序、nvue、vue2、vue3等多端", |
| | | "version": "1.0.4", |
| | | "description": "该数字滚动组件一般用于需要滚动数字到某一个值的场景,目标要求是一个递增的值,一种数字上升的视觉冲击效果。", |
| | | "keywords": [ |
| | | "countTo", |
| | | "uvui", |
| | | "uv-ui", |
| | | "数字滚动", |
| | | "数字变化" |
| | | ], |
| | | "repository": "", |
| | | "engines": { |
| | | "HBuilderX": "^3.1.0" |
| | | }, |
| | | "dcloudext": { |
| | | "type": "component-vue", |
| | | "sale": { |
| | | "regular": { |
| | | "price": "0.00" |
| | | }, |
| | | "sourcecode": { |
| | | "price": "0.00" |
| | | } |
| | | }, |
| | | "contact": { |
| | | "qq": "" |
| | | }, |
| | | "declaration": { |
| | | "ads": "无", |
| | | "data": "插件不采集任何数据", |
| | | "permissions": "无" |
| | | }, |
| | | "npmurl": "" |
| | | }, |
| | | "uni_modules": { |
| | | "dependencies": [ |
| | | "uv-ui-tools" |
| | | ], |
| | | "encrypt": [], |
| | | "platforms": { |
| | | "cloud": { |
| | | "tcb": "y", |
| | | "aliyun": "y" |
| | | }, |
| | | "client": { |
| | | "Vue": { |
| | | "vue2": "y", |
| | | "vue3": "y" |
| | | }, |
| | | "App": { |
| | | "app-vue": "y", |
| | | "app-nvue": "y" |
| | | }, |
| | | "H5-mobile": { |
| | | "Safari": "y", |
| | | "Android Browser": "y", |
| | | "微信浏览器(Android)": "y", |
| | | "QQ浏览器(Android)": "y" |
| | | }, |
| | | "H5-pc": { |
| | | "Chrome": "y", |
| | | "IE": "y", |
| | | "Edge": "y", |
| | | "Firefox": "y", |
| | | "Safari": "y" |
| | | }, |
| | | "小程序": { |
| | | "微信": "y", |
| | | "阿里": "y", |
| | | "百度": "y", |
| | | "字节跳动": "y", |
| | | "QQ": "y", |
| | | "钉钉": "u", |
| | | "快手": "u", |
| | | "飞书": "u", |
| | | "京东": "u" |
| | | }, |
| | | "快应用": { |
| | | "华为": "u", |
| | | "联盟": "u" |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| New file |
| | |
| | | ## CountTo 数字滚动 |
| | | |
| | | > **组件名:uv-count-to** |
| | | |
| | | 该组件一般用于需要滚动数字到某一个值的场景,目标要求是一个递增的值。 |
| | | |
| | | ### <a href="https://www.uvui.cn/components/countTo.html" target="_blank">查看文档</a> |
| | | |
| | | ### [完整示例项目下载 | 关注更多组件](https://ext.dcloud.net.cn/plugin?name=uv-ui) |
| | | |
| | | #### 如使用过程中有任何问题,或者您对uv-ui有一些好的建议,欢迎加入 uv-ui 交流群:<a href="https://ext.dcloud.net.cn/plugin?id=12287" target="_blank">uv-ui</a>、<a href="https://www.uvui.cn/components/addQQGroup.html" target="_blank">官方QQ群</a> |
| | |
| | | // 确认按钮的颜色 |
| | | confirmColor: { |
| | | type: String, |
| | | default: '#EE2626' |
| | | default: '#3c9cff' |
| | | }, |
| | | // 每列中可见选项的数量 |
| | | visibleItemCount: { |
| | |
| | | * @property {String} cancelText 取消按钮的文字 ( 默认 '取消' ) |
| | | * @property {String} confirmText 确认按钮的文字 ( 默认 '确认' ) |
| | | * @property {String} cancelColor 取消按钮的颜色 ( 默认 '#909193' ) |
| | | * @property {String} confirmColor 确认按钮的颜色 ( 默认 '#EE2626' ) |
| | | * @property {String} confirmColor 确认按钮的颜色 ( 默认 '#3c9cff' ) |
| | | * @property {String | Number} visibleItemCount 每列中可见选项的数量 ( 默认 5 ) |
| | | * @property {Boolean} closeOnClickOverlay 是否允许点击遮罩关闭选择器 ( 默认 true ) |
| | | * @property {String | Number} round 圆角 ( 默认 0 ) |
| New file |
| | |
| | | ## 1.0.4(2023-12-06) |
| | | 1. 优化 |
| | | ## 1.0.3(2023-12-06) |
| | | 1. 阻止事件冒泡问题 |
| | | ## 1.0.2(2023-06-01) |
| | | 1. 修复点击触发两次事件的BUG |
| | | ## 1.0.1(2023-05-16) |
| | | 1. 优化组件依赖,修改后无需全局引入,组件导入即可使用 |
| | | 2. 优化部分功能 |
| | | ## 1.0.0(2023-05-10) |
| | | uv-divider 分割线 |
| New file |
| | |
| | | export default { |
| | | props: { |
| | | // 是否虚线 |
| | | dashed: { |
| | | type: Boolean, |
| | | default: false |
| | | }, |
| | | // 是否细线 |
| | | hairline: { |
| | | type: Boolean, |
| | | default: true |
| | | }, |
| | | // 是否以点替代文字,优先于text字段起作用 |
| | | dot: { |
| | | type: Boolean, |
| | | default: false |
| | | }, |
| | | // 内容文本的位置,left-左边,center-中间,right-右边 |
| | | textPosition: { |
| | | type: String, |
| | | default: 'center' |
| | | }, |
| | | // 文本内容 |
| | | text: { |
| | | type: [String, Number], |
| | | default: '' |
| | | }, |
| | | // 文本大小 |
| | | textSize: { |
| | | type: [String, Number], |
| | | default: 14 |
| | | }, |
| | | // 文本颜色 |
| | | textColor: { |
| | | type: String, |
| | | default: '#909399' |
| | | }, |
| | | // 线条颜色 |
| | | lineColor: { |
| | | type: String, |
| | | default: '#dcdfe6' |
| | | }, |
| | | ...uni.$uv?.props?.divider |
| | | } |
| | | } |
| New file |
| | |
| | | <template> |
| | | <view |
| | | class="uv-divider" |
| | | :style="[$uv.addStyle(customStyle)]" |
| | | @tap="click" |
| | | > |
| | | <uv-line |
| | | :color="lineColor" |
| | | :customStyle="leftLineStyle" |
| | | :hairline="hairline" |
| | | :dashed="dashed"></uv-line> |
| | | <text |
| | | v-if="dot" |
| | | class="uv-divider__dot" |
| | | >●</text> |
| | | <text |
| | | v-else-if="text" |
| | | class="uv-divider__text" |
| | | :style="[textStyle]" |
| | | >{{text}}</text> |
| | | <uv-line |
| | | :color="lineColor" |
| | | :customStyle="rightLineStyle" |
| | | :hairline="hairline" |
| | | :dashed="dashed" |
| | | ></uv-line> |
| | | </view> |
| | | </template> |
| | | <script> |
| | | import mpMixin from '@/uni_modules/uv-ui-tools/libs/mixin/mpMixin.js' |
| | | import mixin from '@/uni_modules/uv-ui-tools/libs/mixin/mixin.js' |
| | | import props from './props.js'; |
| | | /** |
| | | * divider 分割线 |
| | | * @description 区隔内容的分割线,一般用于页面底部"没有更多"的提示。 |
| | | * @tutorial https://www.uvui.cn/components/divider.html |
| | | * @property {Boolean} dashed 是否虚线 (默认 false ) |
| | | * @property {Boolean} hairline 是否细线 (默认 true ) |
| | | * @property {Boolean} dot 是否以点替代文字,优先于text字段起作用 (默认 false ) |
| | | * @property {String} textPosition 内容文本的位置,left-左边,center-中间,right-右边 (默认 'center' ) |
| | | * @property {String | Number} text 文本内容 |
| | | * @property {String | Number} textSize 文本大小 (默认 14) |
| | | * @property {String} textColor 文本颜色 (默认 '#909399' ) |
| | | * @property {String} lineColor 线条颜色 (默认 '#dcdfe6' ) |
| | | * @property {Object} customStyle 定义需要用到的外部样式 |
| | | * |
| | | * @event {Function} click divider组件被点击时触发 |
| | | * @example <uv-divider :color="color">锦瑟无端五十弦</uv-divider> |
| | | */ |
| | | export default { |
| | | name: 'uv-divider', |
| | | mixins: [mpMixin, mixin, props], |
| | | emits: ['click'], |
| | | computed: { |
| | | textStyle() { |
| | | const style = {} |
| | | style.fontSize = this.$uv.addUnit(this.textSize) |
| | | style.color = this.textColor |
| | | return style |
| | | }, |
| | | // 左边线条的的样式 |
| | | leftLineStyle() { |
| | | const style = {} |
| | | // 如果是在左边,设置左边的宽度为固定值 |
| | | if (this.textPosition === 'left') { |
| | | style.width = '80rpx' |
| | | } else { |
| | | style.flex = 1 |
| | | } |
| | | return style |
| | | }, |
| | | // 右边线条的的样式 |
| | | rightLineStyle() { |
| | | const style = {} |
| | | // 如果是在右边,设置右边的宽度为固定值 |
| | | if (this.textPosition === 'right') { |
| | | style.width = '80rpx' |
| | | } else { |
| | | style.flex = 1 |
| | | } |
| | | return style |
| | | } |
| | | }, |
| | | methods: { |
| | | // divider组件被点击时触发 |
| | | click() { |
| | | this.$emit('click'); |
| | | } |
| | | } |
| | | } |
| | | </script> |
| | | <style lang="scss" scoped> |
| | | @import '@/uni_modules/uv-ui-tools/libs/css/components.scss'; |
| | | $uv-divider-margin: 15px 0 !default; |
| | | $uv-divider-text-margin: 0 15px !default; |
| | | $uv-divider-dot-font-size: 12px !default; |
| | | $uv-divider-dot-margin: 0 12px !default; |
| | | $uv-divider-dot-color: #c0c4cc !default; |
| | | .uv-divider { |
| | | @include flex; |
| | | flex-direction: row; |
| | | align-items: center; |
| | | margin: $uv-divider-margin; |
| | | &__text { |
| | | margin: $uv-divider-text-margin; |
| | | } |
| | | &__dot { |
| | | font-size: $uv-divider-dot-font-size; |
| | | margin: $uv-divider-dot-margin; |
| | | color: $uv-divider-dot-color; |
| | | } |
| | | } |
| | | </style> |
| New file |
| | |
| | | { |
| | | "id": "uv-divider", |
| | | "displayName": "uv-divider 分割线 全面兼容小程序、nvue、vue2、vue3等多端", |
| | | "version": "1.0.4", |
| | | "description": "区隔内容的分割线,一般用于页面底部没有更多的提示。", |
| | | "keywords": [ |
| | | "divider", |
| | | "uvui", |
| | | "uv-ui", |
| | | "分割线", |
| | | "没有更多" |
| | | ], |
| | | "repository": "", |
| | | "engines": { |
| | | "HBuilderX": "^3.1.0" |
| | | }, |
| | | "dcloudext": { |
| | | "type": "component-vue", |
| | | "sale": { |
| | | "regular": { |
| | | "price": "0.00" |
| | | }, |
| | | "sourcecode": { |
| | | "price": "0.00" |
| | | } |
| | | }, |
| | | "contact": { |
| | | "qq": "" |
| | | }, |
| | | "declaration": { |
| | | "ads": "无", |
| | | "data": "插件不采集任何数据", |
| | | "permissions": "无" |
| | | }, |
| | | "npmurl": "" |
| | | }, |
| | | "uni_modules": { |
| | | "dependencies": [ |
| | | "uv-ui-tools", |
| | | "uv-line" |
| | | ], |
| | | "encrypt": [], |
| | | "platforms": { |
| | | "cloud": { |
| | | "tcb": "y", |
| | | "aliyun": "y" |
| | | }, |
| | | "client": { |
| | | "Vue": { |
| | | "vue2": "y", |
| | | "vue3": "y" |
| | | }, |
| | | "App": { |
| | | "app-vue": "y", |
| | | "app-nvue": "y" |
| | | }, |
| | | "H5-mobile": { |
| | | "Safari": "y", |
| | | "Android Browser": "y", |
| | | "微信浏览器(Android)": "y", |
| | | "QQ浏览器(Android)": "y" |
| | | }, |
| | | "H5-pc": { |
| | | "Chrome": "y", |
| | | "IE": "y", |
| | | "Edge": "y", |
| | | "Firefox": "y", |
| | | "Safari": "y" |
| | | }, |
| | | "小程序": { |
| | | "微信": "y", |
| | | "阿里": "y", |
| | | "百度": "y", |
| | | "字节跳动": "y", |
| | | "QQ": "y", |
| | | "钉钉": "u", |
| | | "快手": "u", |
| | | "飞书": "u", |
| | | "京东": "u" |
| | | }, |
| | | "快应用": { |
| | | "华为": "u", |
| | | "联盟": "u" |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| New file |
| | |
| | | ## Divider 分割线 |
| | | |
| | | > **组件名:uv-divider** |
| | | |
| | | 区隔内容的分割线,一般用于页面底部"没有更多"的提示。 |
| | | |
| | | ### <a href="https://www.uvui.cn/components/divider.html" target="_blank">查看文档</a> |
| | | |
| | | ### [完整示例项目下载 | 关注更多组件](https://ext.dcloud.net.cn/plugin?name=uv-ui) |
| | | |
| | | #### 如使用过程中有任何问题,或者您对uv-ui有一些好的建议,欢迎加入 uv-ui 交流群:<a href="https://ext.dcloud.net.cn/plugin?id=12287" target="_blank">uv-ui</a>、<a href="https://www.uvui.cn/components/addQQGroup.html" target="_blank">官方QQ群</a> |
| New file |
| | |
| | | ## 1.0.5(2024-01-02) |
| | | 1. 修复parentData不变的BUG |
| | | ## 1.0.4(2023-09-28) |
| | | 1. 增加uv-sticky依赖 |
| | | ## 1.0.3(2023-08-29) |
| | | 1. 修复自定义内容,点击自定义内容时会自动关闭弹窗的问题 |
| | | ## 1.0.2(2023-08-22) |
| | | 1. 优化 |
| | | ## 1.0.1(2023-08-22) |
| | | 1. 增加@change回调,返回弹窗关闭状态 |
| | | 2. 增加init方法,方便位置改变进行调整 |
| | | ## 1.0.0(2023-07-30) |
| | | 新增uv-drop-down 下拉筛选组件 |
| New file |
| | |
| | | <template> |
| | | <view class="uv-drop-down-item" @click="clickHandler"> |
| | | <uv-text :text="label" :size="getTextStyle.size" :color="getTextStyle.color" lines="1" :custom-style="{marginRight: '10rpx',maxWidth:'200rpx'}"></uv-text> |
| | | <uv-icon :name="getDownIcon.name" :size="getDownIcon.size" :color="getDownIcon.color" v-if="[1,'1'].indexOf(type)==-1"></uv-icon> |
| | | </view> |
| | | </template> |
| | | <script> |
| | | import mpMixin from '@/uni_modules/uv-ui-tools/libs/mixin/mpMixin.js'; |
| | | import mixin from '@/uni_modules/uv-ui-tools/libs/mixin/mixin.js'; |
| | | /** |
| | | * DropDown 下拉框 |
| | | * @description 下拉筛选 |
| | | * @tutorial https://ext.dcloud.net.cn/plugin?name=uv-drop-down |
| | | * @property {String | Number} name 字段标识 |
| | | * @property {String | Number} type 类型 1 没有筛选项,直接进行选中和不选中 2 有多个选项 |
| | | * @property {String | Number} label 筛选项的文本 |
| | | * @property {Boolean} isDrop 该项是否打开 |
| | | */ |
| | | export default { |
| | | name: 'uv-drop-down-item', |
| | | mixins: [mpMixin, mixin], |
| | | emits: ['click'], |
| | | props: { |
| | | name: { |
| | | type: [String, Number], |
| | | default: '' |
| | | }, |
| | | // 类型 1 没有筛选项,直接进行选中和不选中 2 有多个选项 |
| | | type: { |
| | | type: [String, Number], |
| | | default: '2' |
| | | }, |
| | | // 筛选的文本 |
| | | label: { |
| | | type: [String], |
| | | default: '' |
| | | }, |
| | | // 筛选值 |
| | | value: { |
| | | type: [String, Number, null], |
| | | default: '' |
| | | }, |
| | | // 是否下拉菜单打开 |
| | | isDrop: { |
| | | type: Boolean, |
| | | default: false |
| | | } |
| | | }, |
| | | data() { |
| | | return { |
| | | parentData: { |
| | | defaultValue: [0, '0', 'all'], |
| | | textSize: '30rpx', |
| | | textColor: '#333', |
| | | textActiveSize: '30rpx', |
| | | textActiveColor: '#3c9cff', |
| | | extraIcon: {}, |
| | | extraActiveIcon: {}, |
| | | sign: '', |
| | | clickHandler: Function |
| | | }, |
| | | active: false, |
| | | isDroped: false, |
| | | elId: '' |
| | | } |
| | | }, |
| | | watch: { |
| | | isDrop: { |
| | | handler(newVal) { |
| | | this.isDroped = newVal; |
| | | }, |
| | | immediate: true |
| | | }, |
| | | value: { |
| | | handler(newVal) { |
| | | this.$nextTick(()=>{ |
| | | this.active = this.parentData.defaultValue.indexOf(newVal) == -1; |
| | | }) |
| | | }, |
| | | immediate: true |
| | | } |
| | | }, |
| | | computed: { |
| | | getDownIcon() { |
| | | const style = { |
| | | size: '30rpx', |
| | | color: '#333', |
| | | ...this.parentData.extraIcon |
| | | } |
| | | if (this.active || this.isDroped) { |
| | | style.color = this.parentData.extraActiveIcon?.color ? this.parentData.extraActiveIcon?.color : '#3c9cff'; |
| | | style.size = this.parentData.extraActiveIcon?.size ? this.parentData.extraActiveIcon?.size : '30rpx'; |
| | | } |
| | | if (this.isDroped) { |
| | | style.name = this.parentData.extraActiveIcon?.name; |
| | | } |
| | | return style; |
| | | }, |
| | | getTextStyle() { |
| | | const style = { |
| | | size: this.parentData.textSize, |
| | | color: this.parentData.textColor |
| | | }; |
| | | if (this.active || this.isDroped) { |
| | | style.size = this.parentData.textActiveSize; |
| | | style.color = this.parentData.textActiveColor; |
| | | } |
| | | return style; |
| | | } |
| | | }, |
| | | created() { |
| | | this.init(); |
| | | }, |
| | | methods: { |
| | | init() { |
| | | this.elId = this.$uv.guid(); |
| | | this.getParentData('uv-drop-down'); |
| | | if (!this.parent) { |
| | | this.$uv.error('uv-drop-down必须搭配uv-drop-down-item组件使用'); |
| | | } |
| | | uni.$on('HANDLE_DROPDOWN_ONE', id => { |
| | | if (this.isDroped && this.elId != id) { |
| | | this.isDroped = false; |
| | | } |
| | | }) |
| | | uni.$on(`${this.parentData.sign}_CLOSEPOPUP`, async () => { |
| | | if (this.isDroped) { |
| | | this.isDroped = false; |
| | | } |
| | | }) |
| | | }, |
| | | async clickHandler() { |
| | | let data = {}; |
| | | uni.$emit('HANDLE_DROPDOWN_ONE', this.elId); |
| | | switch (+this.type) { |
| | | case 1: |
| | | this.active = !this.active; |
| | | data = { |
| | | name: this.name, |
| | | active: this.active, |
| | | type: this.type |
| | | }; |
| | | break; |
| | | case 2: |
| | | this.isDroped = !this.isDroped; |
| | | data = { |
| | | name: this.name, |
| | | active: this.isDroped, |
| | | type: this.type |
| | | }; |
| | | break; |
| | | } |
| | | this.parentData.clickHandler(data); |
| | | this.$emit('click', data); |
| | | uni.$emit(`${this.parentData.sign}_CLICKMENU`, { |
| | | show: +this.type > 1 && this.isDroped |
| | | }); |
| | | } |
| | | } |
| | | } |
| | | </script> |
| | | <style scoped lang="scss"> |
| | | @import '@/uni_modules/uv-ui-tools/libs/css/components.scss'; |
| | | .uv-drop-down-item { |
| | | @include flex; |
| | | align-items: center; |
| | | padding: 20rpx; |
| | | } |
| | | </style> |
| New file |
| | |
| | | <template> |
| | | <view class="uv-drop-down-popup"> |
| | | <uv-transition :show="show" mode="fade" :duration="300" :custom-style="overlayStyle" @click="clickOverlay"> |
| | | <view class="uv-dp__container" ref="uvDPContainer" :style="{height: `${height}px`}" @click.stop="blockClick"> |
| | | <view class="uv-dp__container__list" ref="uvDPList"> |
| | | <slot> |
| | | <view class="uv-dp__container__list--item" v-for="(item,index) in list" :key="index" @click="clickHandler(item,index)" :style="[itemCustomStyle(index)]"> |
| | | <uv-text :text="item[keyName]" :size="getTextSize(index)" :color="getTextColor(index)"></uv-text> |
| | | </view> |
| | | </slot> |
| | | </view> |
| | | </view> |
| | | </uv-transition> |
| | | </view> |
| | | </template> |
| | | <script> |
| | | import mpMixin from '@/uni_modules/uv-ui-tools/libs/mixin/mpMixin.js'; |
| | | import mixin from '@/uni_modules/uv-ui-tools/libs/mixin/mixin.js'; |
| | | // #ifdef APP-NVUE |
| | | const animation = uni.requireNativePlugin('animation'); |
| | | const dom = uni.requireNativePlugin('dom'); |
| | | // #endif |
| | | /** |
| | | * DropDownPopup 下拉框 |
| | | * @description 下拉筛选框 |
| | | * @tutorial https://ext.dcloud.net.cn/plugin?name=uv-drop-down |
| | | * @property {String | Number} name 字段标识 |
| | | * @property {String | Number} zIndex 弹出层的层级 |
| | | * @property {String | Number} opacity 遮罩层的透明度 |
| | | * @property {Boolean} clickOverlayOnClose 是否允许点击遮罩层关闭弹窗 |
| | | * @property {Object} currentDropItem 当前下拉筛选菜单对象 |
| | | * @property {String} keyName 指定从当前下拉筛选菜单对象元素中读取哪个属性作为文本展示 |
| | | */ |
| | | export default { |
| | | name: 'uv-drop-down-popup', |
| | | mixins: [mpMixin, mixin], |
| | | props: { |
| | | sign: { |
| | | type: [String, Number], |
| | | default: 'UVDROPDOWN' |
| | | }, |
| | | zIndex: { |
| | | type: [Number, String], |
| | | default: 999 |
| | | }, |
| | | opacity: { |
| | | type: [Number, String], |
| | | default: 0.5 |
| | | }, |
| | | clickOverlayOnClose: { |
| | | type: Boolean, |
| | | default: true |
| | | }, |
| | | // 当前下拉选项对象 |
| | | currentDropItem: { |
| | | type: Object, |
| | | default () { |
| | | return { |
| | | activeIndex: 0, |
| | | child: [] |
| | | } |
| | | } |
| | | }, |
| | | keyName: { |
| | | type: String, |
| | | default: 'label' |
| | | } |
| | | }, |
| | | data() { |
| | | return { |
| | | show: false, |
| | | rect: {}, |
| | | height: 0 |
| | | } |
| | | }, |
| | | computed: { |
| | | overlayStyle() { |
| | | let { height = 0, top = 0 } = this.rect; |
| | | // #ifdef H5 |
| | | top += this.$uv.sys().windowTop; |
| | | // #endif |
| | | const style = { |
| | | position: 'fixed', |
| | | top: `${top+height}px`, |
| | | left: 0, |
| | | right: 0, |
| | | zIndex: this.zIndex, |
| | | bottom: 0, |
| | | 'background-color': `rgba(0, 0, 0, ${this.opacity})` |
| | | } |
| | | return this.$uv.deepMerge(style, this.$uv.addStyle(this.customStyle)) |
| | | }, |
| | | list() { |
| | | try { |
| | | return Array.isArray(this.currentDropItem.child) ? this.currentDropItem.child : []; |
| | | } catch (e) { |
| | | return []; |
| | | } |
| | | }, |
| | | getTextColor(index) { |
| | | return index => { |
| | | const active = this.currentDropItem.activeIndex == index; |
| | | const color = this.currentDropItem.color; |
| | | const activeColor = this.currentDropItem.activeColor; |
| | | if (active) { |
| | | return activeColor ? activeColor : '#3c9cff'; |
| | | } |
| | | return color ? color : '#333'; |
| | | } |
| | | }, |
| | | getTextSize(index) { |
| | | return index => { |
| | | const active = this.currentDropItem.activeIndex == index; |
| | | const size = this.currentDropItem.size; |
| | | const activeSize = this.currentDropItem.activeSize; |
| | | if (active) { |
| | | return activeSize ? activeSize : '30rpx'; |
| | | } |
| | | return size ? size : '30rpx'; |
| | | } |
| | | }, |
| | | itemCustomStyle() { |
| | | return index => { |
| | | const active = this.currentDropItem.activeIndex == index; |
| | | const style = {}; |
| | | if (active && this.currentDropItem.itemActiveCustomStyle) { |
| | | return this.$uv.deepMerge(style, this.$uv.addStyle(this.currentDropItem.itemActiveCustomStyle)); |
| | | } |
| | | if (this.currentDropItem.itemCustomStyle) { |
| | | return this.$uv.deepMerge(style, this.$uv.addStyle(this.currentDropItem.itemCustomStyle)) |
| | | } |
| | | return style; |
| | | } |
| | | } |
| | | }, |
| | | created() { |
| | | this.init(); |
| | | }, |
| | | methods: { |
| | | blockClick() {}, |
| | | clickHandler(item, index) { |
| | | this.currentDropItem.activeIndex = index; |
| | | this.$emit('clickItem', item); |
| | | this.close(); |
| | | }, |
| | | init() { |
| | | uni.$off(`${this.sign}_GETRECT`); |
| | | uni.$on(`${this.sign}_GETRECT`, rect => { |
| | | this.rect = rect; |
| | | }) |
| | | uni.$off(`${this.sign}_CLICKMENU`); |
| | | uni.$on(`${this.sign}_CLICKMENU`, async res => { |
| | | if (res.show) { |
| | | this.open(); |
| | | } else { |
| | | this.close(); |
| | | } |
| | | }) |
| | | }, |
| | | open() { |
| | | this.show = true; |
| | | this.$nextTick(async () => { |
| | | // #ifndef H5 || MP-WEIXIN |
| | | await this.$uv.sleep(60); |
| | | // #endif |
| | | const res = await this.queryRect(); |
| | | // #ifndef APP-NVUE |
| | | this.height = res.height; |
| | | // #endif |
| | | // #ifdef APP-NVUE |
| | | this.animation(res.height); |
| | | // #endif |
| | | this.$emit('popupChange', { show: true }); |
| | | }) |
| | | }, |
| | | close() { |
| | | if(!this.show) return; |
| | | this.height = 0; |
| | | // #ifndef APP-NVUE |
| | | this.height = 0; |
| | | // #endif |
| | | // #ifdef APP-NVUE |
| | | this.animation(0); |
| | | // #endif |
| | | this.show = false; |
| | | uni.$emit(`${this.sign}_CLOSEPOPUP`); |
| | | this.$emit('popupChange', { show: false }); |
| | | }, |
| | | clickOverlay() { |
| | | if (this.clickOverlayOnClose) { |
| | | this.close(); |
| | | } |
| | | }, |
| | | // 查询内容高度 |
| | | queryRect() { |
| | | // #ifndef APP-NVUE |
| | | // 组件内部一般用this.$uvGetRect,对外的为getRect,二者功能一致,名称不同 |
| | | return new Promise(resolve => { |
| | | this.$uvGetRect(`.uv-dp__container__list`).then(size => { |
| | | resolve(size) |
| | | }) |
| | | }) |
| | | // #endif |
| | | // #ifdef APP-NVUE |
| | | // nvue下,使用dom模块查询元素高度 |
| | | // 返回一个promise,让调用此方法的主体能使用then回调 |
| | | return new Promise(resolve => { |
| | | dom.getComponentRect(this.$refs.uvDPList, res => { |
| | | resolve(res.size) |
| | | }) |
| | | }) |
| | | // #endif |
| | | }, |
| | | // nvue下设置高度 |
| | | animation(height, duration = 200) { |
| | | // #ifdef APP-NVUE |
| | | const ref = this.$refs['uvDPContainer']; |
| | | animation.transition(ref, { |
| | | styles: { |
| | | height: `${height}px` |
| | | }, |
| | | duration |
| | | }) |
| | | // #endif |
| | | } |
| | | } |
| | | } |
| | | </script> |
| | | <style scoped lang="scss"> |
| | | .uv-dp__container { |
| | | /* #ifndef APP-NVUE */ |
| | | overflow: hidden; |
| | | transition: all .15s; |
| | | /* #endif */ |
| | | background-color: #fff; |
| | | } |
| | | .uv-dp__container__list { |
| | | &--item { |
| | | padding: 20rpx 60rpx; |
| | | } |
| | | } |
| | | </style> |
| New file |
| | |
| | | <template> |
| | | <uv-sticky :disabled="!isSticky"> |
| | | <view ref="dropDownRef" class="uv-drop-down" :style="[$uv.addStyle(customStyle)]"> |
| | | <slot></slot> |
| | | </view> |
| | | </uv-sticky> |
| | | </template> |
| | | <script> |
| | | import mpMixin from '@/uni_modules/uv-ui-tools/libs/mixin/mpMixin.js'; |
| | | import mixin from '@/uni_modules/uv-ui-tools/libs/mixin/mixin.js'; |
| | | // #ifdef APP-NVUE |
| | | const dom = uni.requireNativePlugin('dom'); |
| | | // #endif |
| | | /** |
| | | * DropDown 下拉框 |
| | | * @description 下拉筛选 |
| | | * @tutorial https://ext.dcloud.net.cn/plugin?name=uv-drop-down |
| | | * @property {String | Number} sign 组件唯一标识,需要手动传 |
| | | * @property {Boolean} is-sticky = [true|false] 是否吸顶 |
| | | * @property {Array} default-value 默认值,表示参数value属于这里面的值,就说明是未选中即是默认展示的值。eg:上面示例中的{label: '全部',value: 'all'} 即是默认值。后续处理逻辑也可以根据是否是其中值进行过滤。 |
| | | * @property {String} textSize 每项字体大小 |
| | | * @property {String} textColor 每项文本颜色 |
| | | * @property {String} textActiveSize 每项选中状态字体大小 |
| | | * @property {String} textActiveColor 每项选中状态文本颜色 |
| | | * @property {Object} extraIcon 每项右侧图标 |
| | | * @property {Object} extraActiveIcon 每项选中后右侧图标 |
| | | */ |
| | | export default { |
| | | name: 'uv-drop-down', |
| | | mixins: [mpMixin, mixin], |
| | | emits: ['click'], |
| | | props: { |
| | | isSticky: { |
| | | type: Boolean, |
| | | default: true |
| | | }, |
| | | sign: { |
| | | type: [String, Number], |
| | | default: 'UVDROPDOWN' |
| | | }, |
| | | defaultValue: { |
| | | type: Array, |
| | | default: () => [0, '0', 'all'] |
| | | }, |
| | | textSize: { |
| | | type: String, |
| | | default: '30rpx' |
| | | }, |
| | | textColor: { |
| | | type: String, |
| | | default: '#333' |
| | | }, |
| | | textActiveSize: { |
| | | type: String, |
| | | default: '30rpx' |
| | | }, |
| | | textActiveColor: { |
| | | type: String, |
| | | default: '#3c9cff' |
| | | }, |
| | | extraIcon: { |
| | | type: Object, |
| | | default () { |
| | | return { |
| | | name: 'arrow-down', |
| | | size: '30rpx', |
| | | color: '#333' |
| | | } |
| | | } |
| | | }, |
| | | extraActiveIcon: { |
| | | type: Object, |
| | | default () { |
| | | return { |
| | | name: 'arrow-up', |
| | | size: '30rpx', |
| | | color: '#3c9cff' |
| | | } |
| | | } |
| | | } |
| | | }, |
| | | computed: { |
| | | parentData() { |
| | | return [this.defaultValue, this.textSize, this.textColor, this.textActiveColor, this.textActiveSize, this.extraIcon, this.extraActiveIcon, this.sign, this.clickHandler]; |
| | | } |
| | | }, |
| | | mounted() { |
| | | this.init(); |
| | | }, |
| | | methods: { |
| | | init() { |
| | | uni.$emit(`${this.sign}_CLICKMENU`, { |
| | | show: false |
| | | }); |
| | | this.$nextTick(async () => { |
| | | const rect = await this.queryRect(); |
| | | uni.$emit(`${this.sign}_GETRECT`, rect); |
| | | }) |
| | | }, |
| | | // 查询内容高度 |
| | | queryRect() { |
| | | // #ifndef APP-NVUE |
| | | // 组件内部一般用this.$uvGetRect,对外的为getRect,二者功能一致,名称不同 |
| | | return new Promise(resolve => { |
| | | this.$uvGetRect(`.uv-drop-down`).then(size => { |
| | | resolve(size) |
| | | }) |
| | | }) |
| | | // #endif |
| | | // #ifdef APP-NVUE |
| | | // nvue下,使用dom模块查询元素高度 |
| | | // 返回一个promise,让调用此方法的主体能使用then回调 |
| | | return new Promise(resolve => { |
| | | dom.getComponentRect(this.$refs.dropDownRef, res => { |
| | | res.size.top = res.size.top <= 0 ? 0 : res.size.top; |
| | | resolve(res.size) |
| | | }) |
| | | }) |
| | | // #endif |
| | | }, |
| | | clickHandler(data) { |
| | | this.$emit('click', data); |
| | | } |
| | | } |
| | | } |
| | | </script> |
| | | <style scoped lang="scss"> |
| | | @import '@/uni_modules/uv-ui-tools/libs/css/components.scss'; |
| | | .uv-drop-down { |
| | | @include flex; |
| | | justify-content: space-between; |
| | | background-color: #fff; |
| | | border-bottom: 1px solid #dadbde; |
| | | } |
| | | </style> |
| New file |
| | |
| | | { |
| | | "id": "uv-drop-down", |
| | | "displayName": "uv-drop-down 下拉筛选 全面兼容vue3+2、app、h5、小程序等多端", |
| | | "version": "1.0.5", |
| | | "description": "该组件主要提供筛选下拉筛选框,内置基础筛选功能,可以根据自己的需求自定义筛选项", |
| | | "keywords": [ |
| | | "uv-drop-down", |
| | | "uvui", |
| | | "uv-ui", |
| | | "下拉筛选", |
| | | "筛选" |
| | | ], |
| | | "repository": "", |
| | | "engines": { |
| | | "HBuilderX": "^3.1.0" |
| | | }, |
| | | "dcloudext": { |
| | | "type": "component-vue", |
| | | "sale": { |
| | | "regular": { |
| | | "price": "0.00" |
| | | }, |
| | | "sourcecode": { |
| | | "price": "0.00" |
| | | } |
| | | }, |
| | | "contact": { |
| | | "qq": "" |
| | | }, |
| | | "declaration": { |
| | | "ads": "无", |
| | | "data": "插件不采集任何数据", |
| | | "permissions": "无" |
| | | }, |
| | | "npmurl": "" |
| | | }, |
| | | "uni_modules": { |
| | | "dependencies": [ |
| | | "uv-ui-tools", |
| | | "uv-icon", |
| | | "uv-text", |
| | | "uv-transition", |
| | | "uv-sticky" |
| | | ], |
| | | "encrypt": [], |
| | | "platforms": { |
| | | "cloud": { |
| | | "tcb": "y", |
| | | "aliyun": "y" |
| | | }, |
| | | "client": { |
| | | "Vue": { |
| | | "vue2": "y", |
| | | "vue3": "y" |
| | | }, |
| | | "App": { |
| | | "app-vue": "y", |
| | | "app-nvue": "y" |
| | | }, |
| | | "H5-mobile": { |
| | | "Safari": "y", |
| | | "Android Browser": "y", |
| | | "微信浏览器(Android)": "y", |
| | | "QQ浏览器(Android)": "y" |
| | | }, |
| | | "H5-pc": { |
| | | "Chrome": "y", |
| | | "IE": "y", |
| | | "Edge": "y", |
| | | "Firefox": "y", |
| | | "Safari": "y" |
| | | }, |
| | | "小程序": { |
| | | "微信": "y", |
| | | "阿里": "y", |
| | | "百度": "y", |
| | | "字节跳动": "y", |
| | | "QQ": "y", |
| | | "钉钉": "u", |
| | | "快手": "u", |
| | | "飞书": "u", |
| | | "京东": "u" |
| | | }, |
| | | "快应用": { |
| | | "华为": "u", |
| | | "联盟": "u" |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| New file |
| | |
| | | ## DropDown 下拉筛选 |
| | | |
| | | > **组件名:uv-drop-down** |
| | | |
| | | 该组件主要提供筛选下拉筛选框,内置基础筛选功能,可以根据自己的需求自定义筛选项。 |
| | | |
| | | 为了兼容app-nvue,需要内置三个组件进行配合使用,uv-drop-down属于菜单项(其实还包括子组件uv-drop-down-item),uv-drop-down-popup属于筛选框。 |
| | | |
| | | 只需要做简单的约定式配置,即可使用该功能,兼容性良好,已经在多端进行了多次测试。 |
| | | |
| | | # <a href="https://www.uvui.cn/components/dropDown.html" target="_blank">查看文档</a> |
| | | |
| | | ## [下载完整示例项目](https://ext.dcloud.net.cn/plugin?name=uv-ui) <small>(请不要 下载插件ZIP)</small> |
| | | |
| | | ### [更多插件,请关注uv-ui组件库](https://ext.dcloud.net.cn/plugin?name=uv-ui) |
| | | |
| | | <a href="https://ext.dcloud.net.cn/plugin?name=uv-ui" target="_blank"> |
| | | |
| | |  |
| | | |
| | | </a> |
| | | |
| | | #### 如使用过程中有任何问题反馈,或者您对uv-ui有一些好的建议,欢迎加入uv-ui官方交流群:<a href="https://www.uvui.cn/components/addQQGroup.html" target="_blank">官方QQ群</a> |
| New file |
| | |
| | | ## 1.0.5(2023-12-20) |
| | | 1. 优化 |
| | | ## 1.0.4(2023-08-04) |
| | | 1. icon支持base64图片 |
| | | ## 1.0.3(2023-07-17) |
| | | 1. 修复 uv-empty 恢复设置mode属性的内置图标 |
| | | ## 1.0.2(2023-07-03) |
| | | 去除插槽判断,避免某些平台不显示的BUG |
| | | ## 1.0.1(2023-05-16) |
| | | 1. 优化组件依赖,修改后无需全局引入,组件导入即可使用 |
| | | 2. 优化部分功能 |
| | | ## 1.0.0(2023-05-10) |
| | | uv-empty 内容为空 |
| New file |
| | |
| | | export default { |
| | | props: { |
| | | // 内置图标名称,或图片路径,建议绝对路径 |
| | | icon: { |
| | | type: String, |
| | | default: '' |
| | | }, |
| | | // 提示文字 |
| | | text: { |
| | | type: String, |
| | | default: '' |
| | | }, |
| | | // 文字颜色 |
| | | textColor: { |
| | | type: String, |
| | | default: '#c0c4cc' |
| | | }, |
| | | // 文字大小 |
| | | textSize: { |
| | | type: [String, Number], |
| | | default: 14 |
| | | }, |
| | | // 图标的颜色 |
| | | iconColor: { |
| | | type: String, |
| | | default: '#c0c4cc' |
| | | }, |
| | | // 图标的大小 |
| | | iconSize: { |
| | | type: [String, Number], |
| | | default: 90 |
| | | }, |
| | | // 选择预置的图标类型 |
| | | mode: { |
| | | type: String, |
| | | default: 'data' |
| | | }, |
| | | // 图标宽度,单位px |
| | | width: { |
| | | type: [String, Number], |
| | | default: 160 |
| | | }, |
| | | // 图标高度,单位px |
| | | height: { |
| | | type: [String, Number], |
| | | default: 160 |
| | | }, |
| | | // 是否显示组件 |
| | | show: { |
| | | type: Boolean, |
| | | default: true |
| | | }, |
| | | // 组件距离上一个元素之间的距离,默认px单位 |
| | | marginTop: { |
| | | type: [String, Number], |
| | | default: 0 |
| | | }, |
| | | ...uni.$uv?.props?.empty |
| | | } |
| | | } |
| New file |
| | |
| | | <template> |
| | | <view |
| | | class="uv-empty" |
| | | :style="[emptyStyle]" |
| | | v-if="show" |
| | | > |
| | | <uv-icon |
| | | v-if="!isImg" |
| | | :name="mode === 'message' ? 'chat' : `empty-${mode}`" |
| | | :size="iconSize" |
| | | :color="iconColor" |
| | | margin-top="14" |
| | | ></uv-icon> |
| | | <image |
| | | v-else |
| | | :style="{ |
| | | width: $uv.addUnit(width), |
| | | height: $uv.addUnit(height) |
| | | }" |
| | | :src="icon" |
| | | mode="widthFix" |
| | | ></image> |
| | | <text |
| | | class="uv-empty__text" |
| | | :style="[textStyle]" |
| | | >{{text ? text : icons[mode]}}</text> |
| | | <view class="uv-empty__wrap"> |
| | | <slot /> |
| | | </view> |
| | | </view> |
| | | </template> |
| | | <script> |
| | | import mpMixin from '@/uni_modules/uv-ui-tools/libs/mixin/mpMixin.js' |
| | | import mixin from '@/uni_modules/uv-ui-tools/libs/mixin/mixin.js' |
| | | import props from './props.js'; |
| | | /** |
| | | * empty 内容为空 |
| | | * @description 该组件用于需要加载内容,但是加载的第一页数据就为空,提示一个"没有内容"的场景, 我们精心挑选了十几个场景的图标,方便您使用。 |
| | | * @tutorial https://www.uvui.cn/components/empty.html |
| | | * @property {String} icon 内置图标名称,或图片路径,建议绝对路径 |
| | | * @property {String} text 提示文字 |
| | | * @property {String} textColor 文字颜色 (默认 '#c0c4cc' ) |
| | | * @property {String | Number} textSize 文字大小 (默认 14 ) |
| | | * @property {String} iconColor 图标的颜色 (默认 '#c0c4cc' ) |
| | | * @property {String | Number} iconSize 图标的大小 (默认 90 ) |
| | | * @property {String} mode 选择预置的图标类型 (默认 'data' ) |
| | | * @property {String | Number} width 图标宽度,单位px (默认 160 ) |
| | | * @property {String | Number} height 图标高度,单位px (默认 160 ) |
| | | * @property {Boolean} show 是否显示组件 (默认 true ) |
| | | * @property {String | Number} marginTop 组件距离上一个元素之间的距离,默认px单位 (默认 0 ) |
| | | * @property {Object} customStyle 定义需要用到的外部样式 |
| | | * |
| | | * @event {Function} click 点击组件时触发 |
| | | * @event {Function} close 点击关闭按钮时触发 |
| | | * @example <uv-empty text="所谓伊人,在水一方" mode="list"></uv-empty> |
| | | */ |
| | | export default { |
| | | name: "uv-empty", |
| | | mixins: [mpMixin, mixin, props], |
| | | data() { |
| | | return { |
| | | icons: { |
| | | car: '购物车为空', |
| | | page: '页面不存在', |
| | | search: '没有搜索结果', |
| | | address: '没有收货地址', |
| | | 'wifi-off': '没有WiFi', |
| | | order: '订单为空', |
| | | coupon: '没有优惠券', |
| | | favor: '暂无收藏', |
| | | permission: '无权限', |
| | | history: '无历史记录', |
| | | news: '无新闻列表', |
| | | message: '消息列表为空', |
| | | list: '列表为空', |
| | | data: '数据为空', |
| | | comment: '暂无评论', |
| | | } |
| | | } |
| | | }, |
| | | computed: { |
| | | // 组件样式 |
| | | emptyStyle() { |
| | | const style = {} |
| | | style.marginTop = this.$uv.addUnit(this.marginTop) |
| | | // 合并customStyle样式,此参数通过mixin中的props传递 |
| | | return this.$uv.deepMerge(style, this.$uv.addStyle(this.customStyle)) |
| | | }, |
| | | // 文本样式 |
| | | textStyle() { |
| | | const style = {} |
| | | style.color = this.textColor |
| | | style.fontSize = this.$uv.addUnit(this.textSize) |
| | | return style |
| | | }, |
| | | // 判断icon是否图片路径 |
| | | isImg() { |
| | | const isBase64 = this.icon.indexOf('data:') > -1 && this.icon.indexOf('base64') > -1; |
| | | return this.icon.indexOf('/') !== -1 || isBase64; |
| | | } |
| | | } |
| | | } |
| | | </script> |
| | | <style lang="scss" scoped> |
| | | @import '@/uni_modules/uv-ui-tools/libs/css/components.scss'; |
| | | $uv-empty-text-margin-top: 20rpx !default; |
| | | $uv-empty-slot-margin-top: 20rpx !default; |
| | | .uv-empty { |
| | | @include flex; |
| | | flex-direction: column; |
| | | justify-content: center; |
| | | align-items: center; |
| | | &__text { |
| | | @include flex; |
| | | justify-content: center; |
| | | align-items: center; |
| | | margin-top: $uv-empty-text-margin-top; |
| | | } |
| | | } |
| | | .uv-slot-wrap { |
| | | @include flex; |
| | | justify-content: center; |
| | | align-items: center; |
| | | margin-top: $uv-empty-slot-margin-top; |
| | | } |
| | | </style> |
| New file |
| | |
| | | { |
| | | "id": "uv-empty", |
| | | "displayName": "uv-empty 内容为空 全面兼容vue3+2、app、h5、小程序等多端", |
| | | "version": "1.0.5", |
| | | "description": "该组件用于需要加载内容,但是加载的第一页数据就为空,提示一个 没有内容 的场景, 我们精心挑选了十几个场景的图标,方便您使用。", |
| | | "keywords": [ |
| | | "empty", |
| | | "uvui", |
| | | "uv-ui", |
| | | "空数据", |
| | | "暂无数据" |
| | | ], |
| | | "repository": "", |
| | | "engines": { |
| | | "HBuilderX": "^3.1.0" |
| | | }, |
| | | "dcloudext": { |
| | | "type": "component-vue", |
| | | "sale": { |
| | | "regular": { |
| | | "price": "0.00" |
| | | }, |
| | | "sourcecode": { |
| | | "price": "0.00" |
| | | } |
| | | }, |
| | | "contact": { |
| | | "qq": "" |
| | | }, |
| | | "declaration": { |
| | | "ads": "无", |
| | | "data": "插件不采集任何数据", |
| | | "permissions": "无" |
| | | }, |
| | | "npmurl": "" |
| | | }, |
| | | "uni_modules": { |
| | | "dependencies": [ |
| | | "uv-ui-tools", |
| | | "uv-icon" |
| | | ], |
| | | "encrypt": [], |
| | | "platforms": { |
| | | "cloud": { |
| | | "tcb": "y", |
| | | "aliyun": "y" |
| | | }, |
| | | "client": { |
| | | "Vue": { |
| | | "vue2": "y", |
| | | "vue3": "y" |
| | | }, |
| | | "App": { |
| | | "app-vue": "y", |
| | | "app-nvue": "y" |
| | | }, |
| | | "H5-mobile": { |
| | | "Safari": "y", |
| | | "Android Browser": "y", |
| | | "微信浏览器(Android)": "y", |
| | | "QQ浏览器(Android)": "y" |
| | | }, |
| | | "H5-pc": { |
| | | "Chrome": "y", |
| | | "IE": "y", |
| | | "Edge": "y", |
| | | "Firefox": "y", |
| | | "Safari": "y" |
| | | }, |
| | | "小程序": { |
| | | "微信": "y", |
| | | "阿里": "y", |
| | | "百度": "y", |
| | | "字节跳动": "y", |
| | | "QQ": "y", |
| | | "钉钉": "u", |
| | | "快手": "u", |
| | | "飞书": "u", |
| | | "京东": "u" |
| | | }, |
| | | "快应用": { |
| | | "华为": "u", |
| | | "联盟": "u" |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| New file |
| | |
| | | ## Empty 内容为空 |
| | | |
| | | > **组件名:uv-empty** |
| | | |
| | | 该组件用于需要加载内容,但是加载的第一页数据就为空,提示一个"没有内容"的场景, 我们精心挑选了十几个场景的图标,方便您使用。 |
| | | |
| | | # <a href="https://www.uvui.cn/components/empty.html" target="_blank">查看文档</a> |
| | | |
| | | ## [下载完整示例项目](https://ext.dcloud.net.cn/plugin?name=uv-ui) <small>(请不要 下载插件ZIP)</small> |
| | | |
| | | ### [更多插件,请关注uv-ui组件库](https://ext.dcloud.net.cn/plugin?name=uv-ui) |
| | | |
| | | <a href="https://ext.dcloud.net.cn/plugin?name=uv-ui" target="_blank"> |
| | | |
| | |  |
| | | |
| | | </a> |
| | | |
| | | #### 如使用过程中有任何问题反馈,或者您对uv-ui有一些好的建议,欢迎加入uv-ui官方交流群:<a href="https://www.uvui.cn/components/addQQGroup.html" target="_blank">官方QQ群</a> |
| | |
| | | ## 1.0.1(20-05-16) |
| | | ## 1.0.1(2023-05-16) |
| | | 1. 优化组件依赖,修改后无需全局引入,组件导入即可使用 |
| | | 2. 优化部分功能 |
| | | ## 1.0.0(2023-05-10) |
| New file |
| | |
| | | ## 1.0.9(2023-12-06) |
| | | 1. 优化 |
| | | ## 1.0.8(2023-12-06) |
| | | 1. 阻止事件冒泡问题 |
| | | ## 1.0.7(2023-10-13) |
| | | 1. unmounted兼容vue3 |
| | | ## 1.0.6(2023-08-14) |
| | | 1. 修复初始的时候闪动的BUG |
| | | ## 1.0.5(2023-06-22) |
| | | 1. 优化修改 |
| | | ## 1.0.4(2023-06-21) |
| | | 1. 修复BUG |
| | | ## 1.0.3(2023-06-01) |
| | | 1. 修复点击触发两次事件的BUG |
| | | ## 1.0.2(2023-05-23) |
| | | 1. 优化 |
| | | ## 1.0.1(2023-05-16) |
| | | 1. 优化组件依赖,修改后无需全局引入,组件导入即可使用 |
| | | 2. 优化部分功能 |
| | | ## 1.0.0(2023-05-10) |
| | | uv-grid 宫格布局 |
| New file |
| | |
| | | export default { |
| | | props: { |
| | | // 宫格的name |
| | | name: { |
| | | type: [String, Number, null], |
| | | default: null |
| | | }, |
| | | // 背景颜色 |
| | | bgColor: { |
| | | type: String, |
| | | default: 'transparent' |
| | | }, |
| | | ...uni.$uv?.props?.gridItem |
| | | } |
| | | } |
| New file |
| | |
| | | <template> |
| | | <!-- #ifndef APP-NVUE --> |
| | | <view |
| | | class="uv-grid-item" |
| | | hover-class="uv-grid-item--hover-class" |
| | | :hover-stay-time="200" |
| | | @tap="clickHandler" |
| | | :class="classes" |
| | | :style="[itemStyle]" |
| | | > |
| | | <slot /> |
| | | </view> |
| | | <!-- #endif --> |
| | | <!-- #ifdef APP-NVUE --> |
| | | <view |
| | | class="uv-grid-item" |
| | | :hover-stay-time="200" |
| | | @tap="clickHandler" |
| | | :class="classes" |
| | | :style="[itemStyle]" |
| | | > |
| | | <slot /> |
| | | </view> |
| | | <!-- #endif --> |
| | | </template> |
| | | |
| | | <script> |
| | | import mpMixin from '@/uni_modules/uv-ui-tools/libs/mixin/mpMixin.js' |
| | | import mixin from '@/uni_modules/uv-ui-tools/libs/mixin/mixin.js' |
| | | import props from './props.js'; |
| | | /** |
| | | * gridItem 提示 |
| | | * @description 宫格组件一般用于同时展示多个同类项目的场景,可以给宫格的项目设置徽标组件(badge),或者图标等,也可以扩展为左右滑动的轮播形式。搭配uv-grid使用 |
| | | * @tutorial https://www.uvui.cn/components/grid.html |
| | | * @property {String | Number} name 宫格的name ( 默认 null ) |
| | | * @property {String} bgColor 宫格的背景颜色 (默认 'transparent' ) |
| | | * @property {Object} customStyle 自定义样式,对象形式 |
| | | * @event {Function} click 点击宫格触发 |
| | | * @example <uv-grid-item></uv-grid-item> |
| | | */ |
| | | export default { |
| | | name: "uv-grid-item", |
| | | mixins: [mpMixin, mixin, props], |
| | | emits: ['$uvGridItem','click'], |
| | | data() { |
| | | return { |
| | | parentData: { |
| | | col: 3, // 父组件划分的宫格数 |
| | | border: true, // 是否显示边框,根据父组件决定 |
| | | }, |
| | | // #ifdef APP-NVUE |
| | | width: 0, // nvue下才这么计算,vue下放到computed中,否则会因为延时造成闪烁 |
| | | // #endif |
| | | classes: [], // 类名集合,用于判断是否显示右边和下边框 |
| | | }; |
| | | }, |
| | | created() { |
| | | // 父组件的实例 |
| | | this.updateParentData() |
| | | }, |
| | | mounted() { |
| | | this.init() |
| | | }, |
| | | computed: { |
| | | // #ifndef APP-NVUE |
| | | // vue下放到computed中,否则会因为延时造成闪烁 |
| | | width() { |
| | | return 100 / Number(this.parentData.col) + '%' |
| | | }, |
| | | // #endif |
| | | itemStyle() { |
| | | const style = { |
| | | background: this.bgColor, |
| | | width: this.width |
| | | } |
| | | return this.$uv.deepMerge(style, this.$uv.addStyle(this.customStyle)) |
| | | } |
| | | }, |
| | | methods: { |
| | | init() { |
| | | // 用于在父组件uv-grid的children中被添加入子组件时, |
| | | // 重新计算item的边框 |
| | | uni.$on('$uvGridItem', () => { |
| | | this.gridItemClasses() |
| | | }) |
| | | // #ifdef APP-NVUE |
| | | // 获取元素该有的长度,nvue下要延时才准确 |
| | | this.$nextTick(function(){ |
| | | this.getItemWidth() |
| | | }) |
| | | // #endif |
| | | // 发出事件,通知所有的grid-item都重新计算自己的边框 |
| | | uni.$emit('$uvGridItem') |
| | | this.gridItemClasses() |
| | | }, |
| | | // 获取父组件的参数 |
| | | updateParentData() { |
| | | // 此方法写在mixin中 |
| | | this.getParentData('uv-grid'); |
| | | }, |
| | | clickHandler() { |
| | | let name = this.name |
| | | // 如果没有设置name属性,历遍父组件的children数组,判断当前的元素是否和本实例this相等,找出当前组件的索引 |
| | | const children = this.parent?.children |
| | | if(children && this.name === null) { |
| | | name = children.findIndex(child => child === this) |
| | | } |
| | | // 调用父组件方法,发出事件 |
| | | this.parent && this.parent.childClick(name) |
| | | this.$emit('click', name) |
| | | }, |
| | | async getItemWidth() { |
| | | // 如果是nvue,不能使用百分比,只能使用固定宽度 |
| | | let width = 0 |
| | | if(this.parent) { |
| | | // 获取父组件宽度后,除以栅格数,得出每个item的宽度 |
| | | const parentWidth = await this.getParentWidth() |
| | | width = parentWidth / Number(this.parentData.col) + 'px' |
| | | } |
| | | this.width = width |
| | | }, |
| | | // 获取父元素的尺寸 |
| | | getParentWidth() { |
| | | // #ifdef APP-NVUE |
| | | // 返回一个promise,让调用者可以用await同步获取 |
| | | const dom = uni.requireNativePlugin('dom') |
| | | return new Promise(resolve => { |
| | | // 调用父组件的ref |
| | | dom.getComponentRect(this.parent.$refs['uv-grid'], res => { |
| | | resolve(res.size.width) |
| | | }) |
| | | }) |
| | | // #endif |
| | | }, |
| | | gridItemClasses() { |
| | | if(this.parentData.border) { |
| | | let classes = [] |
| | | this.parent.children.map((child, index) =>{ |
| | | if(this === child) { |
| | | const len = this.parent.children.length |
| | | // 贴近右边屏幕边沿的child,并且最后一个(比如只有横向2个的时候),无需右边框 |
| | | if((index + 1) % this.parentData.col !== 0 && index + 1 !== len) { |
| | | classes.push('uv-border-right') |
| | | } |
| | | // 总的宫格数量对列数取余的值 |
| | | // 如果取余后,值为0,则意味着要将最后一排的宫格,都不需要下边框 |
| | | const lessNum = len % this.parentData.col === 0 ? this.parentData.col : len % this.parentData.col |
| | | // 最下面的一排child,无需下边框 |
| | | if(index < len - lessNum) { |
| | | classes.push('uv-border-bottom') |
| | | } |
| | | } |
| | | }) |
| | | // 支付宝,头条小程序无法动态绑定一个数组类名,否则解析出来的结果会带有",",而导致失效 |
| | | // #ifdef MP-ALIPAY || MP-TOUTIAO |
| | | classes = classes.join(' ') |
| | | // #endif |
| | | this.classes = classes |
| | | } |
| | | } |
| | | }, |
| | | // #ifdef VUE2 |
| | | beforeDestroy() { |
| | | // 移除事件监听,释放性能 |
| | | uni.$off('$uvGridItem') |
| | | }, |
| | | // #endif |
| | | // #ifdef VUE3 |
| | | unmounted() { |
| | | // 移除事件监听,释放性能 |
| | | uni.$off('$uvGridItem') |
| | | } |
| | | // #endif |
| | | }; |
| | | </script> |
| | | |
| | | <style lang="scss" scoped> |
| | | $show-border: 1; |
| | | $show-border-right: 1; |
| | | $show-border-bottom: 1; |
| | | @import '@/uni_modules/uv-ui-tools/libs/css/variable.scss'; |
| | | @import '@/uni_modules/uv-ui-tools/libs/css/components.scss'; |
| | | @import '@/uni_modules/uv-ui-tools/libs/css/color.scss'; |
| | | $uv-grid-item-hover-class-opcatiy:.5 !default; |
| | | $uv-grid-item-margin-top:1rpx !default; |
| | | $uv-grid-item-border-right-width:0.5px !default; |
| | | $uv-grid-item-border-bottom-width:0.5px !default; |
| | | $uv-grid-item-border-right-color:$uv-border-color !default; |
| | | $uv-grid-item-border-bottom-color:$uv-border-color !default; |
| | | .uv-grid-item { |
| | | align-items: center; |
| | | justify-content: center; |
| | | position: relative; |
| | | flex-direction: column; |
| | | /* #ifndef APP-NVUE */ |
| | | box-sizing: border-box; |
| | | display: flex; |
| | | /* #endif */ |
| | | |
| | | /* #ifdef MP */ |
| | | position: relative; |
| | | float: left; |
| | | /* #endif */ |
| | | |
| | | /* #ifdef MP-WEIXIN */ |
| | | margin-top:$uv-grid-item-margin-top; |
| | | /* #endif */ |
| | | |
| | | &--hover-class { |
| | | opacity:$uv-grid-item-hover-class-opcatiy; |
| | | } |
| | | } |
| | | |
| | | /* #ifdef APP-NVUE */ |
| | | // 由于nvue不支持组件内引入app.vue中再引入的样式,所以需要写在这里 |
| | | .uv-border-right { |
| | | border-right-width:$uv-grid-item-border-right-width; |
| | | border-color: $uv-grid-item-border-right-color; |
| | | } |
| | | |
| | | .uv-border-bottom { |
| | | border-bottom-width:$uv-grid-item-border-bottom-width; |
| | | border-color:$uv-grid-item-border-bottom-color; |
| | | } |
| | | /* #endif */ |
| | | </style> |
| New file |
| | |
| | | export default { |
| | | props: { |
| | | // 分成几列 |
| | | col: { |
| | | type: [String, Number], |
| | | default: 3 |
| | | }, |
| | | // 是否显示边框 |
| | | border: { |
| | | type: Boolean, |
| | | default: false |
| | | }, |
| | | // 宫格对齐方式,表现为数量少的时候,靠左,居中,还是靠右 |
| | | align: { |
| | | type: String, |
| | | default: 'left' |
| | | }, |
| | | ...uni.$uv?.props?.grid |
| | | } |
| | | } |
| New file |
| | |
| | | <template> |
| | | <view |
| | | class="uv-grid" |
| | | ref='uv-grid' |
| | | :style="[gridStyle]" |
| | | > |
| | | <slot /> |
| | | </view> |
| | | </template> |
| | | |
| | | <script> |
| | | import mpMixin from '@/uni_modules/uv-ui-tools/libs/mixin/mpMixin.js' |
| | | import mixin from '@/uni_modules/uv-ui-tools/libs/mixin/mixin.js' |
| | | import props from './props.js'; |
| | | /** |
| | | * grid 宫格布局 |
| | | * @description 宫格组件一般用于同时展示多个同类项目的场景,可以给宫格的项目设置徽标组件(badge),或者图标等,也可以扩展为左右滑动的轮播形式。 |
| | | * @tutorial https://www.uvui.cn/components/grid.html |
| | | * @property {String | Number} col 宫格的列数(默认 3 ) |
| | | * @property {Boolean} border 是否显示宫格的边框(默认 false ) |
| | | * @property {String} align 宫格对齐方式,表现为数量少的时候,靠左,居中,还是靠右 (默认 'left' ) |
| | | * @property {Object} customStyle 定义需要用到的外部样式 |
| | | * @event {Function} click 点击宫格触发 |
| | | * @example <uv-grid :col="3" @click="click"></uv-grid> |
| | | */ |
| | | export default { |
| | | name: 'uv-grid', |
| | | mixins: [mpMixin, mixin, props], |
| | | emits: ['click'], |
| | | data() { |
| | | return { |
| | | index: 0, |
| | | width: 0 |
| | | } |
| | | }, |
| | | watch: { |
| | | // 当父组件需要子组件需要共享的参数发生了变化,手动通知子组件 |
| | | parentData() { |
| | | if (this.children.length) { |
| | | this.children.map(child => { |
| | | // 判断子组件(uv-radio)如果有updateParentData方法的话,就就执行(执行的结果是子组件重新从父组件拉取了最新的值) |
| | | typeof(child.updateParentData) == 'function' && child.updateParentData(); |
| | | }) |
| | | } |
| | | }, |
| | | }, |
| | | created() { |
| | | // 如果将children定义在data中,在微信小程序会造成循环引用而报错 |
| | | this.children = [] |
| | | }, |
| | | computed: { |
| | | // 计算父组件的值是否发生变化 |
| | | parentData() { |
| | | return [this.hoverClass, this.col, this.size, this.border]; |
| | | }, |
| | | // 宫格对齐方式 |
| | | gridStyle() { |
| | | let style = {}; |
| | | switch (this.align) { |
| | | case 'left': |
| | | style.justifyContent = 'flex-start'; |
| | | break; |
| | | case 'center': |
| | | style.justifyContent = 'center'; |
| | | break; |
| | | case 'right': |
| | | style.justifyContent = 'flex-end'; |
| | | break; |
| | | default: |
| | | style.justifyContent = 'flex-start'; |
| | | }; |
| | | return this.$uv.deepMerge(style, this.$uv.addStyle(this.customStyle)); |
| | | } |
| | | }, |
| | | methods: { |
| | | // 此方法由uv-grid-item触发,用于在uv-grid发出事件 |
| | | childClick(name) { |
| | | this.$emit('click', name) |
| | | } |
| | | } |
| | | }; |
| | | </script> |
| | | |
| | | <style lang="scss" scoped> |
| | | @import '@/uni_modules/uv-ui-tools/libs/css/components.scss'; |
| | | $uv-grid-width:100% !default; |
| | | .uv-grid { |
| | | /* #ifdef MP */ |
| | | width: $uv-grid-width; |
| | | position: relative; |
| | | box-sizing: border-box; |
| | | overflow: hidden; |
| | | display: block; |
| | | /* #endif */ |
| | | justify-content: center; |
| | | @include flex; |
| | | flex-wrap: wrap; |
| | | align-items: center; |
| | | } |
| | | </style> |
| New file |
| | |
| | | { |
| | | "id": "uv-grid", |
| | | "displayName": "uv-grid 宫格布局 全面兼容vue3+2、app、h5、小程序等多端", |
| | | "version": "1.0.9", |
| | | "description": "uv-grid 宫格组件一般用于同时展示多个同类项目的场景,可以给宫格的项目设置徽标组件(badge),或者图标等,也可以扩展为左右滑动的轮播形式。", |
| | | "keywords": [ |
| | | "uv-grid", |
| | | "uvui", |
| | | "uv-ui", |
| | | "宫格布局", |
| | | "grid" |
| | | ], |
| | | "repository": "", |
| | | "engines": { |
| | | "HBuilderX": "^3.1.0" |
| | | }, |
| | | "dcloudext": { |
| | | "type": "component-vue", |
| | | "sale": { |
| | | "regular": { |
| | | "price": "0.00" |
| | | }, |
| | | "sourcecode": { |
| | | "price": "0.00" |
| | | } |
| | | }, |
| | | "contact": { |
| | | "qq": "" |
| | | }, |
| | | "declaration": { |
| | | "ads": "无", |
| | | "data": "插件不采集任何数据", |
| | | "permissions": "无" |
| | | }, |
| | | "npmurl": "" |
| | | }, |
| | | "uni_modules": { |
| | | "dependencies": [ |
| | | "uv-ui-tools", |
| | | "uv-icon" |
| | | ], |
| | | "encrypt": [], |
| | | "platforms": { |
| | | "cloud": { |
| | | "tcb": "y", |
| | | "aliyun": "y" |
| | | }, |
| | | "client": { |
| | | "Vue": { |
| | | "vue2": "y", |
| | | "vue3": "y" |
| | | }, |
| | | "App": { |
| | | "app-vue": "y", |
| | | "app-nvue": "y" |
| | | }, |
| | | "H5-mobile": { |
| | | "Safari": "y", |
| | | "Android Browser": "y", |
| | | "微信浏览器(Android)": "y", |
| | | "QQ浏览器(Android)": "y" |
| | | }, |
| | | "H5-pc": { |
| | | "Chrome": "y", |
| | | "IE": "y", |
| | | "Edge": "y", |
| | | "Firefox": "y", |
| | | "Safari": "y" |
| | | }, |
| | | "小程序": { |
| | | "微信": "y", |
| | | "阿里": "y", |
| | | "百度": "y", |
| | | "字节跳动": "y", |
| | | "QQ": "y", |
| | | "钉钉": "u", |
| | | "快手": "u", |
| | | "飞书": "u", |
| | | "京东": "u" |
| | | }, |
| | | "快应用": { |
| | | "华为": "u", |
| | | "联盟": "u" |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| New file |
| | |
| | | ## Grid 宫格布局 |
| | | |
| | | > **组件名:uv-grid** |
| | | |
| | | 宫格组件一般用于同时展示多个同类项目的场景,可以给宫格的项目设置徽标组件(badge),或者图标等,也可以扩展为左右滑动的轮播形式。 |
| | | |
| | | # <a href="https://www.uvui.cn/components/grid.html" target="_blank">查看文档</a> |
| | | |
| | | ### [更多插件,请关注uv-ui组件库](https://ext.dcloud.net.cn/plugin?name=uv-ui) |
| | | |
| | | <a href="https://ext.dcloud.net.cn/plugin?name=uv-ui" target="_blank"> |
| | | |
| | |  |
| | | |
| | | </a> |
| | | |
| | | #### 如使用过程中有任何问题反馈,或者您对uv-ui有一些好的建议,欢迎加入uv-ui官方交流群:<a href="https://www.uvui.cn/components/addQQGroup.html" target="_blank">官方QQ群</a> |
| New file |
| | |
| | | ## 1.0.16(2023-12-21) |
| | | 1. 修复设置show-menu-by-longpress不生效的BUG |
| | | ## 1.0.15(2023-12-06) |
| | | 1. 优化 |
| | | ## 1.0.14(2023-12-06) |
| | | 1. 阻止事件冒泡问题 |
| | | ## 1.0.13(2023-11-15) |
| | | 1. 修复webp之前未使用的BUG |
| | | ## 1.0.12(2023-10-11) |
| | | 1. 修复懒加载报错:https://gitee.com/climblee/uv-ui/issues/I869JS |
| | | ## 1.0.11(2023-08-31) |
| | | 1. 修复设置widthFix时出现显示不全的BUG |
| | | 2. 修复抖音等平台在width和height属性改变时出现不显示的BUG |
| | | ## 1.0.10(2023-08-29) |
| | | 1. 修复异步修改宽高不生效的问题,问题来源:https://gitee.com/climblee/uv-ui/issues/I7WUQ3 |
| | | ## 1.0.9(2023-08-21) |
| | | 1. 修复设置宽高为百分比不生效的BUG |
| | | ## 1.0.8(2023-07-24) |
| | | 1. 优化 nvue模式下增加cellChild参数,是否在list中cell节点下,nvue中cell下建议设置成true |
| | | ## 1.0.7(2023-07-02) |
| | | 修复VUE3模式下可能不显示的BUG |
| | | ## 1.0.6(2023-07-02) |
| | | 优化修改 |
| | | ## 1.0.5(2023-06-28) |
| | | 修复duration属性不生效的BUG |
| | | ## 1.0.4(2023-05-27) |
| | | 1. 修复可能报错的问题 |
| | | ## 1.0.3(2023-05-24) |
| | | 1. 去掉template中存在的this.导致头条小程序编译警告 |
| | | ## 1.0.2(2023-05-23) |
| | | 1. 优化 |
| | | ## 1.0.1(2023-05-16) |
| | | 1. 优化组件依赖,修改后无需全局引入,组件导入即可使用 |
| | | 2. 优化部分功能 |
| | | ## 1.0.0(2023-05-10) |
| | | uv-image 图片 |
| New file |
| | |
| | | export default { |
| | | props: { |
| | | // 图片地址 |
| | | src: { |
| | | type: String, |
| | | default: '' |
| | | }, |
| | | // 裁剪模式 |
| | | mode: { |
| | | type: String, |
| | | default: 'aspectFill' |
| | | }, |
| | | // 宽度,单位任意 |
| | | width: { |
| | | type: [String, Number], |
| | | default: '300' |
| | | }, |
| | | // 高度,单位任意 |
| | | height: { |
| | | type: [String, Number], |
| | | default: '225' |
| | | }, |
| | | // 图片形状,circle-圆形,square-方形 |
| | | shape: { |
| | | type: String, |
| | | default: 'square' |
| | | }, |
| | | // 圆角,单位任意 |
| | | radius: { |
| | | type: [String, Number], |
| | | default: 0 |
| | | }, |
| | | // 是否懒加载,微信小程序、App、百度小程序、字节跳动小程序 |
| | | lazyLoad: { |
| | | type: Boolean, |
| | | default: true |
| | | }, |
| | | // 是否开启observer懒加载,nvue不生效 |
| | | observeLazyLoad: { |
| | | type: Boolean, |
| | | default: false |
| | | }, |
| | | // 开启长按图片显示识别微信小程序码菜单 |
| | | showMenuByLongpress: { |
| | | type: Boolean, |
| | | default: true |
| | | }, |
| | | // 加载中的图标,或者小图片 |
| | | loadingIcon: { |
| | | type: String, |
| | | default: 'photo' |
| | | }, |
| | | // 加载失败的图标,或者小图片 |
| | | errorIcon: { |
| | | type: String, |
| | | default: 'error-circle' |
| | | }, |
| | | // 是否显示加载中的图标或者自定义的slot |
| | | showLoading: { |
| | | type: Boolean, |
| | | default: true |
| | | }, |
| | | // 是否显示加载错误的图标或者自定义的slot |
| | | showError: { |
| | | type: Boolean, |
| | | default: true |
| | | }, |
| | | // 是否需要淡入效果 |
| | | fade: { |
| | | type: Boolean, |
| | | default: true |
| | | }, |
| | | // 只支持网络资源,只对微信小程序有效 |
| | | webp: { |
| | | type: Boolean, |
| | | default: false |
| | | }, |
| | | // 过渡时间,单位ms |
| | | duration: { |
| | | type: [String, Number], |
| | | default: 500 |
| | | }, |
| | | // 背景颜色,用于深色页面加载图片时,为了和背景色融合 |
| | | bgColor: { |
| | | type: String, |
| | | default: '#f3f4f6' |
| | | }, |
| | | // nvue模式下 是否直接显示,在uv-list等cell下面使用就需要设置 |
| | | cellChild: { |
| | | type: Boolean, |
| | | default: false |
| | | }, |
| | | ...uni.$uv?.props?.image |
| | | } |
| | | } |
| New file |
| | |
| | | <template> |
| | | <uv-transition |
| | | v-if="show" |
| | | :show="show" |
| | | mode="fade" |
| | | :duration="fade ? duration : 0" |
| | | :cell-child="cellChild" |
| | | :custom-style="wrapStyle" |
| | | > |
| | | <view |
| | | class="uv-image" |
| | | :class="[`uv-image--${elIndex}`]" |
| | | @tap="onClick" |
| | | :style="[wrapStyle, backgroundStyle]" |
| | | > |
| | | <image |
| | | v-if="!isError && observeShow" |
| | | :src="src" |
| | | :mode="mode" |
| | | @error="onErrorHandler" |
| | | @load="onLoadHandler" |
| | | :show-menu-by-longpress="showMenuByLongpress" |
| | | :lazy-load="lazyLoad" |
| | | class="uv-image__image" |
| | | :style="[imageStyle]" |
| | | :webp="webp" |
| | | ></image> |
| | | <view |
| | | v-if="showLoading && loading" |
| | | class="uv-image__loading" |
| | | :style="{ |
| | | borderRadius: shape == 'circle' ? '50%' : $uv.addUnit(radius), |
| | | backgroundColor: bgColor, |
| | | width: $uv.addUnit(width), |
| | | height: $uv.addUnit(height) |
| | | }" |
| | | > |
| | | <slot name="loading"> |
| | | <uv-icon |
| | | :name="loadingIcon" |
| | | :width="width" |
| | | :height="height" |
| | | ></uv-icon> |
| | | </slot> |
| | | </view> |
| | | <view |
| | | v-if="showError && isError && !loading" |
| | | class="uv-image__error" |
| | | :style="{ |
| | | borderRadius: shape == 'circle' ? '50%' : $uv.addUnit(radius), |
| | | width: $uv.addUnit(width), |
| | | height: $uv.addUnit(height) |
| | | }" |
| | | > |
| | | <slot name="error"> |
| | | <uv-icon |
| | | :name="errorIcon" |
| | | :width="width" |
| | | :height="height" |
| | | ></uv-icon> |
| | | </slot> |
| | | </view> |
| | | </view> |
| | | </uv-transition> |
| | | </template> |
| | | |
| | | <script> |
| | | import mpMixin from '@/uni_modules/uv-ui-tools/libs/mixin/mpMixin.js' |
| | | import mixin from '@/uni_modules/uv-ui-tools/libs/mixin/mixin.js' |
| | | import props from './props.js'; |
| | | /** |
| | | * Image 图片 |
| | | * @description 此组件为uni-app的image组件的加强版,在继承了原有功能外,还支持淡入动画、加载中、加载失败提示、圆角值和形状等。 |
| | | * @tutorial https://www.uvui.cn/components/image.html |
| | | * @property {String} src 图片地址 |
| | | * @property {String} mode 裁剪模式,见官网说明 (默认 'aspectFill' ) |
| | | * @property {String | Number} width 宽度,单位任意,如果为数值,则为px单位 (默认 '300' ) |
| | | * @property {String | Number} height 高度,单位任意,如果为数值,则为px单位 (默认 '225' ) |
| | | * @property {String} shape 图片形状,circle-圆形,square-方形 (默认 'square' ) |
| | | * @property {String | Number} radius 圆角值,单位任意,如果为数值,则为px单位 (默认 0 ) |
| | | * @property {Boolean} lazyLoad 是否懒加载,仅微信小程序、App、百度小程序、字节跳动小程序有效 (默认 true ) |
| | | * @property {Boolean} showMenuByLongpress 是否开启长按图片显示识别小程序码菜单,仅微信小程序有效 (默认 true ) |
| | | * @property {String} loadingIcon 加载中的图标,或者小图片 (默认 'photo' ) |
| | | * @property {String} errorIcon 加载失败的图标,或者小图片 (默认 'error-circle' ) |
| | | * @property {Boolean} showLoading 是否显示加载中的图标或者自定义的slot (默认 true ) |
| | | * @property {Boolean} showError 是否显示加载错误的图标或者自定义的slot (默认 true ) |
| | | * @property {Boolean} fade 是否需要淡入效果 (默认 true ) |
| | | * @property {Boolean} webp 只支持网络资源,只对微信小程序有效 (默认 false ) |
| | | * @property {String | Number} duration 搭配fade参数的过渡时间,单位ms (默认 500 ) |
| | | * @property {String} bgColor 背景颜色,用于深色页面加载图片时,为了和背景色融合 (默认 '#f3f4f6' ) |
| | | * @property {Object} customStyle 定义需要用到的外部样式 |
| | | * @event {Function} click 点击图片时触发 |
| | | * @event {Function} error 图片加载失败时触发 |
| | | * @event {Function} load 图片加载成功时触发 |
| | | * @example <uv-image width="100%" height="300px" :src="src"></uv-image> |
| | | */ |
| | | export default { |
| | | name: 'uv-image', |
| | | emits: ['click','load','error'], |
| | | mixins: [mpMixin, mixin, props], |
| | | data() { |
| | | return { |
| | | // 图片是否加载错误,如果是,则显示错误占位图 |
| | | isError: false, |
| | | // 初始化组件时,默认为加载中状态 |
| | | loading: true, |
| | | // 图片加载完成时,去掉背景颜色,因为如果是png图片,就会显示灰色的背景 |
| | | backgroundStyle: {}, |
| | | // 用于fade模式的控制组件显示与否 |
| | | show: false, |
| | | // 是否开启图片出现在可视范围进行加载(另一种懒加载) |
| | | observeShow: !this.observeLazyLoad, |
| | | elIndex: '', |
| | | // 因为props的值无法修改,故需要一个中间值 |
| | | imgWidth: this.width, |
| | | // 因为props的值无法修改,故需要一个中间值 |
| | | imgHeight: this.height, |
| | | thresholdValue: 50 |
| | | }; |
| | | }, |
| | | watch: { |
| | | src: { |
| | | immediate: true, |
| | | handler(n) { |
| | | if (!n) { |
| | | // 如果传入null或者'',或者false,或者undefined,标记为错误状态 |
| | | this.isError = true |
| | | } else { |
| | | this.isError = false; |
| | | this.loading = true; |
| | | } |
| | | } |
| | | }, |
| | | width(newVal){ |
| | | // 这样做的目的是避免在更新时候,某些平台动画会恢复关闭状态 |
| | | this.show = false; |
| | | this.$uv.sleep(2).then(res=>{ |
| | | this.show = true; |
| | | }); |
| | | this.imgWidth = newVal; |
| | | }, |
| | | height(newVal){ |
| | | // 这样做的目的是避免在更新时候,某些平台动画会恢复关闭状态 |
| | | this.show = false; |
| | | this.$uv.sleep(2).then(res=>{ |
| | | this.show = true; |
| | | }); |
| | | this.imgHeight = newVal; |
| | | } |
| | | }, |
| | | computed: { |
| | | wrapStyle() { |
| | | let style = {}; |
| | | // 通过调用addUnit()方法,如果有单位,如百分比,px单位等,直接返回,如果是纯粹的数值,则加上rpx单位 |
| | | if(this.mode !== 'heightFix') { |
| | | style.width = this.$uv.addUnit(this.imgWidth); |
| | | } |
| | | if(this.mode !== 'widthFix') { |
| | | style.height = this.$uv.addUnit(this.imgHeight); |
| | | } |
| | | // 如果是显示圆形,设置一个很多的半径值即可 |
| | | style.borderRadius = this.shape == 'circle' ? '10000px' : this.$uv.addUnit(this.radius) |
| | | // 如果设置圆角,必须要有hidden,否则可能圆角无效 |
| | | style.overflow = this.radius > 0 ? 'hidden' : 'visible' |
| | | return this.$uv.deepMerge(style, this.$uv.addStyle(this.customStyle)); |
| | | }, |
| | | imageStyle() { |
| | | let style = {}; |
| | | style.borderRadius = this.shape == 'circle' ? '10000px' : this.$uv.addUnit(this.radius); |
| | | // #ifdef APP-NVUE |
| | | style.width = this.$uv.addUnit(this.imgWidth); |
| | | style.height = this.$uv.addUnit(this.imgHeight); |
| | | // #endif |
| | | return style; |
| | | } |
| | | }, |
| | | created() { |
| | | this.elIndex = this.$uv.guid(); |
| | | this.observer = {} |
| | | this.observerName = 'lazyLoadContentObserver' |
| | | }, |
| | | mounted() { |
| | | this.show = true; |
| | | this.$nextTick(()=>{ |
| | | if(this.observeLazyLoad) this.observerFn(); |
| | | }) |
| | | }, |
| | | methods: { |
| | | // 点击图片 |
| | | onClick() { |
| | | this.$emit('click') |
| | | }, |
| | | // 图片加载失败 |
| | | onErrorHandler(err) { |
| | | this.loading = false |
| | | this.isError = true |
| | | this.$emit('error', err) |
| | | }, |
| | | // 图片加载完成,标记loading结束 |
| | | onLoadHandler(event) { |
| | | if(this.mode == 'widthFix') this.imgHeight = 'auto' |
| | | if(this.mode == 'heightFix') this.imgWidth = 'auto' |
| | | this.loading = false |
| | | this.isError = false |
| | | this.$emit('load', event) |
| | | this.removeBgColor() |
| | | }, |
| | | // 移除图片的背景色 |
| | | removeBgColor() { |
| | | // 淡入动画过渡完成后,将背景设置为透明色,否则png图片会看到灰色的背景 |
| | | this.backgroundStyle = { |
| | | backgroundColor: 'transparent' |
| | | }; |
| | | }, |
| | | // 观察图片是否在可见视口 |
| | | observerFn(){ |
| | | // 在需要用到懒加载的页面,在触发底部的时候触发tOnLazyLoadReachBottom事件,保证所有图片进行加载 |
| | | this.$nextTick(() => { |
| | | uni.$once('onLazyLoadReachBottom', () => { |
| | | if (!this.observeShow) this.observeShow = true |
| | | }) |
| | | }) |
| | | setTimeout(() => { |
| | | // #ifndef APP-NVUE |
| | | this.disconnectObserver(this.observerName) |
| | | const contentObserver = uni.createIntersectionObserver(this) |
| | | contentObserver.relativeToViewport({ |
| | | bottom: this.thresholdValue |
| | | }).observe(`.uv-image--${this.elIndex}`, (res) => { |
| | | if (res.intersectionRatio > 0) { |
| | | // 懒加载状态改变 |
| | | this.observeShow = true |
| | | // 如果图片已经加载,去掉监听,减少性能消耗 |
| | | this.disconnectObserver(this.observerName) |
| | | } |
| | | }) |
| | | this[this.observerName] = contentObserver |
| | | // #endif |
| | | // #ifdef APP-NVUE |
| | | this.observeShow = true; |
| | | // #endif |
| | | }, 50) |
| | | }, |
| | | disconnectObserver(observerName) { |
| | | const observer = this[observerName] |
| | | observer && observer.disconnect() |
| | | } |
| | | } |
| | | }; |
| | | </script> |
| | | |
| | | <style lang="scss" scoped> |
| | | @import '@/uni_modules/uv-ui-tools/libs/css/components.scss'; |
| | | @import '@/uni_modules/uv-ui-tools/libs/css/color.scss'; |
| | | $uv-image-error-top:0px !default; |
| | | $uv-image-error-left:0px !default; |
| | | $uv-image-error-width:100% !default; |
| | | $uv-image-error-hight:100% !default; |
| | | $uv-image-error-background-color:$uv-bg-color !default; |
| | | $uv-image-error-color:$uv-tips-color !default; |
| | | $uv-image-error-font-size: 46rpx !default; |
| | | |
| | | .uv-image { |
| | | position: relative; |
| | | transition: opacity 0.5s ease-in-out; |
| | | |
| | | &__image { |
| | | width: 100%; |
| | | height: 100%; |
| | | } |
| | | |
| | | &__loading, |
| | | &__error { |
| | | position: absolute; |
| | | top: $uv-image-error-top; |
| | | left: $uv-image-error-left; |
| | | width: $uv-image-error-width; |
| | | height: $uv-image-error-hight; |
| | | @include flex; |
| | | align-items: center; |
| | | justify-content: center; |
| | | background-color: $uv-image-error-background-color; |
| | | color: $uv-image-error-color; |
| | | font-size: $uv-image-error-font-size; |
| | | } |
| | | } |
| | | </style> |
| New file |
| | |
| | | { |
| | | "id": "uv-image", |
| | | "displayName": "uv-image 图片 全面兼容vue3+2、app、h5、小程序等多端", |
| | | "version": "1.0.16", |
| | | "description": "uv-image 此组件为uni-app的image组件的加强版,在继承了原有功能外,增加observer懒加载功能,还支持淡入动画、加载中、加载失败提示、圆角值和形状等。", |
| | | "keywords": [ |
| | | "uv-image", |
| | | "uvui", |
| | | "uv-ui", |
| | | "image", |
| | | "图片" |
| | | ], |
| | | "repository": "", |
| | | "engines": { |
| | | "HBuilderX": "^3.1.0" |
| | | }, |
| | | "dcloudext": { |
| | | "type": "component-vue", |
| | | "sale": { |
| | | "regular": { |
| | | "price": "0.00" |
| | | }, |
| | | "sourcecode": { |
| | | "price": "0.00" |
| | | } |
| | | }, |
| | | "contact": { |
| | | "qq": "" |
| | | }, |
| | | "declaration": { |
| | | "ads": "无", |
| | | "data": "插件不采集任何数据", |
| | | "permissions": "无" |
| | | }, |
| | | "npmurl": "" |
| | | }, |
| | | "uni_modules": { |
| | | "dependencies": [ |
| | | "uv-ui-tools", |
| | | "uv-transition", |
| | | "uv-icon" |
| | | ], |
| | | "encrypt": [], |
| | | "platforms": { |
| | | "cloud": { |
| | | "tcb": "y", |
| | | "aliyun": "y" |
| | | }, |
| | | "client": { |
| | | "Vue": { |
| | | "vue2": "y", |
| | | "vue3": "y" |
| | | }, |
| | | "App": { |
| | | "app-vue": "y", |
| | | "app-nvue": "y" |
| | | }, |
| | | "H5-mobile": { |
| | | "Safari": "y", |
| | | "Android Browser": "y", |
| | | "微信浏览器(Android)": "y", |
| | | "QQ浏览器(Android)": "y" |
| | | }, |
| | | "H5-pc": { |
| | | "Chrome": "y", |
| | | "IE": "y", |
| | | "Edge": "y", |
| | | "Firefox": "y", |
| | | "Safari": "y" |
| | | }, |
| | | "小程序": { |
| | | "微信": "y", |
| | | "阿里": "y", |
| | | "百度": "y", |
| | | "字节跳动": "y", |
| | | "QQ": "y", |
| | | "钉钉": "u", |
| | | "快手": "u", |
| | | "飞书": "u", |
| | | "京东": "u" |
| | | }, |
| | | "快应用": { |
| | | "华为": "u", |
| | | "联盟": "u" |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| New file |
| | |
| | | ## Image 图片 |
| | | |
| | | > **组件名:uv-image** |
| | | |
| | | 此组件为`uni-app`的`image`组件的加强版,在继承了原有功能外,增加`observer`懒加载功能,还支持淡入动画、加载中、加载失败提示、圆角值和形状等。 |
| | | |
| | | # <a href="https://www.uvui.cn/components/image.html" target="_blank">查看文档</a> |
| | | |
| | | ## [下载完整示例项目](https://ext.dcloud.net.cn/plugin?name=uv-ui) |
| | | |
| | | ### [更多插件,请关注uv-ui组件库](https://ext.dcloud.net.cn/plugin?name=uv-ui) |
| | | |
| | |  |
| | | |
| | | #### 如使用过程中有任何问题反馈,或者您对uv-ui有一些好的建议,欢迎加入uv-ui官方交流群:<a href="https://www.uvui.cn/components/addQQGroup.html" target="_blank">官方QQ群</a> |
| New file |
| | |
| | | ## 1.0.7(2023-11-07) |
| | | 1. 修复sticky属性不生效的BUG |
| | | ## 1.0.6(2023-09-01) |
| | | 1. 修复设置customNavHeight导致定位不准确的BUG |
| | | ## 1.0.5(2023-08-23) |
| | | 1. 修复ios端快速滑动+点击右侧导航会出现白屏的BUG |
| | | ## 1.0.4(2023-07-25) |
| | | 1. 修复全局设置成rpx存在的高度BUG |
| | | 2. 修复其他BUG |
| | | ## 1.0.3(2023-07-03) |
| | | 去除插槽判断,避免某些平台不显示的BUG |
| | | ## 1.0.2(2023-05-27) |
| | | 1. select事件修复 |
| | | ## 1.0.1(2023-05-16) |
| | | 1. 优化组件依赖,修改后无需全局引入,组件导入即可使用 |
| | | 2. 优化部分功能 |
| | | ## 1.0.0(2023-05-10) |
| | | uv-index-list 索引列表 |
| New file |
| | |
| | | export default { |
| | | props: { |
| | | // 列表锚点文本内容 |
| | | text: { |
| | | type: [String, Number], |
| | | default: '' |
| | | }, |
| | | // 列表锚点文字颜色 |
| | | color: { |
| | | type: String, |
| | | default: '#606266' |
| | | }, |
| | | // 列表锚点文字大小,单位默认px |
| | | size: { |
| | | type: [String, Number], |
| | | default: 14 |
| | | }, |
| | | // 列表锚点背景颜色 |
| | | bgColor: { |
| | | type: String, |
| | | default: '#dedede' |
| | | }, |
| | | // 列表锚点高度,单位默认px |
| | | height: { |
| | | type: [String, Number], |
| | | default: 32 |
| | | }, |
| | | ...uni.$uv?.props?.indexAnchor |
| | | } |
| | | } |
| New file |
| | |
| | | <template> |
| | | <!-- #ifdef APP-NVUE --> |
| | | <header> |
| | | <!-- #endif --> |
| | | <view |
| | | :class="['uv-index-anchor',{'uv-index-anchor-sticky': parentData.sticky}]" |
| | | :ref="`uv-index-anchor-${text}`" |
| | | :style="{ |
| | | height: $uv.addUnit(height), |
| | | backgroundColor: bgColor |
| | | }" |
| | | > |
| | | <text |
| | | class="uv-index-anchor__text" |
| | | :style="{ |
| | | fontSize: $uv.addUnit(size), |
| | | color: color |
| | | }" |
| | | >{{ text }}</text> |
| | | </view> |
| | | <!-- #ifdef APP-NVUE --> |
| | | </header> |
| | | <!-- #endif --> |
| | | </template> |
| | | |
| | | <script> |
| | | import mpMixin from '@/uni_modules/uv-ui-tools/libs/mixin/mpMixin.js' |
| | | import mixin from '@/uni_modules/uv-ui-tools/libs/mixin/mixin.js' |
| | | import props from './props.js'; |
| | | // #ifdef APP-NVUE |
| | | const dom = uni.requireNativePlugin('dom') |
| | | // #endif |
| | | /** |
| | | * IndexAnchor 列表锚点 |
| | | * @description |
| | | * @tutorial https://www.uvui.cn/components/indexList.html |
| | | * @property {String | Number} text 列表锚点文本内容 |
| | | * @property {String} color 列表锚点文字颜色 ( 默认 '#606266' ) |
| | | * @property {String | Number} size 列表锚点文字大小,单位默认px ( 默认 14 ) |
| | | * @property {String} bgColor 列表锚点背景颜色 ( 默认 '#dedede' ) |
| | | * @property {String | Number} height 列表锚点高度,单位默认px ( 默认 32 ) |
| | | * @example <uv-index-anchor :text="indexList[index]"></uv-index-anchor> |
| | | */ |
| | | export default { |
| | | name: 'uv-index-anchor', |
| | | mixins: [mpMixin, mixin, props], |
| | | data() { |
| | | return { |
| | | parentData: { |
| | | sticky: true |
| | | } |
| | | } |
| | | }, |
| | | created() { |
| | | this.init() |
| | | }, |
| | | methods: { |
| | | init() { |
| | | // 此处会活动父组件实例,并赋值给实例的parent属性 |
| | | const indexList = this.$uv.$parent.call(this, 'uv-index-list') |
| | | if (!indexList) { |
| | | return this.$uv.error('uv-index-anchor必须要搭配uv-index-list组件使用') |
| | | } |
| | | this.parentData.sticky = indexList.sticky; |
| | | // 将当前实例放入到uv-index-list中 |
| | | indexList.anchors.push(this) |
| | | const indexListItem = this.$uv.$parent.call(this, 'uv-index-item') |
| | | // #ifndef APP-NVUE |
| | | // 只有在非nvue下,uv-index-anchor才是嵌套在uv-index-item中的 |
| | | if (!indexListItem) { |
| | | return this.$uv.error('uv-index-anchor必须要搭配uv-index-item组件使用') |
| | | } |
| | | // 设置uv-index-item的id为anchor的text标识符,因为非nvue下滚动列表需要依赖scroll-view滚动到元素的特性 |
| | | indexListItem.id = this.text.charCodeAt(0) |
| | | // #endif |
| | | } |
| | | }, |
| | | } |
| | | </script> |
| | | |
| | | <style lang="scss" scoped> |
| | | @import '@/uni_modules/uv-ui-tools/libs/css/components.scss'; |
| | | |
| | | .uv-index-anchor { |
| | | @include flex; |
| | | align-items: center; |
| | | padding-left: 15px; |
| | | z-index: 1; |
| | | &-sticky { |
| | | position: sticky; |
| | | top: 0; |
| | | } |
| | | &__text { |
| | | @include flex; |
| | | align-items: center; |
| | | } |
| | | } |
| | | </style> |
| New file |
| | |
| | | <template> |
| | | <!-- #ifdef APP-NVUE --> |
| | | <cell ref="uv-index-item"> |
| | | <!-- #endif --> |
| | | <view |
| | | class="uv-index-item" |
| | | :id="`uv-index-item-${id}`" |
| | | :class="[`uv-index-item-${id}`]" |
| | | > |
| | | <slot /> |
| | | </view> |
| | | <!-- #ifdef APP-NVUE --> |
| | | </cell> |
| | | <!-- #endif --> |
| | | </template> |
| | | |
| | | <script> |
| | | import mpMixin from '@/uni_modules/uv-ui-tools/libs/mixin/mpMixin.js' |
| | | import mixin from '@/uni_modules/uv-ui-tools/libs/mixin/mixin.js' |
| | | // #ifdef APP-NVUE |
| | | // 由于weex为阿里的KPI业绩考核的产物,所以不支持百分比单位,这里需要通过dom查询组件的宽度 |
| | | const dom = uni.requireNativePlugin('dom') |
| | | // #endif |
| | | /** |
| | | * IndexItem |
| | | * @description |
| | | * @tutorial https://www.uvui.cn/components/indexList.html |
| | | * @property {String} |
| | | * @event {Function} |
| | | * @example |
| | | */ |
| | | export default { |
| | | name: 'uv-index-item', |
| | | mixins: [mpMixin, mixin], |
| | | data() { |
| | | return { |
| | | // 本组件到滚动条顶部的距离 |
| | | top: 0, |
| | | height: 0, |
| | | id: '' |
| | | } |
| | | }, |
| | | created() { |
| | | // 子组件uv-index-anchor的实例 |
| | | this.anchor = {} |
| | | }, |
| | | mounted() { |
| | | this.init() |
| | | }, |
| | | methods: { |
| | | init() { |
| | | // 此处会活动父组件实例,并赋值给实例的parent属性 |
| | | this.getParentData('uv-index-list') |
| | | if (!this.parent) { |
| | | return this.$uv.error('uv-index-item必须要搭配uv-index-list组件使用') |
| | | } |
| | | this.$uv.sleep().then(() =>{ |
| | | this.getIndexItemRect().then(size => { |
| | | // 由于对象的引用特性,此处会同时生效到父组件的children数组的本实例的top属性中,供父组件判断读取 |
| | | this.top = Math.ceil(size.top) |
| | | this.height = Math.ceil(size.height) |
| | | }) |
| | | }) |
| | | }, |
| | | getIndexItemRect() { |
| | | return new Promise(resolve => { |
| | | // #ifndef APP-NVUE |
| | | this.$uvGetRect('.uv-index-item').then(size => { |
| | | resolve(size) |
| | | }) |
| | | // #endif |
| | | |
| | | // #ifdef APP-NVUE |
| | | const ref = this.$refs['uv-index-item'] |
| | | dom.getComponentRect(ref, res => { |
| | | resolve(res.size) |
| | | }) |
| | | // #endif |
| | | }) |
| | | } |
| | | }, |
| | | } |
| | | </script> |
| | | |
| | | <style lang="scss" scoped> |
| | | @import '@/uni_modules/uv-ui-tools/libs/css/components.scss'; |
| | | </style> |
| New file |
| | |
| | | export default { |
| | | props: { |
| | | // 右边锚点非激活的颜色 |
| | | inactiveColor: { |
| | | type: String, |
| | | default: '#606266' |
| | | }, |
| | | // 右边锚点激活的颜色 |
| | | activeColor: { |
| | | type: String, |
| | | default: '#5677fc' |
| | | }, |
| | | // 索引字符列表,数组形式 |
| | | indexList: { |
| | | type: Array, |
| | | default: () => [] |
| | | }, |
| | | // 是否开启锚点自动吸顶 |
| | | sticky: { |
| | | type: Boolean, |
| | | default: true |
| | | }, |
| | | // 自定义导航栏的高度 |
| | | customNavHeight: { |
| | | type: [String, Number], |
| | | default: 0 |
| | | }, |
| | | ...uni.$uv?.props?.indexList |
| | | } |
| | | } |
| New file |
| | |
| | | <template> |
| | | <view class="uv-index-list"> |
| | | <!-- #ifdef APP-NVUE --> |
| | | <list |
| | | :scrollTop="scrollTop" |
| | | enable-back-to-top |
| | | :offset-accuracy="1" |
| | | :style="{ |
| | | maxHeight: $uv.addUnit(scrollViewHeight,'px') |
| | | }" |
| | | @scroll="scrollHandler" |
| | | ref="uvList" |
| | | > |
| | | <cell ref="header"> |
| | | <slot name="header" /> |
| | | </cell> |
| | | <slot /> |
| | | <cell> |
| | | <slot name="footer" /> |
| | | </cell> |
| | | </list> |
| | | <!-- #endif --> |
| | | <!-- #ifndef APP-NVUE --> |
| | | <scroll-view |
| | | :scrollTop="scrollTop" |
| | | :scrollIntoView="scrollIntoView" |
| | | :offset-accuracy="1" |
| | | :style="{ |
| | | maxHeight: $uv.addUnit(scrollViewHeight,'px') |
| | | }" |
| | | scroll-y |
| | | @scroll="scrollHandler" |
| | | ref="uvList" |
| | | > |
| | | <view> |
| | | <slot name="header" /> |
| | | </view> |
| | | <slot /> |
| | | <view> |
| | | <slot name="footer" /> |
| | | </view> |
| | | </scroll-view> |
| | | <!-- #endif --> |
| | | <view |
| | | class="uv-index-list__letter" |
| | | ref="uv-index-list__letter" |
| | | :style="{ top: $uv.addUnit(letterInfo.top || 100 ,'px') }" |
| | | @touchstart="touchStart" |
| | | @touchmove.stop.prevent="touchMove" |
| | | @touchend.stop.prevent="touchEnd" |
| | | @touchcancel.stop.prevent="touchEnd" |
| | | > |
| | | <view |
| | | class="uv-index-list__letter__item" |
| | | v-for="(item, index) in uIndexList" |
| | | :key="index" |
| | | :style="{ |
| | | backgroundColor: activeIndex === index ? activeColor : 'transparent' |
| | | }" |
| | | > |
| | | <text |
| | | class="uv-index-list__letter__item__index" |
| | | :style="{color: activeIndex === index ? '#fff' : inactiveColor}" |
| | | >{{ item }}</text> |
| | | </view> |
| | | </view> |
| | | <uv-transition |
| | | mode="fade" |
| | | :show="touching" |
| | | :customStyle="{ |
| | | position: 'fixed', |
| | | right: '40px', |
| | | top: $uv.addUnit(indicatorTop,'px'), |
| | | zIndex: 2 |
| | | }" |
| | | > |
| | | <view class="uv-index-list__indicator__box"> |
| | | <view |
| | | class="uv-index-list__indicator" |
| | | :class="['uv-index-list__indicator--show']" |
| | | :style="{ |
| | | height: $uv.addUnit(indicatorHeight,'px'), |
| | | width: $uv.addUnit(indicatorHeight,'px') |
| | | }" |
| | | > |
| | | <text class="uv-index-list__indicator__text">{{ uIndexList[activeIndex] }}</text> |
| | | </view> |
| | | </view> |
| | | </uv-transition> |
| | | </view> |
| | | </template> |
| | | |
| | | <script> |
| | | const indexList = () => { |
| | | const indexList = []; |
| | | const charCodeOfA = 'A'.charCodeAt(0); |
| | | for (let i = 0; i < 26; i++) { |
| | | indexList.push(String.fromCharCode(charCodeOfA + i)); |
| | | } |
| | | return indexList; |
| | | } |
| | | import mpMixin from '@/uni_modules/uv-ui-tools/libs/mixin/mpMixin.js' |
| | | import mixin from '@/uni_modules/uv-ui-tools/libs/mixin/mixin.js' |
| | | import props from './props.js'; |
| | | // #ifdef APP-NVUE |
| | | // 由于weex为阿里的KPI业绩考核的产物,所以不支持百分比单位,这里需要通过dom查询组件的宽度 |
| | | const dom = uni.requireNativePlugin('dom') |
| | | // #endif |
| | | /** |
| | | * IndexList 索引列表 |
| | | * @description 通过折叠面板收纳内容区域 |
| | | * @tutorial https://www.uvui.cn/components/indexList.html |
| | | * @property {String} inactiveColor 右边锚点非激活的颜色 ( 默认 '#606266' ) |
| | | * @property {String} activeColor 右边锚点激活的颜色 ( 默认 '#5677fc' ) |
| | | * @property {Array} indexList 索引字符列表,数组形式 |
| | | * @property {Boolean} sticky 是否开启锚点自动吸顶 ( 默认 true ) |
| | | * @property {String | Number} customNavHeight 自定义导航栏的高度 ( 默认 0 ) |
| | | * */ |
| | | export default { |
| | | name: 'uv-index-list', |
| | | mixins: [mpMixin, mixin, props], |
| | | // #ifdef MP-WEIXIN |
| | | // 将自定义节点设置成虚拟的,更加接近Vue组件的表现,能更好的使用flex属性 |
| | | options: { |
| | | virtualHost: true |
| | | }, |
| | | // #endif |
| | | data() { |
| | | return { |
| | | // 当前正在被选中的字母索引 |
| | | activeIndex: -1, |
| | | touchmoveIndex: 1, |
| | | // 索引字母的信息 |
| | | letterInfo: { |
| | | height: 0, |
| | | itemHeight: 0, |
| | | top: 0 |
| | | }, |
| | | // 设置字母指示器的高度,后面为了让指示器跟随字母,并将尖角部分指向字母的中部,需要依赖此值 |
| | | indicatorHeight: 50, |
| | | // 字母放大指示器的top值,为了让其指向当前激活的字母 |
| | | // indicatorTop: 0 |
| | | // 当前是否正在被触摸状态 |
| | | touching: false, |
| | | // 滚动条顶部top值 |
| | | scrollTop: 0, |
| | | // scroll-view的高度 |
| | | scrollViewHeight: 0, |
| | | // 系统信息 |
| | | sys: '', |
| | | scrolling: false, |
| | | scrollIntoView: '', |
| | | hasHeight: 0, |
| | | timer: 0, |
| | | disTap: false |
| | | } |
| | | }, |
| | | computed: { |
| | | // 如果有传入外部的indexList锚点数组则使用,否则使用内部生成A-Z字母 |
| | | uIndexList() { |
| | | return this.indexList.length ? this.indexList : indexList() |
| | | }, |
| | | // 字母放大指示器的top值,为了让其指向当前激活的字母 |
| | | indicatorTop() { |
| | | const { |
| | | top, |
| | | itemHeight |
| | | } = this.letterInfo |
| | | return Math.floor(top + itemHeight * this.activeIndex + itemHeight / 2 - this.indicatorHeight / 2) - 8 |
| | | } |
| | | }, |
| | | watch: { |
| | | // 监听字母索引的变化,重新设置尺寸 |
| | | uIndexList: { |
| | | immediate: true, |
| | | handler() { |
| | | this.$uv.sleep().then(() => { |
| | | this.setIndexListLetterInfo() |
| | | }) |
| | | } |
| | | } |
| | | }, |
| | | created() { |
| | | this.sys = this.$uv.sys() |
| | | this.children = [] |
| | | this.anchors = [] |
| | | this.init() |
| | | }, |
| | | mounted() { |
| | | this.setIndexListLetterInfo() |
| | | }, |
| | | methods: { |
| | | init() { |
| | | // 设置列表的高度为整个屏幕的高度 |
| | | //减去this.customNavHeight,并将this.scrollViewHeight设置为maxHeight |
| | | //解决当uv-index-list组件放在tabbar页面时,scroll-view内容较少时,还能滚动 |
| | | this.scrollViewHeight = this.sys.windowHeight - this.$uv.getPx(this.customNavHeight) |
| | | }, |
| | | // 索引列表被触摸 |
| | | touchStart(e) { |
| | | // 获取触摸点信息 |
| | | const touchStart = e.changedTouches[0] |
| | | if (!touchStart || this.disTap) return |
| | | this.touching = true |
| | | const { |
| | | pageY |
| | | } = touchStart |
| | | // 根据当前触摸点的坐标,获取当前触摸的为第几个字母 |
| | | const currentIndex = this.getIndexListLetter(pageY) |
| | | this.setValueForTouch(currentIndex) |
| | | }, |
| | | // 索引字母列表被触摸滑动中 |
| | | touchMove(e) { |
| | | // 获取触摸点信息 |
| | | let touchMove = e.changedTouches[0] |
| | | if (!touchMove || this.disTap) return; |
| | | |
| | | // 滑动结束后迅速开始第二次滑动时候 touching 为 false 造成不显示 indicator 问题 |
| | | if (!this.touching) { |
| | | this.touching = true |
| | | } |
| | | const { |
| | | pageY |
| | | } = touchMove |
| | | const currentIndex = this.getIndexListLetter(pageY) |
| | | this.setValueForTouch(currentIndex) |
| | | }, |
| | | // 触摸结束 |
| | | touchEnd(e) { |
| | | // 延时一定时间后再隐藏指示器,为了让用户看的更直观,同时也是为了消除快速切换uv-transition的show带来的影响 |
| | | this.$uv.sleep(300).then(() => { |
| | | this.touching = false |
| | | }) |
| | | this.$emit('select',this.activeIndex); |
| | | }, |
| | | // 获取索引列表的尺寸以及单个字符的尺寸信息 |
| | | getIndexListLetterRect() { |
| | | return new Promise(resolve => { |
| | | // 延时一定时间,以获取dom尺寸 |
| | | // #ifndef APP-NVUE |
| | | this.$uvGetRect('.uv-index-list__letter').then(size => { |
| | | resolve(size) |
| | | }) |
| | | // #endif |
| | | |
| | | // #ifdef APP-NVUE |
| | | const ref = this.$refs['uv-index-list__letter'] |
| | | dom.getComponentRect(ref, res => { |
| | | resolve(res.size) |
| | | }) |
| | | // #endif |
| | | }) |
| | | }, |
| | | // 设置indexList索引的尺寸信息 |
| | | setIndexListLetterInfo() { |
| | | this.getIndexListLetterRect().then(size => { |
| | | const { |
| | | top, |
| | | height |
| | | } = size |
| | | const windowHeight = this.$uv.sys().windowHeight; |
| | | let customNavHeight = 0 |
| | | // 消除各端导航栏非原生和原生导致的差异,让索引列表字母对屏幕垂直居中 |
| | | if (this.customNavHeight == 0) { |
| | | // #ifdef H5 |
| | | customNavHeight = this.$uv.sys().windowTop |
| | | // #endif |
| | | // #ifndef H5 |
| | | // 在非H5中,为原生导航栏,其高度不算在windowHeight内,这里设置为负值,后面相加时变成减去其高度的一半 |
| | | customNavHeight = 0 |
| | | // #endif |
| | | } else { |
| | | customNavHeight = this.$uv.getPx(this.customNavHeight) |
| | | } |
| | | this.letterInfo = { |
| | | height, |
| | | // 为了让字母列表对屏幕绝对居中,让其对导航栏进行修正,也即往上偏移导航栏的一半高度 |
| | | top: (windowHeight - height) / 2 + customNavHeight / 2, |
| | | itemHeight: Math.floor(height / this.uIndexList.length) |
| | | } |
| | | }) |
| | | }, |
| | | // 获取当前被触摸的索引字母 |
| | | getIndexListLetter(pageY) { |
| | | const { |
| | | top, |
| | | height, |
| | | itemHeight |
| | | } = this.letterInfo |
| | | // 对H5的pageY进行修正,这是由于uni-app自作多情在H5中将触摸点的坐标跟H5的导航栏结合导致的问题 |
| | | // #ifdef H5 |
| | | pageY += this.$uv.sys().windowTop |
| | | // #endif |
| | | // #ifdef APP-NVUE |
| | | pageY += top |
| | | // #endif |
| | | // 对第一和最后一个字母做边界处理,因为用户可能在字母列表上触摸到两端的尽头后依然继续滑动 |
| | | if (pageY < top) { |
| | | return 0 |
| | | } else if (pageY >= top + height) { |
| | | // 如果超出了,取最后一个字母 |
| | | return this.uIndexList.length - 1 |
| | | } else { |
| | | // 将触摸点的Y轴偏移值,减去索引字母的top值,除以每个字母的高度,即可得到当前触摸点落在哪个字母上 |
| | | return Math.floor((pageY - top) / itemHeight); |
| | | } |
| | | }, |
| | | // 设置各项由触摸而导致变化的值 |
| | | setValueForTouch(currentIndex) { |
| | | // 如果偏移量太小,前后得出的会是同一个索引字母,为了防抖,进行返回 |
| | | if (currentIndex === this.activeIndex) return |
| | | this.activeIndex = currentIndex |
| | | // #ifndef APP-NVUE || MP-WEIXIN |
| | | // 在非nvue中,由于anchor和item都在uv-index-item中,所以需要对index-item进行偏移 |
| | | this.scrollIntoView = `uv-index-item-${this.uIndexList[currentIndex].charCodeAt(0)}` |
| | | // #endif |
| | | // #ifdef MP-WEIXIN |
| | | // 微信小程序下,scroll-view的scroll-into-view属性无法对slot中的内容的id生效,只能通过设置scrollTop的形式去移动滚动条 |
| | | this.scrollTop = this.children[currentIndex].top |
| | | // #endif |
| | | // #ifdef APP-NVUE |
| | | // 在nvue中,由于cell和header为同级元素,所以实际是需要对header(anchor)进行偏移 |
| | | const anchor = `uv-index-anchor-${this.uIndexList[currentIndex]}` |
| | | dom.scrollToElement(this.anchors[currentIndex].$refs[anchor], { |
| | | offset: 0, |
| | | animated: false |
| | | }) |
| | | // #endif |
| | | }, |
| | | getHeaderRect() { |
| | | // 获取header slot的高度,因为list组件中获取元素的尺寸是没有top值的 |
| | | return new Promise(resolve => { |
| | | dom.getComponentRect(this.$refs.header, res => { |
| | | resolve(res.size) |
| | | }) |
| | | }) |
| | | }, |
| | | // scroll-view的滚动事件 |
| | | async scrollHandler(e) { |
| | | if (this.touching || this.scrolling) return |
| | | // 每过一定时间取样一次,减少资源损耗以及可能带来的卡顿 |
| | | this.scrolling = true |
| | | this.disTap = true; |
| | | clearTimeout(this.timer); |
| | | this.timer = setTimeout(()=>{ |
| | | this.disTap = false; |
| | | },200) |
| | | this.$uv.sleep(30).then(() => { |
| | | this.scrolling = false |
| | | }) |
| | | let scrollTop = 0 |
| | | const len = this.children.length |
| | | let children = this.children |
| | | const anchors = this.anchors |
| | | const customNavHeight = this.$uv.getPx(this.customNavHeight); |
| | | // #ifdef APP-NVUE |
| | | // nvue下获取的滚动条偏移为负数,需要转为正数 |
| | | scrollTop = Math.abs(e.contentOffset.y) |
| | | // 获取header slot的尺寸信息 |
| | | const header = await this.getHeaderRect() |
| | | // item的top值,在nvue下,模拟出的anchor的top,类似非nvue下的index-item的top |
| | | let top = header.height |
| | | // 由于list组件无法获取cell的top值,这里通过header slot和各个item之间的height,模拟出类似非nvue下的位置信息 |
| | | children = this.children.map((item, index) => { |
| | | if(item.height>0) this.hasHeight = item.height; |
| | | item.height = item.height>0?item.height:this.hasHeight; |
| | | const child = { |
| | | height: item.height, |
| | | top |
| | | } |
| | | // 进行累加,给下一个item提供计算依据 |
| | | top += item.height + anchors[index].height |
| | | return child |
| | | }) |
| | | // #endif |
| | | // #ifndef APP-NVUE |
| | | // 非nvue通过detail获取滚动条位移 |
| | | scrollTop = e.detail.scrollTop |
| | | // #endif |
| | | for (let i = 0; i < len; i++) { |
| | | const item = children[i], |
| | | nextItem = children[i + 1] |
| | | // 如果滚动条高度小于第一个item的top值,此时无需设置任意字母为高亮 |
| | | if (scrollTop + customNavHeight <= children[0].top || scrollTop >= children[len - 1].top + children[len - |
| | | 1].height) { |
| | | this.activeIndex = -1 |
| | | break |
| | | } else if (!nextItem) { |
| | | // 当不存在下一个item时,意味着历遍到了最后一个 |
| | | this.activeIndex = len - 1 |
| | | break |
| | | } else if (scrollTop + customNavHeight > item.top && scrollTop + customNavHeight < nextItem.top) { |
| | | this.activeIndex = i |
| | | break |
| | | } |
| | | } |
| | | }, |
| | | }, |
| | | } |
| | | </script> |
| | | |
| | | <style lang="scss" scoped> |
| | | @import '@/uni_modules/uv-ui-tools/libs/css/components.scss'; |
| | | @import '@/uni_modules/uv-ui-tools/libs/css/color.scss'; |
| | | .uv-index-list { |
| | | |
| | | &__letter { |
| | | position: fixed; |
| | | right: 0; |
| | | text-align: center; |
| | | z-index: 3; |
| | | padding: 0 6px; |
| | | |
| | | &__item { |
| | | width: 16px; |
| | | height: 16px; |
| | | border-radius: 100px; |
| | | margin: 1px 0; |
| | | @include flex; |
| | | align-items: center; |
| | | justify-content: center; |
| | | |
| | | &--active { |
| | | background-color: $uv-primary; |
| | | } |
| | | |
| | | &__index { |
| | | font-size: 12px; |
| | | text-align: center; |
| | | line-height: 12px; |
| | | } |
| | | } |
| | | } |
| | | &__indicator__box { |
| | | width: 65px; |
| | | height: 65px; |
| | | padding: 6px; |
| | | transform: rotate(-45deg); |
| | | } |
| | | &__indicator { |
| | | width: 50px; |
| | | height: 50px; |
| | | border-radius: 100px 100px 0 100px; |
| | | text-align: center; |
| | | color: #ffffff; |
| | | background-color: #c9c9c9; |
| | | @include flex; |
| | | justify-content: center; |
| | | align-items: center; |
| | | |
| | | &__text { |
| | | font-size: 28px; |
| | | line-height: 28px; |
| | | font-weight: bold; |
| | | color: #fff; |
| | | transform: rotate(45deg); |
| | | text-align: center; |
| | | } |
| | | } |
| | | } |
| | | </style> |
| New file |
| | |
| | | { |
| | | "id": "uv-index-list", |
| | | "displayName": "uv-index-list 索引列表 全面兼容vue3+2、app、h5、小程序等多端", |
| | | "version": "1.0.7", |
| | | "description": "该组件用于展示索引列表,右侧带索引的列表,方便快速定位到具体内容,通常用于城市/机场选择等场景。类似于微信通讯录页面", |
| | | "keywords": [ |
| | | "uv-index-list", |
| | | "uvui", |
| | | "uv-ui", |
| | | "index-list", |
| | | "索引列表" |
| | | ], |
| | | "repository": "", |
| | | "engines": { |
| | | "HBuilderX": "^3.1.0" |
| | | }, |
| | | "dcloudext": { |
| | | "type": "component-vue", |
| | | "sale": { |
| | | "regular": { |
| | | "price": "0.00" |
| | | }, |
| | | "sourcecode": { |
| | | "price": "0.00" |
| | | } |
| | | }, |
| | | "contact": { |
| | | "qq": "" |
| | | }, |
| | | "declaration": { |
| | | "ads": "无", |
| | | "data": "插件不采集任何数据", |
| | | "permissions": "无" |
| | | }, |
| | | "npmurl": "" |
| | | }, |
| | | "uni_modules": { |
| | | "dependencies": [ |
| | | "uv-ui-tools", |
| | | "uv-transition" |
| | | ], |
| | | "encrypt": [], |
| | | "platforms": { |
| | | "cloud": { |
| | | "tcb": "y", |
| | | "aliyun": "y" |
| | | }, |
| | | "client": { |
| | | "Vue": { |
| | | "vue2": "y", |
| | | "vue3": "y" |
| | | }, |
| | | "App": { |
| | | "app-vue": "y", |
| | | "app-nvue": "y" |
| | | }, |
| | | "H5-mobile": { |
| | | "Safari": "y", |
| | | "Android Browser": "y", |
| | | "微信浏览器(Android)": "y", |
| | | "QQ浏览器(Android)": "y" |
| | | }, |
| | | "H5-pc": { |
| | | "Chrome": "y", |
| | | "IE": "y", |
| | | "Edge": "y", |
| | | "Firefox": "y", |
| | | "Safari": "y" |
| | | }, |
| | | "小程序": { |
| | | "微信": "y", |
| | | "阿里": "y", |
| | | "百度": "y", |
| | | "字节跳动": "y", |
| | | "QQ": "y", |
| | | "钉钉": "u", |
| | | "快手": "u", |
| | | "飞书": "u", |
| | | "京东": "u" |
| | | }, |
| | | "快应用": { |
| | | "华为": "u", |
| | | "联盟": "u" |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| New file |
| | |
| | | ## IndexList 索引列表 |
| | | |
| | | > **组件名:uv-index-list** |
| | | |
| | | 用于展示索引列表,右侧带索引的列表,方便快速定位到具体内容,通常用于城市/机场选择等场景,类似于微信通讯录页面。 |
| | | |
| | | # <a href="https://www.uvui.cn/components/indexList.html" target="_blank">查看文档</a> |
| | | |
| | | ## [下载完整示例项目](https://ext.dcloud.net.cn/plugin?name=uv-ui) <small>(请不要 下载插件ZIP)</small> |
| | | |
| | | ### [更多插件,请关注uv-ui组件库](https://ext.dcloud.net.cn/plugin?name=uv-ui) |
| | | |
| | | <a href="https://ext.dcloud.net.cn/plugin?name=uv-ui" target="_blank"> |
| | | |
| | |  |
| | | |
| | | </a> |
| | | |
| | | #### 如使用过程中有任何问题反馈,或者您对uv-ui有一些好的建议,欢迎加入uv-ui官方交流群:<a href="https://www.uvui.cn/components/addQQGroup.html" target="_blank">官方QQ群</a> |
| New file |
| | |
| | | ## 1.0.5(2023-10-12) |
| | | 1. 增加disKeys参数,mode = "car"下,被禁用的键,如:['I','O'] |
| | | 2. 增加customabc参数,mode = "car"下,是否启用自定义中英文切换内容模式,为了兼容支付宝等小程序不兼容嵌套插槽,导致同时显示自定义内容和原始内容 |
| | | 3. 增加ref方法changeCarMode,mode = "car"下, 调用此方法可以切换中英文模式 |
| | | 4. 增加@changeCarInputMode,mode = "car"下,调用此方法可以进行切换中英文 |
| | | 5. 增加插槽abc,mode = "car"下,自定义中英文切换内容,具体参考[车牌键盘自定义中英文切换及禁用键等设置](https://www.uvui.cn/components/keyboard.html#车牌键盘自定义中英文切换及禁用键等设置) |
| | | ## 1.0.4(2023-09-04) |
| | | 1. 优化,修改文件名称 |
| | | ## 1.0.3(2023-09-04) |
| | | 1. 修复键盘change回调事件产生冲突的BUG |
| | | ## 1.0.2(2023-07-02) |
| | | uv-keyboard 由于弹出层uv-popup的修改,打开和关闭方法更改,详情参考文档:https://www.uvui.cn/components/keyboard.html |
| | | ## 1.0.1(2023-05-16) |
| | | 1. 优化组件依赖,修改后无需全局引入,组件导入即可使用 |
| | | 2. 优化部分功能 |
| | | ## 1.0.0(2023-05-10) |
| | | uv-keyboard 键盘 |
| New file |
| | |
| | | export default { |
| | | props: { |
| | | // 是否打乱键盘按键的顺序 |
| | | random: { |
| | | type: Boolean, |
| | | default: false |
| | | }, |
| | | // 输入一个中文后,是否自动切换到英文 |
| | | autoChange: { |
| | | type: Boolean, |
| | | default: false |
| | | }, |
| | | // 被禁用的键 |
| | | disKeys: { |
| | | type: Array, |
| | | default: ()=>[] |
| | | }, |
| | | // 是否自定义abc |
| | | customabc: { |
| | | type: Boolean, |
| | | default: false |
| | | } |
| | | } |
| | | } |
| New file |
| | |
| | | <template> |
| | | <view |
| | | class="uv-keyboard" |
| | | @touchmove.stop.prevent="noop" |
| | | > |
| | | <view |
| | | v-for="(group, i) in abc ? engKeyBoardList : areaList" |
| | | :key="i" |
| | | class="uv-keyboard__button" |
| | | :index="i" |
| | | :class="[i + 1 === 4 && 'uv-keyboard__button--center']" |
| | | > |
| | | <view |
| | | v-if="i === 3" |
| | | class="uv-keyboard__button__inner-wrapper" |
| | | > |
| | | <view |
| | | class="uv-keyboard__button__inner-wrapper__left" |
| | | hover-class="uv-hover-class" |
| | | :hover-stay-time="200" |
| | | @tap="changeCarInputMode" |
| | | > |
| | | <slot> |
| | | <template v-if="!customabc"> |
| | | <text |
| | | class="uv-keyboard__button__inner-wrapper__left__lang" |
| | | :class="[!abc && 'uv-keyboard__button__inner-wrapper__left__lang--active']" |
| | | >中</text> |
| | | <text class="uv-keyboard__button__inner-wrapper__left__line">/</text> |
| | | <text |
| | | class="uv-keyboard__button__inner-wrapper__left__lang" |
| | | :class="[abc && 'uv-keyboard__button__inner-wrapper__left__lang--active']" |
| | | >英</text> |
| | | </template> |
| | | </slot> |
| | | </view> |
| | | </view> |
| | | <view |
| | | class="uv-keyboard__button__inner-wrapper" |
| | | v-for="(item, j) in group" |
| | | :key="j" |
| | | > |
| | | <view |
| | | :class="['uv-keyboard__button__inner-wrapper__inner',{'uv-keyboard__button__inner-wrapper__inner--disabled': isDisabled(i,j)}]" |
| | | :hover-stay-time="200" |
| | | @tap="carInputClick(i, j)" |
| | | :hover-class="isDisabled(i,j)?'none':'uv-hover-class'" |
| | | > |
| | | <text class="uv-keyboard__button__inner-wrapper__inner__text">{{ item }}</text> |
| | | </view> |
| | | <view class="uv-keyboard__button__inner-wrapper__disabled--mask" v-if="isDisabled(i,j)"></view> |
| | | </view> |
| | | <view |
| | | v-if="i === 3" |
| | | @touchstart="backspaceClick" |
| | | @touchend="clearTimer" |
| | | class="uv-keyboard__button__inner-wrapper" |
| | | > |
| | | <view |
| | | class="uv-keyboard__button__inner-wrapper__right" |
| | | hover-class="uv-hover-class" |
| | | :hover-stay-time="200" |
| | | > |
| | | <uv-icon |
| | | size="28" |
| | | name="backspace" |
| | | color="#303133" |
| | | ></uv-icon> |
| | | </view> |
| | | </view> |
| | | </view> |
| | | </view> |
| | | </template> |
| | | |
| | | <script> |
| | | import mpMixin from '@/uni_modules/uv-ui-tools/libs/mixin/mpMixin.js' |
| | | import mixin from '@/uni_modules/uv-ui-tools/libs/mixin/mixin.js' |
| | | import props from './props.js'; |
| | | /** |
| | | * keyboard 键盘组件 |
| | | * @description 此为uvui自定义的键盘面板,内含了数字键盘,车牌号键,身份证号键盘3种模式,都有可以打乱按键顺序的选项。 |
| | | * @tutorial https://www.uvui.cn/components/keyboard.html |
| | | * @property {Boolean} random 是否打乱键盘的顺序 |
| | | * @event {Function} change 点击键盘触发 |
| | | * @event {Function} backspace 点击退格键触发 |
| | | * @example <uv-keyboard ref="uKeyboard" mode="car" v-model="show"></uv-keyboard> |
| | | */ |
| | | export default { |
| | | name: "uv-keyboard", |
| | | mixins: [mpMixin, mixin, props], |
| | | emits: ['backspace','change','changeCarInputMode'], |
| | | data() { |
| | | return { |
| | | // 车牌输入时,abc=true为输入车牌号码,bac=false为输入省份中文简称 |
| | | abc: false |
| | | }; |
| | | }, |
| | | computed: { |
| | | areaList() { |
| | | let data = [ |
| | | '京', |
| | | '沪', |
| | | '粤', |
| | | '津', |
| | | '冀', |
| | | '豫', |
| | | '云', |
| | | '辽', |
| | | '黑', |
| | | '湘', |
| | | '皖', |
| | | '鲁', |
| | | '苏', |
| | | '浙', |
| | | '赣', |
| | | '鄂', |
| | | '桂', |
| | | '甘', |
| | | '晋', |
| | | '陕', |
| | | '蒙', |
| | | '吉', |
| | | '闽', |
| | | '贵', |
| | | '渝', |
| | | '川', |
| | | '青', |
| | | '琼', |
| | | '宁', |
| | | '挂', |
| | | '藏', |
| | | '港', |
| | | '澳', |
| | | '新', |
| | | '使', |
| | | '学' |
| | | ]; |
| | | let tmp = []; |
| | | // 打乱顺序 |
| | | if (this.random) data = this.$uv.randomArray(data); |
| | | // 切割成二维数组 |
| | | tmp[0] = data.slice(0, 10); |
| | | tmp[1] = data.slice(10, 20); |
| | | tmp[2] = data.slice(20, 30); |
| | | tmp[3] = data.slice(30, 36); |
| | | return tmp; |
| | | }, |
| | | engKeyBoardList() { |
| | | let data = [ |
| | | 1, |
| | | 2, |
| | | 3, |
| | | 4, |
| | | 5, |
| | | 6, |
| | | 7, |
| | | 8, |
| | | 9, |
| | | 0, |
| | | 'Q', |
| | | 'W', |
| | | 'E', |
| | | 'R', |
| | | 'T', |
| | | 'Y', |
| | | 'U', |
| | | 'I', |
| | | 'O', |
| | | 'P', |
| | | 'A', |
| | | 'S', |
| | | 'D', |
| | | 'F', |
| | | 'G', |
| | | 'H', |
| | | 'J', |
| | | 'K', |
| | | 'L', |
| | | 'Z', |
| | | 'X', |
| | | 'C', |
| | | 'V', |
| | | 'B', |
| | | 'N', |
| | | 'M' |
| | | ]; |
| | | let tmp = []; |
| | | if (this.random) data = this.$uv.randomArray(data); |
| | | tmp[0] = data.slice(0, 10); |
| | | tmp[1] = data.slice(10, 20); |
| | | tmp[2] = data.slice(20, 30); |
| | | tmp[3] = data.slice(30, 36); |
| | | return tmp; |
| | | }, |
| | | isDisabled(i,j) { |
| | | return (i,j)=>{ |
| | | let value = ''; |
| | | if (this.abc) value = this.engKeyBoardList[i][j]; |
| | | else value = this.areaList[i][j]; |
| | | return this.disKeys.indexOf(value) > -1; |
| | | } |
| | | } |
| | | }, |
| | | methods: { |
| | | // 点击键盘按钮 |
| | | carInputClick(i, j) { |
| | | if(this.isDisabled(i,j)) return; |
| | | let value = ''; |
| | | // 不同模式,获取不同数组的值 |
| | | if (this.abc) value = this.engKeyBoardList[i][j]; |
| | | else value = this.areaList[i][j]; |
| | | // 如果允许自动切换,则将中文状态切换为英文 |
| | | if (!this.abc && this.autoChange) this.$uv.sleep(200).then(() => this.abc = true) |
| | | this.$emit('change', value); |
| | | }, |
| | | // 修改汽车牌键盘的输入模式,中文|英文 |
| | | changeCarInputMode() { |
| | | this.abc = !this.abc; |
| | | this.$emit('changeCarInputMode',this.abc); |
| | | }, |
| | | // 点击退格键 |
| | | backspaceClick() { |
| | | this.$emit('backspace'); |
| | | clearInterval(this.timer); //再次清空定时器,防止重复注册定时器 |
| | | this.timer = null; |
| | | this.timer = setInterval(() => { |
| | | this.$emit('backspace'); |
| | | }, 250); |
| | | }, |
| | | clearTimer() { |
| | | clearInterval(this.timer); |
| | | this.timer = null; |
| | | }, |
| | | } |
| | | }; |
| | | </script> |
| | | |
| | | <style lang="scss" scoped> |
| | | $show-hover: 1; |
| | | @import '@/uni_modules/uv-ui-tools/libs/css/variable.scss'; |
| | | @import '@/uni_modules/uv-ui-tools/libs/css/components.scss'; |
| | | @import '@/uni_modules/uv-ui-tools/libs/css/color.scss'; |
| | | $uv-car-keyboard-background-color: rgb(224, 228, 230) !default; |
| | | $uv-car-keyboard-padding:6px 0 6px !default; |
| | | $uv-car-keyboard-button-inner-width:64rpx !default; |
| | | $uv-car-keyboard-button-inner-background-color:#FFFFFF !default; |
| | | $uv-car-keyboard-button-height:80rpx !default; |
| | | $uv-car-keyboard-button-inner-box-shadow:0 1px 0px #999992 !default; |
| | | $uv-car-keyboard-button-border-radius:4px !default; |
| | | $uv-car-keyboard-button-inner-margin:8rpx 5rpx !default; |
| | | $uv-car-keyboard-button-text-font-size:16px !default; |
| | | $uv-car-keyboard-button-text-color:$uv-main-color !default; |
| | | $uv-car-keyboard-center-inner-margin: 0 4rpx !default; |
| | | $uv-car-keyboard-special-button-width:134rpx !default; |
| | | $uv-car-keyboard-lang-font-size:16px !default; |
| | | $uv-car-keyboard-lang-color:$uv-main-color !default; |
| | | $uv-car-keyboard-active-color:$uv-primary !default; |
| | | $uv-car-keyboard-line-font-size:15px !default; |
| | | $uv-car-keyboard-line-color:$uv-main-color !default; |
| | | $uv-car-keyboard-line-margin:0 1px !default; |
| | | $uv-car-keyboard-uv-hover-class-background-color:#BBBCC6 !default; |
| | | |
| | | .uv-keyboard { |
| | | @include flex(column); |
| | | justify-content: space-around; |
| | | background-color: $uv-car-keyboard-background-color; |
| | | align-items: stretch; |
| | | padding: $uv-car-keyboard-padding; |
| | | |
| | | &__button { |
| | | @include flex; |
| | | justify-content: center; |
| | | flex: 1; |
| | | /* #ifndef APP-NVUE */ |
| | | /* #endif */ |
| | | |
| | | &__inner-wrapper { |
| | | position: relative; |
| | | box-shadow: $uv-car-keyboard-button-inner-box-shadow; |
| | | margin: $uv-car-keyboard-button-inner-margin; |
| | | border-radius: $uv-car-keyboard-button-border-radius; |
| | | |
| | | &__disabled--mask { |
| | | position: absolute; |
| | | left: 0; |
| | | top: 0; |
| | | bottom: 0; |
| | | right: 0; |
| | | width: $uv-car-keyboard-button-inner-width; |
| | | height: $uv-car-keyboard-button-height; |
| | | } |
| | | |
| | | &__inner { |
| | | @include flex; |
| | | justify-content: center; |
| | | align-items: center; |
| | | width: $uv-car-keyboard-button-inner-width; |
| | | background-color: $uv-car-keyboard-button-inner-background-color; |
| | | height: $uv-car-keyboard-button-height; |
| | | border-radius: $uv-car-keyboard-button-border-radius; |
| | | |
| | | &--disabled { |
| | | opacity: 0.5; |
| | | } |
| | | |
| | | &__text { |
| | | font-size: $uv-car-keyboard-button-text-font-size; |
| | | color: $uv-car-keyboard-button-text-color; |
| | | } |
| | | } |
| | | |
| | | &__left, |
| | | &__right { |
| | | border-radius: $uv-car-keyboard-button-border-radius; |
| | | width: $uv-car-keyboard-special-button-width; |
| | | height: $uv-car-keyboard-button-height; |
| | | background-color: $uv-car-keyboard-uv-hover-class-background-color; |
| | | @include flex; |
| | | justify-content: center; |
| | | align-items: center; |
| | | box-shadow: $uv-car-keyboard-button-inner-box-shadow; |
| | | } |
| | | |
| | | &__left { |
| | | &__line { |
| | | font-size: $uv-car-keyboard-line-font-size; |
| | | color: $uv-car-keyboard-line-color; |
| | | margin: $uv-car-keyboard-line-margin; |
| | | } |
| | | |
| | | &__lang { |
| | | font-size: $uv-car-keyboard-lang-font-size; |
| | | color: $uv-car-keyboard-lang-color; |
| | | |
| | | &--active { |
| | | color: $uv-car-keyboard-active-color; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | .uv-hover-class { |
| | | background-color: $uv-car-keyboard-uv-hover-class-background-color; |
| | | } |
| | | </style> |
| New file |
| | |
| | | export default { |
| | | props: { |
| | | // 键盘的类型,number-数字键盘,card-身份证键盘 |
| | | mode: { |
| | | type: String, |
| | | default: 'number' |
| | | }, |
| | | // 是否显示键盘的"."符号 |
| | | dotDisabled: { |
| | | type: Boolean, |
| | | default: false |
| | | }, |
| | | // 是否打乱键盘按键的顺序 |
| | | random: { |
| | | type: Boolean, |
| | | default: false |
| | | } |
| | | } |
| | | } |
| New file |
| | |
| | | <template> |
| | | <view |
| | | class="uv-keyboard" |
| | | @touchmove.stop.prevent="noop" |
| | | > |
| | | <view |
| | | class="uv-keyboard__button-wrapper" |
| | | v-for="(item, index) in numList" |
| | | :key="index" |
| | | > |
| | | <view |
| | | class="uv-keyboard__button-wrapper__button" |
| | | :style="[itemStyle(index)]" |
| | | @tap="keyboardClick(item)" |
| | | hover-class="uv-hover-class" |
| | | :hover-stay-time="200" |
| | | > |
| | | <text class="uv-keyboard__button-wrapper__button__text">{{ item }}</text> |
| | | </view> |
| | | </view> |
| | | <view |
| | | class="uv-keyboard__button-wrapper" |
| | | > |
| | | <view |
| | | class="uv-keyboard__button-wrapper__button uv-keyboard__button-wrapper__button--gray" |
| | | hover-class="uv-hover-class" |
| | | :hover-stay-time="200" |
| | | @touchstart.stop="backspaceClick" |
| | | @touchend="clearTimer" |
| | | > |
| | | <uv-icon |
| | | name="backspace" |
| | | color="#303133" |
| | | size="28" |
| | | ></uv-icon> |
| | | </view> |
| | | </view> |
| | | </view> |
| | | </template> |
| | | |
| | | <script> |
| | | import mpMixin from '@/uni_modules/uv-ui-tools/libs/mixin/mpMixin.js' |
| | | import mixin from '@/uni_modules/uv-ui-tools/libs/mixin/mixin.js' |
| | | import props from './props.js'; |
| | | /** |
| | | * keyboard 键盘组件 |
| | | * @description |
| | | * @tutorial |
| | | * @property {String} mode 键盘的类型,number-数字键盘,card-身份证键盘 |
| | | * @property {Boolean} dotDisabled 是否显示键盘的"."符号 |
| | | * @property {Boolean} random 是否打乱键盘按键的顺序 |
| | | * @event {Function} change 点击键盘触发 |
| | | * @event {Function} backspace 点击退格键触发 |
| | | * @example |
| | | */ |
| | | export default { |
| | | mixins: [mpMixin, mixin, props], |
| | | emits: ['backspace','change'], |
| | | data() { |
| | | return { |
| | | backspace: 'backspace', // 退格键内容 |
| | | dot: '.', // 点 |
| | | timer: null, // 长按多次删除的事件监听 |
| | | cardX: 'X' // 身份证的X符号 |
| | | }; |
| | | }, |
| | | computed: { |
| | | // 键盘需要显示的内容 |
| | | numList() { |
| | | let tmp = []; |
| | | if (this.dotDisabled && this.mode == 'number') { |
| | | if (!this.random) { |
| | | return [1, 2, 3, 4, 5, 6, 7, 8, 9, 0]; |
| | | } else { |
| | | return this.$uv.randomArray([1, 2, 3, 4, 5, 6, 7, 8, 9, 0]); |
| | | } |
| | | } else if (!this.dotDisabled && this.mode == 'number') { |
| | | if (!this.random) { |
| | | return [1, 2, 3, 4, 5, 6, 7, 8, 9, this.dot, 0]; |
| | | } else { |
| | | return this.$uv.randomArray([1, 2, 3, 4, 5, 6, 7, 8, 9, this.dot, 0]); |
| | | } |
| | | } else if (this.mode == 'card') { |
| | | if (!this.random) { |
| | | return [1, 2, 3, 4, 5, 6, 7, 8, 9, this.cardX, 0]; |
| | | } else { |
| | | return this.$uv.randomArray([1, 2, 3, 4, 5, 6, 7, 8, 9, this.cardX, 0]); |
| | | } |
| | | } |
| | | }, |
| | | // 按键的样式,在非乱序&&数字键盘&&不显示点按钮时,index为9时,按键占位两个空间 |
| | | itemStyle() { |
| | | return index => { |
| | | let style = {}; |
| | | if (this.mode == 'number' && this.dotDisabled && index == 9) style.width = '464rpx'; |
| | | return style; |
| | | }; |
| | | }, |
| | | // 是否让按键显示灰色,只在非乱序&&数字键盘&&且允许点按键的时候 |
| | | btnBgGray() { |
| | | return index => { |
| | | if (!this.random && index == 9 && (this.mode != 'number' || (this.mode == 'number' && !this |
| | | .dotDisabled))) return true; |
| | | else return false; |
| | | }; |
| | | }, |
| | | }, |
| | | created() { |
| | | |
| | | }, |
| | | methods: { |
| | | // 点击退格键 |
| | | backspaceClick() { |
| | | this.$emit('backspace'); |
| | | clearInterval(this.timer); //再次清空定时器,防止重复注册定时器 |
| | | this.timer = null; |
| | | this.timer = setInterval(() => { |
| | | this.$emit('backspace'); |
| | | }, 250); |
| | | }, |
| | | clearTimer() { |
| | | clearInterval(this.timer); |
| | | this.timer = null; |
| | | }, |
| | | // 获取键盘显示的内容 |
| | | keyboardClick(val) { |
| | | // 允许键盘显示点模式和触发非点按键时,将内容转为数字类型 |
| | | if (!this.dotDisabled && val != this.dot && val != this.cardX) val = Number(val); |
| | | this.$emit('change', val); |
| | | } |
| | | } |
| | | }; |
| | | </script> |
| | | |
| | | <style lang="scss" scoped> |
| | | $show-hover: 1; |
| | | @import '@/uni_modules/uv-ui-tools/libs/css/variable.scss'; |
| | | @import '@/uni_modules/uv-ui-tools/libs/css/components.scss'; |
| | | @import '@/uni_modules/uv-ui-tools/libs/css/color.scss'; |
| | | $uv-number-keyboard-background-color:rgb(224, 228, 230) !default; |
| | | $uv-number-keyboard-padding:8px 10rpx 8px 10rpx !default; |
| | | $uv-number-keyboard-button-width:222rpx !default; |
| | | $uv-number-keyboard-button-margin:4px 6rpx !default; |
| | | $uv-number-keyboard-button-border-top-left-radius:4px !default; |
| | | $uv-number-keyboard-button-border-top-right-radius:4px !default; |
| | | $uv-number-keyboard-button-border-bottom-left-radius:4px !default; |
| | | $uv-number-keyboard-button-border-bottom-right-radius:4px !default; |
| | | $uv-number-keyboard-button-height: 90rpx!default; |
| | | $uv-number-keyboard-button-background-color:#FFFFFF !default; |
| | | $uv-number-keyboard-button-box-shadow:0 2px 0px #BBBCBE !default; |
| | | $uv-number-keyboard-text-font-size:20px !default; |
| | | $uv-number-keyboard-text-font-weight:500 !default; |
| | | $uv-number-keyboard-text-color:$uv-main-color !default; |
| | | $uv-number-keyboard-gray-background-color:rgb(200, 202, 210) !default; |
| | | $uv-number-keyboard-uv-hover-class-background-color: #BBBCC6 !default; |
| | | |
| | | .uv-keyboard { |
| | | @include flex; |
| | | flex-direction: row; |
| | | justify-content: space-around; |
| | | background-color: $uv-number-keyboard-background-color; |
| | | flex-wrap: wrap; |
| | | padding: $uv-number-keyboard-padding; |
| | | |
| | | &__button-wrapper { |
| | | box-shadow: $uv-number-keyboard-button-box-shadow; |
| | | margin: $uv-number-keyboard-button-margin; |
| | | border-top-left-radius: $uv-number-keyboard-button-border-top-left-radius; |
| | | border-top-right-radius: $uv-number-keyboard-button-border-top-right-radius; |
| | | border-bottom-left-radius: $uv-number-keyboard-button-border-bottom-left-radius; |
| | | border-bottom-right-radius: $uv-number-keyboard-button-border-bottom-right-radius; |
| | | |
| | | &__button { |
| | | width: $uv-number-keyboard-button-width; |
| | | height: $uv-number-keyboard-button-height; |
| | | background-color: $uv-number-keyboard-button-background-color; |
| | | @include flex; |
| | | justify-content: center; |
| | | align-items: center; |
| | | border-top-left-radius: $uv-number-keyboard-button-border-top-left-radius; |
| | | border-top-right-radius: $uv-number-keyboard-button-border-top-right-radius; |
| | | border-bottom-left-radius: $uv-number-keyboard-button-border-bottom-left-radius; |
| | | border-bottom-right-radius: $uv-number-keyboard-button-border-bottom-right-radius; |
| | | |
| | | &__text { |
| | | font-size: $uv-number-keyboard-text-font-size; |
| | | font-weight: $uv-number-keyboard-text-font-weight; |
| | | color: $uv-number-keyboard-text-color; |
| | | } |
| | | |
| | | &--gray { |
| | | background-color: $uv-number-keyboard-gray-background-color; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | .uv-hover-class { |
| | | background-color: $uv-number-keyboard-uv-hover-class-background-color; |
| | | } |
| | | </style> |
| New file |
| | |
| | | export default { |
| | | props: { |
| | | // 键盘的类型,number-数字键盘,card-身份证键盘,car-车牌号键盘 |
| | | mode: { |
| | | type: String, |
| | | default: 'number' |
| | | }, |
| | | // 是否显示键盘的"."符号 |
| | | dotDisabled: { |
| | | type: Boolean, |
| | | default: false |
| | | }, |
| | | // 是否显示顶部工具条 |
| | | tooltip: { |
| | | type: Boolean, |
| | | default: true |
| | | }, |
| | | // 是否显示工具条中间的提示 |
| | | showTips: { |
| | | type: Boolean, |
| | | default: true |
| | | }, |
| | | // 工具条中间的提示文字 |
| | | tips: { |
| | | type: String, |
| | | default: '' |
| | | }, |
| | | // 是否显示工具条左边的"取消"按钮 |
| | | showCancel: { |
| | | type: Boolean, |
| | | default: true |
| | | }, |
| | | // 是否显示工具条右边的"完成"按钮 |
| | | showConfirm: { |
| | | type: Boolean, |
| | | default: true |
| | | }, |
| | | // 是否打乱键盘按键的顺序 |
| | | random: { |
| | | type: Boolean, |
| | | default: false |
| | | }, |
| | | // 是否开启底部安全区适配,开启的话,会在iPhoneX机型底部添加一定的内边距 |
| | | safeAreaInsetBottom: { |
| | | type: Boolean, |
| | | default: true |
| | | }, |
| | | // 是否允许通过点击遮罩关闭键盘 |
| | | closeOnClickOverlay: { |
| | | type: Boolean, |
| | | default: true |
| | | }, |
| | | // 是否允许点击确认按钮关闭组件 |
| | | closeOnClickConfirm: { |
| | | type: Boolean, |
| | | default: true |
| | | }, |
| | | // 是否显示遮罩,某些时候数字键盘时,用户希望看到自己的数值,所以可能不想要遮罩 |
| | | overlay: { |
| | | type: Boolean, |
| | | default: true |
| | | }, |
| | | // z-index值 |
| | | zIndex: { |
| | | type: [String, Number], |
| | | default: 10075 |
| | | }, |
| | | // 取消按钮的文字 |
| | | cancelText: { |
| | | type: String, |
| | | default: '取消' |
| | | }, |
| | | // 确认按钮的文字 |
| | | confirmText: { |
| | | type: String, |
| | | default: '确定' |
| | | }, |
| | | // 输入一个中文后,是否自动切换到英文 |
| | | autoChange: { |
| | | type: Boolean, |
| | | default: false |
| | | }, |
| | | // 被禁用的键 |
| | | disKeys: { |
| | | type: Array, |
| | | default: ()=>[] |
| | | }, |
| | | // 是否自定义abc |
| | | customabc: { |
| | | type: Boolean, |
| | | default: false |
| | | }, |
| | | ...uni.$uv?.props?.keyboard |
| | | } |
| | | } |
| New file |
| | |
| | | <template> |
| | | <uv-popup |
| | | ref="keyboardPopup" |
| | | mode="bottom" |
| | | :overlay="overlay" |
| | | :closeOnClickOverlay="closeOnClickOverlay" |
| | | :safeAreaInsetBottom="safeAreaInsetBottom" |
| | | :zIndex="zIndex" |
| | | :customStyle="{ backgroundColor: 'rgb(214, 218, 220)' }" |
| | | @change="popupChange" |
| | | > |
| | | <view class="uv-keyboard"> |
| | | <slot /> |
| | | <view |
| | | class="uv-keyboard__tooltip" |
| | | v-if="tooltip" |
| | | > |
| | | <view |
| | | hover-class="uv-hover-class" |
| | | :hover-stay-time="100" |
| | | > |
| | | <text |
| | | class="uv-keyboard__tooltip__item uv-keyboard__tooltip__cancel" |
| | | v-if="showCancel" |
| | | @tap="onCancel" |
| | | >{{showCancel && cancelText}}</text> |
| | | </view> |
| | | <view> |
| | | <text |
| | | v-if="showTips" |
| | | class="uv-keyboard__tooltip__item uv-keyboard__tooltip__tips" |
| | | >{{tips ? tips : mode == 'number' ? '数字键盘' : mode == 'card' ? '身份证键盘' : '车牌号键盘'}}</text> |
| | | </view> |
| | | <view |
| | | hover-class="uv-hover-class" |
| | | :hover-stay-time="100" |
| | | > |
| | | <text |
| | | v-if="showConfirm" |
| | | @tap="onConfirm" |
| | | class="uv-keyboard__tooltip__item uv-keyboard__tooltip__submit" |
| | | hover-class="uv-hover-class" |
| | | >{{showConfirm && confirmText}}</text> |
| | | </view> |
| | | </view> |
| | | <template v-if="mode == 'number' || mode == 'card'"> |
| | | <uv-keyboard-number |
| | | :random="random" |
| | | @backspace="backspace" |
| | | @change="change" |
| | | :mode="mode" |
| | | :dotDisabled="dotDisabled" |
| | | ></uv-keyboard-number> |
| | | </template> |
| | | <template v-else> |
| | | <uv-keyboard-car |
| | | ref="uvKeyboardCarRef" |
| | | :random="random" |
| | | :autoChange="autoChange" |
| | | :disKeys="disKeys" |
| | | :customabc="customabc" |
| | | @backspace="backspace" |
| | | @change="change" |
| | | @changeCarInputMode="changeCarInputMode" |
| | | > |
| | | <slot name="abc"></slot> |
| | | </uv-keyboard-car> |
| | | </template> |
| | | </view> |
| | | </uv-popup> |
| | | </template> |
| | | |
| | | <script> |
| | | import mpMixin from '@/uni_modules/uv-ui-tools/libs/mixin/mpMixin.js' |
| | | import mixin from '@/uni_modules/uv-ui-tools/libs/mixin/mixin.js' |
| | | import props from './props.js'; |
| | | /** |
| | | * keyboard 键盘 |
| | | * @description 此为uViw自定义的键盘面板,内含了数字键盘,车牌号键,身份证号键盘3中模式,都有可以打乱按键顺序的选项。 |
| | | * @tutorial https://www.uvui.cn/components/keyboard.html |
| | | * @property {String} mode 键盘类型,见官网基本使用的说明 (默认 'number' ) |
| | | * @property {Boolean} dotDisabled 是否显示"."按键,只在mode=number时有效 (默认 false ) |
| | | * @property {Boolean} tooltip 是否显示键盘顶部工具条 (默认 true ) |
| | | * @property {Boolean} showTips 是否显示工具条中间的提示 (默认 true ) |
| | | * @property {String} tips 工具条中间的提示文字,见上方基本使用的说明,如不需要,请传""空字符 |
| | | * @property {Boolean} showCancel 是否显示工具条左边的"取消"按钮 (默认 true ) |
| | | * @property {Boolean} showConfirm 是否显示工具条右边的"完成"按钮( 默认 true ) |
| | | * @property {Boolean} random 是否打乱键盘按键的顺序 (默认 false ) |
| | | * @property {Boolean} safeAreaInsetBottom 是否开启底部安全区适配 (默认 true ) |
| | | * @property {Boolean} closeOnClickOverlay 是否允许点击遮罩收起键盘 (默认 true ) |
| | | * @property {Boolean} show 控制键盘的弹出与收起(默认 false ) |
| | | * @property {Boolean} overlay 是否显示遮罩 (默认 true ) |
| | | * @property {String | Number} zIndex 弹出键盘的z-index值 (默认 1075 ) |
| | | * @property {String} cancelText 取消按钮的文字 (默认 '取消' ) |
| | | * @property {String} confirmText 确认按钮的文字 (默认 '确认' ) |
| | | * @property {Object} customStyle 自定义样式,对象形式 |
| | | * @event {Function} change 按键被点击(不包含退格键被点击) |
| | | * @event {Function} cancel 键盘顶部工具条左边的"取消"按钮被点击 |
| | | * @event {Function} confirm 键盘顶部工具条右边的"完成"按钮被点击 |
| | | * @event {Function} backspace 键盘退格键被点击 |
| | | * @example <uv-keyboard mode="number" v-model="show"></uv-keyboard> |
| | | */ |
| | | export default { |
| | | name: "uv-keyboard", |
| | | mixins: [mpMixin, mixin, props], |
| | | emits: ['close','change','confirm','cancel','backspace','changeCarInputMode'], |
| | | methods: { |
| | | open() { |
| | | this.$refs.keyboardPopup.open(); |
| | | }, |
| | | close() { |
| | | this.$refs.keyboardPopup.close(); |
| | | }, |
| | | popupChange(e) { |
| | | if(!e.show) this.$emit('close'); |
| | | }, |
| | | change(e) { |
| | | this.$emit('change', e); |
| | | }, |
| | | // 输入完成 |
| | | onConfirm() { |
| | | this.$emit('confirm'); |
| | | if(this.closeOnClickConfirm) this.close(); |
| | | }, |
| | | // 取消输入 |
| | | onCancel() { |
| | | this.$emit('cancel'); |
| | | this.close(); |
| | | }, |
| | | // 退格键 |
| | | backspace() { |
| | | this.$emit('backspace'); |
| | | }, |
| | | // car模式切换中文|英文方法 |
| | | changeCarInputMode(e) { |
| | | this.$emit('changeCarInputMode',e); |
| | | }, |
| | | changeCarMode() { |
| | | this.$refs.uvKeyboardCarRef && this.$refs.uvKeyboardCarRef.changeCarInputMode(); |
| | | } |
| | | } |
| | | } |
| | | </script> |
| | | |
| | | <style lang="scss" scoped> |
| | | $show-hover: 1; |
| | | @import '@/uni_modules/uv-ui-tools/libs/css/variable.scss'; |
| | | @import '@/uni_modules/uv-ui-tools/libs/css/components.scss'; |
| | | @import '@/uni_modules/uv-ui-tools/libs/css/color.scss'; |
| | | .uv-keyboard { |
| | | |
| | | &__tooltip { |
| | | @include flex; |
| | | justify-content: space-between; |
| | | background-color: #FFFFFF; |
| | | padding: 14px 12px; |
| | | |
| | | &__item { |
| | | color: #333333; |
| | | flex: 1; |
| | | text-align: center; |
| | | font-size: 15px; |
| | | } |
| | | |
| | | &__submit { |
| | | text-align: right; |
| | | color: $uv-primary; |
| | | } |
| | | |
| | | &__cancel { |
| | | text-align: left; |
| | | color: #888888; |
| | | } |
| | | |
| | | &__tips { |
| | | color: $uv-tips-color; |
| | | } |
| | | } |
| | | } |
| | | </style> |
| New file |
| | |
| | | { |
| | | "id": "uv-keyboard", |
| | | "displayName": "uv-keyboard 键盘 全面兼容vue3+2、app、h5、小程序等多端", |
| | | "version": "1.0.5", |
| | | "description": "uv-keyboard 该组件为自定义的键盘面板,内含了数字键盘,车牌号键,身份证号键盘3种模式,都有可以打乱按键顺序的选项。", |
| | | "keywords": [ |
| | | "uv-keyboard", |
| | | "uvui", |
| | | "uv-ui", |
| | | "keyboard", |
| | | "键盘" |
| | | ], |
| | | "repository": "", |
| | | "engines": { |
| | | "HBuilderX": "^3.1.0" |
| | | }, |
| | | "dcloudext": { |
| | | "type": "component-vue", |
| | | "sale": { |
| | | "regular": { |
| | | "price": "0.00" |
| | | }, |
| | | "sourcecode": { |
| | | "price": "0.00" |
| | | } |
| | | }, |
| | | "contact": { |
| | | "qq": "" |
| | | }, |
| | | "declaration": { |
| | | "ads": "无", |
| | | "data": "插件不采集任何数据", |
| | | "permissions": "无" |
| | | }, |
| | | "npmurl": "" |
| | | }, |
| | | "uni_modules": { |
| | | "dependencies": [ |
| | | "uv-ui-tools", |
| | | "uv-popup", |
| | | "uv-icon" |
| | | ], |
| | | "encrypt": [], |
| | | "platforms": { |
| | | "cloud": { |
| | | "tcb": "y", |
| | | "aliyun": "y" |
| | | }, |
| | | "client": { |
| | | "Vue": { |
| | | "vue2": "y", |
| | | "vue3": "y" |
| | | }, |
| | | "App": { |
| | | "app-vue": "y", |
| | | "app-nvue": "y" |
| | | }, |
| | | "H5-mobile": { |
| | | "Safari": "y", |
| | | "Android Browser": "y", |
| | | "微信浏览器(Android)": "y", |
| | | "QQ浏览器(Android)": "y" |
| | | }, |
| | | "H5-pc": { |
| | | "Chrome": "y", |
| | | "IE": "y", |
| | | "Edge": "y", |
| | | "Firefox": "y", |
| | | "Safari": "y" |
| | | }, |
| | | "小程序": { |
| | | "微信": "y", |
| | | "阿里": "y", |
| | | "百度": "y", |
| | | "字节跳动": "y", |
| | | "QQ": "y", |
| | | "钉钉": "u", |
| | | "快手": "u", |
| | | "飞书": "u", |
| | | "京东": "u" |
| | | }, |
| | | "快应用": { |
| | | "华为": "u", |
| | | "联盟": "u" |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| New file |
| | |
| | | ## Keyboard 键盘 |
| | | |
| | | > **组件名:uv-keyboard** |
| | | |
| | | 该组件为自定义的键盘面板,内含了数字键盘,车牌号键,身份证号键盘3种模式,都有可以打乱按键顺序的选项。 |
| | | |
| | | # <a href="https://www.uvui.cn/components/keyboard.html" target="_blank">查看文档</a> |
| | | |
| | | ## [下载完整示例项目](https://ext.dcloud.net.cn/plugin?name=uv-ui) <small>(请不要 下载插件ZIP)</small> |
| | | |
| | | ### [更多插件,请关注uv-ui组件库](https://ext.dcloud.net.cn/plugin?name=uv-ui) |
| | | |
| | | <a href="https://ext.dcloud.net.cn/plugin?name=uv-ui" target="_blank"> |
| | | |
| | |  |
| | | |
| | | </a> |
| | | |
| | | #### 如使用过程中有任何问题反馈,或者您对uv-ui有一些好的建议,欢迎加入uv-ui官方交流群:<a href="https://www.uvui.cn/components/addQQGroup.html" target="_blank">官方QQ群</a> |
| New file |
| | |
| | | ## 1.0.2(2023-06-20) |
| | | 1. 适配height参数携带单位 |
| | | ## 1.0.1(2023-05-16) |
| | | 1. 优化组件依赖,修改后无需全局引入,组件导入即可使用 |
| | | 2. 优化部分功能 |
| | | ## 1.0.0(2023-05-10) |
| | | uv-line-progress 线形进度条 |
| New file |
| | |
| | | export default { |
| | | props: { |
| | | // 激活部分的颜色 |
| | | activeColor: { |
| | | type: String, |
| | | default: '#19be6b' |
| | | }, |
| | | inactiveColor: { |
| | | type: String, |
| | | default: '#ececec' |
| | | }, |
| | | // 进度百分比,数值 |
| | | percentage: { |
| | | type: [String, Number], |
| | | default: 0 |
| | | }, |
| | | // 是否在进度条内部显示百分比的值 |
| | | showText: { |
| | | type: Boolean, |
| | | default: true |
| | | }, |
| | | // 进度条的高度,单位px |
| | | height: { |
| | | type: [String, Number], |
| | | default: 12 |
| | | }, |
| | | ...uni.$uv?.props?.lineProgress |
| | | } |
| | | } |
| New file |
| | |
| | | <template> |
| | | <view |
| | | class="uv-line-progress" |
| | | :style="[$uv.addStyle(customStyle)]" |
| | | > |
| | | <view |
| | | class="uv-line-progress__background" |
| | | ref="uv-line-progress__background" |
| | | :style="[{ |
| | | backgroundColor: inactiveColor, |
| | | height: $uv.addUnit($uv.getPx(height)) |
| | | }]" |
| | | > |
| | | </view> |
| | | <view |
| | | class="uv-line-progress__line" |
| | | :style="[progressStyle]" |
| | | > |
| | | <slot> |
| | | <text v-if="showText && percentage >= 10" class="uv-line-progress__text">{{innserPercentage + '%'}}</text> |
| | | </slot> |
| | | </view> |
| | | </view> |
| | | </template> |
| | | |
| | | <script> |
| | | import mpMixin from '@/uni_modules/uv-ui-tools/libs/mixin/mpMixin.js' |
| | | import mixin from '@/uni_modules/uv-ui-tools/libs/mixin/mixin.js' |
| | | import props from './props.js'; |
| | | // #ifdef APP-NVUE |
| | | const dom = uni.requireNativePlugin('dom') |
| | | // #endif |
| | | /** |
| | | * lineProgress 线型进度条 |
| | | * @description 展示操作或任务的当前进度,比如上传文件,是一个线形的进度条。 |
| | | * @tutorial https://www.uvui.cn/components/lineProgress.html |
| | | * @property {String} activeColor 激活部分的颜色 ( 默认 '#19be6b' ) |
| | | * @property {String} inactiveColor 背景色 ( 默认 '#ececec' ) |
| | | * @property {String | Number} percentage 进度百分比,数值 ( 默认 0 ) |
| | | * @property {Boolean} showText 是否在进度条内部显示百分比的值 ( 默认 true ) |
| | | * @property {String | Number} height 进度条的高度,单位px ( 默认 12 ) |
| | | * |
| | | * @example <uv-line-progress :percent="70" :show-percent="true"></uv-line-progress> |
| | | */ |
| | | export default { |
| | | name: "uv-line-progress", |
| | | mixins: [mpMixin, mixin, props], |
| | | data() { |
| | | return { |
| | | lineWidth: 0, |
| | | } |
| | | }, |
| | | watch: { |
| | | percentage(n) { |
| | | this.resizeProgressWidth() |
| | | } |
| | | }, |
| | | computed: { |
| | | progressStyle() { |
| | | let style = {} |
| | | style.width = this.lineWidth |
| | | style.backgroundColor = this.activeColor |
| | | style.height = this.$uv.addUnit(this.$uv.getPx(this.height)) |
| | | return style |
| | | }, |
| | | innserPercentage() { |
| | | // 控制范围在0-100之间 |
| | | return this.$uv.range(0, 100, this.percentage) |
| | | } |
| | | }, |
| | | mounted() { |
| | | this.init() |
| | | }, |
| | | methods: { |
| | | init() { |
| | | this.$uv.sleep(20).then(() => { |
| | | this.resizeProgressWidth() |
| | | }) |
| | | }, |
| | | getProgressWidth() { |
| | | // #ifndef APP-NVUE |
| | | return this.$uvGetRect('.uv-line-progress__background') |
| | | // #endif |
| | | |
| | | // #ifdef APP-NVUE |
| | | // 返回一个promise |
| | | return new Promise(resolve => { |
| | | dom.getComponentRect(this.$refs['uv-line-progress__background'], (res) => { |
| | | resolve(res.size) |
| | | }) |
| | | }) |
| | | // #endif |
| | | }, |
| | | resizeProgressWidth() { |
| | | this.getProgressWidth().then(size => { |
| | | const { |
| | | width |
| | | } = size |
| | | // 通过设置的percentage值,计算其所占总长度的百分比 |
| | | this.lineWidth = width * this.innserPercentage / 100 + 'px' |
| | | }) |
| | | } |
| | | } |
| | | } |
| | | </script> |
| | | |
| | | <style lang="scss" scoped> |
| | | @import '@/uni_modules/uv-ui-tools/libs/css/components.scss'; |
| | | |
| | | .uv-line-progress { |
| | | align-items: stretch; |
| | | position: relative; |
| | | @include flex(row); |
| | | flex: 1; |
| | | overflow: hidden; |
| | | border-radius: 100px; |
| | | |
| | | &__background { |
| | | background-color: #ececec; |
| | | border-radius: 100px; |
| | | flex: 1; |
| | | } |
| | | |
| | | &__line { |
| | | position: absolute; |
| | | top: 0; |
| | | left: 0; |
| | | bottom: 0; |
| | | align-items: center; |
| | | @include flex(row); |
| | | color: #ffffff; |
| | | border-radius: 100px; |
| | | transition: width 0.5s ease; |
| | | justify-content: flex-end; |
| | | } |
| | | |
| | | &__text { |
| | | font-size: 10px; |
| | | align-items: center; |
| | | text-align: right; |
| | | color: #FFFFFF; |
| | | margin-right: 5px; |
| | | transform: scale(0.9); |
| | | } |
| | | } |
| | | </style> |
| New file |
| | |
| | | { |
| | | "id": "uv-line-progress", |
| | | "displayName": "uv-line-progress 线形进度条 全面兼容小程序、nvue、vue2、vue3等多端", |
| | | "version": "1.0.2", |
| | | "description": "uv-line-progress 该组件展示操作或任务的当前进度,比如上传文件,是一个线形的进度条。", |
| | | "keywords": [ |
| | | "uv-line-progress", |
| | | "uvui", |
| | | "uv-ui", |
| | | "progress", |
| | | "进度条" |
| | | ], |
| | | "repository": "", |
| | | "engines": { |
| | | "HBuilderX": "^3.1.0" |
| | | }, |
| | | "dcloudext": { |
| | | "type": "component-vue", |
| | | "sale": { |
| | | "regular": { |
| | | "price": "0.00" |
| | | }, |
| | | "sourcecode": { |
| | | "price": "0.00" |
| | | } |
| | | }, |
| | | "contact": { |
| | | "qq": "" |
| | | }, |
| | | "declaration": { |
| | | "ads": "无", |
| | | "data": "插件不采集任何数据", |
| | | "permissions": "无" |
| | | }, |
| | | "npmurl": "" |
| | | }, |
| | | "uni_modules": { |
| | | "dependencies": [ |
| | | "uv-ui-tools" |
| | | ], |
| | | "encrypt": [], |
| | | "platforms": { |
| | | "cloud": { |
| | | "tcb": "y", |
| | | "aliyun": "y" |
| | | }, |
| | | "client": { |
| | | "Vue": { |
| | | "vue2": "y", |
| | | "vue3": "y" |
| | | }, |
| | | "App": { |
| | | "app-vue": "y", |
| | | "app-nvue": "y" |
| | | }, |
| | | "H5-mobile": { |
| | | "Safari": "y", |
| | | "Android Browser": "y", |
| | | "微信浏览器(Android)": "y", |
| | | "QQ浏览器(Android)": "y" |
| | | }, |
| | | "H5-pc": { |
| | | "Chrome": "y", |
| | | "IE": "y", |
| | | "Edge": "y", |
| | | "Firefox": "y", |
| | | "Safari": "y" |
| | | }, |
| | | "小程序": { |
| | | "微信": "y", |
| | | "阿里": "y", |
| | | "百度": "y", |
| | | "字节跳动": "y", |
| | | "QQ": "y", |
| | | "钉钉": "u", |
| | | "快手": "u", |
| | | "飞书": "u", |
| | | "京东": "u" |
| | | }, |
| | | "快应用": { |
| | | "华为": "u", |
| | | "联盟": "u" |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| New file |
| | |
| | | ## LineProgress 线形进度条 |
| | | |
| | | > **组件名:uv-line-progress** |
| | | |
| | | 展示操作或任务的当前进度,比如上传文件,是一个线形的进度条。 |
| | | |
| | | ### <a href="https://www.uvui.cn/components/lineProgress.html" target="_blank">查看文档</a> |
| | | |
| | | ### [完整示例项目下载 | 关注更多组件](https://ext.dcloud.net.cn/plugin?name=uv-ui) |
| | | |
| | | #### 如使用过程中有任何问题,或者您对uv-ui有一些好的建议,欢迎加入 uv-ui 交流群:<a href="https://ext.dcloud.net.cn/plugin?id=12287" target="_blank">uv-ui</a>、<a href="https://www.uvui.cn/components/addQQGroup.html" target="_blank">官方QQ群</a> |
| New file |
| | |
| | | ## 1.0.2(2023-08-13) |
| | | 1. 修复报错的BUG |
| | | ## 1.0.1(2023-05-16) |
| | | 1. 优化组件依赖,修改后无需全局引入,组件导入即可使用 |
| | | 2. 优化部分功能 |
| | | ## 1.0.0(2023-05-10) |
| | | uv-link 超链接组件 |
| New file |
| | |
| | | export default { |
| | | props: { |
| | | // 文字颜色 |
| | | color: { |
| | | type: String, |
| | | default: '' |
| | | }, |
| | | // 字体大小,单位px |
| | | fontSize: { |
| | | type: [String, Number], |
| | | default: 14 |
| | | }, |
| | | // 是否显示下划线 |
| | | underLine: { |
| | | type: Boolean, |
| | | default: false |
| | | }, |
| | | // 要跳转的链接 |
| | | href: { |
| | | type: String, |
| | | default: '' |
| | | }, |
| | | // 小程序中复制到粘贴板的提示语 |
| | | mpTips: { |
| | | type: String, |
| | | default: '链接已复制,请在浏览器打开' |
| | | }, |
| | | // 下划线颜色 |
| | | lineColor: { |
| | | type: String, |
| | | default: '' |
| | | }, |
| | | // 超链接的问题,不使用slot形式传入,是因为nvue下无法修改颜色 |
| | | text: { |
| | | type: String, |
| | | default: '' |
| | | }, |
| | | ...uni.$uv?.props?.link |
| | | } |
| | | } |
| New file |
| | |
| | | <template> |
| | | <text |
| | | class="uv-link" |
| | | @tap.stop="openLink" |
| | | :style="[linkStyle, $uv.addStyle(customStyle)]" |
| | | >{{text}}</text> |
| | | </template> |
| | | |
| | | <script> |
| | | import mpMixin from '@/uni_modules/uv-ui-tools/libs/mixin/mpMixin.js' |
| | | import mixin from '@/uni_modules/uv-ui-tools/libs/mixin/mixin.js' |
| | | import props from './props.js'; |
| | | /** |
| | | * link 超链接 |
| | | * @description 该组件为超链接组件,在不同平台有不同表现形式:在APP平台会通过plus环境打开内置浏览器,在小程序中把链接复制到粘贴板,同时提示信息,在H5中通过window.open打开链接。 |
| | | * @tutorial https://www.uvui.cn/components/link.html |
| | | * @property {String} color 文字颜色 (默认 color['uv-primary'] ) |
| | | * @property {String | Number} fontSize 字体大小,单位px (默认 15 ) |
| | | * @property {Boolean} underLine 是否显示下划线 (默认 false ) |
| | | * @property {String} href 跳转的链接,要带上http(s) |
| | | * @property {String} mpTips 各个小程序平台把链接复制到粘贴板后的提示语(默认“链接已复制,请在浏览器打开”) |
| | | * @property {String} lineColor 下划线颜色,默认同color参数颜色 |
| | | * @property {String} text 超链接的问题,不使用slot形式传入,是因为nvue下无法修改颜色 |
| | | * @property {Object} customStyle 定义需要用到的外部样式 |
| | | * |
| | | * @example <uv-link href="http://www.uvui.cn">蜀道难,难于上青天</uv-link> |
| | | */ |
| | | export default { |
| | | name: "uv-link", |
| | | emits:['click'], |
| | | mixins: [mpMixin, mixin, props], |
| | | computed: { |
| | | linkStyle() { |
| | | const style = { |
| | | color: this.color, |
| | | fontSize: this.$uv.addUnit(this.fontSize), |
| | | // line-height设置为比字体大小多2px |
| | | lineHeight: this.$uv.addUnit(this.$uv.getPx(this.fontSize) + 2), |
| | | textDecoration: this.underLine ? 'underline' : 'none' |
| | | } |
| | | return style |
| | | } |
| | | }, |
| | | methods: { |
| | | openLink() { |
| | | // #ifdef APP-PLUS |
| | | plus.runtime.openURL(this.href) |
| | | // #endif |
| | | // #ifdef H5 |
| | | window.open(this.href) |
| | | // #endif |
| | | // #ifdef MP |
| | | uni.setClipboardData({ |
| | | data: this.href, |
| | | success: () => { |
| | | uni.hideToast(); |
| | | this.$nextTick(() => { |
| | | this.$uv.toast(this.mpTips); |
| | | }) |
| | | } |
| | | }); |
| | | // #endif |
| | | this.$emit('click') |
| | | } |
| | | } |
| | | } |
| | | </script> |
| | | |
| | | <style lang="scss" scoped> |
| | | @import '@/uni_modules/uv-ui-tools/libs/css/components.scss'; |
| | | @import '@/uni_modules/uv-ui-tools/libs/css/color.scss'; |
| | | $uv-link-line-height:1 !default; |
| | | |
| | | .uv-link { |
| | | /* #ifndef APP-NVUE */ |
| | | line-height: $uv-link-line-height; |
| | | /* #endif */ |
| | | @include flex; |
| | | flex-wrap: wrap; |
| | | flex: 1; |
| | | color: $uv-primary; |
| | | } |
| | | </style> |
| New file |
| | |
| | | { |
| | | "id": "uv-link", |
| | | "displayName": "uv-link 超链接 全面兼容小程序、nvue、vue2、vue3等多端", |
| | | "version": "1.0.2", |
| | | "description": "uv-link 该组件为超链接组件", |
| | | "keywords": [ |
| | | "uv-link", |
| | | "uvui", |
| | | "uv-ui", |
| | | "link", |
| | | "超链接" |
| | | ], |
| | | "repository": "", |
| | | "engines": { |
| | | "HBuilderX": "^3.1.0" |
| | | }, |
| | | "dcloudext": { |
| | | "type": "component-vue", |
| | | "sale": { |
| | | "regular": { |
| | | "price": "0.00" |
| | | }, |
| | | "sourcecode": { |
| | | "price": "0.00" |
| | | } |
| | | }, |
| | | "contact": { |
| | | "qq": "" |
| | | }, |
| | | "declaration": { |
| | | "ads": "无", |
| | | "data": "插件不采集任何数据", |
| | | "permissions": "无" |
| | | }, |
| | | "npmurl": "" |
| | | }, |
| | | "uni_modules": { |
| | | "dependencies": [ |
| | | "uv-ui-tools" |
| | | ], |
| | | "encrypt": [], |
| | | "platforms": { |
| | | "cloud": { |
| | | "tcb": "y", |
| | | "aliyun": "y" |
| | | }, |
| | | "client": { |
| | | "Vue": { |
| | | "vue2": "y", |
| | | "vue3": "y" |
| | | }, |
| | | "App": { |
| | | "app-vue": "y", |
| | | "app-nvue": "y" |
| | | }, |
| | | "H5-mobile": { |
| | | "Safari": "y", |
| | | "Android Browser": "y", |
| | | "微信浏览器(Android)": "y", |
| | | "QQ浏览器(Android)": "y" |
| | | }, |
| | | "H5-pc": { |
| | | "Chrome": "y", |
| | | "IE": "y", |
| | | "Edge": "y", |
| | | "Firefox": "y", |
| | | "Safari": "y" |
| | | }, |
| | | "小程序": { |
| | | "微信": "y", |
| | | "阿里": "y", |
| | | "百度": "y", |
| | | "字节跳动": "y", |
| | | "QQ": "y", |
| | | "钉钉": "u", |
| | | "快手": "u", |
| | | "飞书": "u", |
| | | "京东": "u" |
| | | }, |
| | | "快应用": { |
| | | "华为": "u", |
| | | "联盟": "u" |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| New file |
| | |
| | | ## Link 超链接 |
| | | |
| | | > **组件名:uv-link** |
| | | |
| | | 该组件为超链接组件,在不同平台有不同表现形式。 |
| | | |
| | | ### <a href="https://www.uvui.cn/components/link.html" target="_blank">查看文档</a> |
| | | |
| | | ### [完整示例项目下载 | 关注更多组件](https://ext.dcloud.net.cn/plugin?name=uv-ui) |
| | | |
| | | #### 如使用过程中有任何问题,或者您对uv-ui有一些好的建议,欢迎加入 uv-ui 交流群:<a href="https://ext.dcloud.net.cn/plugin?id=12287" target="_blank">uv-ui</a>、<a href="https://www.uvui.cn/components/addQQGroup.html" target="_blank">官方QQ群</a> |
| New file |
| | |
| | | ## 1.0.9(2023-11-10) |
| | | 1. 修复设置ellipsis不生效的BUG |
| | | ## 1.0.8(2023-09-20) |
| | | 1. listItem优化可使用customStyle变量进行样式控制 |
| | | ## 1.0.7(2023-08-29) |
| | | 1. 修复边框的BUG |
| | | ## 1.0.6(2023-08-16) |
| | | 1. 修复switch开关返回undefined的问题 |
| | | 2. 优化初始化可能导致的闪动 |
| | | ## 1.0.5(2023-08-07) |
| | | 1. 修复分包页面在ios端,nvue编译不能滚动的BUG |
| | | ## 1.0.4(2023-08-04) |
| | | 1. nvue修复 触底不触发事件的BUG |
| | | 2. 更新文档说明事件触发 |
| | | ## 1.0.3(2023-07-28) |
| | | 1. 修改可能造成样式污染的BUG |
| | | ## 1.0.2(2023-07-26) |
| | | 1. 全面重构,用法与之前保持一致,参数全部变化 |
| | | 2. 新增多个功能参数,方便一键构建列表 |
| | | 3. List列表组件,包含基本列表样式、默认插槽机制、可扩展插槽机制、长列表性能优化、多端兼容。 |
| | | ## 1.0.1(2023-05-16) |
| | | 1. 优化组件依赖,修改后无需全局引入,组件导入即可使用 |
| | | 2. 优化部分功能 |
| | | ## 1.0.0(2023-05-10) |
| | | uv-list 列表 |
| uni_modules/uv-list/components/uv-list-item/uv-list-item.vue
uni_modules/uv-list/components/uv-list/uv-list.vue
uni_modules/uv-list/package.json
uni_modules/uv-list/readme.md
uni_modules/uv-load-more/changelog.md
uni_modules/uv-load-more/components/uv-load-more/props.js
uni_modules/uv-load-more/components/uv-load-more/uv-load-more.vue
uni_modules/uv-load-more/package.json
uni_modules/uv-load-more/readme.md
uni_modules/uv-modal/changelog.md
uni_modules/uv-modal/components/uv-modal/props.js
uni_modules/uv-modal/components/uv-modal/uv-modal.vue
uni_modules/uv-modal/package.json
uni_modules/uv-modal/readme.md
uni_modules/uv-navbar/changelog.md
uni_modules/uv-navbar/components/uv-navbar/props.js
uni_modules/uv-navbar/components/uv-navbar/uv-navbar.vue
uni_modules/uv-navbar/package.json
uni_modules/uv-navbar/readme.md
uni_modules/uv-no-network/changelog.md
uni_modules/uv-no-network/components/uv-no-network/props.js
uni_modules/uv-no-network/components/uv-no-network/uv-no-network.vue
uni_modules/uv-no-network/package.json
uni_modules/uv-no-network/readme.md
uni_modules/uv-notice-bar/changelog.md
uni_modules/uv-notice-bar/components/uv-column-notice/props.js
uni_modules/uv-notice-bar/components/uv-column-notice/uv-column-notice.vue
uni_modules/uv-notice-bar/components/uv-notice-bar/props.js
uni_modules/uv-notice-bar/components/uv-notice-bar/uv-notice-bar.vue
uni_modules/uv-notice-bar/components/uv-row-notice/props.js
uni_modules/uv-notice-bar/components/uv-row-notice/uv-row-notice.vue
uni_modules/uv-notice-bar/package.json
uni_modules/uv-notice-bar/readme.md
uni_modules/uv-notify/changelog.md
uni_modules/uv-notify/components/uv-notify/props.js
uni_modules/uv-notify/components/uv-notify/uv-notify.vue
uni_modules/uv-notify/package.json
uni_modules/uv-notify/readme.md
uni_modules/uv-number-box/changelog.md
uni_modules/uv-number-box/components/uv-number-box/props.js
uni_modules/uv-number-box/components/uv-number-box/uv-number-box.vue
uni_modules/uv-number-box/package.json
uni_modules/uv-number-box/readme.md
uni_modules/uv-parse/changelog.md
uni_modules/uv-parse/components/uv-parse/node/node.vue
uni_modules/uv-parse/components/uv-parse/parser.js
uni_modules/uv-parse/components/uv-parse/uv-parse.vue
uni_modules/uv-parse/package.json
uni_modules/uv-parse/readme.md
uni_modules/uv-parse/static/app-plus/uv-parse/js/handler.js
uni_modules/uv-parse/static/app-plus/uv-parse/js/uni.webview.min.js
uni_modules/uv-parse/static/app-plus/uv-parse/local.html
uni_modules/uv-pick-color/changelog.md
uni_modules/uv-pick-color/components/uv-pick-color/colors.js
uni_modules/uv-pick-color/components/uv-pick-color/props.js
uni_modules/uv-pick-color/components/uv-pick-color/uv-pick-color.vue
uni_modules/uv-pick-color/package.json
uni_modules/uv-pick-color/readme.md
uni_modules/uv-picker/components/uv-picker/props.js
uni_modules/uv-picker/components/uv-picker/uv-picker.vue
uni_modules/uv-qrcode/changelog.md
uni_modules/uv-qrcode/components/uv-qrcode/cache.js
uni_modules/uv-qrcode/components/uv-qrcode/gcanvas/bridge/bridge-weex.js
uni_modules/uv-qrcode/components/uv-qrcode/gcanvas/context-2d/FillStyleLinearGradient.js
uni_modules/uv-qrcode/components/uv-qrcode/gcanvas/context-2d/FillStylePattern.js
uni_modules/uv-qrcode/components/uv-qrcode/gcanvas/context-2d/FillStyleRadialGradient.js
uni_modules/uv-qrcode/components/uv-qrcode/gcanvas/context-2d/RenderingContext.js
uni_modules/uv-qrcode/components/uv-qrcode/gcanvas/context-webgl/ActiveInfo.js
uni_modules/uv-qrcode/components/uv-qrcode/gcanvas/context-webgl/Buffer.js
uni_modules/uv-qrcode/components/uv-qrcode/gcanvas/context-webgl/Framebuffer.js
uni_modules/uv-qrcode/components/uv-qrcode/gcanvas/context-webgl/GLenum.js
uni_modules/uv-qrcode/components/uv-qrcode/gcanvas/context-webgl/GLmethod.js
uni_modules/uv-qrcode/components/uv-qrcode/gcanvas/context-webgl/GLtype.js
uni_modules/uv-qrcode/components/uv-qrcode/gcanvas/context-webgl/Program.js
uni_modules/uv-qrcode/components/uv-qrcode/gcanvas/context-webgl/Renderbuffer.js
uni_modules/uv-qrcode/components/uv-qrcode/gcanvas/context-webgl/RenderingContext.js
uni_modules/uv-qrcode/components/uv-qrcode/gcanvas/context-webgl/Shader.js
uni_modules/uv-qrcode/components/uv-qrcode/gcanvas/context-webgl/ShaderPrecisionFormat.js
uni_modules/uv-qrcode/components/uv-qrcode/gcanvas/context-webgl/Texture.js
uni_modules/uv-qrcode/components/uv-qrcode/gcanvas/context-webgl/UniformLocation.js
uni_modules/uv-qrcode/components/uv-qrcode/gcanvas/context-webgl/classUtils.js
uni_modules/uv-qrcode/components/uv-qrcode/gcanvas/env/canvas.js
uni_modules/uv-qrcode/components/uv-qrcode/gcanvas/env/image.js
uni_modules/uv-qrcode/components/uv-qrcode/gcanvas/env/tool.js
uni_modules/uv-qrcode/components/uv-qrcode/gcanvas/index.js
uni_modules/uv-qrcode/components/uv-qrcode/props.js
uni_modules/uv-qrcode/components/uv-qrcode/qrcode.js
uni_modules/uv-qrcode/components/uv-qrcode/queue.js
uni_modules/uv-qrcode/components/uv-qrcode/uv-qrcode.vue
uni_modules/uv-qrcode/package.json
uni_modules/uv-qrcode/readme.md
uni_modules/uv-radio/changelog.md
uni_modules/uv-radio/components/uv-radio-group/props.js
uni_modules/uv-radio/components/uv-radio-group/uv-radio-group.vue
uni_modules/uv-radio/components/uv-radio/props.js
uni_modules/uv-radio/components/uv-radio/uv-radio.vue
uni_modules/uv-radio/package.json
uni_modules/uv-radio/readme.md
uni_modules/uv-rate/changelog.md
uni_modules/uv-rate/components/uv-rate/props.js
uni_modules/uv-rate/components/uv-rate/uv-rate.vue
uni_modules/uv-rate/package.json
uni_modules/uv-rate/readme.md
uni_modules/uv-read-more/changelog.md
uni_modules/uv-read-more/components/uv-read-more/props.js
uni_modules/uv-read-more/components/uv-read-more/uv-read-more.vue
uni_modules/uv-read-more/package.json
uni_modules/uv-read-more/readme.md
uni_modules/uv-row/changelog.md
uni_modules/uv-row/components/uv-col/props.js
uni_modules/uv-row/components/uv-col/uv-col.vue
uni_modules/uv-row/components/uv-row/props.js
uni_modules/uv-row/components/uv-row/uv-row.vue
uni_modules/uv-row/package.json
uni_modules/uv-row/readme.md
uni_modules/uv-scroll-list/changelog.md
uni_modules/uv-scroll-list/components/uv-scroll-list/nvue.js
uni_modules/uv-scroll-list/components/uv-scroll-list/props.js
uni_modules/uv-scroll-list/components/uv-scroll-list/scrollWxs.wxs
uni_modules/uv-scroll-list/components/uv-scroll-list/uv-scroll-list.vue
uni_modules/uv-scroll-list/package.json
uni_modules/uv-scroll-list/readme.md
uni_modules/uv-search/changelog.md
uni_modules/uv-search/components/uv-search/props.js
uni_modules/uv-search/components/uv-search/uv-search.vue
uni_modules/uv-search/package.json
uni_modules/uv-search/readme.md
uni_modules/uv-skeleton/changelog.md
uni_modules/uv-skeleton/components/uv-skeleton/props.js
uni_modules/uv-skeleton/components/uv-skeleton/uv-skeleton.vue
uni_modules/uv-skeleton/package.json
uni_modules/uv-skeleton/readme.md
uni_modules/uv-skeletons/changelog.md
uni_modules/uv-skeletons/components/uv-skeletons/uv-skeletons.vue
uni_modules/uv-skeletons/package.json
uni_modules/uv-skeletons/readme.md
uni_modules/uv-slider/changelog.md
uni_modules/uv-slider/components/uv-slider/props.js
uni_modules/uv-slider/components/uv-slider/uv-slider.vue
uni_modules/uv-slider/package.json
uni_modules/uv-slider/readme.md
uni_modules/uv-steps/changelog.md
uni_modules/uv-steps/components/uv-steps-item/props.js
uni_modules/uv-steps/components/uv-steps-item/uv-steps-item.vue
uni_modules/uv-steps/components/uv-steps/props.js
uni_modules/uv-steps/components/uv-steps/uv-steps.vue
uni_modules/uv-steps/package.json
uni_modules/uv-steps/readme.md
uni_modules/uv-sticky/changelog.md
uni_modules/uv-sticky/components/uv-sticky/props.js
uni_modules/uv-sticky/components/uv-sticky/uv-sticky.vue
uni_modules/uv-sticky/package.json
uni_modules/uv-sticky/readme.md
uni_modules/uv-subsection/changelog.md
uni_modules/uv-subsection/components/uv-subsection/props.js
uni_modules/uv-subsection/components/uv-subsection/uv-subsection.vue
uni_modules/uv-subsection/package.json
uni_modules/uv-subsection/readme.md
uni_modules/uv-swipe-action/changelog.md
uni_modules/uv-swipe-action/components/uv-swipe-action-item/index - backup.wxs
uni_modules/uv-swipe-action/components/uv-swipe-action-item/index.wxs
uni_modules/uv-swipe-action/components/uv-swipe-action-item/nvue - backup.js
uni_modules/uv-swipe-action/components/uv-swipe-action-item/nvue.js
uni_modules/uv-swipe-action/components/uv-swipe-action-item/props.js
uni_modules/uv-swipe-action/components/uv-swipe-action-item/uv-swipe-action-item.vue
uni_modules/uv-swipe-action/components/uv-swipe-action-item/wxs.js
uni_modules/uv-swipe-action/components/uv-swipe-action/props.js
uni_modules/uv-swipe-action/components/uv-swipe-action/uv-swipe-action.vue
uni_modules/uv-swipe-action/package.json
uni_modules/uv-swipe-action/readme.md
uni_modules/uv-swiper/changelog.md
uni_modules/uv-swiper/components/uv-swiper-indicator/props.js
uni_modules/uv-swiper/components/uv-swiper-indicator/uv-swiper-indicator.vue
uni_modules/uv-swiper/components/uv-swiper/props.js
uni_modules/uv-swiper/components/uv-swiper/uv-swiper.vue
uni_modules/uv-swiper/package.json
uni_modules/uv-swiper/readme.md
uni_modules/uv-switch/changelog.md
uni_modules/uv-switch/components/uv-switch/props.js
uni_modules/uv-switch/components/uv-switch/uv-switch.vue
uni_modules/uv-switch/package.json
uni_modules/uv-switch/readme.md
uni_modules/uv-tabbar/changelog.md
uni_modules/uv-tabbar/components/uv-tabbar-item/props.js
uni_modules/uv-tabbar/components/uv-tabbar-item/uv-tabbar-item.vue
uni_modules/uv-tabbar/components/uv-tabbar/props.js
uni_modules/uv-tabbar/components/uv-tabbar/uv-tabbar.vue
uni_modules/uv-tabbar/package.json
uni_modules/uv-tabbar/readme.md
uni_modules/uv-tabs/changelog.md
uni_modules/uv-tabs/components/uv-tabs/props.js
uni_modules/uv-tabs/components/uv-tabs/uv-tabs.vue
uni_modules/uv-tabs/package.json
uni_modules/uv-tabs/readme.md
uni_modules/uv-tags/changelog.md
uni_modules/uv-tags/components/uv-tags/props.js
uni_modules/uv-tags/components/uv-tags/uv-tags.vue
uni_modules/uv-tags/package.json
uni_modules/uv-tags/readme.md
uni_modules/uv-text/changelog.md
uni_modules/uv-text/components/uv-text/props.js
uni_modules/uv-text/components/uv-text/uv-text.vue
uni_modules/uv-text/components/uv-text/value.js
uni_modules/uv-text/package.json
uni_modules/uv-text/readme.md
uni_modules/uv-toast/changelog.md
uni_modules/uv-toast/components/uv-toast/uv-toast.vue
uni_modules/uv-toast/package.json
uni_modules/uv-toast/readme.md
uni_modules/uv-toolbar/components/uv-toolbar/props.js
uni_modules/uv-toolbar/components/uv-toolbar/uv-toolbar.vue
uni_modules/uv-toolbar/readme.md
uni_modules/uv-tooltip/changelog.md
uni_modules/uv-tooltip/components/uv-tooltip/props.js
uni_modules/uv-tooltip/components/uv-tooltip/uv-tooltip.vue
uni_modules/uv-tooltip/package.json
uni_modules/uv-tooltip/readme.md
uni_modules/uv-ui/changelog.md
uni_modules/uv-ui/components/uv-ui/uv-ui.vue
uni_modules/uv-ui/package.json
uni_modules/uv-ui/readme.md
uni_modules/uv-upload/changelog.md
uni_modules/uv-upload/components/uv-preview-video/uv-preview-video.vue
uni_modules/uv-upload/components/uv-upload/mixin.js
uni_modules/uv-upload/components/uv-upload/props.js
uni_modules/uv-upload/components/uv-upload/utils.js
uni_modules/uv-upload/components/uv-upload/uv-upload.vue
uni_modules/uv-upload/package.json
uni_modules/uv-upload/readme.md
uni_modules/uv-vtabs/changelog.md
uni_modules/uv-vtabs/components/uv-vtabs-item/uv-vtabs-item.vue
uni_modules/uv-vtabs/components/uv-vtabs/props.js
uni_modules/uv-vtabs/components/uv-vtabs/uv-vtabs.vue
uni_modules/uv-vtabs/package.json
uni_modules/uv-vtabs/readme.md
uni_modules/uv-waterfall/changelog.md
uni_modules/uv-waterfall/components/uv-waterfall/props.js
uni_modules/uv-waterfall/components/uv-waterfall/uv-waterfall.vue
uni_modules/uv-waterfall/package.json
uni_modules/uv-waterfall/readme.md
unpackage/res/icons/1024x1024.png
unpackage/res/icons/120x120.png
unpackage/res/icons/144x144.png
unpackage/res/icons/152x152.png
unpackage/res/icons/167x167.png
unpackage/res/icons/180x180.png
unpackage/res/icons/192x192.png
unpackage/res/icons/20x20.png
unpackage/res/icons/29x29.png
unpackage/res/icons/40x40.png
unpackage/res/icons/58x58.png
unpackage/res/icons/60x60.png
unpackage/res/icons/72x72.png
unpackage/res/icons/76x76.png
unpackage/res/icons/80x80.png
unpackage/res/icons/87x87.png
unpackage/res/icons/96x96.png
util.js |