3-3 触摸事件与下拉刷新 / 上拉加载
配套 Demo
移动端没有鼠标,靠手指触摸。这一章讲触摸事件的基础,以及 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. 在电脑上调试触摸
电脑没触摸屏,两种办法:
- F12 → 设备工具栏(手机图标):进入移动模拟模式,鼠标拖动会模拟触摸。
- 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 部分实战的商品列表就是这个组合。
动手练习
- 打开
demo/3-3-touch.html,在灰色区域用鼠标拖动(或 F12 设备模式下用触摸),看实时显示的「按下点 / 当前点 / 位移 / 方向」。 - 观察:向不同方向拖,方向判断(上/下/左/右)是否正确。
- 看代码里如何用「起点坐标 - 当前坐标」算出位移和方向。
- 概念巩固:回想下拉刷新和上拉加载分别对应哪个 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,给代码加上类型护栏。