事件及其修饰符
v-on
v-on:事件名="表达式"
简写@事件名="表达式"
: 完成事件绑定, 表达式
位置可以写常量、JS表达式、Vue实例所管理的data或method等配置项
- 在Vue当中事件所关联的回调函数必须在
Vue实例的methods中配置项
进行定义,Vue在解析模板语句时只会调用Vue实例管理的回调函数
Vue在调用回调函数的时候会根据情况传递当前发生的事件对象
- 如果表达式中的函数没有参数并且省略了小括号, Vue框架会自动给回调函数传递当前发生的事件对象
- 如果表达式中的函数有括号(无论是否有参数),Vue都不会给回调函数传递当前的事件对象,需要在参数上使用
$event占位符
告诉Vue我需要接收当前事件对象
html
<div id="app">
<h1>{{msg}}</h1>
<!--使用javascript原生代码如何完成事件绑定-->
<button onclick="alert('hello')">hello</button>
<!--以下是错误的,因为alert()和sayHello()都没有被Vue实例管理-->
<button v-on:click="alert('hello')">hello</button>
<button v-on:click="sayHello()">hello</button>
<!--绑定Vue实例method配置项中的回调函数完成事件绑定-->
<button @click="sayHi($event, 'jack')">hi button2</button>
<!--如果函数省略了小括号,Vue框架会自动给回调函数传递当前发生的事件对象-->
<button @click="sayWhat">what button</button>
<!--如果函数没有省略小括号,Vue框架不会给回调函数传递当前发生的事件对象-->
<button @click="sayWhat()">what button</button>
</div>
<!-- vue代码 -->
<script>
// 自定义的函数不会被调用
function sayHello(){
alert('hello')
}
const vm = new Vue({
el: '#app',
data: {
msg: 'Vue的事件绑定'
},
methods: { // 回调函数
// : function 可以省略
sayHi(event, name) {
console.log(name, event)
},
sayWhat(event) {
console.log(event)
//console.log(event.target)
//console.log(event.target.innerText)
}
}
})
</script>
事件回调函数中的this
事件回调函数中的this
就是Vue的实例对象vm
, 箭头函数中没有自己的this,它的this是从父级作用域当中继承过来的
html
<div id="app">
<h1>{{msg}}</h1>
<h1>计数器:{{counter}}</h1>
<button @click="counter++">点击我加1</button>
<button @click="add">点击我加1</button>
<button @click="add2">点击我加1(箭头函数)</button>
</div>
<!-- vue代码 -->
<script>
const vm = new Vue({
el : '#app',
data : {
msg : '关于事件回调函数中的this',
counter : 0
},
methods : {
add(){
// 事件函数中的this就是Vue的实例对象vm
this.counter++;
//vm.counter++;
},
add2:()=>{
// 对于当前程序来说this就是父级作用域(全局作用域)window
console.log(this)
},
sayHi(){
alert('hi...')
}
}
})
</script>
methods对象中的方法可以通过vm去访问(直接复制),但是并没有做数据代理
html
<script>
const vm = new Vue({
data : {
msg : 'hello vue!'
},
methods : {
sayHi(){
// 函数中的this就是Vue的实例对象vm
console.log(this.msg)
},
sayHello(){
alert('hello')
},
sayWhat : () => {
// 对于当前程序来说this就是父级作用域(全局作用域)window
console.log(this)
}
}
})
</script>
javascript
// 定义一个Vue类
class Vue {
// options是一个简单的纯粹的JS对象,有Vue实例对象的配置项
constructor(options) { // 定义构造函数
// 获取所有的属性名
// 获取所有的方法名
Object.keys(options.methods).forEach((methodName, index) => {
// 给当前的Vue实例扩展一个方法,相当于复制了一份
this[methodName] = options.methods[methodName]
})
}
}
事件修饰符
Vue当中提供了事件修饰符:在事件中可以不采用手动调用DOM的方式来完成事件相关的行为,保证回调函数中只负责写业务逻辑代码
passive和prevent修饰符
是对立的不可以共存 , 如果一起用就会报错- 添加事件监听器包括两种不同的方式: 一种是从内到外添加(事件冒泡模式), 一种是从外到内添加(事件捕获模式)
在Vue当中事件修饰符是可以多个联合使用的
,按照书写顺序的先后执行
修饰符 | 作用 |
---|---|
stop | 停止事件冒泡,等同于event.stopPropagation() |
prevent | 阻止事件的默认行为,等同于event.preventDefault() |
capture | 添加事件监听器时使用事件捕获模式(从外到内),先给谁添加谁先执行 |
self | 只有元素本身触发事件才会则执行对应的函数,别人冒泡/捕获传递过来的事件并不会调用事件函数 |
once | 事件只发生一次 |
passive(顺从/不抵抗) | 解除阻止, 无需等待事件函数的内部代码执行完, 优先执行事件的默认行为(如鼠标滚动,页面跳转) |
html
<!-- 容器 -->
<div id="app">
<h1>{{msg}}</h1>
<!--点击链接默认会跳转,使用事件修饰符阻止事件的默认行为-->
<a href="https://www.baidu.com" @click.prevent="yi">百度</a> <br><br>
<!--阻止事件冒泡的行为: 1-->
<div @click="san">
<div @click.stop="er">
<button @click="yi">事件冒泡</button>
</div>
</div>
<!--添加事件监听器时使用事件捕获模式: 3,2,1-->
<div @click.capture="san">
<div @click.capture="er">
<button @click.capture="yi">添加事件监听器的时候采用事件捕获模式</button>
</div>
</div>
<!--添加事件监听器时使用事件捕获模式: 3,1,2-->
<div @click.capture="san">
<!--这里没有添加capture修饰符,这个元素和其子元素默认采用冒泡模式-->
<div @click="er">
<button @click="yi">添加事件监听器的时候采用事件捕获模式</button>
</div>
</div>
<!--self修饰符只有"元素"本身发生触发的事件才会则执行对应的函数:1,3-->
<div @click="san">
<div @click.self="er">
<button @click="yi">self修饰符</button>
</div>
</div>
<!--事件修饰符是可以多个联合使用的@click.self.stop表示先self再stop-->
<div @click="san">
<div @click="er">
<button @click.self.stop="yi">self修饰符</button>
</div>
</div>
<!--once修饰符:事件只发生一次-->
<button @click.once="yi">事件只发生一次</button>
<!--鼠标滚动时的默认行为是滚动条滚动,优先执行事件的默认行为,不会等事件函数中的for循环执行完毕-->
<div class="divList" @wheel.passive="testPassive">
<div class="item">div1</div>
<div class="item">div2</div>
<div class="item">div3</div>
</div>
</div>
<!-- vue代码 -->
<script>
const vm = new Vue({
el : '#app',
data : {
msg : '事件修饰符'
},
methods : {
yi(event){
// 手动调用事件对象的preventDefault()方法,可以阻止事件的默认行为
//event.preventDefault();
alert(1)
},
er(){
alert(2)
},
san(){
alert(3)
},
testPassive(event){
for(let i = 0; i < 100000; i++){
console.log('test passive')
}
}
}
})
</script>
按键修饰符
获取某个键对应的按键修饰符
: 通过event.key
可以获取这个键以kebab-case
风格命名的名字,如PageDown(向下箭头键)-->page-down
- 4个比较特殊的系统修饰键
ctrl、alt、shift、meta(win键)
: ctrl键可以直接触发keydown事件,但不能直接触发keyup事件需要搭配一个组合键盘
自定义按键修饰符
: 通过Vue的全局配置对象config
来进行按键修饰符的自定义,Vue.config.keyCodes.按键修饰符的名字 = 按键的键值
按键 | 按键的修饰符 |
---|---|
Enter | enter |
Tab | tab(必须配合keydown事件使用) |
Delete | delete(捕获"删除"和"退格"键) |
ESC | esc |
空格 | space |
上箭头 | up |
下箭头 | down |
左箭头 | left |
右箭头 | right |
html
<div id="app">
<h1>{{msg}}</h1>
<!--当用户按下回车键并弹起时触发事件执行回调函数-->
回车键:<input type="text" @keyup.enter="getInfo"><br>
回车键(键值):<input type="text" @keyup.13="getInfo"><br>
delete键:<input type="text" @keyup.delete="getInfo"><br>
esc键:<input type="text" @keyup.esc="getInfo"><br>
space键:<input type="text" @keyup.space="getInfo"><br>
up键:<input type="text" @keyup.up="getInfo"><br>
down键:<input type="text" @keyup.down="getInfo"><br>
left键:<input type="text" @keyup.left="getInfo"><br>
right键:<input type="text" @keyup.right="getInfo"><br>
<!--tab键无法触发keyup事件,只能触发keydown事件-->
tab键(keydown): <input type="text" @keydown.tab="getInfo"><br>
PageDown键: <input type="text" @keyup.page-down="getInfo"><br>
huiche键: <input type="text" @keyup.huiche="getInfo"><br>
ctrl键(keydown): <input type="text" @keydown.ctrl="getInfo"><br>
<!--ctrl键加上任意一个组合键可触发事件-->
ctrl键(keyup): <input type="text" @keyup.ctrl="getInfo"><br>
<!--ctrl键加上i键可触发事件-->
ctrl键(keyup): <input type="text" @keyup.ctrl.i="getInfo"><br>
</div>
<script>
// 自定义一个按键修饰符叫huiche
Vue.config.keyCodes.huiche = 13
const vm = new Vue({
el : '#app',
data : {
msg : '按键修饰符'
},
methods : {
getInfo(event){
// 当用户键入回车键的时候,获取用户输入的信息
//if(event.keyCode === 13){}
// 使用了按键修饰符后就不用再判断键值了
console.log(event.target.value)
// 获取按键修饰符的名字
console.log(event.key)
}
}
})
</script>