目录
1.4 .self 只当在 event.target 是当前元素自身时触发处理函数
本篇文章将从一些常用的修饰符入手,进行详细的解释以及例句其用法
1.常用事件修饰符
1.1 .stop 阻止事件冒泡
事件冒泡是指事件在触发后,从最深的元素开始逐层向上执行事件处理函数,直到最顶层元素。
阻止事件冒泡就是阻止向上执行事件处理函数。
相当于调用 event.stopPropagation()方法
<template>
<div @click="divClicked">
<!-- 使用.stop修饰符阻止点击事件冒泡 -->
<button @click.stop="buttonClicked">Click Me</button>
</div>
</template>
<script>
export default {
methods: {
divClicked() {
console.log('DIV clicked');
},
buttonClicked() {
console.log('Button clicked');
}
}
}
</script>
在这个例子中,当按钮被点击时,事件处理函数buttonClicked
会被触发,但是事件不会继续冒泡到外层的div
元素,因此divClicked
不会被调用。这样,你就实现了在Vue中阻止事件冒泡的需求。
1.2 .prevent 阻止标签默认行为
修饰符的作用是调用事件对象的
preventDefault()
方法。
在 JavaScript 中,当某些特定类型的事件(如表单提交事件 submit
或点击链接的 click
事件)被触发时,浏览器可能会有默认的行为。例如,点击一个 <a>
标签会导航到其 href
属性指定的 URL,而提交一个 <form>
会尝试将数据发送到其 action
属性指定的 URL。
有时,你可能希望在触发这些事件时阻止这些默认行为,并执行一些自定义的代码。这时,你可以使用 .prevent
修饰符。
示例:
- 阻止表单提交的默认行为
<template>
<form @submit.prevent="handleSubmit">
<!-- 表单内容 -->
<button type="submit">提交</button>
</form>
</template>
<script>
export default {
methods: {
handleSubmit() {
// 这里是处理表单提交的逻辑,但浏览器不会导航到表单的 action URL
}
}
}
</script>
2.阻止链接的默认导航行为
<template>
<a @click.prevent="handleClick">点击这里不会导航</a>
</template>
<script>
export default {
methods: {
handleClick() {
alert('你点击了链接,但没有导航到新页面!');
}
}
}
</script>
在这个例子中,即使 <a>
标签是一个超链接,但由于我们使用了 .prevent
修饰符,所以当用户点击它时,浏览器不会尝试导航到任何新的 URL,而是会弹出一个警告框。
1.3 .once:事件将只会触发一次
.once用于确保事件处理器只会被触发一次。
这对于一些你只需要在特定事件首次触发时执行的操作特别有用。
示例:
<template>
<div>
<button @click.once="handleClick">点击我(只触发一次)</button>
<p v-if="clickedOnce">你已经点击了按钮!</p>
</div>
</template>
<script>
export default {
data() {
return {
clickedOnce: false
};
},
methods: {
handleClick() {
this.clickedOnce = true;
console.log('按钮被点击了(仅第一次有效)');
// 这里可以添加其他只执行一次的逻辑
}
}
};
</script>
在这个例子中,当你首次点击按钮时,handleClick
方法会被调用,clickedOnce
数据属性会被设置为 true
,并且页面上会显示一个消息“你已经点击了按钮!”。但是,由于我们使用了 .once
修饰符,所以如果你再次点击按钮,handleClick
方法将不会被再次调用。
需要注意的是,.once
修饰符只影响绑定到特定组件实例的特定事件监听器。如果组件被重新渲染(例如,由于 v-if
条件的变化),那么新的实例将不再具有 .once
的限制,因为这是一个全新的组件实例和全新的事件监听器。
1.4 .self 只当在 event.target 是当前元素自身时触发处理函数
它的主要作用是确保只有当事件是从绑定该修饰符的元素本身触发时,才会执行相应的事件处理函数。如果事件是从该元素内部的子元素触发并冒泡上来的,那么带有
.self
修饰符的事件处理函数将不会被执行
这种修饰符在处理事件冒泡时特别有用,因为当你点击一个元素时,它的父元素(以及更上层的元素)的相同类型事件也会被触发,这有时并不是我们想要的行为。通过使用 .self
修饰符,我们可以确保只有直接点击该元素时,事件处理函数才会被执行。
示例:
<template>
<div @click.self="handleOuterClick" class="outer">
外部区域
<div class="inner" @click="handleInnerClick">
内部区域
</div>
</div>
</template>
<script>
export default {
methods: {
handleOuterClick() {
console.log('你点击了外部区域');
},
handleInnerClick() {
console.log('你点击了内部区域');
}
}
}
</script>
在这个例子中,如果你点击了 inner
类的 div
,只有 handleInnerClick
方法会被执行,因为 .self
修饰符阻止了从 inner
区域冒泡到 outer
区域的事件。但是,如果你直接点击 outer
区域(不触及 inner
区域),那么 handleOuterClick
方法将被执行。
1.5 .capture: 使用事件捕获模式
它用于改变事件监听的行为,使得事件在捕获阶段而非冒泡阶段被触发。
在 DOM 中,事件传播分为三个阶段:捕获阶段、目标阶段和冒泡阶段。默认情况下,如果你在一个元素上添加事件监听器,那么这个监听器会在冒泡阶段被触发,也就是说,事件会从最内部的元素开始触发,然后逐渐向外层元素传播。
但是,如果你使用了 .capture
修饰符,那么事件监听器就会在捕获阶段被触发。捕获阶段与冒泡阶段正好相反,它是从外层元素开始,然后逐渐向内层元素传播。
示例:
<template>
<div @click.capture="handleOuterClick" class="outer">
外部区域
<div class="inner" @click="handleInnerClick">
内部区域
</div>
</div>
</template>
<script>
export default {
methods: {
handleOuterClick() {
console.log('外部区域在捕获阶段被点击');
},
handleInnerClick() {
console.log('内部区域在冒泡阶段被点击');
}
}
};
</script>
在这个例子中,如果你点击了内部的 div
(即“内部区域”),则两个方法都会被调用,但 handleOuterClick
会首先被调用(在捕获阶段),然后 handleInnerClick
会在冒泡阶段被调用。如果你只点击了外部的 div
(即“外部区域”且没有触及“内部区域”),那么只有 handleOuterClick
会被调用。
使用 .capture
修饰符可以在某些场景下提供额外的灵活性,特别是当你需要在事件到达目标元素之前进行某些操作时。然而,请注意过度使用它可能会导致代码难以理解和维护,因此应谨慎使用。
1.6 .native:使用时将被当成原生HTML标签看待
主要用于在自定义组件上监听原生DOM事件,而不是组件内定义的事件。
具体来说,当你想要在一个Vue组件的根元素上监听一个原生事件时,你可以使用 .native
修饰符。这是因为Vue组件并不是真正的DOM元素,而是由Vue的虚拟DOM系统管理的。因此,如果你直接在组件上监听一个事件(如 @click
),你实际上是在监听该组件内部定义的自定义事件,而不是组件根元素的原生DOM事件。
然而,通过使用 .native
修饰符,你可以将事件监听器绑定到组件的根元素上,从而监听原生DOM事件。这在你想要访问或修改原生DOM元素的属性或行为时非常有用。
例如,假设你有一个名为 my-button
的自定义按钮组件,你可能想要在该组件的根元素(一个真正的DOM button
元素)上监听 click
事件。你可以这样做:
<my-button @click.native="handleClick"></my-button>
在这个例子中,handleClick
方法将在 my-button
组件的根元素(即一个真正的DOM button
元素)上被触发,而不是在 my-button
组件内部定义的任何自定义事件上被触发。
需要注意的是,.native
修饰符只适用于自定义组件,并且只能用于监听原生DOM事件。对于普通的HTML元素,你不需要使用 .native
修饰符来监听事件,因为Vue会自动处理这些元素上的事件监听。
1.7 .passive 不阻止事件的默认行为
主要作用是提升页面滚动和触摸移动的性能,特别是在移动端设备上。这个修饰符主要用于那些需要频繁触发的事件,如
scroll
、touchmove
、wheel
等。
传统的事件监听器在事件触发时,会先执行事件处理函数,然后再决定是否阻止事件的默认行为(如阻止滚动)。这会导致性能问题,因为浏览器需要等待JavaScript执行完成后才能继续处理其他任务,如滚动页面。而使用 .passive
修饰符可以告诉浏览器,事件处理函数不会阻止事件的默认行为,这样浏览器就不需要等待JavaScript执行完成,可以立即进行其他任务。这可以提高页面的滚动性能,尤其是在移动端设备上。
.passive
修饰符的作用原理是,它表示处理事件函数中不会调用 preventDefault()
函数,从而减少了额外的监听,提高了性能。因此,.passive
修饰符不能和 .prevent
修饰符一同使用,否则浏览器会报错。
简单来说,.passive
修饰符就是告诉浏览器,这个事件处理函数不会阻止事件的默认行为,让浏览器在事件触发时能够更快地执行后续操作,从而优化性能。
提示:使用修饰符时,顺序很重要
使用修饰符时,顺序很重要;相应的代码会以同样的顺序产生。因此,用v-on:click.prevent.self会阻止所有的点击,而 v-on:click.self.prevent 只会阻止对元素自身的点击。
2.表单修饰符
2.1 .lazy 延迟绑定
它的主要作用是实现输入框的延迟绑定
具体来说,默认情况下,当用户在输入框中输入内容时,Vue会立即更新与输入框绑定的数据。但是,如果使用了 .lazy
修饰符,Vue将不会立即更新数据。相反,它会在用户完成输入(例如,光标离开输入框)时更新数据。
这种延迟绑定的方式在某些业务场景下非常有用。例如,你可能不需要实时关注输入框中文案的变化,而只需要在用户输入完成后再进行数据逻辑的处理。这时,.lazy
修饰符就可以派上用场
<template>
<input type="text" v-model.lazy="inputValue" placeholder="请输入内容">
<p>输入的内容是:{{ inputValue }}</p>
</template>
<script>
export default {
data() {
return {
inputValue: ''
}
}
}
</script>
在这个示例中,只有当用户完成输入,即光标离开输入框后,<p>
标签中的内容才会更新为用户输入的值
2.2 .numbe r限制输入数字或将输入的数据转为数字
它的主要作用是将输入框中的字符串值转换为数字类型。
具体来说,当我们在Vue中使用 v-model
指令来双向绑定一个输入框的值到一个变量时,默认情况下这个值会是一个字符串类型。但是,如果我们期望这个值是一个数字类型,并希望Vue能够自动帮我们进行转换,那么我们就可以使用 .number
修饰符。
使用 .number
修饰符后,Vue会使用 parseFloat()
来尝试将输入框中的值转换为数字。但是需要注意的是,.number
修饰符只会对纯数字字符串进行转换,如果字符串中包含非数字字符,那么转换可能会失败,并返回原始值。
此外,.number
修饰符并不会改变输入框的 type
属性,也就是说,即使你使用了 .number
修饰符,输入框仍然可以接受非数字字符的输入。即如果你先输入数字,那它就会限制你输入的只能是数字;如果你先输入字符串则该修饰符失效。
示例
<template>
<input type="number" v-model.number="numberValue" placeholder="请输入一个数字">
<p>你输入的数字是:{{ numberValue }}</p>
</template>
<script>
export default {
data() {
return {
numberValue: 0
}
}
}
</script>
在这个示例中,无论用户输入什么内容,numberValue
变量都会尝试将其转换为数字类型。
2.3 .trim 去除仅首尾的空格
它的主要作用是在用户输入时自动去除输入值的首尾空格,中间的空格不会去掉。
当你在表单元素(如 <input>
或 <textarea>
)上使用 v-model
并希望确保用户输入的值不包含首尾空格时,.trim
修饰符会非常有用。它会在数据被同步到Vue实例的data属性之前自动去除用户输入值的首尾空格。
<template>
<input type="text" v-model.trim="username" placeholder="请输入用户名">
<p>输入的用户名是:{{ username }}</p>
</template>
<script>
export default {
data() {
return {
username: ''
}
}
}
</script>
在这个示例中,无论用户在输入框中输入的内容前后是否有空格,username
变量都会自动去除这些空格,确保存储的是一个没有首尾空格的字符串。这对于某些需要精确匹配用户名或其他字符串的场景非常有用,可以避免因为首尾空格导致的匹配错误。
3.按键修饰符
3.1keyCode
如果不用keyCode修饰符,那我们每次按下键盘都会触发shout,当我们想指定按下某一个键才触发这个shout的时候,这个修饰符就有用了
// 加键盘码,按下回车键触发
<input type="text" @keyup.13="dddd" />
//不加键盘码则随便按就会触发事件
<div id="app">
<label>
输入框:<input type="text" v-on:keyup="show">
</label>
</div>
<script>
var vm = new Vue({
el: '#app',
methods: {
show() {
alert('键盘事件已被触发')
}
},
})
</script>
键盘和鼠标各个键位对应的ASCII码值如下:
这就是键盘和鼠标上各个键位对应的ASCII码,一些支持宏编程的键盘和鼠标上面的一些键位没有专属的ASCII码,具体对应的ASCII码要看编程对应的对象。
3.2常用的keyCode别名
.enter
.tab
.delete (捕获“删除”和“退格”键)
.esc
.space
.up
.down
.left
.right
修饰键:.ctrl
.alt
.shift
.meta
另外
@keyup:键盘抬起
@keydown:键盘按下
示例:
<template>
<p>enter 修饰符</p>
<input type="text" placeholder="按回车键提交内容" @keyup.enter="info">
<p>delete 修饰符</p>
<input type="text" placeholder="按删除键或退格键提交内容" @keyup.delete="info">
<p>esc 修饰符</p>
<input type="text" placeholder="按退出键提交内容" @keyup.esc="info">
<p>space 修饰符</p>
<input type="text" placeholder="按空格键提交内容" @keyup.space="info">
<p>tab 修饰符【特殊,必须配合 keydown 去使用】</p>
<input type="text" placeholder="按换行键提交内容" @keydown.tab="info">
<p>up 修饰符</p>
<input type="text" placeholder="按上键提交内容" @keyup.up="info">
<p>down 修饰符</p>
<input type="text" placeholder="按下键提交内容" @keyup.down="info">
<p>left 修饰符</p>
<input type="text" placeholder="按左键提交内容" @keyup.left="info">
<p>right 修饰符</p>
<input type="text" placeholder="按左键提交内容" @keyup.right="info">
<p>w 修饰符</p>
<input type="text" placeholder="按 w 键提交内容" @keyup.w="info">
<p>......</p>
</template>
<script setup>
const info = (e) => {
console.log(e.target.value);
}
</script>
还可以监听组合键,例如 Ctrl + C 的组合键:
<template>
<input @keyup.ctrl.c="handleCtrlC" />
</template>
<script>
export default {
methods: {
handleCtrlC() {
console.log('Ctrl + C was pressed.');
}
}
}
</script>
3.3自定义按键修饰符别名
Vue 允许你配置自定义按键修饰符别名。这可以通过
Vue.config.keyCodes
对象来完成。
// 在 main.js 或其他全局配置文件中
Vue.config.keyCodes = {
f1: 112,
escape: 27 // 你甚至可以覆盖默认的别名
}
// 然后在模板中
<input @keyup.f1="handleF1" />
注意:从 Vue 3 开始,Vue.config.keyCodes
已被移除。在 Vue 3 中,你可以使用 v-on
或 @
监听器的 keyCode
、key
、altKey
、ctrlKey
、metaKey
、shiftKey
等属性来实现相同的效果。
<template>
<input @keyup="handleKeyup" />
</template>
<script>
export default {
methods: {
handleKeyup(event) {
if (event.key === 'F1') {
console.log('F1 key was pressed.');
}
}
}
}
</script>
注意:键分成了普通常用的键和系统修饰键
当我们写如下代码的时候,我们会发现如果仅仅使用系统修饰键是无法触发keyup事件的。
比如
<input type="text" @keyup.ctrl="shout(4)" />
那该如何呢?我们需要将系统修饰键和其他键码链接起来使用,比如
<input type="text" @keyup.ctrl.67="shout(4)" />
这样当我们同时按下ctrl+c时,就会触发keyup事件。
另,如果是鼠标事件,那就可以单独使用系统修饰符。
<button @mouseover.ctrl="shout(1)" />
<button @mousedown.ctrl="shout(2)" />
<button @click.ctrl.67="shout(3)" />
3.4 . exact精确系统修饰符按键
.exact
修饰符允许控制触发一个事件所需的确定组合的系统按键修饰符。
<!-- 当按下 Ctrl 时,即使同时按下 Alt 或 Shift 也会触发 -->
<button @click.ctrl="onClick">A</button>
<!-- 仅当按下 Ctrl 且未按任何其他键时才会触发 -->
<button @click.ctrl.exact="onCtrlClick">A</button>
<!-- 仅当没有按下任何系统按键时触发 -->
<button @click.exact="onClick">A</button>
4.鼠标修饰符
4.1 .left
修饰符 .left
仅在点击鼠标左键时触发事件。
<!-- 仅在点击左键时触发 click 事件 -->
<div @click.left="handleLeftClick">Click me</div>
4.2 .right
.right是在 点击鼠标右键时触发事件
<!-- 仅在点击右键时触发 contextmenu 事件 --> <div @contextmenu.right="handleRightClick">Right-click me</div>
4.3 .middle
在点击鼠标中键时触发事件
<!-- 仅在点击中键时触发 mousedown 事件 --> <div @mousedown.middle="handleMiddleClick">Middle-click me</div>
5.其他修饰符
下面这几个并不是Vue官方内置的修饰符,所以放到其他中来说。
5.1 .sync
能对props进行一个双向绑定
//父组件
<comp :myMessage.sync="bar"></comp>
//子组件
this.$emit('update:myMessage',params);
以上这种方法相当于以下的简写
//父亲组件
<comp :myMessage="bar" @update:myMessage="func"></comp>
func(e){
this.bar = e;
}
//子组件js
func2(){
this.$emit('update:myMessage',params);
}
使用sync需要注意以下两点:
- 使用sync的时候,子组件传递的事件名格式必须为update:value,其中value必须与子组件中props中声明的名称完全一致
- 注意带有 .sync 修饰符的 v-bind 不能和表达式一起使用
- 将 v-bind.sync 用在一个字面量的对象上,例如 v-bind.sync=”{ title: doc.title }”,是无法正常工作的
5.2 .prop
设置自定义标签属性,避免属性暴露在标签上,防止污染HTML结构
<body>
<div id="app">
<div
:test1="'我会在标签属性中展示'"
:test2.prop="'我不会在标签属性中展示'"
></div>
</div>
<script>
const vm = new Vue({
el: "#app",
data: {
k: "",
},
});
</script>
</body>
打开控制台检查元素
发现只有test1属性暴露在标签上面
5.3 .camel 驼峰命名法
camel
这个词通常与“驼峰命名法”(CamelCase)相关联,这是一种编程中常见的命名约定,其中复合词或短语中的每个单词或缩写词的第一个字母大写,没有下划线或空格分隔单词。
由于HTML 特性是不区分大小写的。
<svg :viewBox="viewBox"></svg>
实际上会渲染为
这将导致渲染失败,因为 SVG 标签只认 viewBox,却不知道 viewbox 是什么。
如果我们使用.camel修饰符,那它就会被渲染为驼峰名。
另,如果你使用字符串模版,则没有这些限制。
const vm = new Vue({
template: '<svg :viewBox="viewBox"></svg>',
});
使用示例:
<template>
<div v-bind:my-camel-case-prop="myCamelCaseProp">...</div>
</template>
<script>
export default {
data() {
return {
myCamelCaseProp: 'some value'
};
}
}
</script>
以上就是常见的修饰符,欢迎留言交流。