Csqqqqq 1 month ago
parent ca79a163a3
commit 3cdee4581f

@ -35,6 +35,13 @@
"navigationStyle": "custom",
"navigationBarTextStyle": "white"
}
},
{
"path": "pages/customerCS/checkManDetail",
"style": {
"navigationStyle": "custom",
"navigationBarTextStyle": "white"
}
}
],
"globalStyle": {

@ -0,0 +1,575 @@
<template>
<view class="checkManDetail">
<u-navbar :bgColor="background" left-icon=" "></u-navbar>
<view class="topImgCon">
<image src="https://wx3.sinaimg.cn/mw1024/007bFxqGly1hrtnqdv7fpj30u00u0afj.jpg" mode="aspectFill" class="topBg"></image>
<image src="../../static/img/2.png" class="topBtBg"></image>
<view class="topTip taste">
<image src="../../static/img/happy1.png"></image> 味道鲜美</view>
<view class="topTip weight">
<image src="../../static/img/happy1.png"></image>足斤足两</view>
<view class="topTip quality">
<image src="../../static/img/happy2.png"></image>肉质鲜嫩</view>
<view class="man-id-card">
<view class="name-box">
<view class="name">验蟹师名字</view>
<view class="visitor">
<image src="../../static/img/eye.png"></image>
访客<text class="visitor-num">121</text>
</view>
</view>
<view class="label-box">
<!-- <view class="label">
<view class="label-img first">
<image src="../../static/img/label1.png" class="labelBg"></image>
<!-- <image src="../../static/img/timeC.png"></image> -->
<!-- </view>
<view class="label-text first">从业14年</view>
</view> -->
<!-- <view class="label">
<view class="label-img second">
<image src="../../static/img/certification.png"></image>
</view>
<view>金牌验蟹师</view>
</view> -->
</view>
<view class="man-detail">
<view class="box left">
<view class="detail-tip">
<image src="../../static/img/map-pin@2x.png" class="detail-img"></image>
南京市
</view>
<view class="detail-tip">
<image src="../../static/img/magic-hands@2x.png" class="detail-img"></image>
已验蟹 2W+
</view>
</view>
<view class="box right">
<view class="rate-text">评分</view>
<view class="rate-value">{{valueCheckman}}</view>
<view class="rate">
<u-rate :count="count" v-model="valueCheckman" size="20rpx" :allowHalf="true"></u-rate>
</view>
</view>
</view>
</view>
</view>
<view class="bodyCon">
<view class="claims-box">
<view class="title">缺斤少两<text>三步</text>轻松理赔</view>
<view class="title-add">蟹联网理赔成功率 99%</view>
<view class="part3">
<view class="steps-box left">
<view class="steps-num">01</view>
<view class="steps-con">提交快递信息</view>
<view class="row left">
<image src="../../static/img/row.png"></image>
</view>
</view>
<view class="steps-box center">
<view class="steps-num">02</view>
<view class="steps-con">补充订单信息</view>
<view class="row right">
<image src="../../static/img/row.png"></image>
</view>
</view>
<view class="steps-box right">
<view class="steps-num">03</view>
<view class="steps-con">上传证明材料</view>
</view>
</view>
<view class="part4">
<button class="claims-btn">
前往理赔
<image src="../../static/img/chevron-right-small@2x.png"></image>
</button>
</view>
</view>
<view class="line"></view>
<view class="claims-assess-box">
<view class="title">您对本次验蟹结果满意吗</view>
<view class="bottom-img">
<view class="img-con">
<image src="../../static/img/anger.png"></image>
<text>很糟糕</text>
</view>
<view class="img-con">
<image src="../../static/img/happy1.png"></image>
<text>还可以</text>
</view>
<view class="img-con">
<image src="../../static/img/happy2.png"></image>
<text>太赞了</text>
</view>
</view>
</view>
<view class="line"></view>
<view class="assess-box">
<view class="assess-top">
<view class="left">
<view class="title">用户评价</view>
<view class="title-add">已有 {{customerNum}} 名用户参与评价</view>
</view>
<view class="right">
<u-rate :count="count" v-model="valueCustomer" size="20rpx" :allowHalf="true"></u-rate>
<view class="rate-value">{{valueCustomer}}</view>
</view>
</view>
<view class="assess-body">
<view class="assess-item" v-for="item in assessList">
{{item.name}}{{item.num}}
</view>
</view>
</view>
</view>
</view>
</template>
<script>
export default {
data(){
return{
background:"transparent",
valueCheckman:4.9,
valueCustomer:3.9,
count:5,
customerNum:6712,
assessList:[{
name:"味道鲜美",
num:8
},
{
name:"饱满香浓",
num:6
},
{
name:"蟹膏浓郁",
num:10
},
{
name:"味道好",
num:8
},
{
name:"肉质鲜嫩",
num:8
},
{
name:"足斤足两",
num:12
}]
}
}
}
</script>
<style lang="scss">
.checkManDetail{
}
.topImgCon{
width: 750rpx;
height: 750rpx;
position: relative;
.topBg{
width: 100%;
height: 100%;
z-index: 5;
}
.topBtBg{
position: absolute;
bottom: 0;
left: 0;
right: 0;
width: 100%;
height: 96rpx;
z-index: 10;
}
.topTip{
width: 184rpx;
height: 56rpx;
background: rgba(0,0,0,0.2);
border-radius: 56rpx 56rpx 56rpx 56rpx;
position: absolute;
display: flex;
justify-content: center;
font-weight: 400;
font-size: 24rpx;
color: #FFFFFF;
line-height: 34rpx;
text-align: center;
padding-top: 12rpx;
box-sizing: border-box;
>image{
width: 40rpx;
height: 40rpx;
margin-right: 8rpx;
}
&.taste{
left: 124rpx;
top: 360rpx;
}
&.weight{
left: 316rpx;
top: 434rpx;
}
&.quality{
left: 416rpx;
top: 360rpx;
}
}
.man-id-card{
z-index: 12;
width: 678rpx;
height: 338rpx;
background: #FFFFFF;
box-shadow: 0rpx 14rpx 58rpx 0rpx rgba(100,100,111,0.2);
border-radius: 24rpx;
position: absolute;
top: 532rpx;
left: 36rpx;
padding: 28rpx;
box-sizing: border-box;
display: flex;
flex-direction: column;
justify-content: space-between;
.name-box{
height: 78rpx;
display: flex;
justify-content: space-between;
.name{
font-weight: 600;
font-size: 56rpx;
color: #222222;
line-height: 78rpx;
}
.visitor{
font-weight: 400;
font-size: 24rpx;
color: rgba(34,34,34,0.6);
line-height: 34rpx;
text-align: left;
display: flex;
>image{
height: 32rpx;
width: 32rpx;
margin-right: 4rpx;
}
>text{
font-weight: 600;
font-size: 26rpx;
color: #222222;
line-height: 36rpx;
margin-left: 4rpx;
}
}
}
.label-box{
height: 40rpx;
// background-color: rebeccapurple;
// display: flex;
// position: relative;
// .label{
// height: 40rpx;
// width: 152rpx;
// display: flex;
// font-weight: 400;
// font-size: 20rpx;
// color: #FFFFFF;
// line-height: 28rpx;
// .label-img{
// .labelBg{
// height: 36rpx;
// width: 36rpx;
// }
// }
// .label-text{
// width: 112rpx;
// height: 30rpx;
// border-radius: 4rpx;
// text-align: center;
// &.first{
// background: #2388FF;
// }
// }
// }
}
.man-detail{
width: 622rpx;
height: 134rpx;
display: flex;
justify-content: space-between;
.box{
width: 310rpx;
height: 134rpx;
background: #F8F9FA;
border-radius: 16rpx 16rpx 16rpx 16rpx;
&.left{
padding: 24rpx;
box-sizing: border-box;
display: flex;
flex-direction: column;
justify-content: space-between;
.detail-tip{
height: 36rpx;
font-weight: 400;
font-size: 26rpx;
color: #333333;
line-height: 36rpx;
text-align: left;
display: flex;
.detail-img{
width: 36rpx;
height: 36rpx;
margin-right: 8rpx;
}
}
}
&.right{
position: relative;
box-sizing: border-box;
.rate-text{
position: absolute;
right:24rpx;
top:24rpx;
font-weight: 400;
font-size: 26rpx;
color: #B2B2B2;
line-height: 36rpx;
}
.rate-value{
position: absolute;
left: 34rpx;
top:20rpx;
font-family: D-DIN-DIN, D-DIN-DIN;
font-weight: bold;
font-size: 92rpx;
color: #FF480B;
line-height: 92rpx;
display: flex;
}
.rate{
position: absolute;
left: 162rpx;
bottom: 36rpx;
}
}
}
}
}
}
.bodyCon{
position: absolute;
top: 878rpx;
.claims-box{
width: 750rpx;
height: 414rpx;
background: #FFFFFF;
//background-color: #FF480B;
padding: 32rpx 36rpx;
box-sizing: border-box;
display: flex;
flex-direction: column;
justify-content: space-between;
.part3{
height: 120rpx;
display: flex;
position: relative;
.steps-box{
height: 120rpx;
background: linear-gradient( 180deg, rgba(51,135,251,0.05) 0%, rgba(51,135,251,0.1) 100%);
width: 240rpx;
border-radius: 16rpx;
display: flex;
flex-direction: column;
justify-content: space-between;
padding: 10rpx 0 12rpx 24rpx;
box-sizing: border-box;
&.center{
width: 266rpx;
padding-left: 56rpx;
}
&.right{
padding-left: 60rpx;
}
}
.steps-num{
font-family: D-DIN-DIN, D-DIN-DIN;
font-weight: bold;
font-size: 48rpx;
color: #3387FB;
line-height: 67rpx;
text-align: left;
}
.steps-con{
font-weight: 400;
font-size: 24rpx;
color: rgba(34,34,34,0.6);
line-height: 34rpx;
text-align: left;
}
.row{
height: 180rpx;
width: 80rpx;
>image{
height: 100%;
width: 100%;
}
&.left{
position: absolute;
left: 194rpx;
top: -30rpx;
}
&.right{
position: absolute;
right: 168rpx;
top: -30rpx;
}
}
}
.part4{
.claims-btn{
width: 678rpx;
height: 92rpx;
background: #FFFFFF;
border-radius: 98rpx 98rpx 98rpx 98rpx;
border: 2rpx solid #2388FF;
display: flex;
justify-content: center;
font-weight: 500;
font-size: 28rpx;
color: #2388FF;
line-height: 39rpx;
padding-top: 26rpx;
>image{
width: 43rpx;
height: 43rpx;
}
}
}
}
.claims-assess-box{
width: 750rpx;
height: 254rpx;
background: #FFFFFF;
//background-color: aqua;
padding: 32rpx 36rpx;
box-sizing: border-box;
display: flex;
flex-direction: column;
justify-content: space-between;
.bottom-img{
width: 496rpx;
height: 106rpx;
margin-left: 96rpx;
display: flex;
justify-content: space-between;
.img-con{
display: flex;
flex-direction: column;
>image{
width: 72rpx;
height: 72rpx;
filter: grayscale(100%);
}
>text{
font-size: 24rpx;
color: #000000;
line-height: 34rpx;
text-align: center;
}
}
}
}
.assess-box{
width: 750rpx;
height: 284rpx;
background: #FFFFFF;
//background-color: blueviolet;
padding: 32rpx 36rpx 28rpx 36rpx;
margin-bottom: 68rpx;
box-sizing: border-box;
display: flex;
flex-direction: column;
justify-content: space-between;
.assess-top{
display: flex;
justify-content: space-between;
.left{
width: 308rpx;
height: 98rpx;
display: flex;
flex-direction: column;
justify-content: space-between;
}
.right{
display: flex;
position: relative;
height: 92rpx;
.u-rate{
position: absolute;
bottom: 12rpx;
right: 140rpx;
}
.rate-value{
font-family: D-DIN-DIN, D-DIN-DIN;
font-weight: bold;
font-size: 92rpx;
color: #FF480B;
line-height: 92rpx;
}
}
}
.assess-body{
width: 680rpx;
height: 108rpx;
display: flex;
flex-wrap: wrap;
justify-content: left;
.assess-item{
width: 160rpx;
height: 50rpx;
background: #F5F5F5;
border-radius: 8rpx;
font-weight: 400;
font-size: 24rpx;
color: rgba(34,34,34,0.6);
line-height: 34rpx;
text-align: center;
padding-top: 8rpx;
box-sizing: border-box;
margin-right: 8rpx;
}
}
}
.line{
width: 714rpx;
height: 0rpx;
border: 2rpx solid rgba(0,0,0,0.04);
margin: 12rpx 18rpx;
}
.title{
font-weight: 600;
font-size: 36rpx;
color: #222222;
line-height: 50rpx;
>text{
color: #2388FF;
}
}
.title-add{
font-weight: 400;
font-size: 26rpx;
color: rgba(0,0,0,0.5);
line-height: 36rpx;
}
}
</style>

@ -0,0 +1,8 @@
<template>
</template>
<script>
</script>
<style>
</style>

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 420 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

@ -0,0 +1,8 @@
## 1.3.82023-03-27
1. 新增useMescroll的hook, 支持vue3 script setup的写法
2. 新增vue3 script setup的示例 ( 根据vue2的示例,全部重写了一遍 )
3. mescroll-body 和 mescroll-uni 无需再写 ref="mescrollRef"
4. 解决mescroll-uni在页面渲染之后,无法动态设置height的问题
5. 解决renderjs在h5返回有时候无法正常滑动的问题
6. 修复小程序编辑器提示 Cannot read property 'nv_optDown' of undefined 的错误
-by 小瑾同学

@ -0,0 +1,19 @@
.mescroll-body {
position: relative; /* 下拉刷新区域相对自身定位 */
height: auto; /* 不可固定高度,否则overflow:hidden导致无法滑动; 同时使设置的最小高生效,实现列表不满屏仍可下拉*/
overflow: hidden; /* 当有元素写在mescroll-body标签前面时,可遮住下拉刷新区域 */
box-sizing: border-box; /* 避免设置padding出现双滚动条的问题 */
}
/* 使sticky生效: 父元素不能overflow:hidden或者overflow:auto属性 */
.mescroll-body.mescorll-sticky{
overflow: unset !important
}
/* 适配 iPhoneX */
@supports (bottom: constant(safe-area-inset-bottom)) or (bottom: env(safe-area-inset-bottom)) {
.mescroll-safearea {
padding-bottom: constant(safe-area-inset-bottom);
padding-bottom: env(safe-area-inset-bottom);
}
}

@ -0,0 +1,400 @@
<template>
<view
class="mescroll-body mescroll-render-touch"
:class="{'mescorll-sticky': sticky}"
:style="{'minHeight':minHeight, 'padding-top': padTop, 'padding-bottom': padBottom}"
@touchstart="wxsBiz.touchstartEvent"
@touchmove="wxsBiz.touchmoveEvent"
@touchend="wxsBiz.touchendEvent"
@touchcancel="wxsBiz.touchendEvent"
:change:prop="wxsBiz.propObserver"
:prop="wxsProp"
>
<!-- 状态栏 -->
<view v-if="topbar&&statusBarHeight" class="mescroll-topbar" :style="{height: statusBarHeight+'px', background: topbar}"></view>
<view class="mescroll-body-content mescroll-wxs-content" :style="{ transform: translateY, transition: transition }" :change:prop="wxsBiz.callObserver" :prop="callProp">
<!-- 下拉加载区域 (支付宝小程序子组件传参给子子组件仍报单项数据流的异常,暂时不通过mescroll-down组件实现)-->
<!-- <mescroll-down :option="mescroll.optDown" :type="downLoadType" :rate="downRate"></mescroll-down> -->
<view v-if="mescroll.optDown.use" class="mescroll-downwarp" :style="{'background':mescroll.optDown.bgColor,'color':mescroll.optDown.textColor}">
<view class="downwarp-content">
<view class="downwarp-progress mescroll-wxs-progress" :class="{'mescroll-rotate': isDownLoading}" :style="{'border-color':mescroll.optDown.textColor, 'transform': downRotate}"></view>
<view class="downwarp-tip">{{downText}}</view>
</view>
</view>
<!-- 列表内容 -->
<slot></slot>
<!-- 空布局 -->
<mescroll-empty v-if="isShowEmpty" :option="mescroll.optUp.empty" @emptyclick="emptyClick"></mescroll-empty>
<!-- 上拉加载区域 (下拉刷新时不显示, 支付宝小程序子组件传参给子子组件仍报单项数据流的异常,暂时不通过mescroll-up组件实现)-->
<!-- <mescroll-up v-if="mescroll.optUp.use && !isDownLoading && upLoadType!==3" :option="mescroll.optUp" :type="upLoadType"></mescroll-up> -->
<view v-if="mescroll.optUp.use && !isDownLoading && upLoadType!==3" class="mescroll-upwarp" :style="{'background':mescroll.optUp.bgColor,'color':mescroll.optUp.textColor}">
<!-- 加载中 (此处不能用v-if,否则android小程序快速上拉可能会不断触发上拉回调) -->
<view v-show="upLoadType===1">
<view class="upwarp-progress mescroll-rotate" :style="{'border-color':mescroll.optUp.textColor}"></view>
<view class="upwarp-tip">{{ mescroll.optUp.textLoading }}</view>
</view>
<!-- 无数据 -->
<view v-if="upLoadType===2" class="upwarp-nodata">{{ mescroll.optUp.textNoMore }}</view>
</view>
</view>
<!-- 底部是否偏移TabBar的高度(默认仅在H5端的tab页生效) -->
<!-- #ifdef H5 -->
<view v-if="bottombar && windowBottom>0" class="mescroll-bottombar" :style="{height: windowBottom+'px'}"></view>
<!-- #endif -->
<!-- 适配iPhoneX -->
<view v-if="safearea" class="mescroll-safearea"></view>
<!-- 回到顶部按钮 (fixed元素需写在transform外面,防止降级为absolute)-->
<mescroll-top v-model="isShowToTop" :option="mescroll.optUp.toTop" @click="toTopClick"></mescroll-top>
<!-- #ifdef MP-WEIXIN || MP-QQ || APP-PLUS || H5 -->
<!-- renderjs的数据载体,不可写在mescroll-downwarp内部,避免use为false时,载体丢失,无法更新数据 -->
<view :change:prop="renderBiz.propObserver" :prop="wxsProp"></view>
<!-- #endif -->
</view>
</template>
<!-- 微信小程序, QQ小程序, app, h5使用wxs -->
<!-- #ifdef MP-WEIXIN || MP-QQ || APP-PLUS || H5 -->
<script src="../mescroll-uni/wxs/wxs.wxs" module="wxsBiz" lang="wxs"></script>
<!-- #endif -->
<!-- app, h5使用renderjs -->
<!-- #ifdef APP-PLUS || H5 -->
<script module="renderBiz" lang="renderjs">
import renderBiz from "../mescroll-uni/wxs/renderjs.js";
export default {
mixins: [renderBiz]
}
</script>
<!-- #endif -->
<script>
// mescroll-uni.js,
import MeScroll from "../mescroll-uni/mescroll-uni.js";
//
import GlobalOption from "../mescroll-uni/mescroll-uni-option.js";
//
import mescrollI18n from '../mescroll-uni/mescroll-i18n.js';
//
import MescrollTop from "../mescroll-uni/components/mescroll-top.vue";
// wxs(renderjs)mixins
import WxsMixin from "../mescroll-uni/wxs/mixins.js";
/**
* mescroll-body 基于page滚动的下拉刷新和上拉加载组件, 支持嵌套原生组件, 性能好
* @property {Object} down 下拉刷新的参数配置
* @property {Object} up 上拉加载的参数配置
* @property {Object} i18n 国际化的参数配置
* @property {String, Number} top 下拉布局往下的偏移量 (支持20, "20rpx", "20px", "20%"格式的值, 其中纯数字则默认单位rpx, 百分比则相对于windowHeight)
* @property {Boolean, String} topbar 偏移量top是否加上状态栏高度, 默认false (使用场景:取消原生导航栏时,配置此项可留出状态栏的占位, 支持传入字符串背景,如色值,背景图,渐变)
* @property {String, Number} bottom 上拉布局往上的偏移量 (支持20, "20rpx", "20px", "20%"格式的值, 其中纯数字则默认单位rpx, 百分比则相对于windowHeight)
* @property {Boolean} safearea 偏移量bottom是否加上底部安全区的距离, 默认false (需要适配iPhoneX时使用)
* @property {Boolean} fixed 是否通过fixed固定mescroll的高度, 默认true
* @property {String, Number} height 指定mescroll最小高度,默认windowHeight,使列表不满屏仍可下拉
* @property {Boolean} bottombar 底部是否偏移TabBar的高度 (仅在H5端的tab页生效)
* @property {Boolean} sticky 是否支持sticky,默认false; 当值配置true时,需避免在mescroll-body标签前面加非定位的元素,否则下拉区域无法隐藏
* @event {Function} init 初始化完成的回调
* @event {Function} down 下拉刷新的回调
* @event {Function} up 上拉加载的回调
* @event {Function} emptyclick 点击empty配置的btnText按钮回调
* @event {Function} topclick 点击回到顶部的按钮回调
* @event {Function} scroll 滚动监听 (需在 up 配置 onScroll:true 才生效)
* @example <mescroll-body @init="mescrollInit" @down="downCallback" @up="upCallback"> ... </mescroll-body>
*/
export default {
name: 'mescroll-body',
mixins: [WxsMixin],
components: {
MescrollTop
},
props: {
down: Object,
up: Object,
i18n: Object,
top: [String, Number],
topbar: [Boolean, String],
bottom: [String, Number],
safearea: Boolean,
height: [String, Number],
bottombar:{
type: Boolean,
default: true
},
sticky: Boolean
},
data() {
return {
mescroll: {optDown:{},optUp:{}}, // mescroll
downHight: 0, //:
downRate: 0, // (inOffset: rate<1; outOffset: rate>=1)
downLoadType: 0, // : 0(loading), 1(inOffset), 2(outOffset), 3(showLoading), 4(endDownScroll)
upLoadType: 0, // 0loading1loading2,END3,END
isShowEmpty: false, //
isShowToTop: false, //
windowHeight: 0, // 使
windowBottom: 0, // 使
statusBarHeight: 0 //
};
},
computed: {
// mescroll,windowHeight,使
minHeight(){
return this.toPx(this.height || '100%') + 'px'
},
// (px)
numTop() {
return this.toPx(this.top)
},
padTop() {
return this.numTop + 'px';
},
// (px)
numBottom() {
return this.toPx(this.bottom);
},
padBottom() {
return this.numBottom + 'px';
},
//
isDownReset() {
return this.downLoadType === 3 || this.downLoadType === 4;
},
//
transition() {
return this.isDownReset ? 'transform 300ms' : '';
},
translateY() {
return this.downHight > 0 ? 'translateY(' + this.downHight + 'px)' : ''; // transform使fixed,fixedmescroll
},
//
isDownLoading(){
return this.downLoadType === 3
},
//
downRotate(){
return 'rotate(' + 360 * this.downRate + 'deg)'
},
//
downText(){
if(!this.mescroll) return ""; //
switch (this.downLoadType){
case 1: return this.mescroll.optDown.textInOffset;
case 2: return this.mescroll.optDown.textOutOffset;
case 3: return this.mescroll.optDown.textLoading;
case 4: return this.mescroll.isDownEndSuccess ? this.mescroll.optDown.textSuccess : this.mescroll.isDownEndSuccess==false ? this.mescroll.optDown.textErr : this.mescroll.optDown.textInOffset;
default: return this.mescroll.optDown.textInOffset;
}
}
},
methods: {
//number,rpx,upx,px,% --> px
toPx(num) {
if (typeof num === 'string') {
if (num.indexOf('px') !== -1) {
if (num.indexOf('rpx') !== -1) {
// "10rpx"
num = num.replace('rpx', '');
} else if (num.indexOf('upx') !== -1) {
// "10upx"
num = num.replace('upx', '');
} else {
// "10px"
return Number(num.replace('px', ''));
}
} else if (num.indexOf('%') !== -1) {
// ,windowHeight,"10%"windowHeight10%
let rate = Number(num.replace('%', '')) / 100;
return this.windowHeight * rate;
}
}
return num ? uni.upx2px(Number(num)) : 0;
},
//
emptyClick() {
this.$emit('emptyclick', this.mescroll);
},
//
toTopClick() {
this.mescroll.scrollTo(0, this.mescroll.optUp.toTop.duration); //
this.$emit('topclick', this.mescroll); //
}
},
// 使createdmescroll; mountedcssH5
created() {
let vm = this;
let diyOption = {
//
down: {
inOffset() {
vm.downLoadType = 1; // offset (mescroll,)
},
outOffset() {
vm.downLoadType = 2; // offset (mescroll,)
},
onMoving(mescroll, rate, downHight) {
// ,;
vm.downHight = downHight; // (mescroll,)
vm.downRate = rate; // (inOffset: rate<1; outOffset: rate>=1)
},
showLoading(mescroll, downHight) {
vm.downLoadType = 3; // (mescroll,)
vm.downHight = downHight; // (mescroll,)
},
beforeEndDownScroll(mescroll){
vm.downLoadType = 4;
return mescroll.optDown.beforeEndDelay //
},
endDownScroll() {
vm.downLoadType = 4; // (mescroll,)
vm.downHight = 0; // (mescroll,)
if(vm.downResetTimer) {clearTimeout(vm.downResetTimer); vm.downResetTimer = null} //
vm.downResetTimer = setTimeout(()=>{ // ,0,inOffsettextInOffset
if(vm.downLoadType === 4) vm.downLoadType = 0
},300)
},
//
callback: function(mescroll) {
vm.$emit('down', mescroll);
}
},
//
up: {
//
showLoading() {
vm.upLoadType = 1;
},
//
showNoMore() {
vm.upLoadType = 2;
},
//
hideUpScroll(mescroll) {
vm.upLoadType = mescroll.optUp.hasNext ? 0 : 3;
},
//
empty: {
onShow(isShow) {
//
vm.isShowEmpty = isShow;
}
},
//
toTop: {
onShow(isShow) {
//
vm.isShowToTop = isShow;
}
},
//
callback: function(mescroll) {
vm.$emit('up', mescroll);
}
}
};
let i18nType = mescrollI18n.getType() //
let i18nOption = {type: i18nType} //
MeScroll.extend(i18nOption, vm.i18n) //
MeScroll.extend(i18nOption, GlobalOption.i18n) //
MeScroll.extend(diyOption, i18nOption[i18nType]); //
MeScroll.extend(diyOption, {down:GlobalOption.down, up:GlobalOption.up}); //
let myOption = JSON.parse(JSON.stringify({down: vm.down,up: vm.up})); // ,props
MeScroll.extend(myOption, diyOption); //
// MeScroll
vm.mescroll = new MeScroll(myOption, true); // true,body
//
vm.mescroll.i18n = i18nOption;
// initmescroll
vm.$emit('init', vm.mescroll);
//
const sys = uni.getSystemInfoSync();
if (sys.windowHeight) vm.windowHeight = sys.windowHeight;
if (sys.windowBottom) vm.windowBottom = sys.windowBottom;
if (sys.statusBarHeight) vm.statusBarHeight = sys.statusBarHeight;
// 使downbottomOffset
vm.mescroll.setBodyHeight(sys.windowHeight);
// 使pagescroll,scrollTo
vm.mescroll.resetScrollTo((y, t) => {
if(typeof y === 'string'){
// view (ycss)
setTimeout(()=>{ // view; 使$nextTick
let selector;
if(y.indexOf('#')==-1 && y.indexOf('.')==-1){
selector = '#'+y // #. id
}else{
selector = y
// #ifdef APP-PLUS || H5 || MP-ALIPAY || MP-DINGTALK
if(y.indexOf('>>>')!=-1){ // ()
selector = y.split('>>>')[1].trim()
}
// #endif
}
uni.createSelectorQuery().select(selector).boundingClientRect(function(rect){
if (rect) {
let top = rect.top
top += vm.mescroll.getScrollTop()
uni.pageScrollTo({
scrollTop: top,
duration: t
})
} else{
console.error(selector + ' does not exist');
}
}).exec()
},30)
} else{
// (y)
uni.pageScrollTo({
scrollTop: y,
duration: t
})
}
});
// up.toTop.safearea,vuesafearea
if (vm.up && vm.up.toTop && vm.up.toTop.safearea != null) {} else {
vm.mescroll.optUp.toTop.safearea = vm.safearea;
}
//
uni.$on("setMescrollGlobalOption", options=>{
if(!options) return;
let i18nType = options.i18n ? options.i18n.type : null
if(i18nType && vm.mescroll.i18n.type != i18nType){
vm.mescroll.i18n.type = i18nType
mescrollI18n.setType(i18nType)
MeScroll.extend(options, vm.mescroll.i18n[i18nType])
}
if(options.down){
let down = MeScroll.extend({}, options.down)
vm.mescroll.optDown = MeScroll.extend(down, vm.mescroll.optDown)
}
if(options.up){
let up = MeScroll.extend({}, options.up)
vm.mescroll.optUp = MeScroll.extend(up, vm.mescroll.optUp)
}
})
},
destroyed() {
//
uni.$off("setMescrollGlobalOption")
}
};
</script>
<style>
@import "../mescroll-body/mescroll-body.css";
@import "../mescroll-uni/components/mescroll-down.css";
@import "../mescroll-uni/components/mescroll-up.css";
</style>

@ -0,0 +1,116 @@
<!--空布局:
遵循easycom规范, 可作为独立的组件, 不使用mescroll的页面也能使用:
<mescroll-empty v-if="isShowEmpty" :option="optEmpty" @emptyclick="emptyClick"></mescroll-empty>
-->
<template>
<view class="mescroll-empty" :class="{ 'empty-fixed': option.fixed }" :style="{ 'z-index': option.zIndex, top: option.top }">
<view> <image v-if="icon" class="empty-icon" :src="icon" mode="widthFix" /> </view>
<view v-if="tip" class="empty-tip">{{ tip }}</view>
<view v-if="btnText" class="empty-btn" @click="emptyClick">{{ btnText }}</view>
</view>
</template>
<script>
//
import GlobalOption from '../mescroll-uni/mescroll-uni-option.js';
//
import mescrollI18n from '../mescroll-uni/mescroll-i18n.js';
export default {
props: {
// empty: GlobalOption.up.empty
option: {
type: Object,
default() {
return {};
}
}
},
// 使computed,option
computed: {
//
icon() {
if (this.option.icon != null) { // 使,
return this.option.icon
} else{
let i18nType = mescrollI18n.getType() //
if (this.option.i18n) {
return this.option.i18n[i18nType].icon
} else{
return GlobalOption.i18n[i18nType].up.empty.icon || GlobalOption.up.empty.icon
}
}
},
//
tip() {
if (this.option.tip != null) { //
return this.option.tip
} else{
let i18nType = mescrollI18n.getType() //
if (this.option.i18n) {
return this.option.i18n[i18nType].tip
} else{
return GlobalOption.i18n[i18nType].up.empty.tip || GlobalOption.up.empty.tip
}
}
},
//
btnText() {
if (this.option.i18n) {
let i18nType = mescrollI18n.getType() //
return this.option.i18n[i18nType].btnText
} else{
return this.option.btnText
}
}
},
methods: {
//
emptyClick() {
this.$emit('emptyclick');
}
}
};
</script>
<style>
/* 无任何数据的空布局 */
.mescroll-empty {
box-sizing: border-box;
width: 100%;
padding: 100rpx 50rpx;
text-align: center;
}
.mescroll-empty.empty-fixed {
z-index: 99;
position: absolute; /*transform会使fixed失效,最终会降级为absolute */
top: 100rpx;
left: 0;
}
.mescroll-empty .empty-icon {
width: 280rpx;
height: 280rpx;
}
.mescroll-empty .empty-tip {
margin-top: 20rpx;
font-size: 24rpx;
color: gray;
}
.mescroll-empty .empty-btn {
display: inline-block;
margin-top: 40rpx;
min-width: 200rpx;
padding: 18rpx;
font-size: 28rpx;
border: 1rpx solid #e04b28;
border-radius: 60rpx;
color: #e04b28;
}
.mescroll-empty .empty-btn:active {
opacity: 0.75;
}
</style>

@ -0,0 +1,55 @@
/* 下拉刷新区域 */
.mescroll-downwarp {
position: absolute;
top: -100%;
left: 0;
width: 100%;
height: 100%;
text-align: center;
}
/* 下拉刷新--内容区,定位于区域底部 */
.mescroll-downwarp .downwarp-content {
position: absolute;
left: 0;
bottom: 0;
width: 100%;
min-height: 60rpx;
padding: 20rpx 0;
text-align: center;
}
/* 下拉刷新--提示文本 */
.mescroll-downwarp .downwarp-tip {
display: inline-block;
font-size: 28rpx;
vertical-align: middle;
margin-left: 16rpx;
/* color: gray; 已在style设置color,此处删去*/
}
/* 下拉刷新--旋转进度条 */
.mescroll-downwarp .downwarp-progress {
display: inline-block;
width: 32rpx;
height: 32rpx;
border-radius: 50%;
border: 2rpx solid gray;
border-bottom-color: transparent !important; /*已在style设置border-color,此处需加 !important*/
vertical-align: middle;
}
/* 旋转动画 */
.mescroll-downwarp .mescroll-rotate {
animation: mescrollDownRotate 0.6s linear infinite;
}
@keyframes mescrollDownRotate {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}

@ -0,0 +1,47 @@
<!-- 下拉刷新区域 -->
<template>
<view v-if="mOption.use" class="mescroll-downwarp" :style="{'background-color':mOption.bgColor,'color':mOption.textColor}">
<view class="downwarp-content">
<view class="downwarp-progress" :class="{'mescroll-rotate': isDownLoading}" :style="{'border-color':mOption.textColor, 'transform':downRotate}"></view>
<view class="downwarp-tip">{{downText}}</view>
</view>
</view>
</template>
<script>
export default {
props: {
option: Object , // down
type: Number, // inOffset1 outOffset2 showLoading3 endDownScroll4
rate: Number // (inOffset: rate<1; outOffset: rate>=1)
},
computed: {
// ,propdefault
mOption(){
return this.option || {}
},
//
isDownLoading(){
return this.type === 3
},
//
downRotate(){
return 'rotate(' + 360 * this.rate + 'deg)'
},
//
downText(){
switch (this.type){
case 1: return this.mOption.textInOffset;
case 2: return this.mOption.textOutOffset;
case 3: return this.mOption.textLoading;
case 4: return this.mOption.textLoading;
default: return this.mOption.textInOffset;
}
}
}
};
</script>
<style>
@import "./mescroll-down.css";
</style>

@ -0,0 +1,99 @@
<!-- 回到顶部的按钮 -->
<template>
<image
v-if="option.src"
class="mescroll-totop"
:class="[isShow ? 'mescroll-totop-in' : 'mescroll-totop-out', {'mescroll-totop-safearea': option.safearea}]"
:style="{'z-index':option.zIndex, 'left': left, 'right': right, 'bottom':addUnit(option.bottom), 'width':addUnit(option.width), 'border-radius':addUnit(option.radius)}"
:src="option.src"
mode="widthFix"
@click="toTopClick"
/>
</template>
<script>
export default {
props: {
// up.toTop
option: {
type: Object,
default(){
return {}
}
},
//
value: false, // vue2
modelValue: false // vue3
},
computed: {
//
left(){
return this.option.left ? this.addUnit(this.option.left) : 'auto';
},
// ()
right() {
return this.option.left ? 'auto' : this.addUnit(this.option.right);
},
//
isShow(){
// #ifdef VUE3
return this.modelValue
// #endif
// #ifdef VUE2
return this.value
// #endif
}
},
methods: {
addUnit(num){
if(!num) return 0;
if(typeof num === 'number') return num + 'rpx';
return num
},
toTopClick() {
// #ifdef VUE3
this.$emit("update:modelValue", false); // 使v-model vue3
// #endif
// #ifdef VUE2
this.$emit('input', false); // 使v-model vue2
// #endif
this.$emit('click'); //
}
}
};
</script>
<style>
/* 回到顶部的按钮 */
.mescroll-totop {
z-index: 9990;
position: fixed !important; /* 加上important避免编译到H5,在多mescroll中定位失效 */
right: 20rpx;
bottom: 120rpx;
width: 72rpx;
height: auto;
border-radius: 50%;
opacity: 0;
transition: opacity 0.5s; /* 过渡 */
margin-bottom: var(--window-bottom); /* css变量 */
}
/* 适配 iPhoneX */
@supports (bottom: constant(safe-area-inset-bottom)) or (bottom: env(safe-area-inset-bottom)) {
.mescroll-totop-safearea {
margin-bottom: calc(var(--window-bottom) + constant(safe-area-inset-bottom)); /* window-bottom + 适配 iPhoneX */
margin-bottom: calc(var(--window-bottom) + env(safe-area-inset-bottom));
}
}
/* 显示 -- 淡入 */
.mescroll-totop-in {
opacity: 1;
}
/* 隐藏 -- 淡出且不接收事件*/
.mescroll-totop-out {
opacity: 0;
pointer-events: none;
}
</style>

@ -0,0 +1,47 @@
/* 上拉加载区域 */
.mescroll-upwarp {
box-sizing: border-box;
min-height: 110rpx;
padding: 30rpx 0;
text-align: center;
clear: both;
}
/*提示文本 */
.mescroll-upwarp .upwarp-tip,
.mescroll-upwarp .upwarp-nodata {
display: inline-block;
font-size: 28rpx;
vertical-align: middle;
/* color: gray; 已在style设置color,此处删去*/
}
.mescroll-upwarp .upwarp-tip {
margin-left: 16rpx;
}
/*旋转进度条 */
.mescroll-upwarp .upwarp-progress {
display: inline-block;
width: 32rpx;
height: 32rpx;
border-radius: 50%;
border: 2rpx solid gray;
border-bottom-color: transparent !important; /*已在style设置border-color,此处需加 !important*/
vertical-align: middle;
}
/* 旋转动画 */
.mescroll-upwarp .mescroll-rotate {
animation: mescrollUpRotate 0.6s linear infinite;
}
@keyframes mescrollUpRotate {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}

@ -0,0 +1,39 @@
<!-- 上拉加载区域 -->
<template>
<view class="mescroll-upwarp" :style="{'background-color':mOption.bgColor,'color':mOption.textColor}">
<!-- 加载中 (此处不能用v-if,否则android小程序快速上拉可能会不断触发上拉回调) -->
<view v-show="isUpLoading">
<view class="upwarp-progress mescroll-rotate" :style="{'border-color':mOption.textColor}"></view>
<view class="upwarp-tip">{{ mOption.textLoading }}</view>
</view>
<!-- 无数据 -->
<view v-if="isUpNoMore" class="upwarp-nodata">{{ mOption.textNoMore }}</view>
</view>
</template>
<script>
export default {
props: {
option: Object, // up
type: Number // 0loading1loading2
},
computed: {
// ,propdefault
mOption() {
return this.option || {};
},
//
isUpLoading() {
return this.type === 1;
},
//
isUpNoMore() {
return this.type === 2;
}
}
};
</script>
<style>
@import './mescroll-up.css';
</style>

@ -0,0 +1,15 @@
// 国际化工具类
const mescrollI18n = {
// 默认语言
def: "zh",
// 获取当前语言类型
getType(){
return uni.getStorageSync("mescroll-i18n") || this.def
},
// 设置当前语言类型
setType(type){
uni.setStorageSync("mescroll-i18n", type)
}
}
export default mescrollI18n

@ -0,0 +1,46 @@
// mescroll-body 和 mescroll-uni 通用
const MescrollMixin = {
data() {
return {
mescroll: null //mescroll实例对象
}
},
// 注册系统自带的下拉刷新 (配置down.native为true时生效, 还需在pages配置enablePullDownRefresh:true;详请参考mescroll-native的案例)
onPullDownRefresh(){
this.mescroll && this.mescroll.onPullDownRefresh();
},
// 注册列表滚动事件,用于判定在顶部可下拉刷新,在指定位置可显示隐藏回到顶部按钮 (此方法为页面生命周期,无法在子组件中触发, 仅在mescroll-body生效)
onPageScroll(e) {
this.mescroll && this.mescroll.onPageScroll(e);
},
// 注册滚动到底部的事件,用于上拉加载 (此方法为页面生命周期,无法在子组件中触发, 仅在mescroll-body生效)
onReachBottom() {
this.mescroll && this.mescroll.onReachBottom();
},
methods: {
// mescroll组件初始化的回调,可获取到mescroll对象
mescrollInit(mescroll) {
this.mescroll = mescroll;
},
// 下拉刷新的回调 (mixin默认resetUpScroll)
downCallback() {
if(this.mescroll.optUp.use){
this.mescroll.resetUpScroll()
}else{
setTimeout(()=>{
this.mescroll.endSuccess();
}, 500)
}
},
// 上拉加载的回调
upCallback() {
// mixin默认延时500自动结束加载
setTimeout(()=>{
this.mescroll.endErr();
}, 500)
}
}
}
export default MescrollMixin;

@ -0,0 +1,64 @@
// 全局配置
// mescroll-body 和 mescroll-uni 通用
const GlobalOption = {
down: {
// 其他down的配置参数也可以写,这里只展示了常用的配置:
offset: 80, // 在列表顶部,下拉大于80px,松手即可触发下拉刷新的回调
native: false // 是否使用系统自带的下拉刷新; 默认false; 仅在mescroll-body生效 (值为true时,还需在pages配置enablePullDownRefresh:true;详请参考mescroll-native的案例)
},
up: {
// 其他up的配置参数也可以写,这里只展示了常用的配置:
offset: 150, // 距底部多远时,触发upCallback,仅mescroll-uni生效 ( mescroll-body配置的是pages.json的 onReachBottomDistance )
toTop: {
// 回到顶部按钮,需配置src才显示
src: "https://www.mescroll.com/img/mescroll-totop.png", // 图片路径 (建议放入static目录, 如 /static/img/mescroll-totop.png )
offset: 1000, // 列表滚动多少距离才显示回到顶部按钮,默认1000px
right: 20, // 到右边的距离, 默认20 (支持"20rpx", "20px", "20%"格式的值, 纯数字则默认单位rpx)
bottom: 120, // 到底部的距离, 默认120 (支持"20rpx", "20px", "20%"格式的值, 纯数字则默认单位rpx)
width: 72 // 回到顶部图标的宽度, 默认72 (支持"20rpx", "20px", "20%"格式的值, 纯数字则默认单位rpx)
},
empty: {
use: true, // 是否显示空布局
icon: "https://www.mescroll.com/img/mescroll-empty.png" // 图标路径 (建议放入static目录, 如 /static/img/mescroll-empty.png )
}
},
// 国际化配置
i18n: {
// 中文
zh: {
down: {
textInOffset: '下拉刷新', // 下拉的距离在offset范围内的提示文本
textOutOffset: '释放更新', // 下拉的距离大于offset范围的提示文本
textLoading: '加载中 ...', // 加载中的提示文本
textSuccess: '加载成功', // 加载成功的文本
textErr: '加载失败', // 加载失败的文本
},
up: {
textLoading: '加载中 ...', // 加载中的提示文本
textNoMore: '-- END --', // 没有更多数据的提示文本
empty: {
tip: '~ 空空如也 ~' // 空提示
}
}
},
// 英文
en: {
down: {
textInOffset: 'drop down refresh',
textOutOffset: 'release updates',
textLoading: 'loading ...',
textSuccess: 'loaded successfully',
textErr: 'loading failed'
},
up: {
textLoading: 'loading ...',
textNoMore: '-- END --',
empty: {
tip: '~ absolutely empty ~'
}
}
}
}
}
export default GlobalOption

@ -0,0 +1,36 @@
.mescroll-uni-warp{
height: 100%;
}
.mescroll-uni-content{
height: 100%;
}
.mescroll-uni {
position: relative;
width: 100%;
height: 100%;
min-height: 200rpx;
overflow-y: auto;
box-sizing: border-box; /* 避免设置padding出现双滚动条的问题 */
}
/* 定位的方式固定高度 */
.mescroll-uni-fixed{
z-index: 1;
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
width: auto; /* 使right生效 */
height: auto; /* 使bottom生效 */
}
/* 适配 iPhoneX */
@supports (bottom: constant(safe-area-inset-bottom)) or (bottom: env(safe-area-inset-bottom)) {
.mescroll-safearea {
padding-bottom: constant(safe-area-inset-bottom);
padding-bottom: env(safe-area-inset-bottom);
}
}

@ -0,0 +1,799 @@
/* mescroll
* version 1.3.7
* 2021-04-12 wenju
* https://www.mescroll.com
*/
export default function MeScroll(options, isScrollBody) {
let me = this;
me.version = '1.3.7'; // mescroll版本号
me.options = options || {}; // 配置
me.isScrollBody = isScrollBody || false; // 滚动区域是否为原生页面滚动; 默认为scroll-view
me.isDownScrolling = false; // 是否在执行下拉刷新的回调
me.isUpScrolling = false; // 是否在执行上拉加载的回调
let hasDownCallback = me.options.down && me.options.down.callback; // 是否配置了down的callback
// 初始化下拉刷新
me.initDownScroll();
// 初始化上拉加载,则初始化
me.initUpScroll();
// 自动加载
setTimeout(function() { // 待主线程执行完毕再执行,避免new MeScroll未初始化,在回调获取不到mescroll的实例
// 自动触发下拉刷新 (只有配置了down的callback才自动触发下拉刷新)
if ((me.optDown.use || me.optDown.native) && me.optDown.auto && hasDownCallback) {
if (me.optDown.autoShowLoading) {
me.triggerDownScroll(); // 显示下拉进度,执行下拉回调
} else {
me.optDown.callback && me.optDown.callback(me); // 不显示下拉进度,直接执行下拉回调
}
}
// 自动触发上拉加载
if(!me.isUpAutoLoad){ // 部分小程序(头条小程序)emit是异步, 会导致isUpAutoLoad判断有误, 先延时确保先执行down的callback,再执行up的callback
setTimeout(function(){
me.optUp.use && me.optUp.auto && !me.isUpAutoLoad && me.triggerUpScroll();
},100)
}
}, 30); // 需让me.optDown.inited和me.optUp.inited先执行
}
/* 配置参数:下拉刷新 */
MeScroll.prototype.extendDownScroll = function(optDown) {
// 下拉刷新的配置
MeScroll.extend(optDown, {
use: true, // 是否启用下拉刷新; 默认true
auto: true, // 是否在初始化完毕之后自动执行下拉刷新的回调; 默认true
native: false, // 是否使用系统自带的下拉刷新; 默认false; 仅mescroll-body生效 (值为true时,还需在pages配置enablePullDownRefresh:true;详请参考mescroll-native的案例)
autoShowLoading: false, // 如果设置auto=true(在初始化完毕之后自动执行下拉刷新的回调),那么是否显示下拉刷新的进度; 默认false
isLock: false, // 是否锁定下拉刷新,默认false;
offset: 80, // 在列表顶部,下拉大于80px,松手即可触发下拉刷新的回调
startTop: 100, // scroll-view快速滚动到顶部时,此时的scroll-top可能大于0, 此值用于控制最大的误差
inOffsetRate: 1, // 在列表顶部,下拉的距离小于offset时,改变下拉区域高度比例;值小于1且越接近0,高度变化越小,表现为越往下越难拉
outOffsetRate: 0.2, // 在列表顶部,下拉的距离大于offset时,改变下拉区域高度比例;值小于1且越接近0,高度变化越小,表现为越往下越难拉
bottomOffset: 20, // 当手指touchmove位置在距离body底部20px范围内的时候结束上拉刷新,避免Webview嵌套导致touchend事件不执行
minAngle: 45, // 向下滑动最少偏移的角度,取值区间 [0,90];默认45度,即向下滑动的角度大于45度则触发下拉;而小于45度,将不触发下拉,避免与左右滑动的轮播等组件冲突;
textInOffset: '下拉刷新', // 下拉的距离在offset范围内的提示文本
textOutOffset: '释放更新', // 下拉的距离大于offset范围的提示文本
textLoading: '加载中 ...', // 加载中的提示文本
textSuccess: '加载成功', // 加载成功的文本
textErr: '加载失败', // 加载失败的文本
beforeEndDelay: 0, // 延时结束的时长 (显示加载成功/失败的时长, android小程序设置此项结束下拉会卡顿, 配置后请注意测试)
bgColor: "transparent", // 背景颜色 (建议在pages.json中再设置一下backgroundColorTop)
textColor: "gray", // 文本颜色 (当bgColor配置了颜色,而textColor未配置时,则textColor会默认为白色)
inited: null, // 下拉刷新初始化完毕的回调
inOffset: null, // 下拉的距离进入offset范围内那一刻的回调
outOffset: null, // 下拉的距离大于offset那一刻的回调
onMoving: null, // 下拉过程中的回调,滑动过程一直在执行; rate下拉区域当前高度与指定距离的比值(inOffset: rate<1; outOffset: rate>=1); downHight当前下拉区域的高度
beforeLoading: null, // 准备触发下拉刷新的回调: 如果return true,将不触发showLoading和callback回调; 常用来完全自定义下拉刷新, 参考案例【淘宝 v6.8.0】
showLoading: null, // 显示下拉刷新进度的回调
afterLoading: null, // 显示下拉刷新进度的回调之后,马上要执行的代码 (如: 在wxs中使用)
beforeEndDownScroll: null, // 准备结束下拉的回调. 返回结束下拉的延时执行时间,默认0ms; 常用于结束下拉之前再显示另外一小段动画,才去隐藏下拉刷新的场景, 参考案例【dotJump】
endDownScroll: null, // 结束下拉刷新的回调
afterEndDownScroll: null, // 结束下拉刷新的回调,马上要执行的代码 (如: 在wxs中使用)
callback: function(mescroll) {
// 下拉刷新的回调;默认重置上拉加载列表为第一页
mescroll.resetUpScroll();
}
})
}
/* 配置参数:上拉加载 */
MeScroll.prototype.extendUpScroll = function(optUp) {
// 上拉加载的配置
MeScroll.extend(optUp, {
use: true, // 是否启用上拉加载; 默认true
auto: true, // 是否在初始化完毕之后自动执行上拉加载的回调; 默认true
isLock: false, // 是否锁定上拉加载,默认false;
isBoth: true, // 上拉加载时,如果滑动到列表顶部是否可以同时触发下拉刷新;默认true,两者可同时触发;
callback: null, // 上拉加载的回调;function(page,mescroll){ }
page: {
num: 0, // 当前页码,默认0,回调之前会加1,即callback(page)会从1开始
size: 10, // 每页数据的数量
time: null // 加载第一页数据服务器返回的时间; 防止用户翻页时,后台新增了数据从而导致下一页数据重复;
},
noMoreSize: 5, // 如果列表已无数据,可设置列表的总数量要大于等于5条才显示无更多数据;避免列表数据过少(比如只有一条数据),显示无更多数据会不好看
offset: 150, // 距底部多远时,触发upCallback,仅mescroll-uni生效 ( mescroll-body配置的是pages.json的 onReachBottomDistance )
textLoading: '加载中 ...', // 加载中的提示文本
textNoMore: '-- END --', // 没有更多数据的提示文本
bgColor: "transparent", // 背景颜色 (建议在pages.json中再设置一下backgroundColorBottom)
textColor: "gray", // 文本颜色 (当bgColor配置了颜色,而textColor未配置时,则textColor会默认为白色)
inited: null, // 初始化完毕的回调
showLoading: null, // 显示加载中的回调
showNoMore: null, // 显示无更多数据的回调
hideUpScroll: null, // 隐藏上拉加载的回调
errDistance: 60, // endErr的时候需往上滑动一段距离,使其往下滑动时再次触发onReachBottom,仅mescroll-body生效
toTop: {
// 回到顶部按钮,需配置src才显示
src: null, // 图片路径,默认null (绝对路径或网络图)
offset: 1000, // 列表滚动多少距离才显示回到顶部按钮,默认1000
duration: 300, // 回到顶部的动画时长,默认300ms (当值为0或300则使用系统自带回到顶部,更流畅; 其他值则通过step模拟,部分机型可能不够流畅,所以非特殊情况不建议修改此项)
btnClick: null, // 点击按钮的回调
onShow: null, // 是否显示的回调
zIndex: 9990, // fixed定位z-index值
left: null, // 到左边的距离, 默认null. 此项有值时,right不生效. (支持20, "20rpx", "20px", "20%"格式的值, 其中纯数字则默认单位rpx)
right: 20, // 到右边的距离, 默认20 (支持20, "20rpx", "20px", "20%"格式的值, 其中纯数字则默认单位rpx)
bottom: 120, // 到底部的距离, 默认120 (支持20, "20rpx", "20px", "20%"格式的值, 其中纯数字则默认单位rpx)
safearea: false, // bottom的偏移量是否加上底部安全区的距离, 默认false, 需要适配iPhoneX时使用 (具体的界面如果不配置此项,则取本vue的safearea值)
width: 72, // 回到顶部图标的宽度, 默认72 (支持20, "20rpx", "20px", "20%"格式的值, 其中纯数字则默认单位rpx)
radius: "50%" // 圆角, 默认"50%" (支持20, "20rpx", "20px", "20%"格式的值, 其中纯数字则默认单位rpx)
},
empty: {
use: true, // 是否显示空布局
icon: null, // 图标路径
tip: '~ 暂无相关数据 ~', // 提示
btnText: '', // 按钮
btnClick: null, // 点击按钮的回调
onShow: null, // 是否显示的回调
fixed: false, // 是否使用fixed定位,默认false; 配置fixed为true,以下的top和zIndex才生效 (transform会使fixed失效,最终会降级为absolute)
top: "100rpx", // fixed定位的top值 (完整的单位值,如 "10%"; "100rpx")
zIndex: 99 // fixed定位z-index值
},
onScroll: false // 是否监听滚动事件
})
}
/* 配置参数 */
MeScroll.extend = function(userOption, defaultOption) {
if (!userOption) return defaultOption;
for (let key in defaultOption) {
if (userOption[key] == null) {
let def = defaultOption[key];
if (def != null && typeof def === 'object') {
userOption[key] = MeScroll.extend({}, def); // 深度匹配
} else {
userOption[key] = def;
}
} else if (typeof userOption[key] === 'object') {
MeScroll.extend(userOption[key], defaultOption[key]); // 深度匹配
}
}
return userOption;
}
/* 简单判断是否配置了颜色 (非透明,非白色) */
MeScroll.prototype.hasColor = function(color) {
if(!color) return false;
let c = color.toLowerCase();
return c != "#fff" && c != "#ffffff" && c != "transparent" && c != "white"
}
/* -------初始化下拉刷新------- */
MeScroll.prototype.initDownScroll = function() {
let me = this;
// 配置参数
me.optDown = me.options.down || {};
if(!me.optDown.textColor && me.hasColor(me.optDown.bgColor)) me.optDown.textColor = "#fff"; // 当bgColor有值且textColor未设置,则textColor默认白色
me.extendDownScroll(me.optDown);
// 如果是mescroll-body且配置了native,则禁止自定义的下拉刷新
if(me.isScrollBody && me.optDown.native){
me.optDown.use = false
}else{
me.optDown.native = false // 仅mescroll-body支持,mescroll-uni不支持
}
me.downHight = 0; // 下拉区域的高度
// 在页面中加入下拉布局
if (me.optDown.use && me.optDown.inited) {
// 初始化完毕的回调
setTimeout(function() { // 待主线程执行完毕再执行,避免new MeScroll未初始化,在回调获取不到mescroll的实例
me.optDown.inited(me);
}, 0)
}
}
/* 列表touchstart事件 */
MeScroll.prototype.touchstartEvent = function(e) {
if (!this.optDown.use) return;
this.startPoint = this.getPoint(e); // 记录起点
this.startTop = this.getScrollTop(); // 记录此时的滚动条位置
this.startAngle = 0; // 初始角度
this.lastPoint = this.startPoint; // 重置上次move的点
this.maxTouchmoveY = this.getBodyHeight() - this.optDown.bottomOffset; // 手指触摸的最大范围(写在touchstart避免body获取高度为0的情况)
this.inTouchend = false; // 标记不是touchend
}
/* 列表touchmove事件 */
MeScroll.prototype.touchmoveEvent = function(e) {
if (!this.optDown.use) return;
let me = this;
let scrollTop = me.getScrollTop(); // 当前滚动条的距离
let curPoint = me.getPoint(e); // 当前点
let moveY = curPoint.y - me.startPoint.y; // 和起点比,移动的距离,大于0向下拉,小于0向上拉
// 向下拉 && 在顶部
// mescroll-body,直接判定在顶部即可
// scroll-view在滚动时不会触发touchmove,当触顶/底/左/右时,才会触发touchmove
// scroll-view滚动到顶部时,scrollTop不一定为0,也有可能大于0; 在iOS的APP中scrollTop可能为负数,不一定和startTop相等
if (moveY > 0 && (
(me.isScrollBody && scrollTop <= 0)
||
(!me.isScrollBody && (scrollTop <= 0 || (scrollTop <= me.optDown.startTop && scrollTop === me.startTop)) )
)) {
// 可下拉的条件
if (!me.inTouchend && !me.isDownScrolling && !me.optDown.isLock && (!me.isUpScrolling || (me.isUpScrolling &&
me.optUp.isBoth))) {
// 下拉的初始角度是否在配置的范围内
if(!me.startAngle) me.startAngle = me.getAngle(me.lastPoint, curPoint); // 两点之间的角度,区间 [0,90]
if (me.startAngle < me.optDown.minAngle) return; // 如果小于配置的角度,则不往下执行下拉刷新
// 如果手指的位置超过配置的距离,则提前结束下拉,避免Webview嵌套导致touchend无法触发
if (me.maxTouchmoveY > 0 && curPoint.y >= me.maxTouchmoveY) {
me.inTouchend = true; // 标记执行touchend
me.touchendEvent(); // 提前触发touchend
return;
}
me.preventDefault(e); // 阻止默认事件
let diff = curPoint.y - me.lastPoint.y; // 和上次比,移动的距离 (大于0向下,小于0向上)
// 下拉距离 < 指定距离
if (me.downHight < me.optDown.offset) {
if (me.movetype !== 1) {
me.movetype = 1; // 加入标记,保证只执行一次
me.isDownEndSuccess = null; // 重置是否加载成功的状态 (wxs执行的是wxs.wxs)
me.optDown.inOffset && me.optDown.inOffset(me); // 进入指定距离范围内那一刻的回调,只执行一次
me.isMoveDown = true; // 标记下拉区域高度改变,在touchend重置回来
}
me.downHight += diff * me.optDown.inOffsetRate; // 越往下,高度变化越小
// 指定距离 <= 下拉距离
} else {
if (me.movetype !== 2) {
me.movetype = 2; // 加入标记,保证只执行一次
me.optDown.outOffset && me.optDown.outOffset(me); // 下拉超过指定距离那一刻的回调,只执行一次
me.isMoveDown = true; // 标记下拉区域高度改变,在touchend重置回来
}
if (diff > 0) { // 向下拉
me.downHight += diff * me.optDown.outOffsetRate; // 越往下,高度变化越小
} else { // 向上收
me.downHight += diff; // 向上收回高度,则向上滑多少收多少高度
}
}
me.downHight = Math.round(me.downHight) // 取整
let rate = me.downHight / me.optDown.offset; // 下拉区域当前高度与指定距离的比值
me.optDown.onMoving && me.optDown.onMoving(me, rate, me.downHight); // 下拉过程中的回调,一直在执行
}
}
me.lastPoint = curPoint; // 记录本次移动的点
}
/* 列表touchend事件 */
MeScroll.prototype.touchendEvent = function(e) {
if (!this.optDown.use) return;
// 如果下拉区域高度已改变,则需重置回来
if (this.isMoveDown) {
if (this.downHight >= this.optDown.offset) {
// 符合触发刷新的条件
this.triggerDownScroll();
} else {
// 不符合的话 则重置
this.downHight = 0;
this.endDownScrollCall(this);
}
this.movetype = 0;
this.isMoveDown = false;
} else if (!this.isScrollBody && this.getScrollTop() === this.startTop) { // scroll-view到顶/左/右/底的滑动事件
let isScrollUp = this.getPoint(e).y - this.startPoint.y < 0; // 和起点比,移动的距离,大于0向下拉,小于0向上拉
// 上滑
if (isScrollUp) {
// 需检查滑动的角度
let angle = this.getAngle(this.getPoint(e), this.startPoint); // 两点之间的角度,区间 [0,90]
if (angle > 80) {
// 检查并触发上拉
this.triggerUpScroll(true);
}
}
}
}
/* 根据点击滑动事件获取第一个手指的坐标 */
MeScroll.prototype.getPoint = function(e) {
if (!e) {
return {
x: 0,
y: 0
}
}
if (e.touches && e.touches[0]) {
return {
x: e.touches[0].pageX,
y: e.touches[0].pageY
}
} else if (e.changedTouches && e.changedTouches[0]) {
return {
x: e.changedTouches[0].pageX,
y: e.changedTouches[0].pageY
}
} else {
return {
x: e.clientX,
y: e.clientY
}
}
}
/* 计算两点之间的角度: 区间 [0,90]*/
MeScroll.prototype.getAngle = function(p1, p2) {
let x = Math.abs(p1.x - p2.x);
let y = Math.abs(p1.y - p2.y);
let z = Math.sqrt(x * x + y * y);
let angle = 0;
if (z !== 0) {
angle = Math.asin(y / z) / Math.PI * 180;
}
return angle
}
/* 触发下拉刷新 */
MeScroll.prototype.triggerDownScroll = function() {
if (this.optDown.beforeLoading && this.optDown.beforeLoading(this)) {
//return true则处于完全自定义状态
} else {
this.showDownScroll(); // 下拉刷新中...
!this.optDown.native && this.optDown.callback && this.optDown.callback(this); // 执行回调,联网加载数据
}
}
/* 显示下拉进度布局 */
MeScroll.prototype.showDownScroll = function() {
this.isDownScrolling = true; // 标记下拉中
if (this.optDown.native) {
uni.startPullDownRefresh(); // 系统自带的下拉刷新
this.showDownLoadingCall(0); // 仍触发showLoading,因为上拉加载用到
} else{
this.downHight = this.optDown.offset; // 更新下拉区域高度
this.showDownLoadingCall(this.downHight); // 下拉刷新中...
}
}
MeScroll.prototype.showDownLoadingCall = function(downHight) {
this.optDown.showLoading && this.optDown.showLoading(this, downHight); // 下拉刷新中...
this.optDown.afterLoading && this.optDown.afterLoading(this, downHight); // 下拉刷新中...触发之后马上要执行的代码
}
/* 显示系统自带的下拉刷新时需要处理的业务 */
MeScroll.prototype.onPullDownRefresh = function() {
this.isDownScrolling = true; // 标记下拉中
this.showDownLoadingCall(0); // 仍触发showLoading,因为上拉加载用到
this.optDown.callback && this.optDown.callback(this); // 执行回调,联网加载数据
}
/* 结束下拉刷新 */
MeScroll.prototype.endDownScroll = function() {
if (this.optDown.native) { // 结束原生下拉刷新
this.isDownScrolling = false;
this.endDownScrollCall(this);
uni.stopPullDownRefresh();
return
}
let me = this;
// 结束下拉刷新的方法
let endScroll = function() {
me.downHight = 0;
me.isDownScrolling = false;
me.endDownScrollCall(me);
if(!me.isScrollBody){
me.setScrollHeight(0) // scroll-view重置滚动区域,使数据不满屏时仍可检查触发翻页
me.scrollTo(0,0) // scroll-view需重置滚动条到顶部,避免startTop大于0时,对下拉刷新的影响
}
}
// 结束下拉刷新时的回调
let delay = 0;
if (me.optDown.beforeEndDownScroll) {
delay = me.optDown.beforeEndDownScroll(me); // 结束下拉刷新的延时,单位ms
if(me.isDownEndSuccess == null) delay = 0; // 没有执行加载中,则不延时
}
if (typeof delay === 'number' && delay > 0) {
setTimeout(endScroll, delay);
} else {
endScroll();
}
}
MeScroll.prototype.endDownScrollCall = function() {
this.optDown.endDownScroll && this.optDown.endDownScroll(this);
this.optDown.afterEndDownScroll && this.optDown.afterEndDownScroll(this);
}
/* 锁定下拉刷新:isLock=ture,null锁定;isLock=false解锁 */
MeScroll.prototype.lockDownScroll = function(isLock) {
if (isLock == null) isLock = true;
this.optDown.isLock = isLock;
}
/* 锁定上拉加载:isLock=ture,null锁定;isLock=false解锁 */
MeScroll.prototype.lockUpScroll = function(isLock) {
if (isLock == null) isLock = true;
this.optUp.isLock = isLock;
}
/* -------初始化上拉加载------- */
MeScroll.prototype.initUpScroll = function() {
let me = this;
// 配置参数
me.optUp = me.options.up || {use: false}
if(!me.optUp.textColor && me.hasColor(me.optUp.bgColor)) me.optUp.textColor = "#fff"; // 当bgColor有值且textColor未设置,则textColor默认白色
me.extendUpScroll(me.optUp);
if (me.optUp.use === false) return; // 配置不使用上拉加载时,则不初始化上拉布局
me.optUp.hasNext = true; // 如果使用上拉,则默认有下一页
me.startNum = me.optUp.page.num + 1; // 记录page开始的页码
// 初始化完毕的回调
if (me.optUp.inited) {
setTimeout(function() { // 待主线程执行完毕再执行,避免new MeScroll未初始化,在回调获取不到mescroll的实例
me.optUp.inited(me);
}, 0)
}
}
/*滚动到底部的事件 (仅mescroll-body生效)*/
MeScroll.prototype.onReachBottom = function() {
if (this.isScrollBody && !this.isUpScrolling) { // 只能支持下拉刷新的时候同时可以触发上拉加载,否则滚动到底部就需要上滑一点才能触发onReachBottom
if (!this.optUp.isLock && this.optUp.hasNext) {
this.triggerUpScroll();
}
}
}
/*列表滚动事件 (仅mescroll-body生效)*/
MeScroll.prototype.onPageScroll = function(e) {
if (!this.isScrollBody) return;
// 更新滚动条的位置 (主要用于判断下拉刷新时,滚动条是否在顶部)
this.setScrollTop(e.scrollTop);
// 顶部按钮的显示隐藏
if (e.scrollTop >= this.optUp.toTop.offset) {
this.showTopBtn();
} else {
this.hideTopBtn();
}
}
/*列表滚动事件*/
MeScroll.prototype.scroll = function(e, onScroll) {
// 更新滚动条的位置
this.setScrollTop(e.scrollTop);
// 更新滚动内容高度
this.setScrollHeight(e.scrollHeight);
// 向上滑还是向下滑动
if (this.preScrollY == null) this.preScrollY = 0;
this.isScrollUp = e.scrollTop - this.preScrollY > 0;
this.preScrollY = e.scrollTop;
// 上滑 && 检查并触发上拉
this.isScrollUp && this.triggerUpScroll(true);
// 顶部按钮的显示隐藏
if (e.scrollTop >= this.optUp.toTop.offset) {
this.showTopBtn();
} else {
this.hideTopBtn();
}
// 滑动监听
this.optUp.onScroll && onScroll && onScroll()
}
/* 触发上拉加载 */
MeScroll.prototype.triggerUpScroll = function(isCheck) {
if (!this.isUpScrolling && this.optUp.use && this.optUp.callback) {
// 是否校验在底部; 默认不校验
if (isCheck === true) {
let canUp = false;
// 还有下一页 && 没有锁定 && 不在下拉中
if (this.optUp.hasNext && !this.optUp.isLock && !this.isDownScrolling) {
if (this.getScrollBottom() <= this.optUp.offset) { // 到底部
canUp = true; // 标记可上拉
}
}
if (canUp === false) return;
}
this.showUpScroll(); // 上拉加载中...
this.optUp.page.num++; // 预先加一页,如果失败则减回
this.isUpAutoLoad = true; // 标记上拉已经自动执行过,避免初始化时多次触发上拉回调
this.num = this.optUp.page.num; // 把最新的页数赋值在mescroll上,避免对page的影响
this.size = this.optUp.page.size; // 把最新的页码赋值在mescroll上,避免对page的影响
this.time = this.optUp.page.time; // 把最新的页码赋值在mescroll上,避免对page的影响
this.optUp.callback(this); // 执行回调,联网加载数据
}
}
/* 显示上拉加载中 */
MeScroll.prototype.showUpScroll = function() {
this.isUpScrolling = true; // 标记上拉加载中
this.optUp.showLoading && this.optUp.showLoading(this); // 回调
}
/* 显示上拉无更多数据 */
MeScroll.prototype.showNoMore = function() {
this.optUp.hasNext = false; // 标记无更多数据
this.optUp.showNoMore && this.optUp.showNoMore(this); // 回调
}
/* 隐藏上拉区域**/
MeScroll.prototype.hideUpScroll = function() {
this.optUp.hideUpScroll && this.optUp.hideUpScroll(this); // 回调
}
/* 结束上拉加载 */
MeScroll.prototype.endUpScroll = function(isShowNoMore) {
if (isShowNoMore != null) { // isShowNoMore=null,不处理下拉状态,下拉刷新的时候调用
if (isShowNoMore) {
this.showNoMore(); // isShowNoMore=true,显示无更多数据
} else {
this.hideUpScroll(); // isShowNoMore=false,隐藏上拉加载
}
}
this.isUpScrolling = false; // 标记结束上拉加载
}
/*
*isShowLoading 是否显示进度布局;
* 1.默认null,不传参,则显示上拉加载的进度布局
* 2.传参true, 则显示下拉刷新的进度布局
* 3.传参false,则不显示上拉和下拉的进度 (常用于静默更新列表数据)
*/
MeScroll.prototype.resetUpScroll = function(isShowLoading) {
if (this.optUp && this.optUp.use) {
let page = this.optUp.page;
this.prePageNum = page.num; // 缓存重置前的页码,加载失败可退回
this.prePageTime = page.time; // 缓存重置前的时间,加载失败可退回
page.num = this.startNum; // 重置为第一页
page.time = null; // 重置时间为空
if (!this.isDownScrolling && isShowLoading !== false) { // 如果不是下拉刷新触发的resetUpScroll并且不配置列表静默更新,则显示进度;
if (isShowLoading == null) {
this.removeEmpty(); // 移除空布局
this.showUpScroll(); // 不传参,默认显示上拉加载的进度布局
} else {
this.showDownScroll(); // 传true,显示下拉刷新的进度布局,不清空列表
}
}
this.isUpAutoLoad = true; // 标记上拉已经自动执行过,避免初始化时多次触发上拉回调
this.num = page.num; // 把最新的页数赋值在mescroll上,避免对page的影响
this.size = page.size; // 把最新的页码赋值在mescroll上,避免对page的影响
this.time = page.time; // 把最新的页码赋值在mescroll上,避免对page的影响
this.optUp.callback && this.optUp.callback(this); // 执行上拉回调
}
}
/* 设置page.num的值 */
MeScroll.prototype.setPageNum = function(num) {
this.optUp.page.num = num - 1;
}
/* 设置page.size的值 */
MeScroll.prototype.setPageSize = function(size) {
this.optUp.page.size = size;
}
/* ,
* dataSize: 当前页的数据量(必传)
* totalPage: 总页数(必传)
* systime: 服务器时间 (可空)
*/
MeScroll.prototype.endByPage = function(dataSize, totalPage, systime) {
let hasNext;
if (this.optUp.use && totalPage != null) hasNext = this.optUp.page.num < totalPage; // 是否还有下一页
this.endSuccess(dataSize, hasNext, systime);
}
/* ,
* dataSize: 当前页的数据量(必传)
* totalSize: 列表所有数据总数量(必传)
* systime: 服务器时间 (可空)
*/
MeScroll.prototype.endBySize = function(dataSize, totalSize, systime) {
let hasNext;
if (this.optUp.use && totalSize != null) {
let loadSize = (this.optUp.page.num - 1) * this.optUp.page.size + dataSize; // 已加载的数据总数
hasNext = loadSize < totalSize; // 是否还有下一页
}
this.endSuccess(dataSize, hasNext, systime);
}
/* ,
* dataSize: 当前页的数据个数(不是所有页的数据总和),用于上拉加载判断是否还有下一页.如果不传,则会判断还有下一页
* hasNext: 是否还有下一页,布尔类型;用来解决这个小问题:比如列表共有20条数据,每页加载10条,共2页.如果只根据dataSize判断,则需翻到第三页才会知道无更多数据,如果传了hasNext,则翻到第二页即可显示无更多数据.
* systime: 服务器时间(可空);用来解决这个小问题:当准备翻下一页时,数据库新增了几条记录,此时翻下一页,前面的几条数据会和上一页的重复;这里传入了systime,那么upCallback的page.time就会有值,把page.time传给服务器,让后台过滤新加入的那几条记录
*/
MeScroll.prototype.endSuccess = function(dataSize, hasNext, systime) {
let me = this;
// 结束下拉刷新
if (me.isDownScrolling) {
me.isDownEndSuccess = true
me.endDownScroll();
}
// 结束上拉加载
if (me.optUp.use) {
let isShowNoMore; // 是否已无更多数据
if (dataSize != null) {
let pageNum = me.optUp.page.num; // 当前页码
let pageSize = me.optUp.page.size; // 每页长度
// 如果是第一页
if (pageNum === 1) {
if (systime) me.optUp.page.time = systime; // 设置加载列表数据第一页的时间
}
if (dataSize < pageSize || hasNext === false) {
// 返回的数据不满一页时,则说明已无更多数据
me.optUp.hasNext = false;
if (dataSize === 0 && pageNum === 1) {
// 如果第一页无任何数据且配置了空布局
isShowNoMore = false;
me.showEmpty();
} else {
// 总列表数少于配置的数量,则不显示无更多数据
let allDataSize = (pageNum - 1) * pageSize + dataSize;
if (allDataSize < me.optUp.noMoreSize) {
isShowNoMore = false;
} else {
isShowNoMore = true;
}
me.removeEmpty(); // 移除空布局
}
} else {
// 还有下一页
isShowNoMore = false;
me.optUp.hasNext = true;
me.removeEmpty(); // 移除空布局
}
}
// 隐藏上拉
me.endUpScroll(isShowNoMore);
}
}
/* 回调失败,结束下拉刷新和上拉加载 */
MeScroll.prototype.endErr = function(errDistance) {
// 结束下拉,回调失败重置回原来的页码和时间
if (this.isDownScrolling) {
this.isDownEndSuccess = false
let page = this.optUp.page;
if (page && this.prePageNum) {
page.num = this.prePageNum;
page.time = this.prePageTime;
}
this.endDownScroll();
}
// 结束上拉,回调失败重置回原来的页码
if (this.isUpScrolling) {
this.optUp.page.num--;
this.endUpScroll(false);
// 如果是mescroll-body,则需往回滚一定距离
if(this.isScrollBody && errDistance !== 0){ // 不处理0
if(!errDistance) errDistance = this.optUp.errDistance; // 不传,则取默认
this.scrollTo(this.getScrollTop() - errDistance, 0) // 往上回滚的距离
}
}
}
/* 显示空布局 */
MeScroll.prototype.showEmpty = function() {
this.optUp.empty.use && this.optUp.empty.onShow && this.optUp.empty.onShow(true)
}
/* 移除空布局 */
MeScroll.prototype.removeEmpty = function() {
this.optUp.empty.use && this.optUp.empty.onShow && this.optUp.empty.onShow(false)
}
/* 显示回到顶部的按钮 */
MeScroll.prototype.showTopBtn = function() {
if (!this.topBtnShow) {
this.topBtnShow = true;
this.optUp.toTop.onShow && this.optUp.toTop.onShow(true);
}
}
/* 隐藏回到顶部的按钮 */
MeScroll.prototype.hideTopBtn = function() {
if (this.topBtnShow) {
this.topBtnShow = false;
this.optUp.toTop.onShow && this.optUp.toTop.onShow(false);
}
}
/* 获取滚动条的位置 */
MeScroll.prototype.getScrollTop = function() {
return this.scrollTop || 0
}
/* 记录滚动条的位置 */
MeScroll.prototype.setScrollTop = function(y) {
this.scrollTop = y;
}
/* 滚动到指定位置 */
MeScroll.prototype.scrollTo = function(y, t) {
this.myScrollTo && this.myScrollTo(y, t) // scrollview需自定义回到顶部方法
}
/* 自定义scrollTo */
MeScroll.prototype.resetScrollTo = function(myScrollTo) {
this.myScrollTo = myScrollTo
}
/* 滚动条到底部的距离 */
MeScroll.prototype.getScrollBottom = function() {
return this.getScrollHeight() - this.getClientHeight() - this.getScrollTop()
}
/*
star: 开始值
end: 结束值
callback(step,timer): 回调step值,计步器timer,可自行通过window.clearInterval(timer)结束计步器;
t: 计步时长,传0则直接回调end值;不传则默认300ms
rate: 周期;不传则默认30ms计步一次
* */
MeScroll.prototype.getStep = function(star, end, callback, t, rate) {
let diff = end - star; // 差值
if (t === 0 || diff === 0) {
callback && callback(end);
return;
}
t = t || 300; // 时长 300ms
rate = rate || 30; // 周期 30ms
let count = t / rate; // 次数
let step = diff / count; // 步长
let i = 0; // 计数
let timer = setInterval(function() {
if (i < count - 1) {
star += step;
callback && callback(star, timer);
i++;
} else {
callback && callback(end, timer); // 最后一次直接设置end,避免计算误差
clearInterval(timer);
}
}, rate);
}
/* 滚动容器的高度 */
MeScroll.prototype.getClientHeight = function(isReal) {
let h = this.clientHeight || 0
if (h === 0 && isReal !== true) { // 未获取到容器的高度,可临时取body的高度 (可能会有误差)
h = this.getBodyHeight()
}
return h
}
MeScroll.prototype.setClientHeight = function(h) {
this.clientHeight = h;
}
/* 滚动内容的高度 */
MeScroll.prototype.getScrollHeight = function() {
return this.scrollHeight || 0;
}
MeScroll.prototype.setScrollHeight = function(h) {
this.scrollHeight = h;
}
/* body的高度 */
MeScroll.prototype.getBodyHeight = function() {
return this.bodyHeight || 0;
}
MeScroll.prototype.setBodyHeight = function(h) {
this.bodyHeight = h;
}
/* 阻止浏览器默认滚动事件 */
MeScroll.prototype.preventDefault = function(e) {
// 小程序不支持e.preventDefault, 已在wxs中禁止
// app的bounce只能通过配置pages.json的style.app-plus.bounce为"none"来禁止, 或使用renderjs禁止
// cancelable:是否可以被禁用; defaultPrevented:是否已经被禁用
if (e && e.cancelable && !e.defaultPrevented) e.preventDefault()
}

@ -0,0 +1,480 @@
<template>
<view class="mescroll-uni-warp">
<scroll-view :id="viewId" class="mescroll-uni" :class="{'mescroll-uni-fixed':isFixed}" :style="{'height':scrollHeight,'padding-top':padTop,'padding-bottom':padBottom,'top':fixedTop,'bottom':fixedBottom}" :scroll-top="scrollTop" :scroll-with-animation="scrollAnim" @scroll="scroll" :scroll-y='scrollable' :enable-back-to-top="true" :throttle="false">
<view class="mescroll-uni-content mescroll-render-touch"
@touchstart="wxsBiz.touchstartEvent"
@touchmove="wxsBiz.touchmoveEvent"
@touchend="wxsBiz.touchendEvent"
@touchcancel="wxsBiz.touchendEvent"
:change:prop="wxsBiz.propObserver"
:prop="wxsProp">
<!-- 状态栏 -->
<view v-if="topbar&&statusBarHeight" class="mescroll-topbar" :style="{height: statusBarHeight+'px', background: topbar}"></view>
<view class="mescroll-wxs-content" :style="{'transform': translateY, 'transition': transition}" :change:prop="wxsBiz.callObserver" :prop="callProp">
<!-- 下拉加载区域 (支付宝小程序子组件传参给子子组件仍报单项数据流的异常,暂时不通过mescroll-down组件实现)-->
<!-- <mescroll-down :option="mescroll.optDown" :type="downLoadType" :rate="downRate"></mescroll-down> -->
<view v-if="mescroll.optDown.use" class="mescroll-downwarp" :style="{'background':mescroll.optDown.bgColor,'color':mescroll.optDown.textColor}">
<view class="downwarp-content">
<view class="downwarp-progress mescroll-wxs-progress" :class="{'mescroll-rotate': isDownLoading}" :style="{'border-color':mescroll.optDown.textColor, 'transform': downRotate}"></view>
<view class="downwarp-tip">{{downText}}</view>
</view>
</view>
<!-- 列表内容 -->
<slot></slot>
<!-- 空布局 -->
<mescroll-empty v-if="isShowEmpty" :option="mescroll.optUp.empty" @emptyclick="emptyClick"></mescroll-empty>
<!-- 上拉加载区域 (下拉刷新时不显示, 支付宝小程序子组件传参给子子组件仍报单项数据流的异常,暂时不通过mescroll-up组件实现)-->
<!-- <mescroll-up v-if="mescroll.optUp.use && !isDownLoading && upLoadType!==3" :option="mescroll.optUp" :type="upLoadType"></mescroll-up> -->
<view v-if="mescroll.optUp.use && !isDownLoading && upLoadType!==3" class="mescroll-upwarp" :style="{'background':mescroll.optUp.bgColor,'color':mescroll.optUp.textColor}">
<!-- 加载中 (此处不能用v-if,否则android小程序快速上拉可能会不断触发上拉回调) -->
<view v-show="upLoadType===1">
<view class="upwarp-progress mescroll-rotate" :style="{'border-color':mescroll.optUp.textColor}"></view>
<view class="upwarp-tip">{{ mescroll.optUp.textLoading }}</view>
</view>
<!-- 无数据 -->
<view v-if="upLoadType===2" class="upwarp-nodata">{{ mescroll.optUp.textNoMore }}</view>
</view>
</view>
<!-- 底部是否偏移TabBar的高度(默认仅在H5端的tab页生效) -->
<!-- #ifdef H5 -->
<view v-if="bottombar && windowBottom>0" class="mescroll-bottombar" :style="{height: windowBottom+'px'}"></view>
<!-- #endif -->
<!-- 适配iPhoneX -->
<view v-if="safearea" class="mescroll-safearea"></view>
</view>
</scroll-view>
<!-- 回到顶部按钮 (fixed元素,需写在scroll-view外面,防止滚动的时候抖动)-->
<mescroll-top v-model="isShowToTop" :option="mescroll.optUp.toTop" @click="toTopClick"></mescroll-top>
<!-- #ifdef MP-WEIXIN || MP-QQ || APP-PLUS || H5 -->
<!-- renderjs的数据载体,不可写在mescroll-downwarp内部,避免use为false时,载体丢失,无法更新数据 -->
<view :change:prop="renderBiz.propObserver" :prop="wxsProp"></view>
<!-- #endif -->
</view>
</template>
<!-- 微信小程序, QQ小程序, app, h5使用wxs -->
<!-- #ifdef MP-WEIXIN || MP-QQ || APP-PLUS || H5 -->
<script src="./wxs/wxs.wxs" module="wxsBiz" lang="wxs"></script>
<!-- #endif -->
<!-- app, h5使用renderjs -->
<!-- #ifdef APP-PLUS || H5 -->
<script module="renderBiz" lang="renderjs">
import renderBiz from './wxs/renderjs.js';
export default {
mixins:[renderBiz]
}
</script>
<!-- #endif -->
<script>
// mescroll-uni.js,
import MeScroll from './mescroll-uni.js';
//
import GlobalOption from './mescroll-uni-option.js';
//
import mescrollI18n from './mescroll-i18n.js';
//
import MescrollTop from './components/mescroll-top.vue';
// wxs(renderjs)mixins
import WxsMixin from './wxs/mixins.js';
/**
* mescroll-uni 嵌在页面某个区域的下拉刷新和上拉加载组件, 如嵌在弹窗,浮层,swiper中...
* @property {Object} down 下拉刷新的参数配置
* @property {Object} up 上拉加载的参数配置
* @property {Object} i18n 国际化的参数配置
* @property {String, Number} top 下拉布局往下的偏移量 (支持20, "20rpx", "20px", "20%"格式的值, 其中纯数字则默认单位rpx, 百分比则相对于windowHeight)
* @property {Boolean, String} topbar 偏移量top是否加上状态栏高度, 默认false (使用场景:取消原生导航栏时,配置此项可留出状态栏的占位, 支持传入字符串背景,如色值,背景图,渐变)
* @property {String, Number} bottom 上拉布局往上的偏移量 (支持20, "20rpx", "20px", "20%"格式的值, 其中纯数字则默认单位rpx, 百分比则相对于windowHeight)
* @property {Boolean} safearea 偏移量bottom是否加上底部安全区的距离, 默认false (需要适配iPhoneX时使用)
* @property {Boolean} fixed 是否通过fixed固定mescroll的高度, 默认true
* @property {String, Number} height 指定mescroll的高度, 此项有值,则不使用fixed. (支持20, "20rpx", "20px", "20%"格式的值, 其中纯数字则默认单位rpx, 百分比则相对于windowHeight)
* @property {Boolean} bottombar 底部是否偏移TabBar的高度 (仅在H5端的tab页生效)
* @property {Boolean} disableScroll 是否禁止滚动, 默认false
* @event {Function} init 初始化完成的回调
* @event {Function} down 下拉刷新的回调
* @event {Function} up 上拉加载的回调
* @event {Function} emptyclick 点击empty配置的btnText按钮回调
* @event {Function} topclick 点击回到顶部的按钮回调
* @event {Function} scroll 滚动监听 (需在 up 配置 onScroll:true 才生效)
* @example <mescroll-uni @init="mescrollInit" @down="downCallback" @up="upCallback"> ... </mescroll-uni>
*/
export default {
name: 'mescroll-uni',
mixins: [WxsMixin],
components: {
MescrollTop
},
props: {
down: Object,
up: Object,
i18n: Object,
top: [String, Number],
topbar: [Boolean, String],
bottom: [String, Number],
safearea: Boolean,
fixed: {
type: Boolean,
default: true
},
height: [String, Number],
bottombar:{
type: Boolean,
default: true
},
disableScroll: Boolean
},
data() {
return {
mescroll: {optDown:{},optUp:{}}, // mescroll
viewId: 'id_' + Math.random().toString(36).substr(2,16), // mescrollid(,)
downHight: 0, //:
downRate: 0, // (inOffset: rate<1; outOffset: rate>=1)
downLoadType: 0, // : 0(loading), 1(inOffset), 2(outOffset), 3(showLoading), 4(endDownScroll)
upLoadType: 0, // : 0(loading), 1loading, 2,END, 3(,END)
isShowEmpty: false, //
isShowToTop: false, //
scrollTop: 0, //
scrollAnim: false, //
windowTop: 0, // 使
windowBottom: 0, // 使
windowHeight: 0, // 使
statusBarHeight: 0 //
}
},
watch: {
height() {
//
this.setClientHeight()
}
},
computed: {
// 使fixed (height,使)
isFixed(){
return !this.height && this.fixed
},
// mescroll
scrollHeight(){
if (this.isFixed) {
return "auto"
} else if(this.height){
return this.toPx(this.height) + 'px'
}else{
return "100%"
}
},
// (px)
numTop() {
return this.toPx(this.top)
},
fixedTop() {
return this.isFixed ? (this.numTop + this.windowTop) + 'px' : 0
},
padTop() {
return !this.isFixed ? this.numTop + 'px' : 0
},
// (px)
numBottom() {
return this.toPx(this.bottom)
},
fixedBottom() {
return this.isFixed ? (this.numBottom + this.windowBottom) + 'px' : 0
},
padBottom() {
return !this.isFixed ? this.numBottom + 'px' : 0
},
//
isDownReset(){
return this.downLoadType===3 || this.downLoadType===4
},
//
transition() {
return this.isDownReset ? 'transform 300ms' : '';
},
translateY() {
return this.downHight > 0 ? 'translateY(' + this.downHight + 'px)' : ''; // transform使fixed,fixedmescroll
},
//
scrollable(){
if(this.disableScroll) return false
return this.downLoadType===0 || this.isDownReset
},
//
isDownLoading(){
return this.downLoadType === 3
},
//
downRotate(){
return 'rotate(' + 360 * this.downRate + 'deg)'
},
//
downText(){
if(!this.mescroll) return ""; //
switch (this.downLoadType){
case 1: return this.mescroll.optDown.textInOffset;
case 2: return this.mescroll.optDown.textOutOffset;
case 3: return this.mescroll.optDown.textLoading;
case 4: return this.mescroll.isDownEndSuccess ? this.mescroll.optDown.textSuccess : this.mescroll.isDownEndSuccess==false ? this.mescroll.optDown.textErr : this.mescroll.optDown.textInOffset;
default: return this.mescroll.optDown.textInOffset;
}
}
},
methods: {
//number,rpx,upx,px,% --> px
toPx(num){
if(typeof num === "string"){
if (num.indexOf('px') !== -1) {
if(num.indexOf('rpx') !== -1) { // "10rpx"
num = num.replace('rpx', '');
} else if(num.indexOf('upx') !== -1) { // "10upx"
num = num.replace('upx', '');
} else { // "10px"
return Number(num.replace('px', ''))
}
}else if (num.indexOf('%') !== -1){
// ,windowHeight,"10%"windowHeight10%
let rate = Number(num.replace("%","")) / 100
return this.windowHeight * rate
}
}
return num ? uni.upx2px(Number(num)) : 0
},
//,
scroll(e) {
this.mescroll.scroll(e.detail, () => {
this.$emit('scroll', this.mescroll) // this.mescroll.scrollTop; this.mescroll.isScrollUp
})
},
//
emptyClick() {
this.$emit('emptyclick', this.mescroll)
},
//
toTopClick() {
this.mescroll.scrollTo(0, this.mescroll.optUp.toTop.duration); //
this.$emit('topclick', this.mescroll); //
},
// (使,)
setClientHeight() {
if (!this.isExec) {
this.isExec = true; //
this.$nextTick(() => { // dom
this.getClientInfo(data=>{
this.isExec = false;
if (data) {
this.mescroll.setClientHeight(data.height);
} else if (this.clientNum != 3) { // ,dom,,3
this.clientNum = this.clientNum == null ? 1 : this.clientNum + 1;
setTimeout(() => {
this.setClientHeight()
}, this.clientNum * 100)
}
})
})
}
},
//
getClientInfo(success){
let query = uni.createSelectorQuery().in(this);
let view = query.select('#' + this.viewId);
view.boundingClientRect(data => {
success(data)
}).exec();
}
},
// 使createdmescroll; mountedcssH5
created() {
let vm = this;
let diyOption = {
//
down: {
inOffset() {
vm.downLoadType = 1; // offset (mescroll,)
},
outOffset() {
vm.downLoadType = 2; // offset (mescroll,)
},
onMoving(mescroll, rate, downHight) {
// ,;
vm.downHight = downHight; // (mescroll,)
vm.downRate = rate; // (inOffset: rate<1; outOffset: rate>=1)
},
showLoading(mescroll, downHight) {
vm.downLoadType = 3; // (mescroll,)
vm.downHight = downHight; // (mescroll,)
},
beforeEndDownScroll(mescroll){
vm.downLoadType = 4;
return mescroll.optDown.beforeEndDelay //
},
endDownScroll() {
vm.downLoadType = 4; // (mescroll,)
vm.downHight = 0; // (mescroll,)
vm.downResetTimer && clearTimeout(vm.downResetTimer)
vm.downResetTimer = setTimeout(()=>{ // ,0,便this.transition,iOS
if(vm.downLoadType===4) vm.downLoadType = 0
},300)
},
//
callback: function(mescroll) {
vm.$emit('down', mescroll)
}
},
//
up: {
//
showLoading() {
vm.upLoadType = 1;
},
//
showNoMore() {
vm.upLoadType = 2;
},
//
hideUpScroll(mescroll) {
vm.upLoadType = mescroll.optUp.hasNext ? 0 : 3;
},
//
empty: {
onShow(isShow) { //
vm.isShowEmpty = isShow;
}
},
//
toTop: {
onShow(isShow) { //
vm.isShowToTop = isShow;
}
},
//
callback: function(mescroll) {
vm.$emit('up', mescroll);
// (mescroll)
vm.setClientHeight()
}
}
}
let i18nType = mescrollI18n.getType() //
let i18nOption = {type: i18nType} //
MeScroll.extend(i18nOption, vm.i18n) //
MeScroll.extend(i18nOption, GlobalOption.i18n) //
MeScroll.extend(diyOption, i18nOption[i18nType]); //
MeScroll.extend(diyOption, {down:GlobalOption.down, up:GlobalOption.up}); //
let myOption = JSON.parse(JSON.stringify({'down': vm.down,'up': vm.up})) // ,props
MeScroll.extend(myOption, diyOption); //
// MeScroll
vm.mescroll = new MeScroll(myOption);
vm.mescroll.viewId = vm.viewId; // id
vm.mescroll.i18n = i18nOption; //
// initmescroll
vm.$emit('init', vm.mescroll);
//
const sys = uni.getSystemInfoSync();
if(sys.windowTop) vm.windowTop = sys.windowTop;
if(sys.windowBottom) vm.windowBottom = sys.windowBottom;
if(sys.windowHeight) vm.windowHeight = sys.windowHeight;
if(sys.statusBarHeight) vm.statusBarHeight = sys.statusBarHeight;
// 使downbottomOffset
vm.mescroll.setBodyHeight(sys.windowHeight);
// 使scrollview,scrollTo
vm.mescroll.resetScrollTo((y, t) => {
vm.scrollAnim = (t !== 0); // t0,使
if(typeof y === 'string'){
// slotscroll-into-view, 使
vm.getClientInfo(function(rect){
let mescrollTop = rect.top // mescroll
let selector;
if(y.indexOf('#')==-1 && y.indexOf('.')==-1){
selector = '#'+y // #. id
}else{
selector = y
// #ifdef APP-PLUS || H5 || MP-ALIPAY || MP-DINGTALK
if(y.indexOf('>>>')!=-1){ // ()
selector = y.split('>>>')[1].trim()
}
// #endif
}
uni.createSelectorQuery().select(selector).boundingClientRect(function(rect){
if (rect) {
let curY = vm.mescroll.getScrollTop()
let top = rect.top - mescrollTop
top += curY
if(!vm.isFixed) top -= vm.numTop
vm.scrollTop = curY;
vm.$nextTick(function() {
vm.scrollTop = top
})
} else{
console.error(selector + ' does not exist');
}
}).exec()
})
return;
}
let curY = vm.mescroll.getScrollTop()
if (t === 0 || t === 300) { // t使300,使
vm.scrollTop = curY;
vm.$nextTick(function() {
vm.scrollTop = y
})
} else {
vm.mescroll.getStep(curY, y, step => { // t
vm.scrollTop = step
}, t)
}
})
// up.toTop.safearea,vuesafearea
if (vm.up && vm.up.toTop && vm.up.toTop.safearea != null) {} else {
vm.mescroll.optUp.toTop.safearea = vm.safearea;
}
//
uni.$on("setMescrollGlobalOption", options=>{
if(!options) return;
let i18nType = options.i18n ? options.i18n.type : null
if(i18nType && vm.mescroll.i18n.type != i18nType){
vm.mescroll.i18n.type = i18nType
mescrollI18n.setType(i18nType)
MeScroll.extend(options, vm.mescroll.i18n[i18nType])
}
if(options.down){
let down = MeScroll.extend({}, options.down)
vm.mescroll.optDown = MeScroll.extend(down, vm.mescroll.optDown)
}
if(options.up){
let up = MeScroll.extend({}, options.up)
vm.mescroll.optUp = MeScroll.extend(up, vm.mescroll.optUp)
}
})
},
mounted() {
//
this.setClientHeight()
},
destroyed() {
//
uni.$off("setMescrollGlobalOption")
}
}
</script>
<style>
@import "./mescroll-uni.css";
@import "./components/mescroll-down.css";
@import './components/mescroll-up.css';
</style>

@ -0,0 +1,47 @@
/**
* mescroll-body写在子组件时,需通过mescroll的mixins补充子组件缺少的生命周期
*/
const MescrollCompMixin = {
// 因为子组件无onPageScroll和onReachBottom的页面生命周期需在页面传递进到子组件 (一级)
onPageScroll(e) {
this.handlePageScroll(e)
},
onReachBottom() {
this.handleReachBottom()
},
// 当down的native: true时, 还需传递此方法进到子组件
onPullDownRefresh(){
this.handlePullDownRefresh()
},
data() {
return {
mescroll: { // mescroll-body写在子子子...组件的情况 (多级)
onPageScroll: e=>{
this.handlePageScroll(e)
},
onReachBottom: ()=>{
this.handleReachBottom()
},
onPullDownRefresh: ()=>{
this.handlePullDownRefresh()
}
}
}
},
methods:{
handlePageScroll(e){
let item = this.$refs["mescrollItem"];
if(item && item.mescroll) item.mescroll.onPageScroll(e);
},
handleReachBottom(){
let item = this.$refs["mescrollItem"];
if(item && item.mescroll) item.mescroll.onReachBottom();
},
handlePullDownRefresh(){
let item = this.$refs["mescrollItem"];
if(item && item.mescroll) item.mescroll.onPullDownRefresh();
}
}
}
export default MescrollCompMixin;

@ -0,0 +1,57 @@
/**
* mescroll-more-item的mixins, 仅在多个 mescroll-body 写在子组件时使用 (参考 mescroll-more 案例)
*/
const MescrollMoreItemMixin = {
// 支付宝小程序不支持props的mixin,需写在具体的页面中
// #ifndef MP-ALIPAY || MP-DINGTALK
props:{
i: Number, // 每个tab页的专属下标
index: { // 当前tab的下标
type: Number,
default(){
return 0
}
}
},
// #endif
data() {
return {
downOption:{
auto:false // 不自动加载
},
upOption:{
auto:false // 不自动加载
},
isInit: false // 当前tab是否已初始化
}
},
watch:{
// 监听下标的变化
index(val){
if (this.i === val && !this.isInit) this.mescrollTrigger()
}
},
methods: {
// mescroll组件初始化的回调,可获取到mescroll对象 (覆盖mescroll-mixins.js的mescrollInit, 为了标记isInit)
mescrollInit(mescroll) {
this.mescroll = mescroll;
// 自动加载当前tab的数据
if(this.i === this.index){
this.mescrollTrigger()
}
},
// 主动触发加载
mescrollTrigger(){
this.isInit = true; // 标记为true
if (this.mescroll) {
if (this.mescroll.optDown.use) {
this.mescroll.triggerDownScroll();
} else{
this.mescroll.triggerUpScroll();
}
}
}
}
}
export default MescrollMoreItemMixin;

@ -0,0 +1,77 @@
/**
* mescroll-body写在子组件时, 需通过mescroll的mixins补充子组件缺少的生命周期
*/
const MescrollMoreMixin = {
data() {
return {
tabIndex: 0, // 当前tab下标
mescroll: { // mescroll-body写在子子子...组件的情况 (多级)
onPageScroll: e=>{
this.handlePageScroll(e)
},
onReachBottom: ()=>{
this.handleReachBottom()
},
onPullDownRefresh: ()=>{
this.handlePullDownRefresh()
}
}
}
},
// 因为子组件无onPageScroll和onReachBottom的页面生命周期需在页面传递进到子组件
onPageScroll(e) {
this.handlePageScroll(e)
},
onReachBottom() {
this.handleReachBottom()
},
// 当down的native: true时, 还需传递此方法进到子组件
onPullDownRefresh(){
this.handlePullDownRefresh()
},
methods:{
handlePageScroll(e){
let mescroll = this.getMescroll(this.tabIndex);
mescroll && mescroll.onPageScroll(e);
},
handleReachBottom(){
let mescroll = this.getMescroll(this.tabIndex);
mescroll && mescroll.onReachBottom();
},
handlePullDownRefresh(){
let mescroll = this.getMescroll(this.tabIndex);
mescroll && mescroll.onPullDownRefresh();
},
// 根据下标获取对应子组件的mescroll
getMescroll(i){
if(!this.mescrollItems) this.mescrollItems = [];
if(!this.mescrollItems[i]) {
// v-for中的refs
let vForItem = this.$refs["mescrollItem"];
if(vForItem){
this.mescrollItems[i] = vForItem[i]
}else{
// 普通的refs,不可重复
this.mescrollItems[i] = this.$refs["mescrollItem"+i];
}
}
let item = this.mescrollItems[i]
return item ? item.mescroll : null
},
// 切换tab,恢复滚动条位置
tabChange(i){
let mescroll = this.getMescroll(i);
if(mescroll){
// 恢复上次滚动条的位置
let y = mescroll.getScrollTop()
mescroll.scrollTo(y, 0)
// 再次恢复上次滚动条的位置, 确保元素已渲染
setTimeout(()=>{
mescroll.scrollTo(y, 0)
},30)
}
}
}
}
export default MescrollMoreMixin;

@ -0,0 +1,109 @@
// 定义在wxs (含renderjs) 逻辑层的数据和方法, 与视图层相互通信
const WxsMixin = {
data() {
return {
// 传入wxs视图层的数据 (响应式)
wxsProp: {
optDown:{}, // 下拉刷新的配置
scrollTop:0, // 滚动条的距离
bodyHeight:0, // body的高度
isDownScrolling:false, // 是否正在下拉刷新中
isUpScrolling:false, // 是否正在上拉加载中
isScrollBody:true, // 是否为mescroll-body滚动
isUpBoth:true, // 上拉加载时,是否同时可以下拉刷新
t: 0 // 数据更新的标记 (只有数据更新了,才会触发wxs的Observer)
},
// 标记调用wxs视图层的方法
callProp: {
callType: '', // 方法名
t: 0 // 数据更新的标记 (只有数据更新了,才会触发wxs的Observer)
},
// 不用wxs的平台使用此处的wxsBiz对象,抹平wxs的写法 (微信小程序和APP使用的wxsBiz对象是./wxs/wxs.wxs)
// #ifndef MP-WEIXIN || MP-QQ || APP-PLUS || H5
wxsBiz: {
//注册列表touchstart事件,用于下拉刷新
touchstartEvent: e=> {
this.mescroll.touchstartEvent(e);
},
//注册列表touchmove事件,用于下拉刷新
touchmoveEvent: e=> {
this.mescroll.touchmoveEvent(e);
},
//注册列表touchend事件,用于下拉刷新
touchendEvent: e=> {
this.mescroll.touchendEvent(e);
},
propObserver(){}, // 抹平wxs的写法
callObserver(){} // 抹平wxs的写法
},
// #endif
// 不用renderjs的平台使用此处的renderBiz对象,抹平renderjs的写法 (app 和 h5 使用的renderBiz对象是./wxs/renderjs.js)
// #ifndef APP-PLUS || H5
renderBiz: {
propObserver(){} // 抹平renderjs的写法
}
// #endif
}
},
methods: {
// wxs视图层调用逻辑层的回调
wxsCall(msg){
if(msg.type === 'setWxsProp'){
// 更新wxsProp数据 (值改变才触发更新)
this.wxsProp = {
optDown: this.mescroll.optDown,
scrollTop: this.mescroll.getScrollTop(),
bodyHeight: this.mescroll.getBodyHeight(),
isDownScrolling: this.mescroll.isDownScrolling,
isUpScrolling: this.mescroll.isUpScrolling,
isUpBoth: this.mescroll.optUp.isBoth,
isScrollBody:this.mescroll.isScrollBody,
t: Date.now()
}
}else if(msg.type === 'setLoadType'){
// 设置inOffset,outOffset的状态
this.downLoadType = msg.downLoadType
// 状态挂载到mescroll对象, 以便在其他组件中使用, 比如<me-video>中
this.$set(this.mescroll, 'downLoadType', this.downLoadType)
// 重置是否加载成功的状态
this.$set(this.mescroll, 'isDownEndSuccess', null)
}else if(msg.type === 'triggerDownScroll'){
// 主动触发下拉刷新
this.mescroll.triggerDownScroll();
}else if(msg.type === 'endDownScroll'){
// 结束下拉刷新
this.mescroll.endDownScroll();
}else if(msg.type === 'triggerUpScroll'){
// 主动触发上拉加载
this.mescroll.triggerUpScroll(true);
}
}
},
mounted() {
// #ifdef MP-WEIXIN || MP-QQ || APP-PLUS || H5
// 配置主动触发wxs显示加载进度的回调
this.mescroll.optDown.afterLoading = ()=>{
this.callProp = {callType: "showLoading", t: Date.now()} // 触发wxs的方法 (值改变才触发更新)
}
// 配置主动触发wxs隐藏加载进度的回调
this.mescroll.optDown.afterEndDownScroll = ()=>{
this.callProp = {callType: "endDownScroll", t: Date.now()} // 触发wxs的方法 (值改变才触发更新)
let delay = 300 + (this.mescroll.optDown.beforeEndDelay || 0)
setTimeout(()=>{
if(this.downLoadType === 4 || this.downLoadType === 0){
this.callProp = {callType: "clearTransform", t: Date.now()} // 触发wxs的方法 (值改变才触发更新)
}
// 状态挂载到mescroll对象, 以便在其他组件中使用, 比如<me-video>中
this.$set(this.mescroll, 'downLoadType', this.downLoadType)
}, delay)
}
// 初始化wxs的数据
this.wxsCall({type: 'setWxsProp'})
// #endif
}
}
export default WxsMixin;

@ -0,0 +1,92 @@
// 使用renderjs直接操作window对象,实现动态控制app和h5的bounce
// bounce: iOS橡皮筋,Android半月弧,h5浏览器下拉背景等效果 (下拉刷新时禁止)
// https://uniapp.dcloud.io/frame?id=renderjs
// 与wxs的me实例一致
var me = {}
// 初始化window对象的touch事件 (仅初始化一次)
if(window && !window.$mescrollRenderInit){
window.$mescrollRenderInit = true
window.addEventListener('touchstart', function(e){
if (me.disabled()) return;
me.startPoint = me.getPoint(e); // 记录起点
}, {passive: true})
window.addEventListener('touchmove', function(e){
if (me.disabled()) return;
if (me.getScrollTop() > 0) return; // 需在顶部下拉,才禁止bounce
var curPoint = me.getPoint(e); // 当前点
var moveY = curPoint.y - me.startPoint.y; // 和起点比,移动的距离,大于0向下拉,小于0向上拉
// 向下拉
if (moveY > 0) {
// 可下拉的条件
if (!me.isDownScrolling && !me.optDown.isLock && (!me.isUpScrolling || (me.isUpScrolling && me.isUpBoth))) {
// 只有touch在mescroll的view上面,才禁止bounce
var el = e.target;
var isMescrollTouch = false;
while (el && el.tagName && el.tagName !== 'UNI-PAGE-BODY' && el.tagName != "BODY") {
var cls = el.classList;
if (cls && cls.contains('mescroll-render-touch')) {
isMescrollTouch = true
break;
}
el = el.parentNode; // 继续检查其父元素
}
// 禁止bounce (不会对swiper和iOS侧滑返回造成影响)
if (isMescrollTouch && e.cancelable && !e.defaultPrevented) e.preventDefault();
}
}
}, {passive: false})
}
/* 获取滚动条的位置 */
me.getScrollTop = function() {
return me.scrollTop || document.documentElement.scrollTop || document.body.scrollTop || 0
}
/* 是否禁用下拉刷新 */
me.disabled = function(){
return !me.optDown || !me.optDown.use || me.optDown.native
}
/* 根据点击滑动事件获取第一个手指的坐标 */
me.getPoint = function(e) {
if (!e) {
return {x: 0,y: 0}
}
if (e.touches && e.touches[0]) {
return {x: e.touches[0].pageX,y: e.touches[0].pageY}
} else if (e.changedTouches && e.changedTouches[0]) {
return {x: e.changedTouches[0].pageX,y: e.changedTouches[0].pageY}
} else {
return {x: e.clientX,y: e.clientY}
}
}
/**
* 监听逻辑层数据的变化 (实时更新数据)
*/
function propObserver(wxsProp) {
me.optDown = wxsProp.optDown
me.scrollTop = wxsProp.scrollTop
me.isDownScrolling = wxsProp.isDownScrolling
me.isUpScrolling = wxsProp.isUpScrolling
me.isUpBoth = wxsProp.isUpBoth
}
/* 导出模块 */
const renderBiz = {
data() {
return {
propObserver: propObserver,
}
}
}
export default renderBiz;

@ -0,0 +1,269 @@
// 使用wxs处理交互动画, 提高性能, 同时避免小程序bounce对下拉刷新的影响
// https://uniapp.dcloud.io/frame?id=wxs
// https://developers.weixin.qq.com/miniprogram/dev/framework/view/interactive-animation.html
// 模拟mescroll实例, 与mescroll.js的写法尽量保持一致
var me = {}
// ------ 自定义下拉刷新动画 start ------
/* 下拉过程中的回调,滑动过程一直在执行 (rate<1为inOffset; rate>1为outOffset) */
me.onMoving = function (ins, rate, downHight){
ins.requestAnimationFrame(function () {
ins.selectComponent('.mescroll-wxs-content').setStyle({
'will-change': 'transform', // 可解决下拉过程中, image和swiper脱离文档流的问题
'transform': 'translateY(' + downHight + 'px)',
'transition': ''
})
// 环形进度条
var progress = ins.selectComponent('.mescroll-wxs-progress')
progress && progress.setStyle({transform: 'rotate(' + 360 * rate + 'deg)'})
})
}
/* 显示下拉刷新进度 */
me.showLoading = function (ins){
me.downHight = me.optDown.offset
ins.requestAnimationFrame(function () {
ins.selectComponent('.mescroll-wxs-content').setStyle({
'will-change': 'auto',
'transform': 'translateY(' + me.downHight + 'px)',
'transition': 'transform 300ms'
})
})
}
/* 结束下拉 */
me.endDownScroll = function (ins){
me.downHight = 0;
me.isDownScrolling = false;
ins.requestAnimationFrame(function () {
ins.selectComponent('.mescroll-wxs-content').setStyle({
'will-change': 'auto',
'transform': 'translateY(0)', // 不可以写空串,否则scroll-view渲染不完整 (延时350ms会调clearTransform置空)
'transition': 'transform 300ms'
})
})
}
/* 结束下拉动画执行完毕后, 清除transform和transition, 避免对列表内容样式造成影响, 如: h5的list-msg示例下拉进度条漏出来等 */
me.clearTransform = function (ins){
ins.requestAnimationFrame(function () {
ins.selectComponent('.mescroll-wxs-content').setStyle({
'will-change': '',
'transform': '',
'transition': ''
})
})
}
// ------ 自定义下拉刷新动画 end ------
/**
* 监听逻辑层数据的变化 (实时更新数据)
*/
function propObserver(wxsProp) {
if(!wxsProp) return
me.optDown = wxsProp.optDown
me.scrollTop = wxsProp.scrollTop
me.bodyHeight = wxsProp.bodyHeight
me.isDownScrolling = wxsProp.isDownScrolling
me.isUpScrolling = wxsProp.isUpScrolling
me.isUpBoth = wxsProp.isUpBoth
me.isScrollBody = wxsProp.isScrollBody
me.startTop = wxsProp.scrollTop // 及时更新touchstart触发的startTop, 避免scroll-view快速惯性滚动到顶部取值不准确
}
/**
* 监听逻辑层数据的变化 (调用wxs的方法)
*/
function callObserver(callProp, oldValue, ins) {
if (me.disabled()) return;
if(callProp.callType){
// 逻辑层App Service的style已失效,需在视图层Webview设置style
if(callProp.callType === 'showLoading'){
me.showLoading(ins)
}else if(callProp.callType === 'endDownScroll'){
me.endDownScroll(ins)
}else if(callProp.callType === 'clearTransform'){
me.clearTransform(ins)
}
}
}
/**
* touch事件
*/
function touchstartEvent(e, ins) {
me.downHight = 0; // 下拉的距离
me.startPoint = me.getPoint(e); // 记录起点
me.startTop = me.getScrollTop(); // 记录此时的滚动条位置
me.startAngle = 0; // 初始角度
me.lastPoint = me.startPoint; // 重置上次move的点
me.maxTouchmoveY = me.getBodyHeight() - me.optDown.bottomOffset; // 手指触摸的最大范围(写在touchstart避免body获取高度为0的情况)
me.inTouchend = false; // 标记不是touchend
me.callMethod(ins, {type: 'setWxsProp'}) // 同步更新wxsProp的数据 (小程序是异步的,可能touchmove先执行,才到propObserver; h5和app是同步)
}
function touchmoveEvent(e, ins) {
var isPrevent = true // false表示不往上冒泡相当于调用了同时调用了stopPropagation和preventDefault (对小程序生效, h5和app无效)
if (me.disabled()) return isPrevent;
var scrollTop = me.getScrollTop(); // 当前滚动条的距离
var curPoint = me.getPoint(e); // 当前点
var moveY = curPoint.y - me.startPoint.y; // 和起点比,移动的距离,大于0向下拉,小于0向上拉
// 向下拉 && 在顶部
// mescroll-body,直接判定在顶部即可
// scroll-view在滚动时不会触发touchmove,当触顶/底/左/右时,才会触发touchmove
// scroll-view滚动到顶部时,scrollTop不一定为0,也有可能大于0; 在iOS的APP中scrollTop可能为负数,不一定和startTop相等
if (moveY > 0 && (
(me.isScrollBody && scrollTop <= 0)
||
(!me.isScrollBody && (scrollTop <= 0 || (scrollTop <= me.optDown.startTop && scrollTop === me.startTop)) )
)) {
// 可下拉的条件
if (!me.inTouchend && !me.isDownScrolling && !me.optDown.isLock && (!me.isUpScrolling || (me.isUpScrolling &&
me.isUpBoth))) {
// 下拉的角度是否在配置的范围内
if(!me.startAngle) me.startAngle = me.getAngle(me.lastPoint, curPoint); // 两点之间的角度,区间 [0,90]
if (me.startAngle < me.optDown.minAngle) return isPrevent; // 如果小于配置的角度,则不往下执行下拉刷新
// 如果手指的位置超过配置的距离,则提前结束下拉,避免Webview嵌套导致touchend无法触发
if (me.maxTouchmoveY > 0 && curPoint.y >= me.maxTouchmoveY) {
me.inTouchend = true; // 标记执行touchend
touchendEvent(e, ins); // 提前触发touchend
return isPrevent;
}
isPrevent = false // 小程序是return false
var diff = curPoint.y - me.lastPoint.y; // 和上次比,移动的距离 (大于0向下,小于0向上)
// 下拉距离 < 指定距离
if (me.downHight < me.optDown.offset) {
if (me.movetype !== 1) {
me.movetype = 1; // 加入标记,保证只执行一次
// me.optDown.inOffset && me.optDown.inOffset(me); // 进入指定距离范围内那一刻的回调,只执行一次
me.callMethod(ins, {type: 'setLoadType', downLoadType: 1})
me.isMoveDown = true; // 标记下拉区域高度改变,在touchend重置回来
}
me.downHight += diff * me.optDown.inOffsetRate; // 越往下,高度变化越小
// 指定距离 <= 下拉距离
} else {
if (me.movetype !== 2) {
me.movetype = 2; // 加入标记,保证只执行一次
// me.optDown.outOffset && me.optDown.outOffset(me); // 下拉超过指定距离那一刻的回调,只执行一次
me.callMethod(ins, {type: 'setLoadType', downLoadType: 2})
me.isMoveDown = true; // 标记下拉区域高度改变,在touchend重置回来
}
if (diff > 0) { // 向下拉
me.downHight += diff * me.optDown.outOffsetRate; // 越往下,高度变化越小
} else { // 向上收
me.downHight += diff; // 向上收回高度,则向上滑多少收多少高度
}
}
me.downHight = Math.round(me.downHight) // 取整
var rate = me.downHight / me.optDown.offset; // 下拉区域当前高度与指定距离的比值
// me.optDown.onMoving && me.optDown.onMoving(me, rate, me.downHight); // 下拉过程中的回调,一直在执行
me.onMoving(ins, rate, me.downHight)
}
}
me.lastPoint = curPoint; // 记录本次移动的点
return isPrevent // false表示不往上冒泡相当于调用了同时调用了stopPropagation和preventDefault (对小程序生效, h5和app无效)
}
function touchendEvent(e, ins) {
// 如果下拉区域高度已改变,则需重置回来
if (me.isMoveDown) {
if (me.downHight >= me.optDown.offset) {
// 符合触发刷新的条件
me.downHight = me.optDown.offset; // 更新下拉区域高度
// me.triggerDownScroll();
me.callMethod(ins, {type: 'triggerDownScroll'})
} else {
// 不符合的话 则重置
me.downHight = 0;
// me.optDown.endDownScroll && me.optDown.endDownScroll(me);
me.callMethod(ins, {type: 'endDownScroll'})
}
me.movetype = 0;
me.isMoveDown = false;
} else if (!me.isScrollBody && me.getScrollTop() === me.startTop) { // scroll-view到顶/左/右/底的滑动事件
var isScrollUp = me.getPoint(e).y - me.startPoint.y < 0; // 和起点比,移动的距离,大于0向下拉,小于0向上拉
// 上滑
if (isScrollUp) {
// 需检查滑动的角度
var angle = me.getAngle(me.getPoint(e), me.startPoint); // 两点之间的角度,区间 [0,90]
if (angle > 80) {
// 检查并触发上拉
// me.triggerUpScroll(true);
me.callMethod(ins, {type: 'triggerUpScroll'})
}
}
}
me.callMethod(ins, {type: 'setWxsProp'}) // 同步更新wxsProp的数据 (小程序是异步的,可能touchmove先执行,才到propObserver; h5和app是同步)
}
/* 是否禁用下拉刷新 */
me.disabled = function(){
return !me.optDown || !me.optDown.use || me.optDown.native
}
/* 根据点击滑动事件获取第一个手指的坐标 */
me.getPoint = function(e) {
if (!e) {
return {x: 0,y: 0}
}
if (e.touches && e.touches[0]) {
return {x: e.touches[0].pageX,y: e.touches[0].pageY}
} else if (e.changedTouches && e.changedTouches[0]) {
return {x: e.changedTouches[0].pageX,y: e.changedTouches[0].pageY}
} else {
return {x: e.clientX,y: e.clientY}
}
}
/* 计算两点之间的角度: 区间 [0,90]*/
me.getAngle = function (p1, p2) {
var x = Math.abs(p1.x - p2.x);
var y = Math.abs(p1.y - p2.y);
var z = Math.sqrt(x * x + y * y);
var angle = 0;
if (z !== 0) {
angle = Math.asin(y / z) / Math.PI * 180;
}
return angle
}
/* 获取滚动条的位置 */
me.getScrollTop = function() {
return me.scrollTop || 0
}
/* 获取body的高度 */
me.getBodyHeight = function() {
return me.bodyHeight || 0;
}
/* 调用逻辑层的方法 */
me.callMethod = function(ins, param) {
if(ins) ins.callMethod('wxsCall', param)
}
/* 导出模块 */
module.exports = {
propObserver: propObserver,
callObserver: callObserver,
touchstartEvent: touchstartEvent,
touchmoveEvent: touchmoveEvent,
touchendEvent: touchendEvent
}

@ -0,0 +1,66 @@
// 小程序无法在hook中使用页面级别生命周期,需单独传入: https://ask.dcloud.net.cn/question/161173
// import { onPageScroll, onReachBottom, onPullDownRefresh} from '@dcloudio/uni-app';
/**
* 初始化mescroll, 相当于vue2的mescroll-mixins.js文件 (mescroll-body mescroll-uni 通用)
* mescroll-body需传入onPageScroll, onReachBottom
* mescroll-uni无需传onPageScroll, onReachBottom
* 当down.native为true时,需传入onPullDownRefresh
*/
function useMescroll(onPageScroll, onReachBottom, onPullDownRefresh){
// mescroll实例对象
let mescroll = null;
// mescroll组件初始化的回调,可获取到mescroll对象
const mescrollInit = (e)=> {
mescroll = e;
}
// 获取mescroll对象, mescrollInit执行之后会有值, 生命周期created中会有值
const getMescroll = ()=>{
return mescroll
}
// 下拉刷新的回调 (mixin默认resetUpScroll)
const downCallback = ()=> {
if(mescroll.optUp.use){
mescroll.resetUpScroll()
}else{
setTimeout(()=>{
mescroll.endSuccess();
}, 500)
}
}
// 上拉加载的回调
const upCallback = ()=> {
// mixin默认延时500自动结束加载
setTimeout(()=>{
mescroll.endErr();
}, 500)
}
// 注册系统自带的下拉刷新 (配置down.native为true时生效, 还需在pages配置enablePullDownRefresh:true;详请参考mescroll-native的案例)
onPullDownRefresh && onPullDownRefresh(() => {
mescroll && mescroll.onPullDownRefresh();
})
// 注册列表滚动事件,用于判定在顶部可下拉刷新,在指定位置可显示隐藏回到顶部按钮 (此方法为页面生命周期,无法在子组件中触发, 仅在mescroll-body生效)
onPageScroll && onPageScroll(e=>{
mescroll && mescroll.onPageScroll(e);
})
// 注册滚动到底部的事件,用于上拉加载 (此方法为页面生命周期,无法在子组件中触发, 仅在mescroll-body生效)
onReachBottom && onReachBottom(()=>{
mescroll && mescroll.onReachBottom();
})
return {
getMescroll,
mescrollInit,
downCallback,
upCallback
}
}
export default useMescroll

@ -0,0 +1,56 @@
import { ref } from 'vue';
// 小程序无法在hook中使用页面级别生命周期,需单独传入: https://ask.dcloud.net.cn/question/161173
// import { onPageScroll, onReachBottom, onPullDownRefresh} from '@dcloudio/uni-app';
/**
* mescroll-body写在子组件时,需通过useMescrollComp补充子组件缺少的生命周期, 相当于vue2的mescroll-comp.js文件
* 必须传入onPageScroll, onReachBottom
* 当down.native为true时,需传入onPullDownRefresh
*/
function useMescrollComp(onPageScroll, onReachBottom, onPullDownRefresh){
// 因为子组件无onPageScroll和onReachBottom的页面生命周期需在页面传递进到子组件
onPageScroll(e=>{
handlePageScroll(e)
})
onReachBottom(()=>{
handleReachBottom()
})
// 当down的native: true时, 还需传递此方法进到子组件
onPullDownRefresh && onPullDownRefresh(()=>{
handlePullDownRefresh()
})
const mescrollItem = ref(null)
const handlePageScroll = (e)=>{
const mescroll = getMescroll()
mescroll && mescroll.onPageScroll(e);
}
const handleReachBottom = ()=>{
const mescroll = getMescroll()
mescroll && mescroll.onReachBottom();
}
const handlePullDownRefresh = ()=>{
const mescroll = getMescroll()
mescroll && mescroll.onPullDownRefresh();
}
const getMescroll = ()=>{
if(mescrollItem.value && mescrollItem.value.getMescroll){
return mescrollItem.value.getMescroll()
}
return null
}
return {
mescrollItem,
getMescroll
}
}
export default useMescrollComp

@ -0,0 +1,69 @@
import { ref } from 'vue';
// 小程序无法在hook中使用页面级别生命周期,需单独传入: https://ask.dcloud.net.cn/question/161173
// import { onPageScroll, onReachBottom, onPullDownRefresh} from '@dcloudio/uni-app';
/** mescroll-more示例写在子组件时,需通过useMescrollMore补充子组件缺少的生命周期, 相当于vue2的mescroll-more.js文件 */
function useMescrollMore(mescrollItems, onPageScroll, onReachBottom, onPullDownRefresh){
// 当前tab下标
const tabIndex = ref(0)
// 因为子组件无onPageScroll和onReachBottom的页面生命周期需在页面传递进到子组件
onPageScroll && onPageScroll(e=>{
handlePageScroll(e)
})
onReachBottom && onReachBottom(()=>{
handleReachBottom()
})
// 当down的native: true时, 还需传递此方法进到子组件
onPullDownRefresh && onPullDownRefresh(()=>{
handlePullDownRefresh()
})
const handlePageScroll = (e)=>{
let mescroll = getMescroll(tabIndex.value);
mescroll && mescroll.onPageScroll(e);
}
const handleReachBottom = ()=>{
let mescroll = getMescroll(tabIndex.value);
mescroll && mescroll.onReachBottom();
}
const handlePullDownRefresh = ()=>{
let mescroll = getMescroll(tabIndex.value);
mescroll && mescroll.onPullDownRefresh();
}
// 根据下标获取对应子组件的mescroll
const getMescroll = (i)=>{
if (mescrollItems && mescrollItems[i]) {
return mescrollItems[i].value.getMescroll()
} else{
return null
}
}
// 切换tab,恢复滚动条位置
const scrollToLastY = ()=>{
let mescroll = getMescroll(tabIndex.value);
if(mescroll){
// 恢复上次滚动条的位置
let y = mescroll.getScrollTop()
mescroll.scrollTo(y, 0)
// 再次恢复上次滚动条的位置, 确保元素已渲染
setTimeout(()=>{
mescroll.scrollTo(y, 0)
},20)
}
}
return {
tabIndex,
getMescroll,
scrollToLastY
}
}
export default useMescrollMore

@ -0,0 +1,76 @@
{
"id": "mescroll-uni",
"displayName": "高性能下拉刷新上拉加载组件 支持vue3 setup",
"version": "1.3.8",
"description": "wxs+renderjs实现, 支持原生页面和局部区域滚动, 支持vue3 script setup的写法",
"keywords": [
"下拉刷新",
"上拉加载",
"翻页分页",
"wxs",
"setup"
],
"repository": "https://github.com/mescroll/mescroll",
"engines": {
},
"dcloudext": {
"sale": {
"regular": {
"price": "0.00"
},
"sourcecode": {
"price": "0.00"
}
},
"contact": {
"qq": ""
},
"declaration": {
"ads": "无",
"data": "无",
"permissions": "无"
},
"npmurl": "https://www.npmjs.com/package/mescroll-uni",
"type": "component-vue"
},
"uni_modules": {
"dependencies": [],
"encrypt": [],
"platforms": {
"cloud": {
"tcb": "y",
"aliyun": "y"
},
"client": {
"App": {
"app-vue": "y",
"app-nvue": "y"
},
"H5-mobile": {
"Safari": "y",
"Android Browser": "y",
"微信浏览器(Android)": "y",
"QQ浏览器(Android)": "y"
},
"H5-pc": {
"Chrome": "y",
"IE": "y",
"Edge": "y",
"Firefox": "y",
"Safari": "y"
},
"小程序": {
"微信": "y",
"阿里": "y",
"百度": "y",
"字节跳动": "y",
"QQ": "y"
},
"快应用": {
"华为": "y",
"联盟": "y"
}
}
}
}
}

@ -0,0 +1,45 @@
## mescroll --【wxs+renderjs实现】高性能的下拉刷新上拉加载组件
1. mescroll的uni版本 是专门用在uni-app的下拉刷新和上拉加载的组件
2. mescroll的uni版本 继承了mescroll.js的实用功能: 自动处理分页, 自动控制无数据, 空布局提示, 回到顶部按钮 ..
3. mescroll的uni版本 丰富的案例, 自由灵活的api, 超详细的注释, 可让您快速自定义真正属于自己的下拉上拉组件
<br/>
## 最新文档(1.3.8版本): <a href="https://www.mescroll.com/uni.html">https://www.mescroll.com/uni.html</a>
2023-03-26 by 小瑾同学 (文档可能会有缓存,建议打开时刷新一下)
## 1.3.5版本已调整为[uni_modules](https://uniapp.dcloud.io/uni_modules)
uni_modules版本的mescroll-body 和 mescroll-empty 支持 [easycom规范](https://uniapp.dcloud.io/collocation/pages?id=easycom)
所以 main.js 无需再为mescroll-body注册全局组件
所以个别页面要单独使用 mescroll-empty , 也无需手动注册
#### 1.3.5以前的用户升级为uni_modules版本:
```
1. 删除原来的 @/components/mescroll-uni 组件
2. 删除 main.js 注册的 mescroll 组件
3. 从插件市场导入最新mescroll组件 (1.3.5+uni_modules版本)
4. 全局搜索 '@/components/mescroll-uni/' 替换为 '@/uni_modules/mescroll-uni/components/mescroll-uni/'
5. mescroll-empty遵循easycom规范, 若某些页面单独使用 'mescroll-empty.vue', 可删除手动导入的代码
```
## 近期已更新优化的内容:
1. 新增vue3 script setup的示例
2. 新增`入门极简`示例, 国际化`mescroll-i18n.vue`示例, 轮播吸顶菜单`mescroll-swiper-sticky.vue`示例
3. 新增 "局部区域滚动" 的案例: mescroll-body-part.vue 和 mescroll-uni-part.vue
4. 新增 me-video 视频组件, 解决APP端视频下拉悬浮错位的问题, 参考 mescroll-options.vue 示例
5. 新增 me-tabs 组件,tabs支持水平滑动; 优化mescroll-more和mescroll-swiper的案例, 顶部tab支持水平滑动
6. 吸顶悬浮提供了原生sticky和监听滚动条实现的示例: sticky.vue 和 sticky-scroll.vue (推荐使用sticky样式实现)
7. mescroll.scrollTo(y)的y支持css选择器, 包括跨自定义组件的后代选择器, 支持滚动到子组件的view (参考 mescroll-options.vue)
8. topbar 顶部是否预留状态栏的高度, 默认false; 还可支持设置状态栏背景: 如 '#ffff00', 'url(xxx) 0 0/100% 100%', 'linear-gradient(xx)'
9. down.bgColor 和 up.bgColor 加载区域的背景,不仅支持色值, 而且还是支持背景图和渐变: 如 'url(xxx) 0 0/100% 100%', 'linear-gradient(xx)'
10. topbar,bgColor支持一行代码定义background: [https://www.runoob.com/cssref/css3-pr-background.html](https://www.runoob.com/cssref/css3-pr-background.html)
<br/>
<br/>
<a href="https://ext.dcloud.net.cn/plugin?id=343&update_log">查看更多 ... </a>
<br/>
#### mescroll不支持nvue,也暂无支持的计划哈,so sorry~

@ -0,0 +1,4 @@
require('./common/runtime.js')
require('./common/vendor.js')
require('./common/main.js')

@ -0,0 +1,27 @@
{
"pages": [
"pages/index/index",
"pages/cloudStore/apply",
"pages/cloudStore/cloudStoreList",
"pages/cloudStore/cloudStoreDetail"
],
"subPackages": [],
"window": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "uni-app",
"navigationBarBackgroundColor": "#F8F8F8",
"backgroundColor": "#F8F8F8"
},
"tabBar": {
"custom": true,
"list": [
{
"pagePath": "pages/index/index"
},
{
"pagePath": "pages/cloudStore/cloudStoreList"
}
]
},
"usingComponents": {}
}

@ -0,0 +1,3 @@
@import './common/main.wxss';
[data-custom-hidden="true"],[bind-data-custom-hidden="true"]{display: none !important;}

@ -0,0 +1 @@
(global["webpackJsonp"]=global["webpackJsonp"]||[]).push([["common/main"],{"0db8":function(e,t,n){"use strict";n.r(t);var o=n("38a4");for(var r in o)["default"].indexOf(r)<0&&function(e){n.d(t,e,(function(){return o[e]}))}(r);n("20be");var c=n("828b"),u=Object(c["a"])(o["default"],void 0,void 0,!1,null,null,null,!1,void 0,void 0);t["default"]=u.exports},"20be":function(e,t,n){"use strict";var o=n("5cff"),r=n.n(o);r.a},"38a4":function(e,t,n){"use strict";n.r(t);var o=n("e0d5"),r=n.n(o);for(var c in o)["default"].indexOf(c)<0&&function(e){n.d(t,e,(function(){return o[e]}))}(c);t["default"]=r.a},"5cff":function(e,t,n){},c528:function(e,t,n){"use strict";(function(e,t){var o=n("47a9"),r=o(n("7ca3"));n("3e3f");var c=o(n("0db8")),u=o(n("adf1")),a=o(n("3240"));function f(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);t&&(o=o.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,o)}return n}n("1aab"),e.__webpack_require_UNI_MP_PLUGIN__=n,a.default.use(u.default),a.default.config.productionTip=!1,c.default.mpType="app";var i=new a.default(function(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?f(Object(n),!0).forEach((function(t){(0,r.default)(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):f(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}({},c.default));t(i).$mount()}).call(this,n("3223")["default"],n("df3c")["createApp"])},e0d5:function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0;var o={onLaunch:function(){console.log("App Launch")},onShow:function(){console.log("App Show")},onHide:function(){console.log("App Hide")}};t.default=o}},[["c528","common/runtime","common/vendor"]]]);

@ -0,0 +1 @@
.u-line-1{display:-webkit-box!important;overflow:hidden;text-overflow:ellipsis;word-break:break-all;-webkit-line-clamp:1;-webkit-box-orient:vertical!important}.u-line-2{display:-webkit-box!important;overflow:hidden;text-overflow:ellipsis;word-break:break-all;-webkit-line-clamp:2;-webkit-box-orient:vertical!important}.u-line-3{display:-webkit-box!important;overflow:hidden;text-overflow:ellipsis;word-break:break-all;-webkit-line-clamp:3;-webkit-box-orient:vertical!important}.u-line-4{display:-webkit-box!important;overflow:hidden;text-overflow:ellipsis;word-break:break-all;-webkit-line-clamp:4;-webkit-box-orient:vertical!important}.u-line-5{display:-webkit-box!important;overflow:hidden;text-overflow:ellipsis;word-break:break-all;-webkit-line-clamp:5;-webkit-box-orient:vertical!important}.u-border{border-width:.5px!important;border-color:#dadbde!important;border-style:solid}.u-border-top{border-top-width:.5px!important;border-color:#dadbde!important;border-top-style:solid}.u-border-left{border-left-width:.5px!important;border-color:#dadbde!important;border-left-style:solid}.u-border-right{border-right-width:.5px!important;border-color:#dadbde!important;border-right-style:solid}.u-border-bottom{border-bottom-width:.5px!important;border-color:#dadbde!important;border-bottom-style:solid}.u-border-top-bottom{border-top-width:.5px!important;border-bottom-width:.5px!important;border-color:#dadbde!important;border-top-style:solid;border-bottom-style:solid}.u-reset-button{padding:0;background-color:initial;font-size:inherit;line-height:inherit;color:inherit}.u-reset-button::after{border:none}.u-hover-class{opacity:.7}.u-primary-light{color:#ecf5ff}.u-warning-light{color:#fdf6ec}.u-success-light{color:#f5fff0}.u-error-light{color:#fef0f0}.u-info-light{color:#f4f4f5}.u-primary-light-bg{background-color:#ecf5ff}.u-warning-light-bg{background-color:#fdf6ec}.u-success-light-bg{background-color:#f5fff0}.u-error-light-bg{background-color:#fef0f0}.u-info-light-bg{background-color:#f4f4f5}.u-primary-dark{color:#398ade}.u-warning-dark{color:#f1a532}.u-success-dark{color:#53c21d}.u-error-dark{color:#e45656}.u-info-dark{color:#767a82}.u-primary-dark-bg{background-color:#398ade}.u-warning-dark-bg{background-color:#f1a532}.u-success-dark-bg{background-color:#53c21d}.u-error-dark-bg{background-color:#e45656}.u-info-dark-bg{background-color:#767a82}.u-primary-disabled{color:#9acafc}.u-warning-disabled{color:#f9d39b}.u-success-disabled{color:#a9e08f}.u-error-disabled{color:#f7b2b2}.u-info-disabled{color:#c4c6c9}.u-primary{color:#3c9cff}.u-warning{color:#f9ae3d}.u-success{color:#5ac725}.u-error{color:#f56c6c}.u-info{color:#909399}.u-primary-bg{background-color:#3c9cff}.u-warning-bg{background-color:#f9ae3d}.u-success-bg{background-color:#5ac725}.u-error-bg{background-color:#f56c6c}.u-info-bg{background-color:#909399}.u-main-color{color:#303133}.u-content-color{color:#606266}.u-tips-color{color:#909193}.u-light-color{color:#c0c4cc}.u-safe-area-inset-top{padding-top:0;padding-top:constant(safe-area-inset-top);padding-top:env(safe-area-inset-top)}.u-safe-area-inset-right{padding-right:0;padding-right:constant(safe-area-inset-right);padding-right:env(safe-area-inset-right)}.u-safe-area-inset-bottom{padding-bottom:0;padding-bottom:constant(safe-area-inset-bottom);padding-bottom:env(safe-area-inset-bottom)}.u-safe-area-inset-left{padding-left:0;padding-left:constant(safe-area-inset-left);padding-left:env(safe-area-inset-left)}::-webkit-scrollbar{display:none;width:0!important;height:0!important;-webkit-appearance:none;background:transparent}page::after{position:fixed;content:'';left:-1000px;top:-1000px;-webkit-animation:shadow-preload .1s;-webkit-animation-delay:3s;animation:shadow-preload .1s;animation-delay:3s}@-webkit-keyframes shadow-preload{0%{background-image:url(https://cdn1.dcloud.net.cn/img/shadow-grey.png)}100%{background-image:url(https://cdn1.dcloud.net.cn/img/shadow-grey.png)}}@keyframes shadow-preload{0%{background-image:url(https://cdn1.dcloud.net.cn/img/shadow-grey.png)}100%{background-image:url(https://cdn1.dcloud.net.cn/img/shadow-grey.png)}}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -0,0 +1,10 @@
(global["webpackJsonp"]=global["webpackJsonp"]||[]).push([["components/tab-bar"],{"0c73":function(t,n,e){"use strict";e.r(n);var a=e("870c"),u=e.n(a);for(var c in a)["default"].indexOf(c)<0&&function(t){e.d(n,t,(function(){return a[t]}))}(c);n["default"]=u.a},"573c":function(t,n,e){"use strict";e.d(n,"b",(function(){return u})),e.d(n,"c",(function(){return c})),e.d(n,"a",(function(){return a}));var a={uTabbar:function(){return Promise.all([e.e("common/vendor"),e.e("uni_modules/uview-ui/components/u-tabbar/u-tabbar")]).then(e.bind(null,"f989"))},uTabbarItem:function(){return Promise.all([e.e("common/vendor"),e.e("uni_modules/uview-ui/components/u-tabbar-item/u-tabbar-item")]).then(e.bind(null,"4bce"))}},u=function(){var t=this.$createElement;this._self._c},c=[]},"870c":function(t,n,e){"use strict";(function(t){Object.defineProperty(n,"__esModule",{value:!0}),n.default=void 0;var e={name:"TabBar",props:{current:Number},data:function(){return{list:[{iconPath:"/static/img/home.png",selectedIconPath:"/static/img/homeHL.png",pagePath:"pages/cloudStore/cloudStoreList",text:"主页",customIcon:!1},{iconPath:"/static/img/user.png",selectedIconPath:"/static/img/userHL.png",pagePath:"pages/index/index",text:"我的",customIcon:!1}]}},methods:{changeTab:function(n){t.switchTab({url:"/"+this.list[n].pagePath})}}};n.default=e}).call(this,e("df3c")["default"])},bad1:function(t,n,e){"use strict";var a=e("dc0f"),u=e.n(a);u.a},dc0f:function(t,n,e){},e1f8:function(t,n,e){"use strict";e.r(n);var a=e("573c"),u=e("0c73");for(var c in u)["default"].indexOf(c)<0&&function(t){e.d(n,t,(function(){return u[t]}))}(c);e("bad1");var i=e("828b"),o=Object(i["a"])(u["default"],a["b"],a["c"],!1,null,null,null,!1,a["a"],void 0);n["default"]=o.exports}}]);
;(global["webpackJsonp"] = global["webpackJsonp"] || []).push([
'components/tab-bar-create-component',
{
'components/tab-bar-create-component':(function(module, exports, __webpack_require__){
__webpack_require__('df3c')['createComponent'](__webpack_require__("e1f8"))
})
},
[['components/tab-bar-create-component']]
]);

@ -0,0 +1,7 @@
{
"usingComponents": {
"u-tabbar": "/uni_modules/uview-ui/components/u-tabbar/u-tabbar",
"u-tabbar-item": "/uni_modules/uview-ui/components/u-tabbar-item/u-tabbar-item"
},
"component": true
}

@ -0,0 +1 @@
<view><u-tabbar class="tabBar" vue-id="9fb413d4-1" value="{{current?current:0}}" fixed="true" safeAreaInsetBottom="true" active-color="#4D5566" inactive-color="#848FA5" data-event-opts="{{[['^change',[['changeTab']]]]}}" bind:change="__e" bind:__l="__l" vue-slots="{{['default']}}"><block wx:for="{{list}}" wx:for-item="item" wx:for-index="index" wx:key="index"><u-tabbar-item vue-id="{{('9fb413d4-2-'+index)+','+('9fb413d4-1')}}" text="{{item.text}}" bind:__l="__l" vue-slots="{{['inactive-icon','active-icon']}}"><image class="tabBarBtn" slot="inactive-icon" src="{{item.iconPath}}"></image><image class="tabBarBtn" slot="active-icon" src="{{item.selectedIconPath}}"></image></u-tabbar-item></block></u-tabbar></view>

@ -0,0 +1 @@
.tabBar{font-size:20rpx;color:#0066d6}.tabBarBtn{width:36rpx;height:39rpx}

File diff suppressed because one or more lines are too long

@ -0,0 +1,12 @@
{
"navigationStyle": "custom",
"navigationBarTextStyle": "white",
"usingComponents": {
"u-navbar": "/uni_modules/uview-ui/components/u-navbar/u-navbar",
"u-form": "/uni_modules/uview-ui/components/u-form/u-form",
"u-form-item": "/uni_modules/uview-ui/components/u-form-item/u-form-item",
"u-input": "/uni_modules/uview-ui/components/u-input/u-input",
"u-upload": "/uni_modules/uview-ui/components/u-upload/u-upload",
"shop-card-deatil": "/pages/cloudStore/components/shopDetailCard"
}
}

File diff suppressed because one or more lines are too long

@ -0,0 +1 @@
.apply.data-v-a9968870{height:100vh;background:linear-gradient(270deg,#3975f1,#4aa4f5);display:flex;flex-direction:column}.apply .shop-detail.data-v-a9968870{border-radius:20rpx;display:flex;justify-content:center;margin-bottom:24rpx}.apply .main-body.data-v-a9968870{box-sizing:border-box;background:#f5f6fa;border-radius:20rpx 20rpx 0rpx 0rpx;padding:36rpx;flex:1;overflow:auto}.apply .main-body .item-con.data-v-a9968870{background:#fff;border-radius:20rpx;padding:4rpx 24rpx;margin-bottom:16rpx}.apply .main-body .idCardCon.data-v-a9968870{display:flex;justify-content:space-between;align-items:center;width:100%;margin-top:12rpx}.apply .main-body .idCardCon .idCardImg.data-v-a9968870{width:300rpx;height:200rpx;border-radius:8rpx;object-fit:cover}.apply .main-body .idCardCon .idCardText.data-v-a9968870{font-weight:400;font-size:24rpx;color:#999;margin-left:58rpx}.apply .bottom.data-v-a9968870{height:180rpx;background:#fff}.apply .bottom .saveBtn.data-v-a9968870{width:678rpx;height:92rpx;background:linear-gradient(91deg,#43a1ff,#2f80f9);border-radius:24rpx;font-size:28rpx;color:#fff;padding-top:12rpx}.apply .Item.data-v-a9968870{display:flex;justify-content:space-between;flex-wrap:wrap}.apply .Item .Con.data-v-a9968870{width:284rpx;height:84rpx;background:#f7f7f7;border-radius:8rpx;margin-top:16rpx;font-weight:400;font-size:28rpx;display:flex;align-items:center;padding-left:24rpx}.apply .Item .checked.data-v-a9968870{background:#e9f0fe;color:#2e6bf6}

@ -0,0 +1 @@
(global["webpackJsonp"]=global["webpackJsonp"]||[]).push([["pages/cloudStore/cloudStoreDetail"],{3371:function(n,e,t){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0;var o={components:{dropshipping:function(){t.e("pages/cloudStore/components/dropshipping").then(function(){return resolve(t("93d5"))}.bind(null,t)).catch(t.oe)},couponsAct:function(){t.e("pages/cloudStore/components/couponsAct").then(function(){return resolve(t("e112"))}.bind(null,t)).catch(t.oe)},wholeSales:function(){Promise.all([t.e("common/vendor"),t.e("pages/cloudStore/components/wholeSales")]).then(function(){return resolve(t("b192"))}.bind(null,t)).catch(t.oe)},shopIntroduce:function(){t.e("pages/cloudStore/components/shopIntroduce").then(function(){return resolve(t("c8b8"))}.bind(null,t)).catch(t.oe)}},data:function(){return{background:"transparent",count:5,value:4.5,tabList:[{name:"一键代发",value:"0"},{name:"卡券激活",value:"1"},{name:"批量采购",value:"2"},{name:"商家介绍",value:"3"}],activeID:1}},methods:{clickTab:function(n){this.activeID=n.value}}};e.default=o},"39fa":function(n,e,t){"use strict";t.d(e,"b",(function(){return u})),t.d(e,"c",(function(){return c})),t.d(e,"a",(function(){return o}));var o={uNavbar:function(){return Promise.all([t.e("common/vendor"),t.e("uni_modules/uview-ui/components/u-navbar/u-navbar")]).then(t.bind(null,"71b6"))},uRate:function(){return Promise.all([t.e("common/vendor"),t.e("uni_modules/uview-ui/components/u-rate/u-rate")]).then(t.bind(null,"91c9"))}},u=function(){var n=this.$createElement;this._self._c},c=[]},"58c4":function(n,e,t){"use strict";var o=t("a31d"),u=t.n(o);u.a},8825:function(n,e,t){"use strict";t.r(e);var o=t("3371"),u=t.n(o);for(var c in o)["default"].indexOf(c)<0&&function(n){t.d(e,n,(function(){return o[n]}))}(c);e["default"]=u.a},a31d:function(n,e,t){},e298:function(n,e,t){"use strict";(function(n,e){var o=t("47a9");t("3e3f");o(t("3240"));var u=o(t("f87b"));n.__webpack_require_UNI_MP_PLUGIN__=t,e(u.default)}).call(this,t("3223")["default"],t("df3c")["createPage"])},f87b:function(n,e,t){"use strict";t.r(e);var o=t("39fa"),u=t("8825");for(var c in u)["default"].indexOf(c)<0&&function(n){t.d(e,n,(function(){return u[n]}))}(c);t("58c4");var a=t("828b"),r=Object(a["a"])(u["default"],o["b"],o["c"],!1,null,null,null,!1,o["a"],void 0);e["default"]=r.exports}},[["e298","common/runtime","common/vendor"]]]);

@ -0,0 +1,12 @@
{
"navigationStyle": "custom",
"navigationBarTextStyle": "white",
"usingComponents": {
"u-navbar": "/uni_modules/uview-ui/components/u-navbar/u-navbar",
"u-rate": "/uni_modules/uview-ui/components/u-rate/u-rate",
"dropshipping": "/pages/cloudStore/components/dropshipping",
"coupons-act": "/pages/cloudStore/components/couponsAct",
"whole-sales": "/pages/cloudStore/components/wholeSales",
"shop-introduce": "/pages/cloudStore/components/shopIntroduce"
}
}

@ -0,0 +1 @@
<view class="cloudStoreDeatil"><u-navbar vue-id="2079f2af-1" fixed="true" leftIconColor="#FFF" bgColor="{{background}}" bind:__l="__l"></u-navbar><view class="topImgCon"><image class="topBg" src="https://wx1.sinaimg.cn/large/006WYq6ngy1hrj1dubvugj30u00u0n09.jpg" mode="aspectFill"></image></view><view class="shopTip"><view class="left"><image src="https://wx3.sinaimg.cn/large/006TzZ4Ugy1hs3zsj97f8j31jk1jkqep.jpg"></image></view><view class="right"><view class="box1">啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊</view><view class="box2"><u-rate bind:input="__e" vue-id="2079f2af-2" count="{{count}}" allowHalf="true" value="{{value}}" data-event-opts="{{[['^input',[['__set_model',['','value','$event',[]]]]]]}}" bind:__l="__l"></u-rate><text class="rateValue">{{''+value}}</text></view><view class="box3"><view class="label1"><image src="https://files.hecrab.com/crab-net/cloud-store-list-5.png" mode="aspectFit"></image><text>三码合一</text></view><view class="label2"><image src="https://files.hecrab.com/crab-net/cloud-store-list-1.png" mode="aspectFit"></image><text>验蟹师品质保</text></view></view></view></view><view class="shopBody"><view class="bodyHeader"><block wx:for="{{tabList}}" wx:for-item="item" wx:for-index="index" wx:key="value"><view data-event-opts="{{[['tap',[['clickTab',['$0'],[[['tabList','value',item.value]]]]]]]}}" class="itemBox" bindtap="__e">{{item.name}}</view></block><view class="{{['active','act-'+activeID]}}">{{tabList[activeID].name}}</view></view><view class="body"><block wx:if="{{activeID==0}}"><dropshipping vue-id="2079f2af-3" bind:__l="__l"></dropshipping></block><block wx:if="{{activeID==1}}"><coupons-act vue-id="2079f2af-4" bind:__l="__l"></coupons-act></block><block wx:if="{{activeID==2}}"><whole-sales vue-id="2079f2af-5" bind:__l="__l"></whole-sales></block><block wx:if="{{activeID==3}}"><shop-introduce vue-id="2079f2af-6" bind:__l="__l"></shop-introduce></block></view></view></view>

@ -0,0 +1 @@
.cloudStoreDeatil{min-height:100vh;background:#f5f5f6}.topImgCon{height:300rpx;width:752rpx;overflow-y:hidden}.topBg{width:752rpx;position:relative}.shopTip{width:678rpx;height:176rpx;background:#fff;border-radius:20rpx 20rpx 20rpx 20rpx;display:flex;margin:0 auto;position:absolute;top:248rpx;right:0;left:0;padding:16rpx;box-sizing:border-box}.shopTip .left > image{width:144rpx;height:144rpx;background:#fff;border-radius:20rpx;border:2rpx solid rgba(0,0,0,.1);margin-right:12rpx}.shopTip .right{display:flex;flex-direction:column;justify-content:space-between}.shopTip .right .box1{font-weight:500;font-size:32rpx;color:#000;width:490rpx;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.shopTip .right .box2{display:flex}.shopTip .right .box3{display:flex}.shopTip .right .box3 .label1{width:156rpx;height:42rpx;border-radius:12rpx;border:2rpx solid rgba(6,115,237,.3);display:flex;box-sizing:border-box;padding-top:1rpx;justify-content:center}.shopTip .right .box3 .label1 > image{width:32rpx;height:32rpx}.shopTip .right .box3 .label1 > text{font-weight:500;font-size:24rpx;color:#0673ed}.shopTip .right .box3 .label2{width:204rpx;height:42rpx;border-radius:8rpx;border:2rpx solid rgba(155,118,56,.3);display:flex;box-sizing:border-box;padding-top:1rpx;justify-content:center}.shopTip .right .box3 .label2 > image{width:32rpx;height:32rpx}.shopTip .right .box3 .label2 > text{font-weight:500;font-size:24rpx;color:#9b7638}.shopBody{position:absolute;top:452rpx;background:#fff;left:0;right:0;border-radius:18rpx}.shopBody .bodyHeader{height:196rpx;border-radius:20rpx 20rpx 0rpx 0rpx;background:linear-gradient(91deg,#43a1ff,#2f80f9);display:flex}.shopBody .bodyHeader .itemBox{width:196rpx;font-weight:400;font-size:32rpx;text-align:center;padding-top:36rpx;box-sizing:border-box;color:#fff}.shopBody .bodyHeader .active{width:224rpx;height:135rpx;font-weight:600;font-size:32rpx;color:#0066d6;line-height:45rpx;background-size:100% 100%;bottom:70rpx;box-sizing:border-box}.shopBody .bodyHeader .active.act-0{position:absolute;left:0;background-image:url(https://files.hecrab.com/crab-net/yxs-cloudStore-rate-tab-left.png);padding-top:42rpx;padding-left:20rpx}.shopBody .bodyHeader .active.act-1{position:absolute;left:170rpx;background-image:url(https://files.hecrab.com/crab-net/yxs-cloudStore-rate-tab-center.png);padding-top:42rpx;text-align:center}.shopBody .bodyHeader .active.act-2{position:absolute;left:360rpx;background-image:url(https://files.hecrab.com/crab-net/yxs-cloudStore-rate-tab-center.png);padding-top:42rpx;text-align:center}.shopBody .bodyHeader .active.act-3{position:absolute;right:0;background-image:url(https://files.hecrab.com/crab-net/yxs-cloudStore-rate-tab-right.png);padding-top:42rpx;text-align:center}.shopBody .body{border-radius:18rpx;position:absolute;top:104rpx;box-sizing:border-box}

@ -0,0 +1 @@
(global["webpackJsonp"]=global["webpackJsonp"]||[]).push([["pages/cloudStore/cloudStoreList"],{2473:function(n,t,e){"use strict";(function(n,t){var o=e("47a9");e("3e3f");o(e("3240"));var a=o(e("6787"));n.__webpack_require_UNI_MP_PLUGIN__=e,t(a.default)}).call(this,e("3223")["default"],e("df3c")["createPage"])},6787:function(n,t,e){"use strict";e.r(t);var o=e("d15c"),a=e("823f");for(var u in a)["default"].indexOf(u)<0&&function(n){e.d(t,n,(function(){return a[n]}))}(u);e("d278");var c=e("828b"),r=Object(c["a"])(a["default"],o["b"],o["c"],!1,null,null,null,!1,o["a"],void 0);t["default"]=r.exports},"6afa":function(n,t,e){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0;var o={components:{tabBar:function(){e.e("components/tab-bar").then(function(){return resolve(e("e1f8"))}.bind(null,e)).catch(e.oe)},shopItemVue:function(){e.e("pages/cloudStore/components/shopItem").then(function(){return resolve(e("bb02"))}.bind(null,e)).catch(e.oe)}},data:function(){return{shopList:[{shopName:"susu",shopIcon:"https://wx2.sinaimg.cn/large/00754ABFgy1hrslrtgykuj318g18gwph.jpg",likeValue:2},{shopName:"宋鱼鱼",shopIcon:"https://wx2.sinaimg.cn/large/00754ABFgy1hrslrlxs7sj318g18gk2g.jpg",likeValue:3},{shopName:"信号灯塔",shopIcon:"https://wx2.sinaimg.cn/large/00754ABFgy1hrslrrlp2jj30ze0zejt3.jpg",likeValue:3.5},{shopName:"abcdef",shopIcon:"https://wx3.sinaimg.cn/large/005UJ76vgy1hs2x7gyhsyj30m80m8jty.jpg",likeValue:4}]}},onLoad:function(){},onPullDownRefresh:function(){this.getnewsList()},onReachBottom:function(){},methods:{}};t.default=o},"716b":function(n,t,e){},"823f":function(n,t,e){"use strict";e.r(t);var o=e("6afa"),a=e.n(o);for(var u in o)["default"].indexOf(u)<0&&function(n){e.d(t,n,(function(){return o[n]}))}(u);t["default"]=a.a},d15c:function(n,t,e){"use strict";e.d(t,"b",(function(){return o})),e.d(t,"c",(function(){return a})),e.d(t,"a",(function(){}));var o=function(){var n=this.$createElement;this._self._c},a=[]},d278:function(n,t,e){"use strict";var o=e("716b"),a=e.n(o);a.a}},[["2473","common/runtime","common/vendor"]]]);

@ -0,0 +1,8 @@
{
"navigationBarTitleText": "全部云拣仓",
"enablePullDownRefresh": true,
"usingComponents": {
"tab-bar": "/components/tab-bar",
"shop-item-vue": "/pages/cloudStore/components/shopItem"
}
}

@ -0,0 +1 @@
<view class="cloudStoreList"><block wx:for="{{shopList}}" wx:for-item="item" wx:for-index="__i0__"><view class="shopItemIcon"><shop-item-vue vue-id="{{'3ec49702-1-'+__i0__}}" shopName="{{item.shopName}}" shopIcon="{{item.shopIcon}}" value="{{item.likeValue}}" bind:__l="__l"></shop-item-vue></view></block><tab-bar vue-id="3ec49702-2" current="{{0}}" bind:__l="__l"></tab-bar></view>

@ -0,0 +1 @@
.cloudStoreList{min-height:100vh;background:#f5f5f5}

@ -0,0 +1,10 @@
(global["webpackJsonp"]=global["webpackJsonp"]||[]).push([["pages/cloudStore/components/couponsAct"],{"0eff":function(t,n,e){},"636d":function(t,n,e){"use strict";Object.defineProperty(n,"__esModule",{value:!0}),n.default=void 0;n.default={data:function(){return{cardList:[{state:0},{state:1},{state:2},{state:3},{state:4}]}},methods:{setImage:function(t){var n="http://file.hecrab.com/crab-net/yxs-cloud-store-card-state";return 1!=t&&2!=t||(n+=1),3==t&&(n+=2),4==t&&(n+=3),n+".png"}}}},c6bc:function(t,n,e){"use strict";e.r(n);var u=e("636d"),a=e.n(u);for(var r in u)["default"].indexOf(r)<0&&function(t){e.d(n,t,(function(){return u[t]}))}(r);n["default"]=a.a},d46a:function(t,n,e){"use strict";var u=e("0eff"),a=e.n(u);a.a},e112:function(t,n,e){"use strict";e.r(n);var u=e("f781"),a=e("c6bc");for(var r in a)["default"].indexOf(r)<0&&function(t){e.d(n,t,(function(){return a[t]}))}(r);e("d46a");var o=e("828b"),c=Object(o["a"])(a["default"],u["b"],u["c"],!1,null,null,null,!1,u["a"],void 0);n["default"]=c.exports},f781:function(t,n,e){"use strict";e.d(n,"b",(function(){return a})),e.d(n,"c",(function(){return r})),e.d(n,"a",(function(){return u}));var u={uInput:function(){return Promise.all([e.e("common/vendor"),e.e("uni_modules/uview-ui/components/u-input/u-input")]).then(e.bind(null,"208a"))}},a=function(){var t=this,n=t.$createElement,e=(t._self._c,t.__map(t.cardList,(function(n,e){var u=t.__get_orig(n),a=t._f("formatDate")(n.expirationTime,"yyyy 年 MM 月 dd 日"),r=t.setImage(n.state);return{$orig:u,f0:a,m0:r}})));t.$mp.data=Object.assign({},{$root:{l0:e}})},r=[]}}]);
;(global["webpackJsonp"] = global["webpackJsonp"] || []).push([
'pages/cloudStore/components/couponsAct-create-component',
{
'pages/cloudStore/components/couponsAct-create-component':(function(module, exports, __webpack_require__){
__webpack_require__('df3c')['createComponent'](__webpack_require__("e112"))
})
},
[['pages/cloudStore/components/couponsAct-create-component']]
]);

@ -0,0 +1,6 @@
{
"usingComponents": {
"u-input": "/uni_modules/uview-ui/components/u-input/u-input"
},
"component": true
}

@ -0,0 +1 @@
<view class="coupousAct"><view class="search-header"><u-input vue-id="cb3c985c-1" shape="square" maxlength="-1" placeholder="输入激活码" border="none" fontSize="28rpx" color="#AFAFAF" bind:__l="__l"></u-input><view class="{{['search-btn','act']}}">搜索</view></view><view class="cardBody"><block wx:for="{{$root.l0}}" wx:for-item="item" wx:for-index="__i0__"><view class="{{['card',[(item.$orig.state>2)?'inactive':'']]}}"><view class="left"><view class="code">{{"编号: "+item.$orig.code}}</view><view class="part2"><text class="price">{{item.$orig.price||'/'}}</text><text class="type">{{item.$orig.type+" 498 普通型"}}</text></view><view class="part3">{{'发放主体:'+item.$orig.bodyName+''}}</view><view class="part4">{{'有效期至:'+item.f0+''}}</view></view><view class="right"><block wx:if="{{item.$orig.state==0}}"><view class="active-btn">立即激活</view></block><image class="active-state" src="{{item.m0}}"></image></view><view class="top circle"></view><view class="bottom circle"></view></view></block></view></view>

@ -0,0 +1 @@
@charset "UTF-8";.coupousAct{width:750rpx;min-height:100vh;background:#fff;border-radius:20rpx 20rpx 0rpx 0rpx;padding:24rpx 36rpx;box-sizing:border-box}.search-header{width:678rpx;height:92rpx;background:#f8fafb;border-radius:12rpx;display:flex;align-items:center;justify-content:center;padding:26rpx 0 26rpx 20rpx;box-sizing:border-box}.search-header .search-btn{width:144rpx;height:68rpx;background:#d2d2d2;border-radius:12rpx;text-align:center;font-weight:400;font-size:28rpx;color:#fff;line-height:39rpx;padding-top:14rpx;box-sizing:border-box}.card{width:678rpx;height:206rpx;background:#fef1f0;border-radius:20rpx;padding:24rpx;margin-top:32rpx;box-sizing:border-box;display:flex;justify-content:space-between;position:relative;overflow:hidden}.card.inactive{background:#f4f6f6;color:#afafaf}.card.inactive .left .price{color:#222}.card.inactive .left .price::before{color:#222}.card .left{width:422rpx;height:170rpx;font-size:24rpx;color:#afafaf;line-height:34rpx;text-align:left;display:flex;flex-direction:column;justify-content:space-between;border-right:2rpx dashed #ffc7b8}.card .left .price{font-weight:600;font-size:40rpx;color:red;line-height:56rpx;text-align:left;margin-right:12rpx}.card .left .price::before{content:"¥";font-weight:500;font-size:24rpx;color:red;line-height:34rpx;text-align:left}.card .right{padding:42rpx 16rpx 42rpx 0;box-sizing:border-box;position:relative}.card .right .active-btn{width:136rpx;height:74rpx;background:#ee4d21;border-radius:20rpx;font-weight:500;font-size:24rpx;color:#fff;line-height:34rpx;padding:20rpx;box-sizing:border-box}.card .right .active-state{position:absolute;bottom:-38rpx;right:-28rpx;width:130rpx;height:128rpx}.card .circle{width:30rpx;height:30rpx;border-radius:15rpx;background:#fff;position:absolute;right:216rpx}.card .circle.top{top:-16rpx}.card .circle.bottom{bottom:-16rpx}

@ -0,0 +1,10 @@
(global["webpackJsonp"]=global["webpackJsonp"]||[]).push([["pages/cloudStore/components/dropshipping"],{"01b5":function(e,n,t){"use strict";var u=t("ad78"),o=t.n(u);o.a},"2f46":function(e,n,t){"use strict";Object.defineProperty(n,"__esModule",{value:!0}),n.default=void 0;n.default={data:function(){return{searchKeyword:"",filterList:[{name:"综合",value:0},{name:"价格",value:1},{name:"筛选",value:2}],activeId:0,dataList:[],searchForm:{pageNum:1,pageSize:4,sortType:1,goodsName:"",flagshipShopId:"1",bottomPrice:"",topPrice:"",priceOrderFlag:""},scrollTop:636}},methods:{filterClick:function(e){this.activeId=e.value}}}},"91a7":function(e,n,t){"use strict";t.d(n,"b",(function(){return o})),t.d(n,"c",(function(){return i})),t.d(n,"a",(function(){return u}));var u={uSearch:function(){return Promise.all([t.e("common/vendor"),t.e("uni_modules/uview-ui/components/u-search/u-search")]).then(t.bind(null,"f756"))},uIcon:function(){return Promise.all([t.e("common/vendor"),t.e("uni_modules/uview-ui/components/u-icon/u-icon")]).then(t.bind(null,"3642"))}},o=function(){var e=this.$createElement;this._self._c},i=[]},"93d5":function(e,n,t){"use strict";t.r(n);var u=t("91a7"),o=t("96b9");for(var i in o)["default"].indexOf(i)<0&&function(e){t.d(n,e,(function(){return o[e]}))}(i);t("01b5");var r=t("828b"),a=Object(r["a"])(o["default"],u["b"],u["c"],!1,null,null,null,!1,u["a"],void 0);n["default"]=a.exports},"96b9":function(e,n,t){"use strict";t.r(n);var u=t("2f46"),o=t.n(u);for(var i in u)["default"].indexOf(i)<0&&function(e){t.d(n,e,(function(){return u[e]}))}(i);n["default"]=o.a},ad78:function(e,n,t){}}]);
;(global["webpackJsonp"] = global["webpackJsonp"] || []).push([
'pages/cloudStore/components/dropshipping-create-component',
{
'pages/cloudStore/components/dropshipping-create-component':(function(module, exports, __webpack_require__){
__webpack_require__('df3c')['createComponent'](__webpack_require__("93d5"))
})
},
[['pages/cloudStore/components/dropshipping-create-component']]
]);

@ -0,0 +1,7 @@
{
"usingComponents": {
"u-search": "/uni_modules/uview-ui/components/u-search/u-search",
"u-icon": "/uni_modules/uview-ui/components/u-icon/u-icon"
},
"component": true
}

@ -0,0 +1 @@
<view class="dropshipping"><view class="searchTop"><u-search style="width:270rpx;" vue-id="226dfb3a-1" placeholder="搜索商品" shape="round" height="56rpx" showAction="{{false}}" bind:__l="__l"></u-search><block wx:for="{{filterList}}" wx:for-item="item" wx:for-index="__i0__" wx:key="value"><view data-event-opts="{{[['clear',[['getData',['$event']]]],['tap',[['filterClick',['$0'],[[['filterList','value',item.value]]]]]]]}}" class="{{['filter-item',[(activeId===item.value)?'act':'']]}}" bindclear="__e" bindtap="__e"><text class="filter-name">{{item.name}}</text><u-icon vue-id="{{'226dfb3a-2-'+__i0__}}" name="arrow-down-fill" size="10" bind:__l="__l"></u-icon></view></block></view><view class="detail"><block wx:for="{{10}}" wx:for-item="item" wx:for-index="index"><view class="goodsBox"><image src="https://wx4.sinaimg.cn/large/006TzZ4Ugy1hs3zsjzgkfj31jk1jkwvr.jpg"></image><text class="goodsName">商品名称</text><view class="bottom"><text class="goodsPrice">0.60</text><text class="sales">销量470,000+</text></view></view></block></view></view>

@ -0,0 +1 @@
@charset "UTF-8";.dropshipping{min-height:100vh;background:#fff;border-radius:20rpx 20rpx 0rpx 0rpx}.dropshipping .searchTop{width:750rpx;height:92rpx;display:flex;align-items:center;padding:2rpx;box-sizing:border-box}.dropshipping .searchTop .filter-item{width:124rpx;height:56rpx;border-radius:12rpx;background:#f8fafb;font-size:28rpx;color:#868a9b;display:flex;justify-content:space-between;align-items:center;box-sizing:border-box;padding:0 18rpx;margin-left:8rpx}.dropshipping .searchTop .filter-item.act{color:#222;background:#edeeef;font-weight:600}.dropshipping .detail{padding:36rpx;display:flex;justify-content:space-around;flex-wrap:wrap}.dropshipping .goodsBox{width:328rpx;height:422rpx;flex:1;display:flex;flex-direction:column;justify-content:space-between;margin-bottom:22rpx;margin-right:10rpx}.dropshipping .goodsBox > image{width:328rpx;height:320rpx}.dropshipping .goodsBox .goodsName{font-weight:500;font-size:32rpx}.dropshipping .goodsBox .bottom{display:flex;height:42rpx;text-align:left;position:relative}.dropshipping .goodsBox .bottom .goodsPrice{font-family:OPPOSans;font-weight:700;font-size:32rpx;color:red;position:absolute;left:0;bottom:0}.dropshipping .goodsBox .bottom .goodsPrice::before{content:"¥";font-size:24rpx;color:#ff3c26}.dropshipping .goodsBox .bottom .sales{font-weight:400;font-size:24rpx;color:#666;position:absolute;right:0;bottom:0}

@ -0,0 +1,10 @@
(global["webpackJsonp"]=global["webpackJsonp"]||[]).push([["pages/cloudStore/components/shopDetailCard"],{"05b0":function(n,t){},"0878":function(n,t,e){"use strict";var c=e("1eab"),u=e.n(c);u.a},"1eab":function(n,t,e){},"78ce":function(n,t,e){"use strict";e.r(t);var c=e("05b0"),u=e.n(c);for(var a in c)["default"].indexOf(a)<0&&function(n){e.d(t,n,(function(){return c[n]}))}(a);t["default"]=u.a},cec2:function(n,t,e){"use strict";e.d(t,"b",(function(){return c})),e.d(t,"c",(function(){return u})),e.d(t,"a",(function(){}));var c=function(){var n=this.$createElement;this._self._c},u=[]},fd41:function(n,t,e){"use strict";e.r(t);var c=e("cec2"),u=e("78ce");for(var a in u)["default"].indexOf(a)<0&&function(n){e.d(t,n,(function(){return u[n]}))}(a);e("0878");var r=e("828b"),o=Object(r["a"])(u["default"],c["b"],c["c"],!1,null,null,null,!1,c["a"],void 0);t["default"]=o.exports}}]);
;(global["webpackJsonp"] = global["webpackJsonp"] || []).push([
'pages/cloudStore/components/shopDetailCard-create-component',
{
'pages/cloudStore/components/shopDetailCard-create-component':(function(module, exports, __webpack_require__){
__webpack_require__('df3c')['createComponent'](__webpack_require__("fd41"))
})
},
[['pages/cloudStore/components/shopDetailCard-create-component']]
]);

@ -0,0 +1,4 @@
{
"usingComponents": {},
"component": true
}

@ -0,0 +1 @@
<view class="shopDeatilCard"><view class="left"><view class="top"><view class="shopName">店铺名称</view><view class="bodyName">公司名称</view></view><view class="bottom">提交申请后由对应云拣仓负责人进行审核</view></view><view class="right"><view class="rightText">正在申请</view><image class="rightIamge" src="https://wx4.sinaimg.cn/large/006joT8tgy1hs17gom6tnj30k00k0q4l.jpg"></image></view></view>

@ -0,0 +1 @@
.shopDeatilCard{width:678rpx;height:220rpx;background-size:100% 100%;background-image:url(https://files.hecrab.com/crab-net/yxs-cloudStore-shopDetialCard-bg1.png);display:flex}.shopDeatilCard .left{flex:1;padding:24rpx;display:flex;flex-direction:column;justify-content:space-between}.shopDeatilCard .left .shopName{font-weight:600;font-size:40rpx;color:#000}.shopDeatilCard .left .bodyName{font-weight:400;font-size:28rpx;color:#606266}.shopDeatilCard .left .bottom{font-weight:400;font-size:24rpx;color:#999}.shopDeatilCard .right .rightText{margin-top:16rpx;padding-left:46rpx;right:0;font-weight:500;font-size:24rpx;color:#fff}.shopDeatilCard .right .rightIamge{margin:28rpx;width:120rpx;height:120rpx;background:#e7e7e7;border-radius:12rpx 12rpx 12rpx 12rpx}

@ -0,0 +1,10 @@
(global["webpackJsonp"]=global["webpackJsonp"]||[]).push([["pages/cloudStore/components/shopIntroduce"],{3884:function(n,t,u){},"402d":function(n,t,u){"use strict";var o=u("3884"),e=u.n(o);e.a},4408:function(n,t,u){"use strict";u.d(t,"b",(function(){return e})),u.d(t,"c",(function(){return c})),u.d(t,"a",(function(){return o}));var o={uIcon:function(){return Promise.all([u.e("common/vendor"),u.e("uni_modules/uview-ui/components/u-icon/u-icon")]).then(u.bind(null,"3642"))}},e=function(){var n=this.$createElement;this._self._c},c=[]},8576:function(n,t,u){"use strict";u.r(t);var o=u("a50b"),e=u.n(o);for(var c in o)["default"].indexOf(c)<0&&function(n){u.d(t,n,(function(){return o[n]}))}(c);t["default"]=e.a},a50b:function(n,t){},c8b8:function(n,t,u){"use strict";u.r(t);var o=u("4408"),e=u("8576");for(var c in e)["default"].indexOf(c)<0&&function(n){u.d(t,n,(function(){return e[n]}))}(c);u("402d");var r=u("828b"),i=Object(r["a"])(e["default"],o["b"],o["c"],!1,null,null,null,!1,o["a"],void 0);t["default"]=i.exports}}]);
;(global["webpackJsonp"] = global["webpackJsonp"] || []).push([
'pages/cloudStore/components/shopIntroduce-create-component',
{
'pages/cloudStore/components/shopIntroduce-create-component':(function(module, exports, __webpack_require__){
__webpack_require__('df3c')['createComponent'](__webpack_require__("c8b8"))
})
},
[['pages/cloudStore/components/shopIntroduce-create-component']]
]);

@ -0,0 +1,6 @@
{
"usingComponents": {
"u-icon": "/uni_modules/uview-ui/components/u-icon/u-icon"
},
"component": true
}

@ -0,0 +1 @@
<view class="shopIntroduce"><view class="part1"><image src="https://files.hecrab.com/crab-net/yxs-cloud-store-vrCenterLogo.png"></image></view><view class="part2"><view class="item"><text class="firstC">2000m²</text><view class="_br"></view><text class="secondC">仓库面积</text></view><view class="item"><text class="firstC">900m²</text><view class="_br"></view><text class="secondC">暂养池</text></view><view class="item"><text class="firstC">21</text><view class="_br"></view><text class="secondC">员工数</text></view><view class="item"><text class="firstC">12121</text><view class="_br"></view><text class="secondC">日均发货量(斤)</text></view><view class="bottom"><view class="bottom-box"><image class="left-icon" src="https://files.hecrab.com/crab-net/yxs-cloudStore-body-icon.png"></image><text>南京良庄农产品有限公司</text><u-icon vue-id="141ad01c-1" name="arrow-right" size="14" color="#000000" bind:__l="__l"></u-icon></view><view class="bottom-box"><image class="left-icon" src="https://files.hecrab.com/crab-net/yxs-cloudStore-map-icon.png"></image><text>江苏省南京市高淳区淳溪路22号</text><u-icon vue-id="141ad01c-2" name="arrow-right" size="14" color="#000000" bind:__l="__l"></u-icon></view></view></view><view class="part3"><view class="left"><view class="top3"><image class="top3-icon" src="https://files.hecrab.com/crab-net/yxs-cloudStore-checkman-icon-left.png"></image><view class="top3-text">验蟹师品质保障</view><image class="top3-icon" src="https://files.hecrab.com/crab-net/yxs-cloudStore-checkman-icon-right.png"></image></view><view class="bottom3">验蟹师承诺螃蟹绝无缺斤少两,如遇消费者投诉云拣仓将进行双倍赔付。</view></view><view class="right"><image class="medal" src="https://files.hecrab.com/crab-net/yxs-cloudStore-checkman-icon-medal.png"></image></view></view><view class="part4"><view class="top4"><text class="left-text">云拣仓展示</text><text class="more">更多</text></view><view class="bottom4"><view class="bottom-box4"><image src="https://wx3.sinaimg.cn/large/008eGzyTly1hs8atswuhtj31be1bewop.jpg"></image><view class="image-bottom">入口</view></view><view class="bottom-box4"><image src="https://wx3.sinaimg.cn/large/008eGzyTly1hs8atswuhtj31be1bewop.jpg"></image><view class="image-bottom">入口</view></view><view class="bottom-box4"><image src="https://wx3.sinaimg.cn/large/008eGzyTly1hs8atswuhtj31be1bewop.jpg"></image><view class="image-bottom">入口</view></view><view class="bottom-box4"><image src="https://wx3.sinaimg.cn/large/008eGzyTly1hs8atswuhtj31be1bewop.jpg"></image><view class="image-bottom">入口</view></view></view></view><view class="part5"><view class="top5">经营表现</view><view class="bottom5"><view class="bottom-box5"><text class="firstC">1212</text><view class="_br"></view><text class="secondC">近30日订单</text></view><view class="bottom-box5"><text class="firstC">99%</text><view class="_br"></view><text class="secondC">发货准时率</text></view><view class="bottom-box5"><text class="firstC">3</text><view class="_br"></view><text class="secondC">近30日理赔</text></view></view></view><view class="blank"></view><view class="inputBtnCon"><view class="inputBtn">申请成为代理</view></view></view>

@ -0,0 +1 @@
.shopIntroduce{padding:48rpx 36rpx 0 36rpx;min-height:100vh;background:#fff;width:750rpx;border-radius:20rpx 20rpx 0rpx 0rpx;box-sizing:border-box}.part1{width:678rpx;height:300rpx;background:#fff;border-radius:20rpx;margin-bottom:16rpx;background-image:url(https://wx4.sinaimg.cn/large/a6949f40ly1hmwuc3yktyj20wt0wt47z.jpg);display:flex;align-items:center}.part1 > image{width:140rpx;height:140rpx;margin:0 auto}.part2{width:678rpx;height:420rpx;background:#f5f5f6;border-radius:20rpx;margin-bottom:16rpx;display:flex;justify-content:space-between;flex-wrap:wrap;padding:24rpx;box-sizing:border-box}.part2 .item{width:310rpx;height:120rpx;background:#fff;border-radius:12rpx;text-align:center;padding-top:16rpx;box-sizing:border-box}.part2 .bottom{width:632rpx}.part2 .bottom .bottom-box{height:40rpx;display:flex;align-items:center;margin-top:20rpx}.part2 .bottom .bottom-box .left-icon{width:40rpx;height:40rpx}.part2 .bottom .bottom-box > text{font-weight:400;font-size:28rpx;color:#000;flex:1;margin-left:12rpx}.part3{width:678rpx;height:204rpx;background:linear-gradient(180deg,#fff5e9,#fff);border-radius:20rpx;border:2rpx solid #f3e8de;margin-bottom:16rpx;padding:24rpx;box-sizing:border-box;display:flex}.part3 .left .top3{display:flex}.part3 .left .top3 .top3-icon{width:36rpx;height:36rpx}.part3 .left .top3 .top3-text{font-weight:500;font-size:32rpx;color:#8b511e;line-height:38rpx;text-align:left}.part3 .left .bottom3{width:510rpx;height:80rpx;font-weight:400;font-size:28rpx;color:#666;line-height:33rpx;text-align:left;margin-top:32rpx}.part3 .medal{width:88rpx;height:88rpx;background:#fbefe3;margin-left:22rpx}.part4{width:678rpx;height:272rpx;background:#f5f5f6;border-radius:20rpx;margin-bottom:16rpx;padding:24rpx;box-sizing:border-box}.part4 .top4{display:flex;justify-content:space-between}.part4 .top4 .left-text{font-weight:600;font-size:32rpx;color:#000;line-height:45rpx;text-align:left}.part4 .top4 .more{font-weight:400;font-size:24rpx;color:#000;line-height:34rpx}.part4 .bottom4{display:flex;justify-content:space-between;box-sizing:border-box;margin-top:32rpx}.part4 .bottom4 .bottom-box4{width:148rpx;height:148rpx;background:#e2e2e2;border-radius:12rpx;overflow:hidden;position:relative}.part4 .bottom4 .bottom-box4 > image{width:100%;height:100%;position:absolute}.part4 .bottom4 .bottom-box4 .image-bottom{position:absolute;bottom:0;width:148rpx;height:44rpx;background:rgba(0,0,0,.4);border-radius:0rpx;font-weight:400;font-size:20rpx;color:#fff;text-align:center;line-height:44rpx}.part5{width:678rpx;height:244rpx;background:#f5f5f6;border-radius:20rpx;margin-bottom:16rpx;padding:24rpx;box-sizing:border-box}.part5 .top5{font-weight:600;font-size:32rpx;color:#000}.part5 .bottom5{display:flex;justify-content:space-between}.part5 .bottom5 .bottom-box5{margin-top:32rpx;width:202rpx;height:120rpx;background:#fff;border-radius:12rpx;text-align:center;padding-top:16rpx;box-sizing:border-box}.firstC{font-weight:500;font-size:40rpx;color:#000;margin:0 auto}.secondC{font-weight:400;font-size:24rpx;color:#999;text-align:center}.blank{height:200rpx}.inputBtnCon{height:180rpx;background:#fff;bottom:0;position:fixed;padding-top:20rpx}.inputBtnCon .inputBtn{width:678rpx;height:92rpx;background:linear-gradient(91deg,#43a1ff,#2f80f9);border-radius:24rpx;font-weight:500;font-size:28rpx;color:#fff;line-height:39rpx;text-align:center;padding-top:26rpx;box-sizing:border-box}

@ -0,0 +1,10 @@
(global["webpackJsonp"]=global["webpackJsonp"]||[]).push([["pages/cloudStore/components/shopItem"],{"4c97":function(e,n,t){"use strict";var u=t("6313"),r=t.n(u);r.a},"51bd":function(e,n,t){"use strict";t.d(n,"b",(function(){return r})),t.d(n,"c",(function(){return o})),t.d(n,"a",(function(){return u}));var u={uRate:function(){return Promise.all([t.e("common/vendor"),t.e("uni_modules/uview-ui/components/u-rate/u-rate")]).then(t.bind(null,"91c9"))}},r=function(){var e=this.$createElement;this._self._c},o=[]},"5ab9":function(e,n,t){"use strict";t.r(n);var u=t("b4c6"),r=t.n(u);for(var o in u)["default"].indexOf(o)<0&&function(e){t.d(n,e,(function(){return u[e]}))}(o);n["default"]=r.a},6313:function(e,n,t){},b4c6:function(e,n,t){"use strict";Object.defineProperty(n,"__esModule",{value:!0}),n.default=void 0;var u={props:{shopName:{type:String,required:!0},shopIcon:{type:String,required:!0},value:{type:Number,required:!0}},data:function(){return{count:5,sales:28773,value:this.value}}};n.default=u},bb02:function(e,n,t){"use strict";t.r(n);var u=t("51bd"),r=t("5ab9");for(var o in r)["default"].indexOf(o)<0&&function(e){t.d(n,e,(function(){return r[e]}))}(o);t("4c97");var a=t("828b"),i=Object(a["a"])(r["default"],u["b"],u["c"],!1,null,null,null,!1,u["a"],void 0);n["default"]=i.exports}}]);
;(global["webpackJsonp"] = global["webpackJsonp"] || []).push([
'pages/cloudStore/components/shopItem-create-component',
{
'pages/cloudStore/components/shopItem-create-component':(function(module, exports, __webpack_require__){
__webpack_require__('df3c')['createComponent'](__webpack_require__("bb02"))
})
},
[['pages/cloudStore/components/shopItem-create-component']]
]);

@ -0,0 +1,6 @@
{
"usingComponents": {
"u-rate": "/uni_modules/uview-ui/components/u-rate/u-rate"
},
"component": true
}

@ -0,0 +1 @@
<view class="shopItem"><view class="left"><image class="shopIcon" src="{{shopIcon}}"></image></view><view class="right"><text class="shopTitle">{{shopName}}</text><view class="secondPart"><u-rate bind:input="__e" vue-id="a6cf24a4-1" count="{{count}}" allowHalf="true" value="{{value}}" data-event-opts="{{[['^input',[['__set_model',['','value','$event',[]]]]]]}}" bind:__l="__l"></u-rate><text class="rateValue">{{value}}</text><text class="sales">{{"月售 "+sales}}</text></view><view class="thridPart"><view class="label1"><image src="https://files.hecrab.com/crab-net/cloud-store-list-1.png" mode="aspectFit"></image><text>验蟹师品质保</text></view><view class="label2"><image src="https://files.hecrab.com/crab-net/cloud-store-list-2.png" mode="aspectFit"></image><text>一件代发</text></view><view class="label3"><image src="https://files.hecrab.com/crab-net/cloud-store-list-3.png" mode="aspectFit"></image><text>批发</text></view></view><view class="shopCommodity"><block wx:for="{{10}}" wx:for-item="item" wx:for-index="__i0__"><view class="shopCommodityCon"><image src="https://wx3.sinaimg.cn/large/006upAuggy1hs44n9w981j30u00u0te3.jpg"></image><text>susu福福</text><view class="price">0.60</view></view></block></view></view></view>

@ -0,0 +1 @@
@charset "UTF-8";.shopItem{width:678rpx;height:396rpx;background:#fff;border-radius:20rpx;padding:16rpx;margin:0 auto;display:flex;margin-top:20rpx}.shopIcon{width:144rpx;height:144rpx;background:#fff;border-radius:20rpx 20rpx 20rpx 20rpx;border:2rpx solid rgba(0,0,0,.1)}.right{margin-left:12rpx;width:490rpx;height:364rpx}.right .shopTitle{font-size:32rpx;font-weight:600}.right .secondPart{width:490rpx;height:34rpx;border-radius:0rpx 0rpx 0rpx 0rpx;display:flex;margin-top:16rpx;position:relative}.right .secondPart .rateValue{font-weight:400;font-size:24rpx;color:#ff480b;line-height:34rpx;margin-left:4rpx}.right .secondPart .sales{text-align:center;position:absolute;right:0;font-weight:400;font-size:24rpx;color:#999;line-height:34rpx}.right .thridPart{width:492rpx;height:42rpx;margin-top:18rpx;display:flex;justify-content:space-between}.right .thridPart .label1{width:204rpx;border-radius:8rpx 8rpx 8rpx 8rpx;border:2rpx solid rgba(155,118,56,.3);display:flex;justify-content:center}.right .thridPart .label1 > image{width:32rpx;height:32rpx}.right .thridPart .label1 > text{font-weight:500;font-size:24rpx;color:#9b7638;margin-left:2rpx}.right .thridPart .label2{width:156rpx;border-radius:12rpx;border:2rpx solid rgba(6,115,237,.3);display:flex;justify-content:center}.right .thridPart .label2 > image{width:32rpx;height:32rpx}.right .thridPart .label2 > text{font-weight:500;font-size:24rpx;color:#0673ed;margin-left:2rpx}.right .thridPart .label3{width:108rpx;border-radius:8rpx;border:2rpx solid rgba(249,64,64,.3);display:flex;justify-content:center}.right .thridPart .label3 > image{width:32rpx;height:32rpx}.right .thridPart .label3 > text{font-weight:500;font-size:24rpx;color:#f94040;margin-left:2rpx}.right .shopCommodity{width:506rpx;height:196rpx;margin-top:20rpx;display:flex;overflow-x:auto}.right .shopCommodity .shopCommodityCon{width:120rpx;height:196rpx;margin-right:20rpx}.right .shopCommodity .shopCommodityCon > image{width:120rpx;height:120rpx}.right .shopCommodity .shopCommodityCon > text{font-weight:300;font-size:24rpx;color:#999}.right .shopCommodity .shopCommodityCon .price{font-weight:500;font-size:24rpx;color:#ff3c26}.right .shopCommodity .shopCommodityCon .price::before{content:"¥";font-size:20rpx;color:#ff3c26}

@ -0,0 +1,10 @@
(global["webpackJsonp"]=global["webpackJsonp"]||[]).push([["pages/cloudStore/components/wholeSales"],{"0f4c":function(e,n,u){"use strict";u.d(n,"b",(function(){return o})),u.d(n,"c",(function(){return i})),u.d(n,"a",(function(){return t}));var t={uPicker:function(){return Promise.all([u.e("common/vendor"),u.e("uni_modules/uview-ui/components/u-picker/u-picker")]).then(u.bind(null,"eb84"))},uIcon:function(){return Promise.all([u.e("common/vendor"),u.e("uni_modules/uview-ui/components/u-icon/u-icon")]).then(u.bind(null,"3642"))},uNumberBox:function(){return Promise.all([u.e("common/vendor"),u.e("uni_modules/uview-ui/components/u-number-box/u-number-box")]).then(u.bind(null,"3306"))}},o=function(){var e=this,n=e.$createElement;e._self._c;e._isMounted||(e.e0=function(n){e.show=!1},e.e1=function(n){e.show=!0})},i=[]},2801:function(e,n,u){"use strict";var t=u("4363"),o=u.n(t);o.a},3416:function(e,n,u){"use strict";var t=u("47a9");Object.defineProperty(n,"__esModule",{value:!0}),n.default=void 0;t(u("adf1"));n.default={data:function(){return{clist:[{type:"6.0公",price:"50.60",value:0},{type:"5.5公",price:"50.60",value:0},{type:"5.0公",price:"50.60",value:0},{type:"6.0母",price:"50.60",value:0},{type:"6.0公",price:"50.60",value:0},{type:"6.0公",price:"50.60",value:0},{type:"6.0公",price:"50.60",value:0},{type:"6.0公",price:"50.60",value:0}],allValue:2888,allPrice:2888888,show:!1,columns:[["50规格","49规格","38规格"]],index:0}},methods:{valChange:function(e){},confirm:function(e){this.show=!1,this.index=e.indexs[0]}}}},4363:function(e,n,u){},"82f7":function(e,n,u){"use strict";u.r(n);var t=u("3416"),o=u.n(t);for(var i in t)["default"].indexOf(i)<0&&function(e){u.d(n,e,(function(){return t[e]}))}(i);n["default"]=o.a},b192:function(e,n,u){"use strict";u.r(n);var t=u("0f4c"),o=u("82f7");for(var i in o)["default"].indexOf(i)<0&&function(e){u.d(n,e,(function(){return o[e]}))}(i);u("2801");var c=u("828b"),r=Object(c["a"])(o["default"],t["b"],t["c"],!1,null,null,null,!1,t["a"],void 0);n["default"]=r.exports}}]);
;(global["webpackJsonp"] = global["webpackJsonp"] || []).push([
'pages/cloudStore/components/wholeSales-create-component',
{
'pages/cloudStore/components/wholeSales-create-component':(function(module, exports, __webpack_require__){
__webpack_require__('df3c')['createComponent'](__webpack_require__("b192"))
})
},
[['pages/cloudStore/components/wholeSales-create-component']]
]);

@ -0,0 +1,8 @@
{
"usingComponents": {
"u-picker": "/uni_modules/uview-ui/components/u-picker/u-picker",
"u-icon": "/uni_modules/uview-ui/components/u-icon/u-icon",
"u-number-box": "/uni_modules/uview-ui/components/u-number-box/u-number-box"
},
"component": true
}

@ -0,0 +1 @@
<view class="wholeSales"><view class="top"><text>批发规格</text><view><u-picker class="vue-ref" vue-id="d3ed9efc-1" show="{{show}}" columns="{{columns}}" data-ref="uPicker" data-event-opts="{{[['^cancel',[['e0']]],['^confirm',[['confirm']]]]}}" bind:cancel="__e" bind:confirm="__e" bind:__l="__l"></u-picker><view data-event-opts="{{[['tap',[['e1',['$event']]]]]}}" class="openBtn" bindtap="__e">{{''+columns[0][index]+''}}<u-icon vue-id="d3ed9efc-2" name="arrow-down-fill" bind:__l="__l"></u-icon></view></view></view><view class="body"><block wx:for="{{clist}}" wx:for-item="item" wx:for-index="__i0__"><view class="item"><view class="type-price"><text class="ctype">{{item.type}}</text><text class="price">{{item.price}}</text></view><view class="bottom"><text class="bottom-text">批发重量(斤)</text><u-number-box vue-id="{{'d3ed9efc-3-'+__i0__}}" button-size="30" value="{{item.value}}" data-event-opts="{{[['^change',[['valChange']]],['^input',[['__set_model',['$0','value','$event',[]],[[['clist','',__i0__]]]]]]]}}" bind:change="__e" bind:input="__e" bind:__l="__l"></u-number-box></view></view></block></view><view class="wholeSales-bottom"><view class="tip">当前未满足 50 斤最低起批量,无法下单</view><view class="inputBtnCon"><view class="left">共<text class="allValue">{{allValue}}</text>斤<view class="_br"></view><text>共计金额</text></view><view class="allPrice"><text>{{allPrice}}</text></view><button class="inputBtn">批发下单</button></view></view></view>

@ -0,0 +1 @@
@charset "UTF-8";.wholeSales{min-height:100vh;width:750rpx;background:#fff;box-sizing:border-box;padding-left:38rpx;border-radius:20rpx 20rpx 0rpx 0rpx}.wholeSales .top{height:92rpx;display:flex}.wholeSales .top > text{font-weight:400;font-size:28rpx;color:#afafaf;margin:32rpx 0 0 32rpx}.wholeSales .top .openBtn{width:220rpx;height:56rpx;background:#edeeef;border-radius:12rpx 12rpx 12rpx 12rpx;display:flex;justify-content:space-between;padding:8rpx 20rpx;margin:24rpx 0 12rpx 18rpx;box-sizing:border-box;font-weight:600;font-size:28rpx;color:#222}.wholeSales .body .item{margin:0 auto;width:676rpx;height:140rpx;border-bottom:2rpx solid rgba(0,0,0,.06);display:flex;flex-direction:column;justify-content:space-between;flex-wrap:wrap;margin-top:24rpx;padding-bottom:28rpx;box-sizing:border-box}.wholeSales .body .item .type-price{display:flex;justify-content:space-between;flex-wrap:wrap}.wholeSales .body .item .type-price .ctype{font-weight:600;font-size:32rpx;color:#222;width:90rpx;text-align-last:justify}.wholeSales .body .item .type-price .price{font-family:OPPOSans;font-weight:700;font-size:32rpx;color:red}.wholeSales .body .item .type-price .price::before{content:"¥";font-size:24rpx;margin-right:4rpx}.wholeSales .body .item .bottom{display:flex;justify-content:space-between;flex-wrap:wrap}.wholeSales .body .item .bottom .bottom-text{font-weight:400;font-size:24rpx;color:#afafaf;margin-top:34rpx}.wholeSales .wholeSales-bottom{position:fixed;bottom:0;z-index:100}.wholeSales .tip{width:750rpx;height:72rpx;background:#fff7e8;border-radius:0rpx 0rpx 0rpx 0rpx;border:0rpx solid #fff7e8;font-weight:400;font-size:28rpx;color:#ff7d00;justify-content:center;padding:16rpx 0 16rpx 32rpx;box-sizing:border-box}.wholeSales .inputBtnCon{width:100%;height:184rpx;background:#fff;display:flex}.wholeSales .inputBtnCon .left{height:74rpx;font-weight:400;font-size:24rpx;color:rgba(0,0,0,.3);margin-top:42rpx;text-align-last:justify;margin-right:12rpx}.wholeSales .inputBtnCon .left .allValue{font-weight:600;font-size:30rpx;color:#222}.wholeSales .inputBtnCon .allPrice{margin-top:46rpx;width:148rpx;height:68rpx;font-weight:500;font-size:48rpx;color:#ff2d46;line-height:67rpx;text-align:right;margin-right:12rpx}.wholeSales .inputBtnCon .allPrice::before{content:"¥";font-size:24rpx;margin-right:4rpx}.wholeSales .inputBtnCon .inputBtn{width:346rpx;height:92rpx;background:linear-gradient(91deg,#43a1ff,#2f80f9),#fff;border-radius:24rpx;font-weight:500;font-size:28rpx;color:#fff;margin-top:24rpx;padding-top:10rpx;box-sizing:border-box}

@ -0,0 +1 @@
(global["webpackJsonp"]=global["webpackJsonp"]||[]).push([["pages/index/index"],{"4e4c":function(n,e,t){"use strict";t.r(e);var c=t("f8df"),u=t("8fd8");for(var o in u)["default"].indexOf(o)<0&&function(n){t.d(e,n,(function(){return u[n]}))}(o);t("676c");var a=t("828b"),r=Object(a["a"])(u["default"],c["b"],c["c"],!1,null,null,null,!1,c["a"],void 0);e["default"]=r.exports},"58b7":function(n,e,t){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0;var c={components:{tabBar:function(){t.e("components/tab-bar").then(function(){return resolve(t("e1f8"))}.bind(null,t)).catch(t.oe)}},data:function(){return{title:"Hello"}},onLoad:function(){},methods:{}};e.default=c},"676c":function(n,e,t){"use strict";var c=t("911e"),u=t.n(c);u.a},"8fd8":function(n,e,t){"use strict";t.r(e);var c=t("58b7"),u=t.n(c);for(var o in c)["default"].indexOf(o)<0&&function(n){t.d(e,n,(function(){return c[n]}))}(o);e["default"]=u.a},"911e":function(n,e,t){},c65e:function(n,e,t){"use strict";(function(n,e){var c=t("47a9");t("3e3f");c(t("3240"));var u=c(t("4e4c"));n.__webpack_require_UNI_MP_PLUGIN__=t,e(u.default)}).call(this,t("3223")["default"],t("df3c")["createPage"])},f8df:function(n,e,t){"use strict";t.d(e,"b",(function(){return c})),t.d(e,"c",(function(){return u})),t.d(e,"a",(function(){}));var c=function(){var n=this.$createElement;this._self._c},u=[]}},[["c65e","common/runtime","common/vendor"]]]);

@ -0,0 +1,6 @@
{
"navigationBarTitleText": "uni-app",
"usingComponents": {
"tab-bar": "/components/tab-bar"
}
}

@ -0,0 +1 @@
<view class="content"><image class="logo" src="/static/logo.png"></image><view class="text-area"><text class="title">{{title}}</text></view><tab-bar vue-id="8dd740cc-1" current="{{1}}" bind:__l="__l"></tab-bar></view>

@ -0,0 +1 @@
.content{display:flex;flex-direction:column;align-items:center;justify-content:center}.logo{height:200rpx;width:200rpx;margin-top:200rpx;margin-left:auto;margin-right:auto;margin-bottom:50rpx}.text-area{display:flex;justify-content:center}.title{font-size:36rpx;color:#8f8f94}

@ -0,0 +1,29 @@
{
"description": "项目配置文件。",
"packOptions": {
"ignore": [],
"include": []
},
"setting": {
"urlCheck": false,
"es6": false,
"postcss": false,
"minified": false,
"newFeature": true,
"bigPackageSizeSupport": true,
"babelSetting": {
"ignore": [],
"disablePlugins": [],
"outputPath": ""
}
},
"compileType": "miniprogram",
"libVersion": "3.5.3",
"appid": "wx423c9a965e959576",
"projectname": "3",
"condition": {},
"editorSetting": {
"tabIndent": "insertSpaces",
"tabSize": 2
}
}

@ -0,0 +1,20 @@
{
"description": "项目私有配置文件。此文件中的内容将覆盖 project.config.json 中的相同字段。项目的改动优先同步到此文件中。详见文档https://developers.weixin.qq.com/miniprogram/dev/devtools/projectconfig.html",
"projectname": "3",
"setting": {
"compileHotReLoad": true
},
"condition": {
"miniprogram": {
"list": [
{
"name": "pages/cloudStore/cloudStoreDetail",
"pathName": "pages/cloudStore/cloudStoreDetail",
"query": "",
"launchMode": "default",
"scene": null
}
]
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 984 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 794 B

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save