Nuxt中使用Apollo fetchMore分页后如何自动滚动到指定div位置
解决方案
问题根因
你的滚动代码未生效的核心原因是 Apollo的fetchMore为异步操作,你同步执行滚动逻辑时,新分页的帖子数据还未完成响应式更新、也未渲染到DOM节点上,此时获取的scrollHeight仍是旧数据对应的高度,同时DOM更新触发的重排也可能导致页面回到顶部。
实现步骤
1. 等待异步数据和DOM更新完成后再执行滚动
在fetchMore的逻辑中,要先等待接口返回、缓存更新、Vue完成DOM渲染后,再触发滚动逻辑,loadMore方法示例如下:
async loadMorePosts() { // 执行fetchMore请求新分页数据 await this.$apollo.queries.postList.fetchMore({ variables: { offset: this.postList.length, pageSize: 10 }, updateQuery: (oldResult, { fetchMoreResult }) => { if (!fetchMoreResult) return oldResult return { postList: [...oldResult.postList, ...fetchMoreResult.postList] } } }) // 等待Vue完成DOM更新,这步是核心 await this.$nextTick() // 调用滚动方法 this.handleScrollToTarget() }
2. 根据滚动容器类型写对应滚动逻辑
场景A:帖子放在固定高度、自带滚动条的#container容器内
handleScrollToTarget() { const container = this.$el.querySelector('#container') container.scrollTo({ top: container.scrollHeight, behavior: 'smooth' // 不需要平滑滚动可删除该行 }) }
场景B:页面为全局视口滚动,无单独滚动容器
handleScrollToTarget() { const targetEl = document.querySelector('#container') targetEl.scrollIntoView({ behavior: 'smooth', block: 'end' // 滚动到容器底部,要滚动到容器顶部可改为'start' }) }
3. 兜底优化
如果触发加载的按钮用了<a>标签或自带默认行为的元素,给点击事件加.prevent修饰符,阻止默认行为导致的页面跳顶:
<button @click.prevent="loadMorePosts">加载更多内容</button>
内容的提问来源于stack exchange,提问作者Marvin
相关产品推荐
相关产品推荐

