在使用vant-ui组件库的van-list列表组件时,经常会出现切换页面回来后滚动条回到顶部的情况,难免会影响使用体验,下面给出一种简单的解决办法。

  1. 首先准备template模版和data

    <template>
    <div ref="myContainerRef" v-app-title="'列表'" class="list-box">
        <van-list
            v-model="loading"
            :finished="finished"
            finished-text="没有更多了"
            @load="onLoad"
        >
            <van-cell v-for="(item,index) in list" :key="item" @click="jumpTo(item,index)">
                <div class="item">
                    {{ item }}
                </div>
            </van-cell>
        </van-list>
    </div>
    </template>
    <script>
    import { List } from "vant"; // 按需加载
    export default {
    	name: "ListView",
    	components: {
    		"van-list": List , // 注册van-list
    	},
    	data: () => {
    		return {
    		// nothing
    			list: [],
    			loading: false,
    			finished: false,
    		}; 
    	},
    	computed: {
    		// nothing
    	},
    	created() {
    		// nothing
    	},
    	activated() {
    	},
    	deactivated(){
    	},
    	methods: {
    		onLoad() {
    			// 异步更新数据
    			// setTimeout 仅做示例,真实场景中一般为 ajax 请求
    			setTimeout(() => {
    				for (let i = 0; i < 10; i++) {
    					this.list.push(this.list.length + 1);
    				}
    				// 加载状态结束
    				this.loading = false;
    				// 数据全部加载完成
    				if (this.list.length >= 30) {
    					this.finished = true;
    				}
    			}, 1000);
    		},
    		// 为了体现页面切换滚动条焦点丢失的场景,需要正确配置detail页面路由
    		jumpTo(item, i){
    			this.$router.push({
    				name: "detail",
    				query: {
    					name: item
    				},
    				params: {
    					age: i
    				}
    			});
    		},
    	}
    };
    </script>
    
    

    其中loading表示加载状态、finished代表是否加载完毕、onLoad属性定义了list数据的来源,请求请见 van-list官方文档

  2. 页面初始化(或activated时)监听页面滚动事件,scrollHandlder的定义

    activated() {
    	window.addEventListener("scroll", this.scrollHandlder, true);
    	// 命中缓存
    	this.onLoad(); // 模拟http(s)请求加载列表数据
    },
    methods: {
    	// 滚动的监听回调函数
    	scrollHandlder(){
    		// 获取元素节点
    		let myContainer = this.$refs.myContainerRef;
    		if (myContainer) {
    			// van-lsit外层dom元素滚动时监听,记下滚动的高度
    			myContainer.onscroll = () => {
    				setTimeout(() => {
    					this.scrollTop = myContainer.scrollTop;
    				}, 800); // 节流
    			};
    		}
    	},
    }
    
  3. 页面激活时设置van-lsit外层dom元素滚动的高度

    	activated() {
    	// 延时处理(宏任务),等到列表数据更新后再设置滚动距离
    	setTimeout(() => {
    		if (this.scrollTop) {
    			// 设置滚动距离
    			this.$refs.myContainerRef.scrollTop = this.scrollTop;
    		}
    	});
    },
    
  4. 最后,记得在页面销毁(或deactivated)时,去掉页面的监听时间

    deactivated(){
    	window.removeEventListener("scroll", this.scrollHandlder, true);
    },
    
Posted on 2023-10-11 11:02  易烊千玺圈外女友  阅读(1979)  评论(0)    收藏  举报