ElementUI之el-scrollbar + el-backtop + el-timeline实现时间轴触底刷新和一键返回页面顶部。

背景:ElementUI的版本(vue.global.js = 3.2.36, index.css = 2.4.4, index.full.js = 2.4.4)

废话不多说,先看动图效果↓↓↓

Web前端篇——ElementUI之el-scrollbar + el-backtop + el-timeline实现时间轴触底刷新和一键返回页面顶部-LMLPHP

然后直接上代码。(注意代码中有注释的地方,是容易出错的关键地方。)

<html>
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width,initial-scale=1.0" />
    <!-- viewport设置, 简单页面兼容手机端显示 -->
    <script src="https://unpkg.com/vue@3.2.36/dist/vue.global.js"></script>
    <link rel="stylesheet" href="https://unpkg.com/element-plus@2.4.4/dist/index.css">
    <script src="https://unpkg.com/element-plus@2.4.4/dist/index.full.js"></script>
    <title>Test Web Page</title>
    <style>
      .el-timeline {
        padding-left: 0;
      }
    </style>
  </head>
  <body>
    <div id="app" class="allpack" style="height:100%;overflow: hidden;">
      <!-- 最外层overflow要设置为hidden, 否则会和el-scrollbar冲突, 显示2个滚动条且滚动不舒服-->
      <el-scrollbar class="scrollbar" ref="scrollbar" style="height:100%;">
        <el-backtop target=".scrollbar .el-scrollbar__wrap" :bottom="100">
          <!-- 这里设置target除了添加el-scrollbar本体,还要添加.el-scrollbar__wrap, 否则无效 -->
          <div
            style="
              height: 100%;
              width: 100%;
              background-color: var(--el-bg-color-overlay);
              box-shadow: var(--el-box-shadow-lighter);
              text-align: center;
              line-height: 40px;
              color: #1989fa;
            "
          >
            UP
          </div>
        </el-backtop>
        <h1 align="center">Test Message</h1>
        <el-row>
          <!-- 只是为了给布局添加自适应的边距, 不重要, 读者可不使用 -->
	      <el-col :span="1">
            <div class="grid-content ep-bg-purple">
            </div>
          </el-col>
	        <el-col :span="22">
	          <div class="grid-content ep-bg-purple-light">
	            <el-timeline>
                  <el-timeline-item
		            v-for="(activity, index) in activities"
                    placement="top"
                    :key="index"
                    :timestamp="activity.timestamp"
	              >
                    <el-card>
		              <h4>{{ activity.content }}</h4>
        	          <p>{{ activity.timestamp }}</p>
                    </el-card>
	              </el-timeline-item>
	            </el-timeline>
            </div>
          </el-col>
	        <el-col :span="1">
              <div class="grid-content ep-bg-purple">
              </div>
          </el-col>
        </el-row>
      </el-scrollbar>
    </div>
    <script>
      const App = {
        data() {
          return {
	        message: "Hello Element Plus",
            activities: [
              {
                content: 'Custom icon',
                timestamp: '2018-04-12 20:46',
              },
              {
                content: 'Custom color',
                timestamp: '2018-04-03 20:46',
              },
              {
                content: 'Custom size',
                timestamp: '2018-04-03 20:46',
              },
              {
                content: 'Custom hollow',
                timestamp: '2018-04-03 20:46',
              },
              {
                content: 'Default node',
                timestamp: '2018-04-03 20:46',
	          },
	          {
                content: 'Custom hollow',
                timestamp: '2018-04-03 20:46',
              },
              {
                content: 'Default node',
                timestamp: '2018-04-03 20:46',
	          },
	          {
                content: 'Custom hollow',
                timestamp: '2018-04-03 20:46',
              },
              {
                content: 'Default node',
                timestamp: '2018-04-03 20:46',
              },
            ]
          };
	    },
	    methods: {
	      updateData() {
            var obj = {
              content: 'aaaaaaaa',
              timestamp: '2023-04-03 20:46',
            };
	        this.activities.push(obj);
	        this.activities.push(obj);
	        this.activities.push(obj);
	        this.activities.push(obj);
	        this.activities.push(obj);
	        this.activities.push(obj);
	      },
	      scrollerFunc() {
            //这里要注意用document.getElementById去获取scrollbar组件读取滚动距离值是错误的,要用this.$refs.scrollbar.$el
	        let let1 = this.$refs.scrollbar.$el.firstChild.scrollTop; //滚动条滚动距离
            let let2 = this.$refs.scrollbar.$el.firstChild.scrollHeight; //浏览器总高度
            let let3 = this.$refs.scrollbar.$el.scrollHeight; //浏览器可见高度
	        console.log(let1, let2, let3);
            if(let1 + let3 == let2){
              console.log("页面触底啦")
              let loadingInstance = this.$loading({
                target: "#load",
                text: "加载中"
              });
              setTimeout(() => {
                //你用的时候这里就可以访问后端数据进行更新,我这里直接本地更新数据了
                this.updateData();
                loadingInstance.close();
              }, 1000);
	        }
          }
	    },
	    mounted() {
	      this.$refs.scrollbar.$el.addEventListener("scroll", this.scrollerFunc, true);  
          //这里要注意用document.getElementById去获取scrollbar组件绑定滚动事件无效,要使用this.$refs.scrollbar.$el
	    }
      };

      const app = Vue.createApp(App);
      app.use(ElementPlus);
      app.mount("#app");
    </script>
  </body>
</html>

为避免篇幅过长,更多细节的处理、集成分页功能等就不在此展示了,完全可自行实现。

01-05 08:15