以凡人之躯,用js事件监听自定义——写一个滚动组件,懒加载数据
一、组件是什么?
所谓组件化,就是把页面拆分成多个组件,每个组件依赖的 CSS、JS、模板、图片等资源放在一起开发和维护。 因为组件是资源独立的,所以组件在系统内部可复用,组件和组件之间可以嵌套,如果项目比较复杂,可以极大简化代码量,并且对后期的需求变更和维护也更加友好。
二、使用步骤
1.创建一个公共组件
代码如下(示例):
<template>
<div id="listScroll" ref="listScroll">
<div
v-for="(item,index) in dataSource"
:key="index"
class="scrollItem"
>{{item.name}}--{{item.age}}</div>
</div>
</template>
<script>
export default {
name: "listScroll",
props: ["height", "width"],
data() {
return {
dataSource: [],
listData: [
{ name: "asd", age: 21 },
{ name: "asd", age: 21 },
{ name: "asd", age: 21 },
{ name: "asd", age: 21 },
{ name: "asd", age: 21 },
{ name: "asd", age: 21 },
{ name: "asd", age: 21 },
{ name: "asd", age: 21 },
{ name: "asd", age: 21 },
{ name: "asd", age: 21 },
{ name: "asd", age: 21 },
{ name: "asd", age: 21 },
{ name: "asd", age: 21 },
{ name: "asd", age: 21 },
{ name: "asd", age: 21 },
{ name: "asd", age: 21 },
{ name: "asd", age: 21 },
{ name: "asd", age: 21 },
{ name: "asd", age: 21 },
{ name: "asd", age: 21 },
{ name: "asd", age: 21 },
{ name: "asd", age: 21 },
{ name: "asd", age: 21 },
{ name: "asd", age: 21 },
{ name: "asd", age: 21 },
{ name: "asd", age: 21 },
{ name: "asd", age: 21 },
{ name: "asd", age: 21 },
{ name: "asd", age: 21 },
{ name: "asd", age: 21 },
{ name: "asd", age: 21 },
{ name: "asd", age: 21 },
{ name: "asd", age: 21 },
{ name: "asd", age: 21 },
{ name: "asd", age: 21 },
{ name: "asd", age: 21 },
{ name: "asd", age: 21 },
{ name: "asd", age: 21 },
{ name: "asd", age: 211 },
],
massage: false,
page: {
pageNo: 1,
pageSize: 10,
},
};
},
mounted() {
this.setHW();
this.loadMore();
this.$el.addEventListener(
"scroll",
(e) => {
if (
e.currentTarget.scrollTop + e.currentTarget.clientHeight ==
e.currentTarget.scrollHeight
) {
this.loadMore();
}
},
false
);
},
destroyed() {
this.$el.removeEventListener(
"scroll",
(e) => {
if (
e.currentTarget.scrollTop + e.currentTarget.clientHeight ==
e.currentTarget.scrollHeight
) {
this.loadMore();
}
},
false
);
},
methods: {
loadMore() {
let promise = new Promise((resolve, reject) => {
let res = {
code: undefined,
massage: undefined,
result: undefined,
};
if (this.page.pageNo * this.page.pageSize > this.listData.length) {
res.code = 500;
res.massage = "暂无更多数据";
res.result = [];
resolve(res);
} else {
res.code = 200;
res.massage = "成功";
if (
this.listData.length >
this.page.pageNo * this.page.pageSize + 10
) {
res.result = this.listData.slice(
this.page.pageNo * this.page.pageSize,
this.page.pageNo * this.page.pageSize + 10
);
} else {
res.result = this.listData.slice(
this.page.pageNo * this.page.pageSize,
this.listData.length
);
}
resolve(res);
}
reject("vue error");
});
promise.then(
(res) => {
if (res.code === 200) {
this.page.pageNo += 1;
res.result.forEach((element) => {
this.dataSource.push(element);
});
} else {
if (!this.massage) {
this.massage = true;
alert(res.massage);
}
}
},
(err) => {
alert(err.massage);
}
);
},
setHW() {
this.$refs.listScroll.style.height = this.height + "px";
this.$refs.listScroll.style.width = this.width + "px";
},
},
};
</script>
<style scoped>
#listScroll {
background: slategray;
overflow: scroll;
margin-right: 50px;
}
.scrollItem {
padding: 8px 10px;
height: 24px;
width: 100%;
}
.scrollItem:hover {
cursor: pointer;
background: rgba(64, 224, 208, 0.329);
color: turquoise;
}
</style>
2.组件调用
代码如下(示例):
<template>
<div id="componentHtml">
<div id="centerBody">
<div class="scrollComponent">
<listScroll height="300" width="200" />
<listScroll height="300" width="200" />
<listScroll height="300" width="200" />
</div>
</div>
</div>
</template>
<script>
import listScroll from "./listScroll";
export default {
name: "componentHtml",
components: { listScroll },
data() {
return {};
},
};
</script>
<style scoped>
@import "../../common/css/bodycss.css";
#componentHtml {
height: 100%;
}
#centerBody .scrollComponent {
margin: 10px 15px;
display: flex;
justify-content: center;
}
</style>
3.效果展示
链接: https://github.com/NotBerlin/ES6Project/tree/dev_services.