Csqqqqq 6 months 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