h5分页加载的实现

h5分页加载功能的实现

项目场景涉及到分页加载,之前文章有用过使用better-scroll 这个插件在进行处理(文章具体地址:https://blog.csdn.net/u013262823/article/details/91979851),今天我们使用滚动的方式来实现分页加载的功能,比起使用better-scroll更简单易懂,我们先介绍一下实现的大致原理:
1、监听滚动事件,滚动到距离底部一定距离的时候去请求接口数据(指定距离可以自己去设置)
2、接口返回数据与先前请求数据合并
3、接口请求后去判断是否还存在未加载完数据

scrollTop、innerHeight、scrollHeight的计算

我们认为当满足scrollHeight = innerHeight + scrollTop,说明已经到达底部。scrollTop代表了滚动条滚动的长度(如果想让元素快速回到顶部,则可设置scrollTop=0),innerHeight代表了窗口文档显示区的高度,scrollHeight 代表了滚动元素的高度

功能代码实现

html代码部分

<div class="msg-container" ref="notice" @scroll.passive="onScroll">
            <ul class="msg-list" :class="{line: signList.length > 0}">
                <v-message-card v-for="(item, index) in signList"
                                :message="item"
                                :key="index">
                    <p v-if="item.dayBar.show" class="title fz20" slot="">{
     {
     item.dayBar.text}}</p>
                </v-message-card>
            </ul>
            <div class="c-9 t-c fz14" :style="{marginBottom: isIphoneX ? '45px' : '10px'}" v-if="!hasNext && signList.length > 0">没有更多了</div>
        </div>
        <v-loading :loading="loading"></v-loading>

js 代码部分

		data() {
     
            return {
     
                lastSignId: -1, //分页传给服务端的标识
                signList: [], //接口数据存储
                loading: false, //数据是否加载中
                hasNext: true, //判断是否还存在未加载数据
            }
        },
        // watch监听 (lastSignId进行监听,数据变化则去触发数据加载)
         watch: {
     
            lastSignId() {
     
                this.initPage()
            }
        },
        // 方法部分
        methods: {
     
        	 onScroll() {
     
                let scrollTop = this.$refs.notice.scrollTop //获取滚动长度
                let innerHeight = window.innerHeight //文档显示宽度
                let scrollHeight = this.$refs.notice.scrollHeight //滚动元素高度
                // 若distance = 0 则认为到底,我们设临界值未20
                const distance = scrollHeight - innerHeight - scrollTop
                // loading 判断为了限制接口请求过程中不允许重复请求
                if (!this.loading && this.hasNext && distance < 20) {
     
                    this.lastSignId = this.signList[this.signList.length -1].signId
                    //  this.getRcvOutSignInList(this.lastSignId) 也可以这些操作,而不去使用watch监听
                }
            },
            initPage() {
     
                this.getRcvOutSignInList(this.lastSignId).then((res) => {
     
                    if (res.retcode === 0) {
     
                    // 数据处理
                        this.handleResponse(res.data)
                    } else {
     
                        this.hasNext = true
                    }
                })
            },
            // 接口请求
            getRcvOutSignInList(lastSignId) {
     
                const orgId = getQuery('orgId') || Cookie.get('orgId')
                this.loading  = true
                return new Promise((resolve, reject) => {
     
                    post(getAaceApi('xxxx', 'xxxx'), {
     
                        orgId,
                        signId: lastSignId
                    }).then((res) => {
     
                        this.loading = false
                        resolve(res)
                    }).catch((error) => {
     
                        this.loading = false
                        reject(error)
                    })
                })
            },
            handleResponse(data) {
     
            // 数据处理部分
                const {
      rcvList } = data
                this.signList = this.signList.concat(
                    rcvList.map((x, index) => {
     
                        return {
     
                            ...x,
                            userInfo: {
     
                                uid: x.senderUid,
                                name: x.senderName
                            },
                            time: this.getTimeFormat(x.signTime)
                        }
                    })
                )
                if (rcvList.length < 20) {
     
                	// 页面每次请求20条数据
                    this.hasNext = false
                }
            },
        }

好了,一个简单的分页加载的功能就实现啦。

你可能感兴趣的:(vue,js,vue.js,javascript,分页,下拉加载)