如何通过在移动端开发教程中应用指令修饰符.passive优化滚动流畅度?
- 内容介绍
- 相关推荐
本文共计566个文字,预计阅读时间需要3分钟。
简单修改伪创新以下开头内容,不要试图解释问题,不要数落,不超过100个字,直接输出结果:
为什么移动端滚动特别需要 .passive
移动端 touchmove 和 scroll 事件每秒可触发上百次。浏览器默认认为你可能要阻止滚动(比如做下拉刷新或禁止滑动),所以每次都会等你的 JS 回调执行完再滚动——哪怕回调只是一行空语句,也会造成肉眼可见的延迟。
加上 .passive 后,浏览器不再查询、不等待、不阻塞,手指一动,页面即滚,帧率更稳。
怎么在 Vue 中正确使用 @scroll.passive
模板中直接写,无需额外配置:
-
基础写法:
<div @scroll.passive="onScroll">...</div> -
搭配防抖/节流更稳妥:即使用了
.passive,仍建议对onScroll做轻量节流(如 16ms 一次),避免高频触发逻辑影响主线程 -
别混用 .prevent 或 .stop:
.passive和.prevent冲突,因为后者本质就是调用preventDefault(),浏览器会报错并忽略passive: true
哪些场景必须加 .passive
以下情况不加就容易卡:
- 长列表页(商品瀑布流、信息流)的容器滚动监听
- 自定义下拉刷新区域(
@touchstart.passive+@touchmove.passive,但下拉触发时需临时切为非 passive) - 弹窗内可滚动内容(避免滚动穿透的同时保持内部滑动流畅)
- 任何绑了
@scroll或@touchmove却没调用preventDefault()的地方
补充:原生 JS 也要配 options
不用 Vue 时,记得显式传 { passive: true }:
el.addEventListener('scroll', handler, { passive: true });el.addEventListener('touchmove', handler, { passive: true });- 漏掉这个参数,Chrome 控制台会警告 "Unable to preventDefault inside passive event listener",且滚动依然滞后
本文共计566个文字,预计阅读时间需要3分钟。
简单修改伪创新以下开头内容,不要试图解释问题,不要数落,不超过100个字,直接输出结果:
为什么移动端滚动特别需要 .passive
移动端 touchmove 和 scroll 事件每秒可触发上百次。浏览器默认认为你可能要阻止滚动(比如做下拉刷新或禁止滑动),所以每次都会等你的 JS 回调执行完再滚动——哪怕回调只是一行空语句,也会造成肉眼可见的延迟。
加上 .passive 后,浏览器不再查询、不等待、不阻塞,手指一动,页面即滚,帧率更稳。
怎么在 Vue 中正确使用 @scroll.passive
模板中直接写,无需额外配置:
-
基础写法:
<div @scroll.passive="onScroll">...</div> -
搭配防抖/节流更稳妥:即使用了
.passive,仍建议对onScroll做轻量节流(如 16ms 一次),避免高频触发逻辑影响主线程 -
别混用 .prevent 或 .stop:
.passive和.prevent冲突,因为后者本质就是调用preventDefault(),浏览器会报错并忽略passive: true
哪些场景必须加 .passive
以下情况不加就容易卡:
- 长列表页(商品瀑布流、信息流)的容器滚动监听
- 自定义下拉刷新区域(
@touchstart.passive+@touchmove.passive,但下拉触发时需临时切为非 passive) - 弹窗内可滚动内容(避免滚动穿透的同时保持内部滑动流畅)
- 任何绑了
@scroll或@touchmove却没调用preventDefault()的地方
补充:原生 JS 也要配 options
不用 Vue 时,记得显式传 { passive: true }:
el.addEventListener('scroll', handler, { passive: true });el.addEventListener('touchmove', handler, { passive: true });- 漏掉这个参数,Chrome 控制台会警告 "Unable to preventDefault inside passive event listener",且滚动依然滞后

