You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

223 lines
5.6 KiB
Vue

1 year ago
<template>
<view class="tm-pullBottom">
<scroll-view
class="tm-pullBottom-sroll"
:refresher-enabled="disabled"
:refresher-threshold="pullY"
:refresher-triggered="isRefresh"
:scroll-y="true"
refresher-default-style="none"
:lower-threshold="bottomY"
@scrolltolower="pullBottom"
@refresherpulling="onPulling"
@refresherrefresh="onRefresh"
@refresherrestore="onRestore"
@refresherabort="onAbort"
:style="{
height:activeHeight+'px'
}">
<view v-if="bottomLoadding==true" class="tm-pullBottom-top flex-center flex-col">
<view v-if="loading">
<view>
<slot name="pull" v-if="isPullDown==true&&showScrollPic">
<view class="tm-pullBottom-top-icon flex-center pull"
>
<tm-icons :color="color" name="icon-long-arrow-up"></tm-icons>
</view>
<view class="flex-center tm-pullBottom-top-text text-size-n"
:class="[`text-${color}`]">继续下拉刷新</view>
</slot>
<slot name="pullReresh" v-if="isPullDown==false&&showScrollPic">
<view class="tm-pullBottom-top-icon flex-center "
>
<tm-icons :color="color" name="icon-long-arrow-up"></tm-icons>
</view>
<view class="flex-center tm-pullBottom-top-text text-size-n"
:class="[`text-${color}`]" >松开刷新</view>
</slot>
</view>
<tm-loadding v-if="showScrollPic==false" ></tm-loadding>
</view>
</view>
<slot name="default"></slot>
<tm-loadding v-if="bottomLoadding==false&&loading" ></tm-loadding>
</scroll-view>
</view>
</template>
<script>
/**
* 上拉触底刷新
* @property {String|Number} height = [] 默认0默认0使用父高度
* @property {Number} pullY = [] 默认80下拉多长的距离执行刷新
* @property {Number} bottomY = [] 默认0离底部多高度多少执行加载
* @property {String} color = [] 默认primary主题色
* @property {Boolean} loading = [] 默认 false需要loading.sync执行双向绑定加载状态true加载中false加载完成
* @property {Boolean} disabled = [] 默认 true是否启用下拉刷新不影响触底刷新功能
* @property {Boolean} finish = [] 默认 false是否数据没有了如果为true触底后将不会触发刷新操作
* @property {Function} refresh 当下拉或者触底时触发此函数参数e=pull为下拉刷新bottom为触底刷新
* @example <tm-pullBottom :loading.sync="loading" @refresh="getdata"></tm-pullBottom>
*/
import tmIcons from "@/tm-vuetify/components/tm-icons/tm-icons.vue"
import tmLoadding from "@/tm-vuetify/components/tm-loadding/tm-loadding.vue"
export default {
components:{tmIcons,tmLoadding},
name:"tm-pullBottom",
props:{
// 高度默认为0时自动使用父组件的高度.
height: {
type: String | Number,
default: 0
},
pullY:{
type: Number,
default: 80
},
bottomY:{
type: Number,
default: 0
},
color: {
type: String,
default: 'primary'
},
loading:{
type:Boolean,
default:false
},
// 是否没有更多数据了。
finish:{
type:Boolean,
default:false
},
disabled:{
type:Boolean,
default:true
}
},
watch:{
loading:function(newval){
if(newval==false){
// 结束操作。
this.susscess();
}
},
},
data() {
return {
activeHeight: 0,
isRefresh:false,//是否触发了下拉刷新区域。
freshing:false,//是否刷新 中。
showScrollPic:false,//是否拖动了下拉区域,显示图标。停止不显示。
isPullDown:false,//是否下正确的下拉刷新区域。
bottomLoadding:true,//当前是底部还是顶部刷新操作。false为底部。true为顶部。
};
},
computed:{
},
mounted() {
this.guid = uni.$tm.guid();
let t = this;
this.$nextTick(async function() {
this.activeHeight = uni.upx2px(this.height);
if (!this.activeHeight) {
let wsz = await this.$Querey(".tm-pullBottom",this).catch(e=>{})
this.activeHeight = wsz[0].height||150;
}
if(this.loading===true){
this.$emit('update:loading',false)
}
});
},
methods: {
onRefresh(e) {
let t = this;
this.isRefresh = true;
setTimeout(function() {
t.isRefresh = false;
t.showScrollPic = false;
if(t.freshing==true) return;
t.freshing = true;
t.pullChangeOk();
}, 200);
},
onPulling(e){
if(this.loading === false){
this.$emit('update:loading',true)
}
this.bottomLoadding = true;
this.showScrollPic = true;//显示刷新 图标。
let dy = e.target.dy || 0
// #ifdef H5
dy = e.target.deltaY;
// #endif
if(dy < this. pullY){
this.isPullDown = true;
}else{
this.isPullDown = false;
}
},
onAbort(e){
this.$emit('update:loading',false)
this.showScrollPic = false;//显示刷新 图标。
},
onRestore(e){
this.isRefresh = 'restore'; // 需要重置
},
// 结束操作。
susscess(){
this.freshing = false;
this.$emit('update:loading',false)
},
pullChangeOk(){
this.$emit("refresh",'pull')
},
// 触底加载中。
pullBottom(){
if(this.finish) return;
this.bottomLoadding = false;
if(this.loading === false){
this.$emit('update:loading',true)
this.$emit("refresh",'bottom')
}
},
},
}
</script>
<style lang="scss" scoped>
.tm-pullBottom{
height: 100%;
.tm-pullBottom-sroll{
position: relative;
.tm-pullBottom-top{
width: 100%;
position: relative;
.tm-pullBottom-top-icon{
transition: all 0.5s;
&.pull{
transform: rotate(180deg);
}
}
}
}
}
</style>