vue移动端下拉刷新和上滑加载

Vue移动端下拉刷新和上滑加载攻略

移动端下拉刷新和上滑加载是常见的用户操作需求。在Vue中,我们可以通过一些插件或者自己实现一些组件来完成这些功能。本文将介绍两种实现方式——使用Mint-UI组件和自己实现。

使用Mint-UI实现下拉刷新和上滑加载

Mint-UI是饿了么前端团队推出的一套基于Vue的组件库,提供了丰富的移动端组件。其中,它的下拉刷新和上滑加载组件已经封装好了,我们只需要按照文档来使用即可。

1、安装Mint-UI

# 安装 mint-ui
npm install mint-ui -S

# 引入 mint-ui 样式文件,在入口文件中引入
import 'mint-ui/lib/style.css'

2、使用下拉刷新和上滑加载组件

<template>
  <div>
    <mt-header title="下拉刷新和上滑加载"></mt-header>
    <mt-loadmore :auto-fill="false" :bottom-method="loadBottom" :bottom-all-loaded="allLoaded">
      <!-- 这里是列表内容 -->
    </mt-loadmore>
  </div>
</template>

<script>
  import { InfiniteScroll, Loadmore, Header } from 'mint-ui';

  export default {
    components: {
      'mt-header': Header,
      'mt-loadmore': Loadmore
    },
    directives: { InfiniteScroll },
    data() {
      return {
        allLoaded: false,
        list: []
      }
    },
    methods: {
      loadBottom() {
        // 这里是上滑加载的逻辑
        // 向服务端请求数据
        // 更新allLoaded值
      }
    }
  }
</script>

在这个例子中,我们使用了<mt-header>组件来显示标题,然后使用了<mt-loadmore>组件来显示列表内容,并使用了组件提供的bottom-method属性来监听上滑加载事件。当触发上滑事件时,我们在loadBottom方法中向服务端请求数据,请求完成后再更新allLoaded的值,这样就可以完成上滑加载功能了。

3、使用下拉刷新和上滑加载组件注意事项

在使用Mint-UI的下拉刷新和上滑加载组件时,有一些比较重要的注意事项:

  • 需要在created生命周期函数中调用this.$nextTick(),否则会出现滚动区域和列表高度不一致的问题;
  • 需要监听mounted生命周期函数和window对象的resize事件,以便正确计算滚动区域的高度;
  • 使用InfiniteScroll指令来确保上滑加载事件正确触发。

自己实现下拉刷新和上滑加载

自己实现下拉刷新和上滑加载需要编写大量的代码,但也具有较高的可定制化性和灵活度。

1、确保可以滚动

为了让页面可以滚动,需要在HTML中添加一些必要的CSS样式:

/* 添加以下样式 */
html,
body {
  height: 100%;
  overflow: hidden;
}

.wrapper {
  position: absolute;
  height: 100%;
  width: 100%;
  overflow: scroll;
  -webkit-overflow-scrolling: touch;
}

在实际使用时,可以使用Vue的动态class和style来控制wrapper的样式。

2、实现下拉刷新功能

首先,我们需要在wrapper中添加一个列表,并且将其高度设置为屏幕高度。然后,我们需要监听下拉动作,并在下拉释放后执行刷新逻辑:

<template>
  <div class="wrapper" ref="wrapper">
    <!-- 添加一些列表的DOM结构 -->
  </div>
</template>

<script>
  export default {
    mounted() {
      const wrapper = this.$refs.wrapper;
      const list = wrapper.querySelector('.list');
      const pullDownEl = document.createElement('div');
      pullDownEl.className = 'pullDown';
      pullDownEl.innerHTML = '<span class="pullDownIcon"></span><span class="pullDownLabel">下拉可以刷新</span>';
      list.insertBefore(pullDownEl, list.childNodes[0]);

      let startY, endY, moveY, movePoint = [];
      let isMove = false;
      let pullDownElHeight = 34;
      let startTranslate = -pullDownElHeight;
      let limitScrollY = 100;

      wrapper.addEventListener('touchstart', function (e) {
        startY = e.touches[0].clientY;
        movePoint = [];
        pullDownEl.style.transition = ''
        isMove = false;
      })

      wrapper.addEventListener('touchmove', function (e) {
        moveY = e.touches[0].clientY - startY;
        if (moveY > 0 && wrapper.scrollTop <= 0) {
          if (movePoint.unshift(moveY) > 5) {
            isMove = true;
            e.preventDefault();
            pullDownEl.style.transform = `translate3d(0, ${startTranslate + moveY}px, 0)`
          }
        }
      })

      wrapper.addEventListener('touchend', function (e) {
        if (isMove) {
          pullDownEl.style.transition = 'all .3s';
          let translateY = movePoint[0] + startTranslate;
          pullDownEl.style.transform = `translate3d(0, ${translateY}px, 0)`

          if (translateY > limitScrollY) {
            // 这里是刷新逻辑
            // 更新列表数据
            // 还原元素状态
            setTimeout(() => {
              pullDownEl.style.transition = 'all .3s';
              pullDownEl.style.transform = `translate3d(0, ${startTranslate}px, 0)`
            }, 1000)
          } else {
            setTimeout(() => {
              pullDownEl.style.transition = 'all .3s';
              pullDownEl.style.transform = `translate3d(0, ${startTranslate}px, 0)`
            }, 300)
          }
        }
      })
    }
  }
