Skip to content

3-3 触摸事件与下拉刷新 / 上拉加载

移动端没有鼠标,靠手指触摸。这一章讲触摸事件的基础,以及 H5 列表两大高频交互:下拉刷新上拉加载更多。实战里这两个几乎每个列表页都有。

配套 demo:demo/3-3-touch.html(触摸轨迹可视化,鼠标也能拖,方便在电脑上观察)。


1. 触摸事件三件套

移动端的核心触摸事件:

事件触发时机类比鼠标
touchstart手指按下mousedown
touchmove手指移动(连续触发)mousemove
touchend手指抬起mouseup

在 Vue 里用 @touchstart 等绑定:

html
<div @touchstart="onStart" @touchmove="onMove" @touchend="onEnd">滑我</div>
js
function onStart(e) {
  const touch = e.touches[0]        // 第一个触摸点
  console.log('按下位置', touch.clientX, touch.clientY)
}
function onMove(e) {
  const touch = e.touches[0]
  console.log('移动到', touch.clientX, touch.clientY)
}

要点:

  • 触摸点信息在 e.touches(当前屏上的手指)里,e.touches[0] 是第一根手指。
  • clientX/clientY 是相对视口的坐标。
  • 用「按下坐标」和「移动坐标」算差值,就能判断滑动方向和距离(实现滑动删除、轮播等)。

实战提示:多数情况你不用手写触摸逻辑。滑动、轮播、下拉刷新这些,Vant 都有现成组件(见下)。手写主要用于特殊自定义交互。


2. 在电脑上调试触摸

电脑没触摸屏,两种办法:

  1. F12 → 设备工具栏(手机图标):进入移动模拟模式,鼠标拖动会模拟触摸。
  2. demo 里我同时绑了鼠标事件,直接用鼠标拖也能看到效果

3. 下拉刷新:Vant PullRefresh

「列表顶部往下拉,松手刷新数据」。Vant 一个组件搞定:

html
<van-pull-refresh v-model="refreshing" @refresh="onRefresh">
  <van-cell v-for="item in list" :key="item.id" :title="item.text" />
</van-pull-refresh>
js
const refreshing = ref(false)   // 是否正在刷新
const list = ref([...])

async function onRefresh() {
  // 下拉时触发:去重新拉数据
  list.value = await fetchLatest()
  refreshing.value = false       // 拉完把刷新状态关掉,收起动画
}

逻辑:v-model="refreshing" 绑定刷新状态,用户下拉触发 @refresh,你拉完数据后把 refreshing 设回 false


4. 上拉加载更多:Vant List

「列表滚到底,自动加载下一页」(分页)。用 Vant List:

html
<van-list v-model:loading="loading" :finished="finished" finished-text="没有更多了"
          @load="onLoad">
  <van-cell v-for="item in list" :key="item.id" :title="item.text" />
</van-list>
js
const list = ref([])
const loading = ref(false)    // 是否正在加载下一页
const finished = ref(false)   // 是否全部加载完
let page = 1

async function onLoad() {
  // 滚到底时自动触发
  const res = await fetchPage(page)
  list.value.push(...res.items)   // 追加到现有列表
  loading.value = false           // 本页加载完
  page++
  if (res.items.length === 0) finished.value = true  // 没数据了,标记完成
}

三个状态记牢:

  • loading:正在加载下一页(组件显示「加载中」)。
  • finished:全部加载完,不再触发 @load
  • @load:滚到底自动调用,你在里面拉下一页并 push 追加。

后端类比:就是分页接口(page/size)的前端消费,只不过触发方式是「滚到底」而不是点「下一页」按钮。


5. 下拉刷新 + 上拉加载 组合(实战标配)

两者经常一起用:外层 van-pull-refresh 包住内层 van-list

html
<van-pull-refresh v-model="refreshing" @refresh="onRefresh">
  <van-list v-model:loading="loading" :finished="finished" @load="onLoad">
    <van-cell v-for="item in list" :key="item.id" :title="item.text" />
  </van-list>
</van-pull-refresh>

下拉 = 重置到第一页重新加载;滚到底 = 加载下一页。第 5 部分实战的商品列表就是这个组合。


动手练习

  1. 打开 demo/3-3-touch.html,在灰色区域用鼠标拖动(或 F12 设备模式下用触摸),看实时显示的「按下点 / 当前点 / 位移 / 方向」。
  2. 观察:向不同方向拖,方向判断(上/下/左/右)是否正确。
  3. 看代码里如何用「起点坐标 - 当前坐标」算出位移和方向。
  4. 概念巩固:回想下拉刷新和上拉加载分别对应哪个 Vant 组件、各自的关键状态变量。

小结

  • 触摸三件套:touchstart / touchmove / touchend,坐标在 e.touches[0]
  • 电脑调试用 F12 设备工具栏。
  • 下拉刷新 → Vant van-pull-refresh(refreshing 状态 + @refresh)。
  • 上拉加载 → Vant van-list(loading / finished + @load,push 追加)。
  • 实战常把两者组合用于列表页。

🎉 第 3 部分完成!你已掌握 H5 适配、Vant 组件、移动端交互。 ➡️ 下一部分 第 4 部分:TypeScript,给代码加上类型护栏。

写给有后端基础、想系统学习 Vue 3 与 H5 的开发者