3 files added
1 files modified
| | |
| | | /** |
| | | * image picker |
| | | * textarea |
| | | * @author Tevin |
| | | */ |
| | | |
New file |
| | |
| | | /** |
| | | * CInfiniteScroll |
| | | * @author Tevin |
| | | */ |
| | | |
| | | <template> |
| | | <scroll-view |
| | | class="c-infinite-scroll" |
| | | :scrollY="true" |
| | | @scroll="evt=>onScroll(evt)" |
| | | > |
| | | <slot /> |
| | | <view class="bottom"> |
| | | <view v-if="loading">加载中,请稍后...</view> |
| | | <view v-if="ending"> |
| | | <text v-if="pageTatal > 0">-- 没有更多了 --</text> |
| | | <text |
| | | class="empty" |
| | | v-else |
| | | >暂无数据...</text> |
| | | </view> |
| | | </view> |
| | | </scroll-view> |
| | | </template> |
| | | |
| | | <script> |
| | | import { AtActivityIndicator } from 'taro-ui-vue'; |
| | | import './cInfiniteScroll.scss'; |
| | | |
| | | export default { |
| | | name: 'CInfiniteScroll', |
| | | components: { |
| | | AtActivityIndicator, |
| | | }, |
| | | props: { |
| | | autoInit: { |
| | | type: Boolean, |
| | | default: false, |
| | | }, |
| | | onLoadMore: Function, |
| | | }, |
| | | data() { |
| | | return { |
| | | inital: false, |
| | | current: 0, |
| | | pageTotal: 1, |
| | | loading: false, |
| | | ending: false, |
| | | lastScrollTop: 0, |
| | | scrollTimer: 0, |
| | | }; |
| | | }, |
| | | methods: { |
| | | hanldeLoadMore() { |
| | | // 结束后跳过 |
| | | if (this.ending) { |
| | | return; |
| | | } |
| | | // 加载中跳过 |
| | | if (this.loading) { |
| | | return; |
| | | } |
| | | // 开始加载 |
| | | this.inital = true; |
| | | this.loading = true; |
| | | this.onLoadMore({ |
| | | current: this.current, |
| | | next: this.current + 1, |
| | | // 加载成功 |
| | | success: (options) => { |
| | | // 没有数据 |
| | | if (!options.pageTotal || options.pageTotal <= 0) { |
| | | this.ending = true; |
| | | } |
| | | // 有数据 |
| | | else { |
| | | this.pageTotal = options.pageTotal; |
| | | this.current = this.current + 1; |
| | | // 已到最后一页 |
| | | if (this.current >= this.pageTotal) { |
| | | this.ending = true; |
| | | } |
| | | } |
| | | setTimeout(() => { |
| | | this.loading = false; |
| | | }, 100); |
| | | }, |
| | | // 加载失败 |
| | | fail: () => { |
| | | this.loading = false; |
| | | }, |
| | | }); |
| | | }, |
| | | onScroll(evt) { |
| | | // 往上 |
| | | if (this.lastScrollTop >= evt.detail.scrollTop) { |
| | | this.lastScrollTop = evt.detail.scrollTop; |
| | | return; |
| | | } |
| | | // 往下 |
| | | else { |
| | | const viewHeight = evt.target.offsetHeight; |
| | | const { scrollTop, scrollHeight } = evt.detail; |
| | | // 阀值 100 像素,向下滚动到最后 100 像素,识别为启动加载 |
| | | if (viewHeight + scrollTop >= scrollHeight - 100) { |
| | | clearTimeout(this.scrollTimer); |
| | | this.scrollTimer = setTimeout(() => { |
| | | this.hanldeLoadMore(); |
| | | }, 200); |
| | | } |
| | | } |
| | | }, |
| | | initScroll() { |
| | | // 已初始化,跳过 |
| | | if (this.inital) { |
| | | return; |
| | | } |
| | | this.hanldeLoadMore(); |
| | | }, |
| | | }, |
| | | mounted() { |
| | | // 开启自动初始化 |
| | | if (this.autoInit) { |
| | | this.hanldeLoadMore(); |
| | | } |
| | | }, |
| | | }; |
| | | </script> |
New file |
| | |
| | | /** |
| | | * CInfiniteScroll |
| | | * @author Tevin |
| | | */ |
| | | |
| | | @import "../../common/sassMixin"; |
| | | |
| | | .c-infinite-scroll { |
| | | .bottom { |
| | | height: 1.8rem; |
| | | text-align: center; |
| | | line-height: 1.5rem; |
| | | color: #666; |
| | | .empty { |
| | | line-height: 5rem; |
| | | color: #999; |
| | | } |
| | | } |
| | | } |
New file |
| | |
| | | /** |
| | | * CInfiniteScroll |
| | | * @author Tevin |
| | | */ |
| | | |
| | | import CInfiniteScroll from '@components/plugins/infiniteScroll/CInfiniteScroll.vue'; |
| | | |
| | | export { |
| | | CInfiniteScroll, |
| | | } |