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

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<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>