Vue 事件修饰符使用笔记
在表单提交、弹层点击和列表事件中,经常要调用 event.preventDefault() 或 event.stopPropagation()。Vue 把这些 DOM 层的行为做成了指令修饰符,可以让处理方法更专注于业务数据。下面保留基本语法,再结合实际场景说说容易写错的地方。
为了解决这个问题,Vue.js 为 v-on 提供了事件修饰符。之前提过,修饰符是由点开头的指令后缀来表示的。
.stop
.prevent
.capture
.self
.once
.passive
<!-- 阻止单击事件继续传播 -->
<a v-on:click.stop="doThis"></a>
<!-- 提交事件不再重载页面 -->
<form v-on:submit.prevent="onSubmit"></form>
<!-- 修饰符可以串联 -->
<a v-on:click.stop.prevent="doThat"></a>
<!-- 只有修饰符 -->
<form v-on:submit.prevent></form>
<!-- 添加事件监听器时使用事件捕获模式 -->
<!-- 即元素自身触发的事件先在此处理,然后才交由内部元素进行处理 -->
<div v-on:click.capture="doThis">...</div>
<!-- 只当在 event.target 是当前元素自身时触发处理函数 -->
<!-- 即事件不是从内部元素触发的 -->
<div v-on:click.self="doThat">...</div>
使用修饰符时,顺序很重要;相应的代码会以同样的顺序产生。因此,用 v-on:click.prevent.self 会阻止所有的点击,而 v-on:click.self.prevent 只会阻止对元素自身的点击。
2.1.4 新增
<!-- 点击事件将只会触发一次 -->
<a v-on:click.once="doThis"></a>
不像其它只能对原生的 DOM 事件起作用的修饰符,.once 修饰符还能被用到自定义的组件事件上。如果你还没有阅读关于组件的文档,现在大可不必担心。
2.3.0 新增
Vue 还对应 addEventListener 中的 passive 选项提供了 .passive 修饰符。
<!-- 滚动事件的默认行为 (即滚动行为) 将会立即触发 -->
<!-- 而不会等待 `onScroll` 完成 -->
<!-- 这其中包含 `event.preventDefault()` 的情况 -->
<div v-on:scroll.passive="onScroll">...</div>
这个 .passive 修饰符尤其能够提升移动端的性能。
不要把 .passive 和 .prevent 一起使用,因为 .prevent 将会被忽略,同时浏览器可能会向你展示一个警告。请记住,.passive 会告诉浏览器你不想阻止事件的默认行为。
实际场景怎么选
.prevent 最常见的场景是表单:@submit.prevent="save" 既避免页面刷新,又让 save 中不需要接收 DOM 事件。.stop 更常用于嵌套点击,例如点击列表卡片会跳转,但卡片内的删除按钮不应同时触发跳转。这时可以在删除按钮上写 @click.stop="remove"。
.self 很适合弹层遮罩。点遮罩关闭、点弹窗内容不关闭,可以把事件绑在遮罩层并使用 @click.self="close"。它与 .stop 的思路不同:.stop 阻止事件继续冒泡,.self 允许事件冒泡到当前元素,但只在目标就是当前元素时执行方法。
.capture 改变的是监听阶段,普通业务页面很少需要。如果只是解决父子元素同时触发,优先检查 .stop 或结构是否合理,不要在没弄清事件传播顺序前就把多层元素都改成捕获。
修饰符顺序为什么重要
Vue 会按书写顺序生成事件处理代码。@click.prevent.self 会先阻止默认行为,再判断是否点了元素自身,因此子元素触发的点击也已经被 preventDefault。@click.self.prevent 则先判断目标,只有点到当前元素才阻止默认行为。两者语法都对,但行为不同。
.passive 表示监听器不会调用 preventDefault,浏览器因此不用等处理函数结束就能继续滚动。它适合只记录位置或更新轻量状态的滚动监听,不适合需要禁止滚动的手势逻辑。如果处理函数本身很耗时,加了 .passive 也不会自动解决主线程卡顿,仍然需要节流或减少工作量。
可用性说明:本文发布于 2019 年 6 月,距今已超过五年。文中涉及的软件版本、接口、下载地址、命令参数和操作界面可能已经发生变化,部分方案在当前环境下可能失效。请结合官方最新文档核对后再操作,生产环境使用前务必先行验证。
版权声明: 本文首发于 指尖魔法屋-Vue 事件修饰符使用笔记(https://blog.thinkmoon.cn/post/317-notes-vue-javascript/) 转载或引用必须申明原指尖魔法屋来源及源地址!
评论
使用 GitHub 账号登录后即可留言,支持 Markdown。