223 lines
5.6 KiB
Vue
223 lines
5.6 KiB
Vue
<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>
|