uni-app 的 longpress 事件非原生支持,需通过 touchstart + touchend + settimeout 手动模拟,仅 h5 支持 v-longpress 指令,小程序和 app 端须自行封装跨平台方案。

uni-app 的 longpress 事件不是原生支持的独立事件
uni-app 的 view、text 等组件没有直接暴露 longpress 事件,它不像 click 或 tap 那样可直接绑定。所谓“长按触发”,实际是靠 touchstart + touchend + 定时器模拟出来的逻辑。
你写 @longpress="handleLongPress" 是无效的——编译不报错但永远不会触发,因为框架根本不识别这个事件名。
- 真机上只有
button组件在部分平台(如微信小程序)有内置长按反馈,但不提供事件回调 - H5 端完全无原生
longpress,必须手写 - App 端(iOS/Android)和小程序端行为也不一致:微信小程序里
bindlongtap是存在的,但 uni-app 抽象层把它屏蔽了,统一走模拟逻辑
用 touchstart + touchend + setTimeout 手动实现
核心思路:按下时记下时间,抬起时判断是否超过阈值(比如 500ms),超时就当长按。
注意别漏掉 touchcancel —— 用户中途滑出区域或切后台,必须清除定时器,否则可能误触发。
- 推荐阈值设为
500,太短易误触,太长(如 1000)用户感知差 - 所有 touch 类事件需加
preventDefault吗?不需要。除非你在做手势识别,否则默认行为(如滚动)应保留 - 避免在
v-for列表里每个 item 都新建一个定时器变量,建议用ref或闭包绑定唯一 id 控制
// 示例:在组件 methods 中
onTouchStart() {
this.longPressTimer = setTimeout(() => {
this.handleLongPress();
}, 500);
},
onTouchEnd() {
clearTimeout(this.longPressTimer);
},
onTouchCancel() {
clearTimeout(this.longPressTimer);
}
uni-app 2.9+ 提供了 longpress 指令,但仅限 H5 平台
新版 uni-app 在 H5 端增加了 v-longpress 指令,底层就是封装了上面的手动逻辑。但它在小程序和 App 端不生效,写了等于没写。
- 写法:
<view v-longpress="handleLongPress">长按我</view> - 只对 H5 有效;微信小程序里会静默忽略,App 端也无反应
- 不支持传参,也不能阻止默认长按菜单(如 iOS 上弹出“复制”菜单),得额外加
user-select: none和-webkit-user-select: none - 如果你项目只跑 H5,可以用;否则必须自己封装跨平台方案
封装成可复用的 mixin 或 composables(Vue 3)更稳妥
手动写三四个事件监听容易出错,尤其在列表渲染、条件显示场景下,定时器清理不干净会导致内存泄漏或跨 item 触发。
真正稳定的方案是抽离逻辑:用 useLongPress hook(Vue 3)或 longPressMixin(Vue 2),把计时、清理、防抖都包进去。
- 关键点:每次
touchstart前必须先clearTimeout,哪怕上次已结束 - 不要依赖
event.target做判断,用绑定时的上下文(如item.id)更可靠 - 如果同时需要
tap和longpress,必须在touchend里区分:未超时就执行 tap,超时则跳过 - App 端 Android 有时
touchend不稳定,可加touchmove监听辅助判断是否滑动离开
跨平台长按最麻烦的不是实现,而是各端 touch 事件触发时机和精度差异——iOS 的 touchend 延迟比 Android 明显,微信小程序又会吞掉部分 touchcancel。所以阈值不能死设,最好留个配置项,上线后根据埋点数据调优。










