element ui 虚拟滚动 滚动到底部加载下一页

引入element ui的InfiniteScroll 无限滚动插件

javascript 复制代码
<div class="news-left">
    <div class="infinite-list-wrapper" style="overflow:auto;height: 70vh">
        <ul class="list" v-infinite-scroll="load">
            <li :class="isActive !== index ? 'media-list' : 'media-active'" @click="newsClick(index, item)"
                v-for="(item, index) in mediumList" :key="index">
                <div class="media-item">
                    <div class="media-title" :title="item.title">
                        {{ item.title }}
                    </div>
                </div>
                <div :class="isActive !== index ? '' : 'media-left-sharp'"
                    v-if="isActive == index ? true : false"></div>
            </li>
        </ul>

        <p v-if="loading" class="news-tip">加载中...</p>
        <p v-if="noMore" class="news-tip">没有更多了</p>
    </div>
</div>

滚动到最底部的时候调用接口,判断是否大于总数,大于则不调用接口

javascript 复制代码
      //滚动到最底部加载下一页
      load() {
        if (this.count <= this.total - 1 && !this.loading) {
          this.page += 1
          this.count += 10
          this.getNewsListData()
        } else {
          this.loading = false
        }
      },

完整代码

javascript 复制代码
<template>
    <Modal v-model="showModal" :closable="false" width="80%" class="modal-news">
      <div slot="header" style="margin-top: 2vh">
        <i class="modal-close" @click="closeModal"></i>
        <div>{{ modalName }}</div>
      </div>
      <div class="news">
        <div class="news-left">
          <div class="infinite-list-wrapper" style="overflow:auto;height: 70vh">
            <ul class="list" v-infinite-scroll="load">
              <li :class="isActive !== index ? 'media-list' : 'media-active'" @click="newsClick(index, item)"
                v-for="(item, index) in mediumList" :key="index">
                <div class="media-item">
                  <div class="media-title" :title="item.title">
                    {{ item.title }}
                  </div>
                </div>
                <div :class="isActive !== index ? '' : 'media-left-sharp'" v-if="isActive == index ? true : false"></div>
              </li>
            </ul>
  
            <p v-if="loading" class="news-tip">加载中...</p>
            <p v-if="noMore" class="news-tip">没有更多了</p>
          </div>
        </div>
        <div class="news-right">
          <div class="platform-right-content">
            <vuescroll :ops="ops" style="margin-top: 0.5vh">
              <div style="height: 60vh">
                <div class="modal-wrap" v-html="selected.content"></div>
              </div>
            </vuescroll>
          </div>
        </div>
      </div>
      <div slot="footer"></div>
    </Modal>
  </template>
  
  <script>
  import vuescroll from "vuescroll";
  import {
    getNewsList
  } from "@/api/serviceSupport";
  import { getPolicyNewsList } from "@/api/platform/fillData.js";
  
  export default {
    components: {
      vuescroll,
    },
    props: {
      total: {
        type: Number,
        default: 10
      },
    },
    data() {
      return {
        reqType: '',
        count: 0,
        loading: false,
        showModal: false,
        modalName: "",
        isActive: 0,
        selected: {},
        mediumList: [],
        page: 1,
        pageSize: 10,
        newsType: '',
        checkState: "",
        ops: {
          vuescroll: {},
          scrollPanel: {
            scrollingX: false,
          },
          rail: {
            keepShow: true,
          },
          bar: {
            hoverStyle: true,
            onlyShowBarOnScroll: false, //是否只有滚动的时候才显示滚动条
            background: "#ccc", //滚动条颜色
            opacity: 0.5, //滚动条透明度
          },
        },
      };
    },
    computed: {
      noMore() {
        return this.count >= this.total
      },
    },
    mounted() {
      console.log(this.total);
    },
    methods: {
      showModalAction(list, index, title) {
        this.showModal = true;
        this.modalName = title;
        this.mediumList = list;
        this.isActive = index || 0;
        this.modalName = title
        this.selected = list[this.isActive];
        this.count = this.mediumList.length
        this.page = 1
      },
      //设置接口调用的参数
      setData(newsType, checkState, reqType) {
        this.newsType = newsType;
        this.checkState = checkState;
        this.reqType = reqType;
      },
      closeModal() {
        this.showModal = false;
      },
      //滚动到最底部加载下一页
      load() {
        if (this.count <= this.total - 1 && !this.loading) {
          this.page += 1
          this.count += 10
          this.getNewsListData()
        } else {
          this.loading = false
        }
      },
      newsClick(index, item) {
        this.isActive = index;
        this.selected = item;
      },
      async getNewsListData() {
        this.loading = true
        var that = this;
        const { data } = await getNewsList({
          newsType: this.newsType,
          checkState: this.checkState,
          page: this.page,
          pageSize: this.pageSize,
        });
        this.loading = false
        if (data && data.records.length > 0) {
          data.records.map((p) => {
            that.mediumList.push({
              time: p.publishTime && p.publishTime.substring(0, 10),
              title: (p.title && p.title) || "",
              newsSourceStr: p.newsSourceStr && p.newsSourceStr,
            });
          });
        }
      },
    },
  };
  </script>
  
  <style lang="less" scoped>
  .modal-news {
    .news-tip {
      color: #fff;
      text-align: center;
      margin: 0.3rem;
    }
  
    .modal-title {
      width: 100%;
      display: flex;
      justify-content: space-between;
      align-items: center;
      padding: 0.2rem 0.5rem;
  
      .title-bj {
        max-width: 90%;
        min-width: 50%;
        height: 4vh;
        display: flex;
        align-items: center;
  
        .title-logo {
          width: 8px;
          height: 8px;
          background: #f8de90;
          box-shadow: 0px 0px 17px 2px rgba(255, 104, 0, 0.95);
          margin-right: 0.3rem;
        }
  
        p {
          font-size: 0.5rem;
          font-family: YouSheBiaoTiHei, YouSheBiaoTiHei-Regular;
          font-weight: 400;
          color: #ffffff;
          cursor: pointer;
        }
      }
    }

  }
  
  .news {
    display: flex;
    height: 72vh;
    padding: 0 0.5rem;
  
    .news-left {
      width: 25%;
      height: 100%;
      overflow: hidden;
    }
  
    .news-right {
      width: 75%;
      margin-left: 2%;
      height: 100%;
    }
  }
  

  </style>
  
