123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209 |
- <template>
- <view class="load-refresh">
- <!-- 刷新动画 -->
- <animation :type="refreshType" :color="color" :playState="playState"></animation>
- <view class="cover-container" :style="[{
- background: backgroundCover,
- transform: coverTransform,
- transition: coverTransition
- }]"
- @touchstart="coverTouchstart" @touchmove="coverTouchmove" @touchend="coverTouchend">
- <scroll-view scroll-y show-scrollbar="true" class="list" :scroll-top="scrollTop" @scrolltolower="loadMore" :style="getHeight">
- <!-- 数据集插槽 -->
- <slot name="content-list"></slot>
- <!-- 上拉加载 -->
- <view class="load-more" v-if="isPaging">{{loadText}}</view>
- </scroll-view>
- </view>
- </view>
- </template>
- <script>
- import animation from './animation.vue'
- export default {
- name: 'loadRefresh',
- components: {
- animation
- },
- props: {
- isRefresh: {
- type: Boolean,
- default: true
- },
- refreshTime: {
- type: String,
- default: '1000'
- },
- refreshType: {
- type: String,
- default: 'hollowDots'
- },
- heightReduce: {
- type: String,
- default: '0'
- },
- color: {
- type: String,
- default: '#04C4C4'
- },
- backgroundCover: {
- type: String,
- default: 'white'
- },
- pageNo: {
- type: Number,
- default: 0
- },
- totalPageNo: {
- type: Number,
- default: 0
- },
- isPaging: {
- type: Boolean,
- default: true
- }
- },
- data() {
- return {
- startY: 0,
- moveY: 0,
- hasMore: true,
- moving: false,
- refresh: false,
- loading: false,
- scrollTop: -1,
- coverTransform: 'translateY(0px)',
- coverTransition: '0s',
- playState: 'paused' // 动画的状态 暂停/开始
- }
- },
- computed: {
- // 计算组件所占屏幕高度
- getHeight() {
- let height = uni.getSystemInfoSync().windowHeight - uni.upx2px(0 + this.heightReduce)
- return `height: ${height}px;`
- },
- // 判断loadText
- // 可以根据需求自定义
- loadText() {
- const {
- pageNo,
- totalPageNo,
- loading
- } = this
- if (loading) {
- return '加载中...'
- } else if (pageNo < totalPageNo) {
- return '上拉加载更多'
- } else {
- return '已经到底啦~'
- }
- }
- },
- watch: {
- // 监听refresh值 避免多次触发@refresh
- 'refresh'(val) {
- if (val) {
- this.$emit('refresh')
- }
- }
- },
- methods: {
- // 根据pageNo和totalPageNo的值来判断 是否触发@loadMore
- loadMore() {
- const {
- pageNo,
- totalPageNo
- } = this
- if (pageNo < totalPageNo) {
- this.loading = true
- this.$emit('loadMore')
- }
- },
- // 单次加载结束
- loadOver() {
- this.loading = false
- },
- // 回弹效果
- coverTouchstart(e) {
- if (!this.isRefresh) {
- return
- }
- this.coverTransition = 'transform .1s linear'
- this.startY = e.touches[0].clientY
- },
- coverTouchmove(e) {
- if (!this.isRefresh || this.refresh) {
- return
- }
- this.moveY = e.touches[0].clientY
- let moveDistance = this.moveY - this.startY
- if (moveDistance < 0) {
- this.moving = false
- return
- }
- this.moving = true
- if (moveDistance >= 60) {
- this.refresh = true
- this.coverTransform = `translateY(60px)`
- this.playState = 'running'
- }
- },
- coverTouchend() {
- if (!(this.isRefresh && this.refresh)) {
- return
- }
- setTimeout(() => {
- if (this.moving === false) {
- return
- }
- this.moving = false
- this.refresh = false
- this.coverTransition = 'transform 0.3s cubic-bezier(.21,1.93,.53,.64)'
- this.coverTransform = 'translateY(0px)'
- this.playState = 'paused'
- }, this.refreshTime)
- },
- runRefresh() {
- // 开始
- this.scrollTop = 0
- this.refresh = true
- this.coverTransition = 'transform .1s linear'
- this.coverTransform = `translateY(60px)`
- this.playState = 'running'
- // 结束
- setTimeout(() => {
- this.scrollTop = -1
- this.refresh = false
- this.coverTransition = 'transform 0.3s cubic-bezier(.21,1.93,.53,.64)'
- this.coverTransform = 'translateY(0px)'
- this.playState = 'paused'
- }, this.refreshTime)
- }
- }
- }
- </script>
- <style lang="scss" scoped>
- .load-refresh {
- margin: 0;
- padding: 0;
- width: 100%;
- .cover-container {
- width: 100%;
- margin-top: -100rpx;
- .list {
- width: 100%;
- .load-more {
- font-size: 28rpx;
- text-align: center;
- color: #AAAAAA;
- padding: 35rpx;
- }
- }
- }
- }
- </style>
|