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

yizhihongxing

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日

相关文章

  • mysql数据类型decimal用法详解

    MySQL数据类型DECIMAL用法详解 在MySQL中,DECIMAL是一种数字数据类型,用于存储固定精度的十进制数。下面详细介绍MySQL数据类型DECIMAL的用法。 DECIMAL类型的定义 DECIMAL的精度定义如下: DECIMAL(M, D) 其中M表示总位数,D表示小数的位数,范围为0到M。例如,DECIMAL(5, 2)表示总共5位,其中…

    其他 2023年3月28日
    00
  • Win10 2004慢速预览版19041.21怎么手动更新?

    当你加入了Win10 2004慢速预览版,但还没有收到最新的更新时,你可以手动触发更新过程来获取最新版本。下面,我为你提供完整的攻略。 步骤一:检查当前版本 在手动更新之前,请确保你已经加入了Win10 2004慢速预览版,而且当前安装的版本不是最新的。你可以通过以下步骤检查: 打开“设置”(快捷键为Win + I)。 选择“系统”。 选择“关于”。 在右侧…

    other 2023年6月27日
    00
  • js手机号码简单正则校验

    js手机号码简单正则校验 在网页开发中,我们常常需要对用户输入进行校验,以保证数据的合法性和正确性。手机号码是我们常常需要验证的一个输入项,本文将介绍如何使用Javascript实现手机号码的简单正则校验。 1. 正则表达式 正则表达式是一种用来匹配字符串的模式,它由一些特定的字符和元字符组成。在进行手机号码校验时,我们需要用到以下正则表达式: /^1[34…

    其他 2023年3月28日
    00
  • 用html制作日历表

    用HTML制作日历表 HTML是一种非常流行的网页制作语言,除了可以编写网页的文本内容,还可以利用HTML标签来设计网页结构、排版和样式。其中,制作日历表是一个非常有趣的HTML项目,不仅可以丰富网页的内容,也可以提高网页设计的能力。 制作一个简单的日历表 首先,我们来看一下如何利用HTML标签制作一个简单的日历表。 示例代码如下: <table&gt…

    其他 2023年3月28日
    00
  • WinXP、Win7、Win8系统电脑查看本机IP地址的方法图文教程

    查看本机IP地址的方法 Windows XP 点击“开始”按钮,选择“运行”。 在运行对话框中输入“cmd”并按下回车键,打开命令提示符窗口。 在命令提示符窗口中输入“ipconfig”并按下回车键。 在输出结果中查找“IPv4 地址”或“IP 地址”,即可找到本机的IP地址。 示例说明: 假设在Windows XP系统中,命令提示符窗口中的输出结果如下: …

    other 2023年7月30日
    00
  • Android利用ViewPager实现可滑动放大缩小画廊效果

    Android利用ViewPager实现可滑动放大缩小画廊效果攻略 在Android开发中,我们可以使用ViewPager来实现可滑动放大缩小的画廊效果。下面是一个详细的攻略,包含两个示例说明。 步骤一:添加依赖 首先,在项目的build.gradle文件中添加ViewPager的依赖: implementation ‘androidx.viewpager2…

    other 2023年8月26日
    00
  • 如何解决json中携带的反斜杠

    如何解决JSON中携带的反斜杠 在处理JSON数据的时候,我们常常会遇到携带反斜杠的字符串。这是因为在JSON中,某些特殊字符需要用反斜杠进行转义,比如双引号、单引号、斜杆、制表符等。而有时候,我们在处理JSON数据的时候,可能并不需要这些反斜杠,甚至会影响后续操作的进行。下面我们将介绍几种解决方法。 1. 使用JSON.parse方法 JavaScript…

    其他 2023年3月28日
    00
  • vue cli4.0项目引入typescript的方法

    第一步:安装Vue CLI 和 Typescript 首先,你需要安装 Vue CLI 和 Typescript。运行如下命令: npm install -g @vue/cli npm install -g typescript 第二步:创建 Typescript 项目 使用 Vue CLI 创建一个新的项目,并选择手动配置,勾选需要的特性。运行如下命令: …

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