Vue 列表 懒加载 触底加载
Vue 列表懒加载 触底加载
·
一、方法一
描述:列表懒加载+节流
效果图:
实现:
组件:LazyLoading
<template>
<div class="lazy-list">
<slot></slot>
</div>
</template>
<script>
export default {
name: "LazyLoading",
data() {
return {};
},
methods: {
// 懒加载
handleScroll(event) {
// 标准浏览器中:定义一个形参event,但当事件触发的时候,并没有给event赋实际的值,
// 则浏览器会把”事件“的对象赋给这个形参e,这时这个e是个系统级的对象:事件;
const scrollDistance =
// 正文全文高
event.target.scrollHeight -
// 被卷去的高
event.target.scrollTop -
// 可见区域的宽度
event.target.clientHeight;
// 滚动条距离底部小于等于0证明已经到底了,可以请求接口了
if (scrollDistance <= 0) {
this.$emit("onButtomBy");//到底了
}
},
// 节流
throttle(fn, wait) {
let context, args;
let previous = 0;
return function () {
let now = +new Date();
context = this;
args = arguments; // 取throttle执行作用域的this
if (now - previous > wait) {
fn.apply(context, args); // 用apply指向调用throttle的对象,相当于throttle.fn(args);
previous = now;
}
};
},
throttleFun(event) {
this.throttle(this.handleScroll(event), 1000);
},
},
mounted() {
// 注册 滚动事件
window.addEventListener("scroll", this.throttleFun, true);
},
};
</script>
<style >
.lazy-list {
/* 注意:懒加载必须设置 列表容器的高度哈 */
/* height: calc(100% - 200px); */
height: 100%;
overflow: auto;
}
</style>
注意: 如果 懒加载组件
是被包裹在 keep-alive
下的话,会被缓存,需要在 deactivated
钩子中对 scroll
事件 进行解绑
参考:https://blog.csdn.net/qq_24930411/article/details/107252548
deactivated() {
window.removeEventListener("scroll", this.throttleFun, true);
},
列表页面引用懒加载组件:
import LazyLoading from "./LazyLoading.vue";
<template>
<div class="refresh-list-extend-con">
<lazy-loading @onButtomBy="onButtomBy">
<div v-for="(item, index) in listBody" :key="index" class="item-con">
<div class="item"></div>
</div>
</lazy-loading>
</div>
</template>
<script>
import LazyLoading from "./LazyLoading.vue";
export default {
name: "HomeList",
components: {
LazyLoading,
},
data() {
return {
listBody: [{}, {}, {}, {}, {}, {}, {}, {}],
pages: 1, // 数据总页数
current: 1, // 当前页数
onOff: false, // 节流标识
};
},
methods: {
// 加载数据
loadTaksData() {
// todo 调用接口获取数据给 items 对象赋值
let params = {
current: this.current,
size: 8,
};
console.log("接口参数为:", params);
/* // 调用接口的方法
this.xxxx(params).then((res)=>{
console.log('接口返回的数据为:', res);
this.items = res.body.records;
// todo 接口返回后需要将 节流标识 设置为 this.onOff = false
this.onOff = false;
// todo 当前页数和总页数在第一次请求数据就要保存起来
this.pages = res.body.pages;
})
*/
// 临时数据
this.listBody = [{}, {}, {}, {}, {}, {}, {}, {}]; //当前页数据
this.pages = 4; //总页数
this.onOff = false;
},
// 到底了
onButtomBy() {
//这个开关是为了避免请求数据中 再次被请求
if (this.onOff) return;
this.onOff = true;
//当前页数小于总页数 就请求
if (this.current < this.pages) {
this.current += 1;
this.loadTaksData();
}
},
},
created() {
this.loadTaksData();
},
};
</script>
<style>
.refresh-list-extend-con {
width: 300px;
height: 300px;
border: 1px solid #ccc;
overflow-y: auto;
}
.item-con .item {
width: 100px;
height: 50px;
background: #f5f5f5;
margin: 10px 0;
}
</style>
打印参数如下:
二、 方法二
描述:一个简单的适用于 Vue 的下拉刷新,触底加载组件
效果图:
实现:
组件: RefreshList
代码:
<template>
<div
class="list-warp-template"
@touchstart="handlerStart"
@touchend="handlerEnd"
@touchmove="handlerMove"
@scroll="handlerScroll"
ref="listWrapRef"
>
<div class="top-refresh" :style="{ height: refresh.height + 'px' }">
<div v-show="refresh.height > 30">
{{ refreshLoading ? "刷新中" : "松开刷新" }}
</div>
</div>
<div class="main-list">
<slot></slot>
</div>
<div class="bottom-loading" v-show="bottomLoading">加载中</div>
</div>
</template>
<script>
let timer = null;
export default {
name: "RefreshList",
props: {
refreshLoading: {
type: Boolean,
default: false,
},
},
data() {
return {
position: 0,
startInit: 0,
bottomLoading: false,
refresh: {
height: 0,
},
};
},
created() {},
watch: {
refreshLoading(val) {
if (!val) {
this.refresh.height = 0;
}
},
},
computed: {},
mounted() {},
methods: {
handlerScroll(e) {
const eDom = e.target;
const scrollTop = e.target.scrollTop;
// 判断是否到底了
let scrollPosition = eDom.scrollHeight - e.target.offsetHeight;
if (timer) {
clearTimeout(timer);
}
timer = setTimeout(() => {
this.bottomLoading = true;
if (scrollPosition <= scrollTop) {
this.$emit("on-bottom"); //到底了
}
}, 200);
this.position = scrollTop;
// 滚动事件,返回当前滚动位置
this.$emit("on-scroll", scrollPosition);
},
// 返回顶部
handlerBackTop() {
const dom = this.$refs.listWrapRef;
dom.scrollTop = 0;
},
// 触摸开始
handlerStart(e) {
this.startInit = parseInt(e.touches[0].clientY);
},
// 滑动中,下拉
handlerMove(e) {
if (this.position === 0 && !this.refreshLoading) {
const Y = parseInt(e.touches[0].clientY);
const range = Y - this.startInit;
this.refresh.height = range;
}
},
// 滑动结束
handlerEnd() {
if (this.refresh.height >= 30) {
this.refresh.height = 40;
this.$emit("on-refresh");
this.$emit("update:refreshLoading", true);
} else {
this.refresh.height = 0;
}
this.startInit = 0;
},
},
};
</script>
<style >
.list-warp-template {
display: block;
/* height: 100vh; */
height: 100%;
overflow-y: auto;
}
.top-refresh {
background-color: #ccc;
height: 0;
width: 100%;
transition: height 0.1s linear;
overflow: hidden;
color: #fff;
display: flex;
align-items: center;
justify-content: center;
}
.main-list {
width: 100%;
}
.bottom-loading {
height: 40px;
display: flex;
align-items: center;
justify-content: center;
color: #999;
width: 100%;
background-color: #f0f0f0;
}
</style>
列表页面:
引入懒加载组件:import RefreshList from "./refreshList.vue";
<template>
<div class="refresh-list-con">
<refresh-list @on-bottom="onBotttom">
<div v-for="(item, index) in listBody" :key="index" class="item-con">
<div class="item"></div>
</div>
</refresh-list>
</div>
</template>
<script>
import RefreshList from "./refreshList.vue";
export default {
name: "HomeRefresh",
props: {},
components: {
RefreshList,
},
data() {
return {
listBody: [{}, {}, {}, {}, {}, {}, {}, {}],
};
},
methods: {
// 到底了
onBotttom() {
console.log("触底加载...");
},
},
created() {},
};
</script>
<style scoped>
.refresh-list-con {
width: 300px;
height: 300px;
border: 1px solid #ccc;
overflow-y: auto;
}
.item-con .item {
width: 100px;
height: 50px;
background: #f5f5f5;
margin: 10px 0;
}
</style>
备注
1、Vue3 手写一个简单的触底刷新:
利用 addEventListener 来监听视图层的高度,还有滚动条的高度
const handleScroll = () => {
window.addEventListener("scroll", () => {
let scrollTop = document.documentElement.scrollTop || document.body.scrollTop
let windowHeight = document.documentElement.clientHeight || document.body.clientHeight
let scrollHeight = document.documentElement.scrollHeight || document.body.scrollHeight
if (scrollTop + windowHeight == scrollHeight) {
console.log("到了底部")
getOrderList()
}
})
}
onMounted(() => {
handleScroll()
})
onBeforeUnmount(() => {
window.removeEventListener("scroll", () => {})
})
注意:离开前不要忘记销毁
2、
更多推荐
已为社区贡献4条内容
所有评论(0)