.passive修饰符应加在@touchmove和@scroll事件上,且处理函数不调用event.preventDefault()时;不可用于需阻止默认行为的场景,如下拉刷新或模态框禁滚动。

在 Vue 3 中,`.passive` 修饰符主要用在 `@touchmove` 和 `@scroll` 事件上,而不是 `@touchstart`——因为 `touchstart` 本身不涉及持续滚动行为,浏览器也不会因它产生性能阻塞;真正影响滚动流畅度的是 `touchmove`(手指滑动过程)和 `scroll`(容器滚动触发)。所以优化重点应落在 `@touchmove.passive` 和 `@scroll.passive` 上。
哪些场景必须加 `.passive`
只要满足两个条件,就该加上:监听的是 `touchmove` 或 `scroll`,且处理函数里**不调用 `event.preventDefault()`**。典型例子包括:
- 懒加载判断:监听滚动位置,检查图片是否进入视口
- 吸顶导航:根据 `scrollTop` 动态切换 fixed 状态
- 滚动进度条:读取 `event.target.scrollTop` 更新 UI
- 手势方向识别(仅读取 `touches[0].clientY`,不阻止默认滚动)
Vue 3 中的正确写法
语法与 Vue 2 一致,直接追加在事件指令后:
立即学习“前端免费学习笔记(深入)”;
将静态 Vue 页面(index.vue)改造为动态页面(Custom.vue);稿源仅限 index.vue、其引用的 CSS 与资源路径,禁止参考仓库内其他文件。Invoke when user wants to transform a static Vue page into a dynamic data-driven page with Element UI components.
注意:`.passive` 是编译期处理,Vue 会自动为 `addEventListener` 的 `options` 参数传入 `{ passive: true }`,无需手动配置。
哪些情况不能加 `.passive`
一旦代码中可能出现 `event.preventDefault()`,就必须移除 `.passive`,否则控制台报错且行为失效:
- 模态框弹出时禁止背景滚动 → 改用 `document.body.style.overflow = 'hidden'` 或 `touch-action: none`
- 下拉刷新(需阻止默认下拉)→ 改用 `@touchmove.prevent` 或原生 `addEventListener(..., { passive: false })`
- 拖拽排序、滑动开关等自定义手势 → 需精确控制默认行为,`.passive` 不适用
配合 CSS 进一步提效
单靠 `.passive` 不够,还需避免滚动过程中触发重排或强制同步布局:
- 给滚动容器设置明确高度和 `overflow-y: auto`,防止回退到 `body` 滚动
- 避免在 `scroll` 回调中读取 `offsetTop`、`getComputedStyle` 后立刻改样式;优先用 `getBoundingClientRect()` + `requestAnimationFrame` 批量更新
- 高频滚动区可谨慎添加 `will-change: scroll-position`,但不要滥用(可能引发额外内存开销)


