</script>

<style>
  .wrapper {
    // 添加必要的样式
  }

  .list {
    position: relative;
    height: 100%;
  }

  .pullDown {
    position: absolute;
    top: -34px;
    left: 0;
    right: 0;
    height: 34px;
    line-height: 34px;
    text-align: center;
    font-size: 14px;
    color: #999;
    transition: all .3s;
  }

  .pullDownIcon {
    display: inline-block;
    width: 30px; 
    height: 30px; 
    margin-right: 10px; 
    border-radius: 15px; 
    background: url('icon-pull-down.png') no-repeat center center; 
    background-size: 100% 100%; 
    transform: rotate(180deg);
  }

  .pullDown.pullDownLoading {
    color: #999;
    padding-left: 30px;
    background:url('icon-loading.png') no-repeat center center;
    background-size: 100% 100%; 
    animation: loading 1.5s linear infinite;
    -webkit-animation: loading 1.5s linear infinite;
  }

  @keyframes loading {
    from { transform: rotate(0deg); }
    to { transform: rotate(360deg); }
  }

  @-webkit-keyframes loading {
    from { -webkit-transform: rotate(0deg); }
    to { -webkit-transform: rotate(360deg); }
  }
</style>

在这个例子中,我们监听了wrapper的touchstart、touchmove、touchend事件,并在事件处理函数中根据不同的状态执行不同的逻辑。当我们下拉到一定距离后,会出现一个提示字样,松开手指可以进行刷新。在刷新完毕后,我们需要还原元素状态,并重新渲染列表。

3、实现上滑加载功能

实现上滑加载的逻辑也比较简单,我们需要在列表末尾添加一个类似“上拉加载更多”的提示,并且监听wrapper的scroll事件,在滑动到达指定位置时触发加载逻辑。

<template>
  <div class="wrapper" ref="wrapper" @scroll="onScroll">
    <!-- 添加一些列表的DOM结构 -->
    <div class="pullUp">
      <span class="pullUpIcon"></span>
      <span class="pullUpLabel">上拉加载更多</span>
    </div>
  </div>
</template>

<script>
  export default {
    data() {
      return {
        isLoading: false,
        isFinished: false,
        page: 0,
        pageSize: 10,
        list: []
      }
    },
    methods: {
      loadData() {
        if (this.isLoading || this.isFinished) {
          return;
        }
        this.isLoading = true;
        fetch(`/api/list?page=${this.page}&pageSize=${this.pageSize}`)
          .then(res => res.json())
          .then(data => {
            this.list = this.list.concat(data);
            this.isLoading = false;
            this.isFinished = data.length < this.pageSize;
            this.page++;
          })
          .catch(e => {
            console.log(e);
            this.isLoading = false;
          })
      },
      onScroll(e) {
        const el = e.target;
        const scrollTop = el.scrollTop;
        const height = el.offsetHeight;
        const scrollHeight = el.scrollHeight;
        if (scrollHeight - scrollTop - height < 20 && !this.isLoading && !this.isFinished) {
          this.loadData();
        }
      }
    }
  }
</script>

<style>
  .wrapper {
    // 添加必要的样式
  }

  .list {
    position: relative;
    height: 100%;
  }

  .pullUp {
    margin-top: 10px;
    text-align: center;
    line-height: 30px;
    font-size: 14px;
    color: #999;
  }

  .pullUpIcon {
    display: inline-block;
    width: 30px; 
    height: 30px; 
    margin-right: 10px; 
    border-radius: 15px; 
    background: url('icon-pull-up.png') no-repeat center center;
    background-size: 100% 100%; 
    transform: rotate(180deg); 
  }

  .pullUp.pullUpLoading {
    color: #999;
    padding-left: 30px;
    background:url('icon-loading.png') no-repeat center center;
    background-size: 100% 100%; 
    animation: loading 1.5s linear infinite;
    -webkit-animation: loading 1.5s linear infinite;
  }
