<div id="app">
<mt-loadmore :top-method="loadTop" :bottom-method="loadBottom" :bottom-all-loaded="allLoaded" :max-distance="150"
@top-status-change="handleTopChange" ref="loadmore">
<div slot="top" class="mint-loadmore-top">
<span v-show="topStatus === 'pull'" :class="{ 'rotate': topStatus === 'drop' }">↓</span>
<span v-show="topStatus === 'loading'">Loading...</span>
<span v-show="topStatus === 'drop'">释放更新</span>
</div>
<ul class="scroll-wrapper">
<li v-for="item in list" @click="itemClick(item)">{{ item }}</li>
</ul>
</mt-loadmore>
</div>
<link rel="stylesheet" href="https://unpkg.com/mint-ui/lib/style.css" rel="external nofollow" >
*{
margin: 0;
padding: 0;
}
html, body{
height: 100%;
}
#app{
height: 100%;
overflow: scroll;
}
.scroll-wrapper{
margin: 0;
padding: 0;
list-style: none;
}
.scroll-wrapper li{
line-height: 120px;
font-size: 60px;
text-align: center;
}
<!-- 先引入 Vue -->
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<!-- 引入组件库 -->
<script src="https://unpkg.com/mint-ui/lib/index.js"></script>
<script>
new Vue({
el: '#app',
data: {
list: [],
allLoaded: false,
topStatus: ''
},
created: function () {
var i =0, len=20;
for (; i< len; i++){
this.list.push('demo' + i);
}
},
methods: {
loadTop: function () { // 刷新数据的操作
var self = this;
setTimeout(function () {
self.list.splice(0, self.list.length);
var i =0, len=20;
for (; i< len; i++){
self.list.push('demo' + i);
}
self.$refs.loadmore.onTopLoaded();
}, 2000);
},
loadBottom: function () { // 加载更多数据的操作
//load data
//this.allLoaded = true;// 若数据已全部获取完毕
var self = this;
setTimeout(function () {
var i =0; len = 10;
for (; i< len; i++){
self.list.push('dddd' + i);
}
self.$refs.loadmore.onBottomLoaded();
}, 2000);
},
handleTopChange: function (status) {
this.topStatus = status;
},
itemClick: function (data) {
console.log('item click, msg : ' + data);
}
}
});
</script>
<div class="mint-loadmore">
<div class="mint-loadmore-content" :class="{ 'is-dropped': topDropped || bottomDropped}" :style="{ 'transform': 'translate3d(0, ' + translate + 'px, 0)' }">
<slot name="top">
<div class="mint-loadmore-top" v-if="topMethod">
<spinner v-if="topStatus === 'loading'" class="mint-loadmore-spinner" :size="20" type="fading-circle"></spinner>
<span class="mint-loadmore-text">{{ topText }}</span>
</div>
</slot>
<slot></slot>
<slot name="bottom">
<div class="mint-loadmore-bottom" v-if="bottomMethod">
<spinner v-if="bottomStatus === 'loading'" class="mint-loadmore-spinner" :size="20" type="fading-circle"></spinner>
<span class="mint-loadmore-text">{{ bottomText }}</span>
</div>
</slot>
</div>
</div>
data() {
return {
translate: 0, // 此变量决定当前组件上下移动,
scrollEventTarget: null, // 滚动的dom节点
containerFilled: false, // 当前滚动的内容是否填充完整,不完成会调用 loadmore的回调函数
topText: '', // 下拉刷新,显示的文本
topDropped: false, // 记录当前drop状态,用给组件dom添加is-dropped class(添加回到原点的动画)
bottomText: '', // 上拉加载更多 显示的文本
bottomDropped: false, // 同topDropped
bottomReached: false, // 当前滚动是否滚动到了底部
direction: '', // touch-move过程中, 当前滑动的方向
startY: 0, // touch-start 起始的y的坐标值
startScrollTop: 0, // touch-start 起始的滚动dom的 scrollTop
currentY: 0, // touch-move 过程中的 y的坐标
topStatus: '', // 下拉刷新的状态: pull(下拉) drop(释放) loading(正在加载数据)
bottomStatus: '' // 上拉加载更多的状态: 状态同上
};
}
watch: {
topStatus(val) {
this.$emit('top-status-change', val);
switch (val) {
case 'pull':
this.topText = this.topPullText;
break;
case 'drop':
this.topText = this.topDropText;
break;
case 'loading':
this.topText = this.topLoadingText;
break;
}
},
bottomStatus(val) {
this.$emit('bottom-status-change', val);
switch (val) {
case 'pull':
this.bottomText = this.bottomPullText;
break;
case 'drop':
this.bottomText = this.bottomDropText;
break;
case 'loading':
this.bottomText = this.bottomLoadingText;
break;
}
}
}
mounted() {
this.init();// 当前 vue component挂载完成之后, 执行init()函数
}
init() {
this.topStatus = 'pull';
this.bottomStatus = 'pull';
this.topText = this.topPullText;
this.scrollEventTarget = this.getScrollEventTarget(this.$el); // 获取滚动的dom节点
if (typeof this.bottomMethod === 'function') {
this.fillContainer(); // 判断当前滚动内容是否填满,没有执行外部传入的loadmore回调函数加载数据
this.bindTouchEvents(); // 为当前组件dom注册touch事件
}
if (typeof this.topMethod === 'function') {
this.bindTouchEvents();
}
},
fillContainer() {
if (this.autoFill) {
this.$nextTick(() => {
if (this.scrollEventTarget === window) {
this.containerFilled = this.$el.getBoundingClientRect().bottom >=
document.documentElement.getBoundingClientRect().bottom;
} else {
this.containerFilled = this.$el.getBoundingClientRect().bottom >=
this.scrollEventTarget.getBoundingClientRect().bottom;
}
if (!this.containerFilled) { // 如果没有填满内容, 执行loadmore的操作
this.bottomStatus = 'loading';
this.bottomMethod();// 调用外部的loadmore函数,加载更多数据
}
});
}
}
handleTouchStart(event) {
this.startY = event.touches[0].clientY; // 手指按下的位置, 用于下面move事件计算手指移动的距离
this.startScrollTop = this.getScrollTop(this.scrollEventTarget); // 起始scroll dom的 scrollTop(滚动的距离)
//下面重置状态变量
this.bottomReached = false;
if (this.topStatus !== 'loading') {
this.topStatus = 'pull';
this.topDropped = false;
}
if (this.bottomStatus !== 'loading') {
this.bottomStatus = 'pull';
this.bottomDropped = false;
}
}
handleTouchMove(event) {
//确保当前touch节点的y的位置,在当前loadmore组件的内部
if (this.startY < this.$el.getBoundingClientRect().top && this.startY > this.$el.getBoundingClientRect().bottom) {
return;
}
this.currentY = event.touches[0].clientY;
let distance = (this.currentY - this.startY) / this.distanceIndex;
this.direction = distance > 0 ? 'down' : 'up';
// 下拉刷新,条件(1.外部传入了刷新的回调函数 2.滑动方向是向下的 3.当前滚动节点的scrollTop为0 4.当前topStatus不是loading)
if (typeof this.topMethod === 'function' && this.direction === 'down' &&
this.getScrollTop(this.scrollEventTarget) === 0 && this.topStatus !== 'loading') {
event.preventDefault();
event.stopPropagation();
//计算translate(将要平移的距离), 如果当前移动的距离大于设置的最大距离,那么此次这次移动就不起作用了
if (this.maxDistance > 0) {
this.translate = distance <= this.maxDistance ? distance - this.startScrollTop : this.translate;
} else {
this.translate = distance - this.startScrollTop;
}
if (this.translate < 0) {
this.translate = 0;
}
this.topStatus = this.translate >= this.topDistance ? 'drop' : 'pull';// drop: 到达指定的阈值,可以执行刷新操作了
}
// 上拉操作, 判断当前scroll dom是否滚动到了底部
if (this.direction === 'up') {
this.bottomReached = this.bottomReached || this.checkBottomReached();
}
if (typeof this.bottomMethod === 'function' && this.direction === 'up' &&
this.bottomReached && this.bottomStatus !== 'loading' && !this.bottomAllLoaded) {
event.preventDefault();
event.stopPropagation();
// 判断的逻辑思路同上
if (this.maxDistance > 0) {
this.translate = Math.abs(distance) <= this.maxDistance
? this.getScrollTop(this.scrollEventTarget) - this.startScrollTop + distance : this.translate;
} else {
this.translate = this.getScrollTop(this.scrollEventTarget) - this.startScrollTop + distance;
}
if (this.translate > 0) {
this.translate = 0;
}
this.bottomStatus = -this.translate >= this.bottomDistance ? 'drop' : 'pull';
}
this.$emit('translate-change', this.translate);
}
checkBottomReached() {
if (this.scrollEventTarget === window) {
return document.body.scrollTop + document.documentElement.clientHeight >= document.body.scrollHeight;
} else {
return this.$el.getBoundingClientRect().bottom <= this.scrollEventTarget.getBoundingClientRect().bottom + 1;
}
}
handleTouchEnd() {
if (this.direction === 'down' && this.getScrollTop(this.scrollEventTarget) === 0 && this.translate > 0) {
this.topDropped = true; // 为当前组件添加 is-dropped class(也就是添加动画处理)
if (this.topStatus === 'drop') { // 到达了loading的状态
this.translate = '50'; // top slot的高度
this.topStatus = 'loading';
this.topMethod(); // 执行回调函数
} else { // 没有到达,回调原点
this.translate = '0';
this.topStatus = 'pull';
}
}
// 处理逻辑同上
if (this.direction === 'up' && this.bottomReached && this.translate < 0) {
this.bottomDropped = true;
this.bottomReached = false;
if (this.bottomStatus === 'drop') {
this.translate = '-50';
this.bottomStatus = 'loading';
this.bottomMethod();
} else {
this.translate = '0';
this.bottomStatus = 'pull';
}
}
this.$emit('translate-change', this.translate);
this.direction = '';
}
}
机械节能产品生产企业官网模板...
大气智能家居家具装修装饰类企业通用网站模板...
礼品公司网站模板
宽屏简约大气婚纱摄影影楼模板...
蓝白WAP手机综合医院类整站源码(独立后台)...苏ICP备2024110244号-2 苏公网安备32050702011978号 增值电信业务经营许可证编号:苏B2-20251499 | Copyright 2018 - 2025 源码网商城 (www.ymwmall.com) 版权所有