别用 navigator.vibrate;真机有效且跨端可用的只有 uni.vibrateshort 和 uni.vibratelong,但需按平台特性调用,ios/android 行为差异极大。
直接结论:别用 navigator.vibrate,它在 uni-app 里基本等于摆设;真机有效、跨端可用的只有 uni.vibrateshort 和 uni.vibratelong,但必须按平台特性调用,且 ios/android 行为差异极大。
uni.vibrateShort / uni.vibrateLong 为什么有时没反应
这两个 API 是 uni-app 官方封装的、唯一真正打通原生震动能力的接口,但失效原因和平台强相关:
- iOS 真机不震?先确认「设置 → 辅助功能 → 触感反馈」已开启;静音开关拨下时,
uni.vibrateShort会彻底静默,连fail回调都不会触发 - Android 没反应?检查
manifest.json是否在"androidPermissions"里声明了"android.permission.VIBRATE";国产 ROM(如小米、华为)还需手动进「应用通知权限 → 振动提醒」打开开关 - 打包成 App 后仍无效?确保不是 H5 或小程序环境误调——
uni.vibrateShort在 H5 和小程序中完全不生效,调用即丢弃
Android 和 iOS 震动行为根本不同
不能把震动当成“统一播放一段毫秒波形”,iOS 和 Android 底层机制完全不同:
- Android 的
uni.vibrateShort实际调用系统 Vibrator,约 15ms 短震,响应快、可高频触发(但需间隔 ≥50ms) - iOS 的
uni.vibrateShort并非“短时间震动”,而是触发系统预设的轻量触感样式(Taptic Engine),它不接受毫秒参数,也不支持自定义时长;传uni.vibrateShort({ duration: 10 })会被忽略 -
uni.vibrateLong在两端都固定为 400ms 左右,iOS 上表现为一次中等强度触感,Android 上是明确马达震动
连续点击或节奏震动怎么写才不翻车
震动没有 Promise、没有完成回调,纯异步且无状态,连点场景下极易错乱:
- 不要用
setTimeout手动拼“滴滴-滴”节奏——iOS 会直接丢弃后续调用,Android 可能合并成一次长震或被系统限频 - 节流是必须的:两次
uni.vibrateShort调用间隔至少 50ms,建议用lastVibrateTime记录 + 时间差判断 - 想模拟复杂触感(比如按钮按下+释放双反馈),iOS 必须换原生方案:
plus.ios.importClass("UIImpactFeedbackGenerator"),但仅限 App 端,且需impact.prepare()+impact.impactOccurred()配合 - H5 端放弃震动,改用
uni.showToast({ icon: 'success', duration: 80 })或 CSS 动画反馈更实际
manifest.json 和权限配置漏掉就全白干
很多开发者卡在“代码没错却没震动”,问题出在构建配置和系统级授权链上:
- Android 12+(API 31+)强制要求在
manifest.json的"androidPermissions"数组中显式添加:"android.permission.VIBRATE",否则打包后静默失败,无任何提示 - iOS 不需要声明权限,但用户必须手动开启「触感反馈」——这个开关不在应用内弹窗能控制,只能引导用户去系统设置
- App 端使用
plus.device.vibrate(比如传数组实现模式震动)前,必须确保plus环境就绪:if (typeof plus !== 'undefined' && plus.device),且只在onReady或onLoad后调用
震动不是“写了 API 就响”,它是平台能力、系统设置、用户习惯、ROM 厂商策略四层叠加的结果。最稳的做法是:用 uni.vibrateShort 做基础点击反馈,加节流 + 用户引导文案;复杂触感需求直接上原生插件,别硬啃跨端封装的边界。真机测试前,先看一眼手机设置里的震动开关有没有开。