</style>

在这个例子中,我们监听了wrapper的scroll事件,并在事件处理函数中计算当前滚动位置和高度,并进行判断是否触发上滑加载逻辑。在加载完成后,我们需要更新列表数据,并在判断是否还有更多数据可以加载。

总结

本文介绍了两种实现下拉刷新和上滑加载功能的方法——使用Mint-UI组件和自己实现。前者可以快速实现功能,但不具有太高的灵活度和可定制性;后者可以自由控制样式和逻辑,但需要编写较多的代码。在实际项目中,可以根据具体情况选择合适的方法来实现这个功能。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:vue移动端下拉刷新和上滑加载 - Python技术站

(0)
上一篇 2023年6月25日
下一篇 2023年6月25日

相关文章

  • java生成随机字符串方法(三种)

    以下是关于Java生成随机字符串方法的完整攻略,包括三种生成随机字符串的方法和两个示例说明。 方法一:使用Random类生成随机字符串 使用Java的Random类可以生成随机字符串。以下是使用Random类生成随机字符串的步骤: 创建一个Random对象; 定义一个字符串变量,用于存储生成的随机字符串; 使用Random对象生成随机数,并将其转换为字符; …

    other 2023年5月7日
    00
  • Visual Studio 14 初试,vNext

    Visual Studio 14 初试,vNext 最近,微软推出了他们的全新 Visual Studio 14,它的正式名称应该是 Visual Studio 2015,但是现在还没有官方发布。此外,作为一位站长,还听说了有一个 vNext 版本的 Visual Studio,是什么呢? Visual Studio 14 最近 Visual Studio …

    其他 2023年3月28日
    00
  • PHP常量及变量区别原理详解

    PHP常量及变量区别原理详解 常量(Constants) 常量是在程序执行过程中不可改变的值。在PHP中,常量使用define()函数定义,一旦定义后就不能再次修改或取消定义。常量的命名规则与变量相同,但通常使用大写字母来表示。 定义常量 可以使用define()函数来定义常量,它接受两个参数:常量的名称和常量的值。例如: define(\"PI\…

    other 2023年8月9日
    00
  • matlab中normalize函数用法

    以下是关于“Matlab中normalize函数用法”的完整攻略: normalize函数概述 normalize函数是Matlab中的一个函数,用于将向量或矩阵归一化。归一化后的向量或矩阵的范数为1。 normalize函数语法 normalize函数的语法如下: B = normalize(A) B = normalize(A,dim) B = norm…

    other 2023年5月7日
    00
  • Composition API思想封装NProgress示例详解

    我将为你详细讲解“Composition API思想封装NProgress示例详解”的完整攻略。 简介 首先,我们需要了解什么是Composition API及NProgress。 Composition API是Vue.js 3.0中新引入的一种API风格,它提供了更明确、更简洁、更灵活的代码结构和组合方式,让我们能够更快速地编写可维护性更高的代码。 而N…

    other 2023年6月25日
    00
  • Springboot实现ENC加密的详细流程

    Spring Boot实现ENC加密的详细流程攻略 1. 简介 在Spring Boot中,我们可以使用Jasypt库来实现ENC加密。Jasypt是一个Java库,提供了对称和非对称加密的功能,可以用于保护应用程序中的敏感信息,如数据库密码、API密钥等。 2. 添加依赖 首先,我们需要在pom.xml文件中添加Jasypt的依赖: <depende…

    other 2023年8月6日
    00
  • Apache下分析ab性能测试结果

    很抱歉,由于我是一个文本模型,无法提供标准的markdown格式文本。但是我可以为您提供一个关于如何分析Apache下ab性能测试结果的完整攻略,包含两个示例说明: Apache下分析ab性能测试结果 1. 运行ab性能测试 首先,使用ab命令在Apache服务器上运行性能测试。例如,使用以下命令运行一个简单的GET请求测试: ab -n 100 -c 10…

    other 2023年10月17日
    00
  • Spring注解开发生命周期原理解析

    下面我给您具体讲解一下“Spring注解开发生命周期原理解析”的完整攻略。 1. 什么是Spring注解开发生命周期? Spring框架核心IOC容器负责管理bean的生命周期,Spring提供了两种方式来管理bean的生命周期: 实现BeanFactoryAware接口来得到BeanFactory的引用 实现ApplicationContextAware接…

    other 2023年6月27日
    00
合作推广
合作推广
分享本页
返回顶部