效果描述:

列表查询页、每页10条数据、滚动至底部加载更多数据、点击进入详情。再次返回列表查询页不希望从第一页重新查找、而是直接滚动到上次浏览的位置。

实现思路:

点击列表进入详情页时、记录当前点击的位置、将参数传入详情页、返回列表页时将参数再传递回来。列表页初次加载时判断是否存在上次记录的位置参数、存在表示有历史记录、直接请求数据、找到位置、然后调用 scrollIntoView() 方法滚动到指定位置。

举例:我上一次点击了第180条数据、记录索引108、每页10条数据、所以当时记录的页码pageNo是第 11 页、下一次返回列表界面、第一pageNo是1、一次性请求110条数据、pageSize是110、数据请求回来后、DOM渲染结束、找到相应的位置、滚动到指定位置即可。

 <div
          v-for="(item, index) in dataList"
          :key="index"
          class="contentDataList"
          :id="'item' + index"
          @click="InfoClick(item, index)"
          v-show="dataList.length > 0"
        >
          <div class="contentData">
            <div class="contentName">{{ item.deviceName }}</div>
            <div class="contentManufactor">{{ item.manufactor }}</div>
            <div class="contentNumber flex">
              <div>{{ item.deviceNo }}</div>
              <div>{{ item.certificateNo }}</div>
            </div>
          </div>
          <div class="dataSource flex">
            <div>数据来源</div>
            <van-icon name="arrow" />
          </div>
        </div>
        <EmptyData v-show="dataList.length === 0"></EmptyData>
data(){
    return {
        
      historyType: false, // 是否记录了上次位置

    }
},
mounted() {
    // 滚动到上次浏览的位置
    let itemVal = this.$route.params;
    this.params.pageNo = 1;
    this.dataList = [];
    if (itemVal.indexVal) {
      if (itemVal.indexVal > 10) {
        this.params.pageSize = Math.ceil(itemVal.indexVal + 1)
        this.historyType = true;
      } else {
        this.params.pageSize = 10;
      }
    } else {
      itemVal.indexVal = 0;
    }
    this.getTransferFileList().then(() => {
      this.$nextTick(() => {
        const timer = setInterval(() => {
          const item = document.getElementById("item" + itemVal.indexVal);
          if (item) {
            item.scrollIntoView({
              behavior: "smooth", // 平滑过渡
              block: "center", // 页面中央
            });
            clearInterval(timer);
          }
        }, 500);
      });
    });
  },
methods:{
     getTransferFileList() {
      return getTransferFileList(this.params).then((res) => {
        const data = res.data;
        this.loading = false;
        if (data.code === 200) {
          this.dataList = this.dataList.concat(data.data.list);
          // 向上取整,有小数就整数部分加1
          if (this.historyType) {
            this.params.pageNo = Math.ceil(this.params.pageSize / 10);
            this.params.pageSize = 10;
            this.historyType = false;
          }
          if (data.data.isLastPage) {
            this.finished = true; // 关闭load事件
          }
        }
      });
    }
}

以上方法是未优化之前的、鉴于最近项目这个功能比较多、封装进公共方法。

下面是优化后的。

首先、将代码优化、放入公共方法

/**
 * 返回上一页历史记录位置--计算pageSize
 * @param {params}  传入页面参数 paramsData{ params(接口请求参数)、indexVal是记录的位置索引、itemName(id标识)defaultPageSize(支持自定义pageSize)}
 * indexVal{ Number } 索引必须Number
 * itemName{ String } id标识必须字符串
 * defaultPageSize{ Number } 自定义pageSize必须Number
*/
export const returnHistorySeat = (paramsData) => {
  const defaultPageSize = paramsData.defaultPageSize ? paramsData.defaultPageSize : 10
  if (paramsData.indexVal) {
    paramsData.params.pageSize = paramsData.indexVal > defaultPageSize ? paramsData.indexVal + defaultPageSize + 1 : defaultPageSize
    paramsData.params.pageNo = 1;
  } else {
    paramsData.indexVal = 0;
  }
  paramsData.params.historyType = Boolean(paramsData.indexVal);
  return paramsData
}
/**
 * 返回上一页历史记录位置--滚动到目标位置
 * @param {params}  传入页面参数 paramsData{ params(接口请求参数)、indexVal是记录的位置索引、itemName(id标识)}
 * @param {String}  behaviorVal滑动效果、smooth 平滑过渡、instant 直接过去、 auto默认值、正常滑动
 * @param {String}  blockVal滚动位置、center页面中央、start页面顶部、end页面底部、nearest最近的位置
*/
export const scrollIntoViewHistory = (paramsData) => {
  const defaultPageSize = paramsData.defaultPageSize ? paramsData.defaultPageSize : 10
  if (paramsData.params.historyType) {
    paramsData.params.pageNo = Math.ceil(paramsData.indexVal / defaultPageSize);
    paramsData.params.pageSize = defaultPageSize;
    paramsData.params.historyType = false;
  }
  const timer = setInterval(() => {
    const domItem = document.getElementById(paramsData.itemName + paramsData.indexVal);
    if (domItem) {
      domItem.scrollIntoView({
        behavior: paramsData.behaviorVal ? paramsData.behaviorVal : "smooth",
        block: paramsData.blockVal ? paramsData.blockVal : "center",
        // inline:'auto'   // 滚动至容器左右位置  值和block用法一致
      });
      clearInterval(timer);
    }
    // 防止Dom一直拿不到、两分钟后停止定时器
    setTimeout(() => {
      clearInterval(timer);
    }, 120000);
  }, 500);
}

然后界面引用即可。

import { returnHistorySeat, scrollIntoViewHistory } from "@/libs/util";


  mounted() {
    // 参数  defaultPageSize可以不用传、,默认10条数据、如果非要查指定数量、可以传
    const paramsData = {
      params: this.params,
      indexVal: this.$route.params.indexVal,
      itemName: "item",
      defaultPageSize: 5,
    };
     // 调用
    returnHistorySeat(paramsData);
    this.getTransferFileList().then(() => {
      this.$nextTick(() => {
        //调用
        scrollIntoViewHistory(paramsData);
      });
    });
  },

ok、简洁多了。

Logo

前往低代码交流专区

更多推荐