2.1.1 事件处理的核心语法
2.1.1.1、事件处理知识点
1.指令的语法格式:
<标签 v-指令名:参数名="表达式">{{插值语法}}</标签>
“表达式”位置都可以写什么?
常量、JS表达式、Vue实例所管理的XXX
2. 在Vue当中完成事件绑定需要哪个指令呢?
v-on指令。
语法格式:
v-on:事件名="表达式"
例如:
v-on:click="表达式" 表示当发生鼠标单击事件之后,执行表达式。
v-on:keydown="表达式" 表示当发生键盘按下事件之后,执行表达式。
3. 配置项methods
在Vue当中,所有事件所关联的回调函数,需要在Vue实例的配置项methods中进行定义。
methods是一个对象:{}
在这个methods对象中可以定义多个回调函数。
4. v-on指令也有简写形式
v-on:click 简写为 @click
v-on:keydown 简写为 @keydown
v-on:mouseover 简写为 @mouseover
....
5. 绑定的回调函数,如果函数调用时不需要传递任何参数,小括号()可以省略。默认传递事件对象event
6. Vue在调用回调函数的时候,会自动给回调函数传递一个对象,这个对象是:当前发生的事件对象。
7. 在绑定回调函数的时候,可以在回调函数的参数上使用 $event 占位符,
Vue框架看到这个 $event 占位符之后,会自动将当前事件以对象的形式传过去。
<body>
<!-- 容器 -->
<div id="app">
<h1>{{msg}}</h1>
<!--需求一: 使用javascript原生代码实现,点击弹出‘hello提示’。 -->
<button onclick="alert('hello')">按钮1</button>
<!--需求二: 使用Vue来完成事件绑定 -->
<!-- 1、注意:alert()并没有被Vue实例管理,无法直接调用-->
<!-- <button v-on:click="alert('hello')">按钮2</button> -->
<!-- 2、注意:全局定义的sayHello()也不会被Vue实例管理。 -->
<!-- <button v-on:click="sayHello()">按钮3</button> -->
<!-- 3、正确的写法,配合methods配置项 -->
<button v-on:click="sayHello()">按钮4</button>
<!-- 4、v-on指令的简写形式 -->
<button @click="sayHi()">按钮5</button>
<!-- 5、v-on指令的传参 sayHi($event, 'jack') -->
<button @click="sayHi($event, 'jack')">按钮6</button>
<!-- 6、 绑定的回调函数,如果不需要传任何参数,小括号() 可以省略 -->
<button @click="sayWhat">按钮7</button>
</div>
<!-- vue代码 -->
<script>
// 自定义一个函数
// function sayHello(){
// alert('hello')
// }
const vm = new Vue({
el: "#app",
data: {
num: 1,
},
methods: {
//函数的完整写法
// sayHello:function {
// alert("hello");
// },
// 回调函数
sayHello() {
alert("hello");
},
sayHi(event, name) {
console.log(name, event);
//alert("hi " + name)
},
sayWhat(event) {
// console.log(event)
// console.log(event.target)
// console.log(event.target.innerText)
// alert('hello')
},
},
});
</script>
</body>
2.1.1.2、事件回调函数中的this
(1) 常规写法下:回调函数中的this是vm。
箭头函数写法下:回调函数中的this是window
箭头函数没有自己的this,它的this是继承过来的,默认这个this是箭头函数所在的宿主对象。这个宿主对象其实就是它的父级作用域。而对象又不能构成单独的作用域,所以这个父级作用域是全局作用域,也就是window。
(2) 可以在函数中改变data中的数据,例如:this.num++,这样会联动页面上产生动态效果。
<body>
<!-- 容器 -->
<div id="app">
<h1>{{msg}}</h1>
<h1>计数器:{{num}}</h1>
//在模版中,可以拿到num,对num++,数据改变了,就会改变页面
<button @click="num++">点击我加1</button>
// 方法的实现
<button @click="add">点击我加2</button>
<button @click="add2">点击我加3(箭头函数)</button>
</div>
<!-- vue代码 -->
<script>
const vm = new Vue({
el: "#app",
data: {
msg: "关于事件回调函数中的this",
num: 0,
},
methods: {
add() {
//num+=2; // 错误的。
// 在这里需要操作num变量?怎么办?
//console.log(vm === this)
// console.log(this)
// this.num+=2;
// vm.num+=3;
},
add2: () => {
//this.num+=3;
//console.log(this === vm)
//箭头函数中没有this,箭头函数中的this是从父级作用域当中继承过来的。
//对于当前程序来说,父级作用域是全局作用域:window
console.log(this);
},
//控制台通过vm直接调用
sayhello() {
alert("hello");
},
},
});
</script>
</body>
(3) 回调函数并没有在vm对象上,为什么通过vm可以直接调用函数呢?尝试手写Vue框架。
// 定义一个Vue类
class MyVue {
// 定义构造函数
// options 是一个对象{}
constructor(options) {
// 源码实现methods 目的希望vm可以直接调用方法
Object.keys(options.methods).forEach((methodName, index) => {
// 给当前的vue实例拓展一个方法
this[methodName]=options.methods[methodName]
});
}
}
<head>
<meta charset="UTF-8" />
<title>methods实现原理</title>
<!-- 引入我们自己的vue.js -->
<script src="../js/myvue.js"></script>
</head>
<body>
<!-- vue程序 -->
<script>
const vm = new MyVue({
data: {
msg: "hello vue!",
},
methods: {
sayHi() {
//console.log(this === vm)
// console.log(this.msg);
console.log("hi");
},
sayHello: () => {
//console.log(this === vm)
console.log("hello");
},
},
});
</script>
</body>
2.1.2 事件修饰符
方法只有纯粹的数据逻辑,而不是去处理 DOM 事件细节。为了解决这个问题,Vue.js 为 v-on
提供了事件修饰符。之前提过,修饰符是由点开头的指令后缀来表示的。
- .prevent : 等同于 event.preventDefault() 阻止事件的默认行为。
- .stop : 停止事件冒泡,等同于 event.stopPropagation()。
- .capture :添加事件监听器时使用事件捕获模式
添加事件监听器包括两种不同的方式:
一种是从内到外添加。(事件冒泡模式)
一种是从外到内添加。(事件捕获模式) - .self :这个事件如果是“我自己元素”上发生的事件,这个事件不是别人给我传递过来的事件,则执行对应的程序。
- .once : 事件只发生一次
- .passive :passive翻译为顺从/不抵抗。无需等待,直接继续(立即)执行事件的默认行为。
.prevent:阻止事件的默认行为,.passive:解除阻止,这两种修饰符是对立的。不可以共存。(如果一起用,就会报错。)
<head>
<meta charset="UTF-8" />
<title>事件修饰符</title>
<!-- 安装Vue -->
<script src="../js/vue.js"></script>
<style>
div:not(#app) {
background-color: pink;
padding: 10px;
margin: 5px;
}
.divList {
width: 300px;
height: 200px;
background-color: aquamarine;
overflow: auto;
}
.item {
width: 300px;
height: 200px;
}
</style>
</head>
<body>
<!-- 容器 -->
<div id="app">
<h1>{{msg}}</h1>
<!--1、 阻止事件的默认行为 .prevent -->
<a href="https://www.baidu.com" @click.prevent="fun">百度</a>
<hr />
<!--2、 停止事件冒泡 .stop-->
<div @click="san">
<div @click="er">
<button @click="fun">事件冒泡</button>
</div>
</div>
<hr />
<!--3、 添加事件监听器时使用事件捕获模式 .capture -->
<!-- 默认采用冒泡模式。 -->
<div @click="san">
<div @click="er">
<button @click="fun">添加事件监听器的时候采用事件捕获模式</button>
</div>
</div>
<hr />
<!--4、 .self修饰符 只有点击到自己的时候会运行-->
<div @click="san">
<div @click="er">
<button @click="fun">self修饰符</button>
</div>
</div>
<hr />
<!-- 在Vue当中,事件修饰符是可以多个联合使用的。
但是需要注意:
@click.self.stop:先.self,再.stop
@click.stop.self:先.stop,再.self
-->
<div @click="san">
<div @click.self.stop="er">
<button @click="fun">.self+.stop</button>
</div>
</div>
<hr />
<!-- 5、.once修饰符:事件只发生一次 -->
<button @click.once="fun">事件只发生一次</button>
<!-- 6、.passive修饰符 -->
<div class="divList" @wheel.passive="testPassive">
<div class="item">div1</div>
<div class="item">div2</div>
<div class="item">div3</div>
</div>
<!-- vue代码 -->
</div>
<script>
const vm = new Vue({
el: "#app",
data: {
msg: "事件修饰符",
},
methods: {
fun(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");
}
// 阻止事件的默认行为
//event.preventDefault()
},
},
});
</script>
</body>
9个比较常用的按键修饰符:
.enter
.tab (必须配合keydown事件使用。)
.delete (捕获“删除”和“退格”键)
.esc
.space
.up
.down
.left
.right
回车键:<input type="text" @keyup.enter="getInfo" />
<hr />
//数字不具有通用性,不同的键盘排序不一,数字可能会变
回车键(键值):<input type="text" @keyup.13="getInfo" />
<hr />
delete键:<input type="text" @keyup.delete="getInfo" />
<hr />
esc键:<input type="text" @keyup.esc="getInfo" />
<hr />
space键:<input type="text" @keyup.space="getInfo" />
<hr />
up键:<input type="text" @keyup.up="getInfo" />
<hr />
down键:<input type="text" @keyup.down="getInfo" />
<hr />
left键:<input type="text" @keyup.left="getInfo" />
<hr />
right键:<input type="text" @keyup.right="getInfo" />
<hr />
2、怎么获取某个键的按键修饰符?
第一步:通过event.key获取这个键的真实名字。
第二步:将这个真实名字以kebab-case风格进行命名。PageDown是真实名字。经过命名之后:page-down
<!-- 其他按键修饰符 mac的pagedown是fn+向下箭头 -->
PageDown键: <input type="text" @keyup.page-down="getInfo" />
<hr />
3、按键修饰符是可以自定义的?
第一步:获取按键的键值 :event.keyCode
第二步:通过Vue的全局配置对象config来进行按键修饰符的自定义。
语法规则:Vue.config.keyCodes.按键修饰符的名字 = 键值
<!-- 3、自定义按键修饰符 -->
huiche键: <input type="text" @keyup.huiche="getInfo" />
<hr />
4、系统修饰键:4个比较特殊的键
ctrl、alt、shift、meta
对于keydown事件来说:只要按下ctrl键,keydown事件就会触发。
对于keyup事件来说:需要按下ctrl键,并且加上按下组合键,然后松开组合键之后,keyup事件才能触发。
<!-- 4、系统修饰键: ctrl、alt、shift、meta -->
ctrl键(keydown): <input type="text" @keydown.ctrl="getInfo" />
<hr />
<!-- ctrl+其他键 -->
ctrl键(keyup): <input type="text" @keyup.ctrl="getInfo" />
<hr />
<!-- ctrl+i键时才能触发 -->
ctrl键(keyup): <input type="text" @keyup.ctrl.i="getInfo" />
<hr />
标签:事件处理,Vue,console,log,vm,事件,event,2.4
From: https://blog.csdn.net/weixin_59152833/article/details/144421934