当在不同的上下文中输出 this
时,会得到不同的结果以下是几个例子来演示不同上下文中的 this
:
全局上下文中的 this
:
console.log(this); // 在浏览器环境中输出全局对象 window,在 Node.js 中输出全局对象 global
对象方法中的 this
:
const person = { name: 'John', sayHello: function() { console.log(this); // 指向当前对象 person } }; person.sayHello();
构造函数中的 this
:
function Person(name) { this.name = name; console.log(this); // 指向新创建的对象实例 } const john = new Person('John');
箭头函数中的 this
:
const myArrowFunction = () => { console.log(this); // 在浏览器环境中指向全局对象 window(如果没有外围上下文的话) }; myArrowFunction();
加下外围函数的this:
当在外围函数中使用箭头函数时,箭头函数会继承外围函数的上下文这意味着,在外围函数中定义的箭头函数会共享外围函数的 this
值让我们来看一个示例:
function outerFunction() { console.log(this); // 外围函数的 this const innerArrow = () => { console.log(this); // 继承外围函数的 this }; innerArrow(); } const myObject = { name: 'John', outer: outerFunction }; myObject.outer(); // 外围函数的 this 是 myObject,箭头函数继承了外围函数的 this
再来一个,加强理解
在data中的this:
data: { name: '即兴小索奇', age: '6', showInfo(){ console.log(this) // 输出window }}
在全局作用域(即没有嵌套在任何函数或对象中)中定义对象字面量,这个函数实际上会成为全局对象的属性,那么对象字面量内部的函数的 this
默认会指向全局对象 window
所以,在对象字面量中定义了 showInfo
方法时,它的上下文(this
的值)会指向全局对象 window
,而不是 Vue 实例
事件修饰符
用不同的事件修饰符时,以不同的方式行动
重点
- **
.prevent
**:这个修饰符就像是阻止事件按照平常的方式去做举个例子,你点击一个链接,但是加了.prevent
修饰符,链接就不会打开新页面 - **
.stop
**:阻止事件传播给其他元素(阻止事件冒泡) - **
.once
**:只会触发一次事件,后面再次点击事件就无效了 - **
.capture
**:让事件监听器在捕获阶段就能听到事件,而不是等到冒泡阶段就好像是你提前听到了一个消息,比其他人都早 - **
.self
**:只有event.target是当前操作的元素时事件才会被触发; - **
.passive
**:事件的默认行为立即执行,告诉事件先做你的事情,无需等待事件回调执行完毕
修饰符可以连着写,比如@click.stop.prevent
索奇问答
A:什么是事件冒泡?
Q:事件冒泡是指当在DOM中触发一个事件时,事件会从触发的元素开始,然后逐级向上(向外)传播到DOM树的更高层次的元素,直到达到根节点为止这个过程就像气泡一样从水底冒到水面,所以称为“冒泡”
看下面的代码
<div class="demo1" @click="showInfo"> <button @click="showInfo">看我小索奇冒泡</button> </div>
new Vue({ el: '.demo1', methods: { showInfo: function() { console.log('看我小索奇冒泡'); } } });
当你点击按钮时,以下事情会发生:
- 首先,按钮的点击事件会触发,因为按钮也绑定了
@click
事件这时会执行按钮自己的showInfo
方法,控制台会打印出 "看我小索奇冒泡" - 事件会冒泡到外部的
div
元素,也会执行div
绑定的showInfo
方法,再次打印出 "看我小索奇冒泡"
弹窗两次
事件冒泡
点击按钮会依次触发按钮自己的点击事件处理程序和外部 div
元素的点击事件处理程序,这就是事件冒泡的过程
如果你想要阻止事件冒泡,就需要用到上面提到的修饰符,如 @click.stop
修饰符 stop
会阻止事件继续向上层元素传播,这样只会触发按钮自己的点击事件处理程序,不会再触发外部 div
元素的点击事件处理程序
什么是capture
?
简记重点:捕获是从外到里,冒泡是从里到外
当加上capture
时,即使点击box2
,box1
在捕获阶段就开始处理了,即使点击2
事件,先触发的也是1
事件
<div class="box1" @click.capture="showMsg(1)"> div1 <div class="box2" @click="showMsg(2)"> div2 </div> </div>
什么是self
?
// 上面的@click.self只是管div的,只有target是div时候才会调用它的方法 <div class="container" @click.self="handleContainerClick"> <button @click="handleButtonClick">点我提示信息</button> </div>
methods: { handleContainerClick(event) { console.log("Container被点击,触发了handleContainerClick方法"); console.log("事件目标 (target):", event.target); }, handleButtonClick() { console.log("按钮被点击,触发了handleButtonClick方法"); } }
- 由于我们在外部的
container
元素上使用了.self
修饰符,只有点击container
元素自身时,才会触发handleContainerClick
方法如果点击按钮,事件目标是按钮,所以不会触发container
上的点击事件处理程序 - 无论点击
container
元素的哪个部分,都只有在点击container
自身时才会触发点击事件处理程序点击按钮,事件会从按钮冒泡到container
,但由于我们使用了.self
修饰符,它不会触发container
上的点击事件处理程序
可能有点绕吧...仔细理解一下~
详解passive
- 在给移动端使用的时候用的会偏多一些
passive
是一个用于优化浏览器滚动性能的事件修饰符在Web开发中,滚动事件(例如滚动页面或元素)可能会触发一些复杂的处理,这可能导致页面性能下降,因为浏览器需要等待事件处理程序完成才能继续执行默认滚动行为
通过使用 passive
修饰符,可以告诉浏览器事件监听器,使浏览器在执行事件处理程序时更加高效,不必等待事件处理完成这对于优化滚动性能非常有帮助~
看下面代码演示
<style> #scroll-container { height: 400px; overflow: auto; } ul li { border-left: 50px; height: 400px; width: 400px; background-color: aquamarine; } </style> </head> <body> <div id="app"> <!-- 使用 passive 优化滚动性能 --> <div id="scroll-container" @scroll.passive="handleScroll('优化')"> <ul> <li>1</li> <li>2</li> <li>3</li> <li>4</li> </ul> </div> </div> <script type="text/JS"> new Vue({ el: '#app', methods: { handleScroll(type) { console.log(`${type}滚动事件处理`); } } }); </script> </body>
滚动时,不用等待事件处理完成才能够执行操作
键盘事件
键盘上的每个按键都有自己的名称和编码,例如:回车键是13
Vue还对一些常用按键起了别名方便使用
Vue中常用的按键别名有下面一些(注意:别名是小写的,大些也可以,但是为了方便大多数写小写)
记住一下常见的即可
- 回车
enter
- 删除
delete
(退格和删除键都能够捕获) - 退出
esc
- 空格
space
- 换行
tab
特殊 - 上下左右分别对应
up
、down
、left
、right
Q:不用别名如何使用?
A:需要配合键值达到效果
<body> <div id="root"> <h2>{{name}}</h2> <input type="text" placeholder="按下回车提示输入" @keyup = "showInfo"> </div> <script type="text/JS"> Vue.config.productionTip = false new Vue({ el:'#root', data:{ name:"即兴小索奇" }, methods:{ showInfo(e){ // console.log(e.target.value) //输入什么出什么value if(e.keyCode !=13){ console.log(e.target.value) // 当点击回车的时候再显示对应的value } console.log(e.keyCode) } } }) </script> </body>
上面配合别名只需要在@keyup
后面添加别名即可,比如上面的案例使用 @keyup.enter
即可,省去了非常多的麻烦
拓展
Vue未提供别名的按键,可以使用按键原始的key值去绑定,但注意要转为kebab-case(烤肉串格式)
如:给CapsLock绑定事件 = @keyup.caps-lock
tips:可以借助下面获取键名和键码
想要获取每一个键名和键码可以用event.key
,event.keyCode
console.log(e.key,e.keyCode)
image-20230818010846033
其中需要注意一些按键
- tap:因为它的作用就是跳出,所以需要配合
keyup.down
按下时候就触发的事件使用,否则没效果
特殊:系统修饰键(用法特殊)ctrl、alt、shift、meta(meta就是win菜单键)
都一样的道理,比如@keydown.ctrl
- 配合keyup使用:按下修饰键的同时,再按下其他键,随后释放其他键,事件才被触发
- 配合keydown:能够正常触发事件,不用搭配其他按键
自定义别名
// 定义一个name 它的keyCode是66 vue.config.keyCodes.name = 66
对您有用的话点个免费的赞叭~