相关推荐
github_is_geeksKai3 小时前
浏览器端文件处理的边界:PDF 面单、GPX 隐私与 EPUB 修复
前端
deli0073 小时前
从一句反馈到一次升级:Mystudy 的自进化实践
前端
FungLeo4 小时前
成为全栈·Vue 管理后台篇·用 fetch 建一层可控的请求内核
前端·javascript·vue.js·http·fetch·formdata·接口封装
FungLeo6 小时前
成为全栈·Vue 管理后台篇·Vue Router如何守住多角色后台边界
前端·javascript·vue.js·rbac·vue router·路由守卫·前端权限
FungLeo6 小时前
成为全栈·Vue 管理后台篇·分页只显示第一页:从接口total 定位到前端修复
前端·vue.js·状态模式·分页·naive ui·服务端分页·前端问题排查
ZhengEnCi6 小时前
苹果滑动为什么有「肉感」:橡皮筋越界阻尼与弹簧动画的物理原理
前端
Moment6 小时前
不会后期的我,发现了一个开源胶片神器😍😍😍
前端·后端·开源
L1mbo6 小时前
Lite模式 缓解微信开发者工具卡顿,附 uni-app 实践方案
前端·微信小程序
FungLeo7 小时前
成为全栈·Vue管理后台篇·仪表盘不是几张卡片:组合统计接口与角色视图
前端·javascript·vue.js·rbac·仪表盘·管理后台·tanstack query
SameX7 小时前
HarmonyOS 做桌面卡片 onAddForm 要同步返回但数据在数据库里的解法
前端