在 Vue 中,修饰符是一种特殊的后缀,用于改变指令的默认行为
stop
javascript
<template>
<div>
<h2>vue修饰符</h2>
<div class="box" @click="boxClikc">
<button @click="btnClick">按钮</button>
</div>
</div>
</template>
<script setup>
const boxClikc=()=>{
console.log('box被点击');
}
const btnClick=()=>{
console.log('btn被点击');
}
</script>
<style>
.box{
padding: 20px;
border: 1px solid red;
width: 100px;
}
</style>

当点击按钮外的空白区域,box的事件触发,点击按钮的时候,box和btn的事件都触发了。(事件冒泡是一种事件传播的方式,当一个元素上触发了某个事件时,该事件会从这个元素开始,逐级向上传播到它的父元素,再到父元素的父元素,以此类推,直到传播到文档对象)。 为了避免事件冒泡可以使用.stop修饰符
html
<div class="box" @click="boxClikc">
<button @click.stop="btnClick">按钮</button>
</div>
在点击按钮的时候就会阻止冒泡了,在点击按钮就不会在触发box的事件了

prevent
阻止默认行为修饰符
javascript
<template>
<div>
<h2>vue修饰符</h2>
<form @submit="submitForm.prevent">
<input type="text" v-model="message">
<button type="submit">提交</button>
</form>
</div>
</template>
<script setup>
import { ref } from 'vue';
const message=ref('qqq');
const submitForm=()=>{
console.log('表单提交默认行为被阻止了');
}
</script>
<style>
.box{
padding: 20px;
border: 1px solid red;
width: 100px;
}
</style>
不加.prevent 点击提交后会刷新页面
capture
使用事件捕获模式,即事件从外层元素开始触发,而不是默认的从内层元素开始
javascript
<template>
<div>
<h2>vue修饰符</h2>
<div @click.capture="clickParent">
<div @click="clickSon">capture</div>
</div>
</div>
</template>
<script setup>
import { ref } from "vue";
const clickParent = () => {
console.log("点击了外层盒子");
};
const clickSon = () => {
console.log("点击内层盒子");
};
</script>

不加capture修饰符的话 会默认先打印内层盒子,在打印外层盒子
self
只当事件是从绑定元素本身触发时才触发回调,也就是说如果事件是从子元素冒泡上来的,不会触发该事件处理函数。
javascript
<template>
<div>
<h2>vue修饰符</h2>
<div class="box" @click.self="clickParent">
<div class="innerbox" @click="clickSon">capture</div>
</div>
</div>
</template>
<script setup>
import { ref } from "vue";
const clickParent = () => {
console.log("点击了外层盒子");
};
const clickSon = () => {
console.log("点击内层盒子");
};
</script>
<style>
.box {
padding: 20px;
border: 1px solid red;
width: 100px;
}
.innerbox{
width: 50px; border: 1px solid blueviolet;
}
</style>
当点击内层盒子的时候,不会在触发外层盒子的事件,只有自己外层盒子本身才会触发事件

once
当点击按钮的时候,只会执行一次。
javascript
<button @click.once="textOnce">once</button>
const textOnce=()=>{
console.log('事件触发');
}
passive
在 Vue 里,passive修饰符主要和 DOM 事件监听器相关,它本质上是基于原生 JavaScript 的addEventListener方法的passive选项。这个修饰符主要用于优化滚动性能,尤其是在处理像 scroll,touchmove这类滚动相关事件时。
在默认情况下,浏览器在触发滚动事件时,会先等待事件监听器执行完毕,以判断是否调用 event.preventDefault()来阻止默认行为。但在滚动场景中,这样做可能会导致滚动不流畅,出现卡顿现象。
而使用passive修饰符后,就相当于告诉浏览器:"我不会调用event.preventDefault() 来阻止默认行为,你可以直接执行滚动操作,不用等待我的事件监听器执行完毕"。这样浏览器就能立即响应滚动事件,从而提升滚动的流畅度
javascript
<template>
<div>
<h2>vue修饰符</h2>
<!-- 不加 passive 修饰符 -->
<div class="scroll" @scroll="onScroll">
<h2>不加 passive 修饰符</h2>
<!-- 大量文本用于测试滚动 -->
<p v-for="i in 1000" :key="i">
这是一段文字用来测试 passive 的 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
</p>
</div>
<!-- 加 passive 修饰符 -->
<div class="scroll" @scroll.passive="onScroll">
<h2>加 passive 修饰符</h2>
<p v-for="i in 1000" :key="i + 1000">
这是一段文字用来测试 passive 的 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
</p>
</div>
</div>
</template>
<script setup>
import { ref } from "vue";
const onScroll = () => {
console.log("滚动事件触发");
};
</script>
<style>
.scroll {
width: 150px;
padding: 50px;
height: 30px;
/* 出现y轴上的滚动条 */
overflow-y: auto;
/* 文字超出宽度的时候 换行 */
word-wrap: break-word;
border: 1px solid rgb(235, 214, 32);
}
</style>
当快速滚动这两个区域时,可能会感觉到加了passive修饰符的滚动区域更加流畅,因为浏览器不需要等待事件监听器执行完毕就可以继续滚动。

按键修饰符
按键修饰符用于监听特定的按键事件
javascript
<template>
<div>
<div>
<input type="text" @keyup.enter="onEnter">
<br>
<button @keyup.delete="onDelete">删除</button>
<button @keyup.esc="onEsc">Esc</button>
<button @keyup.space="onSpace">空格</button>
<button @keyup.right="onRight">右键</button>
<!-- div默认没有聚焦的 需要加上tabindex 让div可以聚焦 -->
<div @keyup.down="onDown" tabindex="0">down</div>
</div>
</div>
</template>
<script setup>
const onEnter=()=>{
console.log('用户按下了回车键');
}
const onDelete=()=>{
console.log('用户按下了删除键');
}
const onEsc=()=>{
console.log('用户按下了esc键');
}
const onSpace=()=>{
console.log('用户按下了空格键');
}
const onRight=()=>{
console.log('用户按下了右键');
}
const onDown=()=>{
console.log('用户按下了下键');
}
</script>
当元素聚焦且按下当对应的按键的时候,就会执行相对应的方法

除了以上列举的修饰符外,还有left,up修饰符分别是左键和上键,使用方式一样的。
表单修饰符
lazy修饰符,input失去焦点或者回车后在更新,等于说是把input事件改为了change
number修饰符,绑定的是字符串的话 会转成number类型
trim修饰符,去掉前后空格
javascript
<template>
<div>
<h2>表单修饰符</h2>
<div>
<input type="text" v-model.lazy="message" placeholder="lazy修饰符">
<input type="number" v-model.number="num" @blur="getNum" placeholder="num修饰符">
<input type="text" v-model.trim="message2" placeholder="trim修饰符">
<div>
message:{{ message }} <br> message2:{{ message2 }} <br> num:{{ num }}
</div>
</div>
</div>
</template>
<script setup>
import { ref } from 'vue';
const message=ref('');
const message2=ref('');
const num=ref('15');
const getNum=()=>{
console.log('num',num);
}
</script>
<style>
</style>

不绑定lazy,message会和输入框输入的内容同步更新,绑定后失去焦点才更新
当输入框失去焦点打印了num的值,可以看到已经被转为数字类型的了。
trim 去掉了空格