1.理解Vue事件的绑定方式
1.1 原生行内事件绑定
说明:
-
vue
采用行内事件绑定的方式. - 因此在学习
vue
事件绑定方式之前,先回顾一下JS的行内事件绑定 - 学习中对比
vue
的行内事件绑定和JS
原生行内事件绑定的不同
示例代码如下:
<style>
.box{
color:red;
}
.wrap{
color:skyblue;
}
</style>
<div id="app">
<h2 id="box" class="box">Hello World</h2>
<button onclick="changeColor()">点击切换颜色</button>
</div>
<script>
let className = "box"
function changeColor(){
if(className =='box'){
box.className = className = "wrap"
}else{
box.className = className = "box"
}
}
</script>
注意:
-
这种原生绑定事件方式不常用,因为耦合性太高
-
onclick属性值是函数执行字符串,在点击触发后会把这个字符串强制转为
js
语句执行
vue
采用这种方式绑定事件,
原因在于这种绑定方式比较直观的处理事件的绑定, 省去了大量获取DOM的操作.
不用担心Vue的问题, Vue在采用行内事件绑定,内部肯定做了大量的优化处理
2.v-on(@) 事件的绑定与基本使用
为了让用户和你的应用进行交互,我们可以用 v-on
指令添加一个事件监听器,通过事件监听器触发事件执行程序
2.1 v-on
指令的认识和使用
v-on
指令说明
-
v-on
指令和其他指令一样,通过v-on
绑定事件后,事件属性值将不再是字符串,而是表达式 - 因此接班是表达式就可以在引号中做一些基本的操作
<div id="app">
<h2 class="box">点击次数: {{ count }}</h2>
<!-- 既然click 的值是表达式,那么我们就可以动态的拿到vue ,data属性中的数据,然后操作-->
<button v-on:click="count++">暴击</button>
</div>
<script>
const vm = new Vue({
el: "#app",
data: {
count: 0
}
})
</script>
示例说明:
- 通过
v-on
指令绑定click
单机事件 -
v-on
指定绑定事件的属性值是表达式,表达式中可以直接获取vue
中的数据 - 因此可以是表达式中直接对数据进行修改
通过上面的说明就能理解,每次点击都会修改数据,数据的修改触发vue
响应系统,进而改变页面显示
之中直接修改数据一般情况下用的比较少,原因在于:
- 通过
v-on
绑定的事件属性值虽然是表达式,但是只能处理单个表达式逻辑 - 如果处理复杂的程序就会有局限性
- 同时没发在引号中使用事件对象,来处理事件的细节
因此,通常会选择在表达式中绑定vue
的方法,将方法作为事件函数处理
2.2 v-on
指定绑定methods
方法
调用在 Vue 实例中定义的方法
说明:
- 在选项对象属性
methods
中定义vue
示例的方法 - 通过方法名将
vue
办法绑定给事件,作为事件处理函数使用
示例1:修改上一个示例,限制点击次数
<!-- 限定点击次数 -->
<div id="app">
<h2 class="box">点击次数: {{ count }}</h2>
<button v-on:click="handleClick">点击</button>
</div>
<script>
const vm = new Vue({
el: "#app",
data: {
count: 0
},
methods: {
handleClick(){
let count = this.count;
// 限定显示最大点击次数
this.count = Math.min(++count,5)
}
}
})
</script>
示例2: 翻转消息
<!-- HTML --->
<div id="app-5">
<p>{{ message }}</p>
<button v-on:click="reverseMessage">逆转消息</button>
</div>
<!-- JS --->
<script>
new Vue({
el: "#app-5",
data: {
message: 'Hello Vue.js'
},
methods: {
reverseMessage: function(){
this.message = this.message.split('').reverse().join('')
}
}
})
</script>
示例说明:
- 通过示例,当按钮绑定button被点击时,就会触发
methods
属性中的的方法, - 在方法中修改数据, 当数据被修改时触发响应系统, 响应系统触发视图的重新渲染,
注意.
methods中方法,不能和data的数据重名,因为data中的数据和methods中的方法都会在Vue初始化时成为Vue示例的属性或方法
2.3 事件绑定的简写方式
<!-- 完整语法 -->
<button v-on:click="reverseMessage">逆转消息</button>
<!-- 缩写 -->
<button @click="reverseMessage">逆转消息</button>
3. 关于函数内的this指向问题
3.1 普通函数this
方法内this默认指向实例对象,就可以通过实例对象处理很多操作
<div id="app">
<!-- 绑定事件触发Vue方法 -->
<button @click="reversed">按钮</button>
</div>
<script>
let vm = new Vue({
el: "#app",
data: {
msg: "Hello Vue"
},
methods: {
reversed() {
console.log(this) // 实例对象
}
}
})
</script>
点击结果

3.2 箭头函数中this
如果改为箭头函数为如下写法:
{
reversed:() => {
console.log(this) // 实例对象
}
}
那么我们就将实例中的方法换成箭头函数
<div id="app">
<!-- 绑定事件触发Vue方法 -->
<button @click="reversed">按钮</button>
</div>
<script>
let vm = new Vue({
el: "#app",
data: {
msg: "Hello Vue"
},
methods: {
reversed:()=> {
console.log(this) // 实例对象
}
}
})
</script>
点击结果:

4. methods方法中不推荐使用箭头函数
其实在上一小节中了解方法的不同写法会导致this
的不同, 那么就来罗列一下不推荐使用箭头函数的原因
4.1 methods不推荐使用箭头函数
不推荐使用功能箭头函数说明:
1.vue
是以数据作为驱动的,数据的变化将会触发vue响应系统,同时更改页面的渲染结果,
-
vue
以数据为驱动,也就是说我们在未来的操作中将大量操作数据, - 数据被处理为
Vue
实例vm
上的属性,那么我们就需要大量的通过vm
对象来调用数据 - 甚至
methods
的中的方法也会挂在在vm
对象上的, - 因此箭头函数会影响我们对于数据和方法的获取,因为箭头函数
this
是window
也正式因为这些原因,我们不推荐方法使用箭头函数,因为这样会丢失this指向, 那么我们就不能利用this 来获取数据和其他方法了.
看下面的例子
<div id="app">
<button @click="handleClick">非箭头函数中this</button>
<button @click="handleClickTwo">箭头函数中的this</button>
</div>
<script>
const vm = new Vue({
el: "#app",
data: {
msg: "hello"
},
methods: {
handleClick(){
console.log(this) // vue实例化对象
},
handleClickTwo: () => {
console.log(this) // window 对象
},
}
})
</script>
这样我们就会发现如果我们使用普通函数, 那么要获取数据就很简单
handleClick(){
console.log(this) // vue实例化对象
// 利用this 获取数据
console.log(this.msg) // 获取数据
},
总结:
methods属性中方法函数中如果不需要操作Vue实例上的属性和方法, 可以使用箭头函数,
但是一般不推荐使用箭头函数, 原因
- 一是因为我们随时可能需要在方法中获取Vue实例的其他数据或其他方法,
- 二是统一的编码风格,总不至于有的用箭头函数,有的不用吧,
4.2 关于Vue方法里使用箭头函数误区
但是我们需要避免一个误区:
我们推荐不使用箭头函数是methods的方法, 不是说真个Vue项目里都不能使用箭头函数,
比如我们如果在方法里还有函数,在函数中需要使用vue实例化对象我们这个时候用箭头函数会比非箭头函数要
例如
<div id="app">
<button @click="handleClick">查看this</button>
</div>
<script>
const vm = new Vue({
el: "#app",
data: {
msg: "hello"
},
methods: {
handleClick(){
console.log(this) // vue实例化对象
// 延迟修改数据
// 1.方法内使用普通函数,查看普通函数中this
setTimeout(function(){
console.log(this) // window 对象
// 这个是有要修改数据,还的使用vm
vm.msg = "wrod"
}, 1000)
// 2.方法内使用箭头函数, 查看函数内this
setTimeout(() => {
console.log(this) // vue实例对象
// 这个是有修改数据,依然可以使用this
this.msg = "wuwei"
}, 2000)
},
}
})
</script>
通过示例就能看出,用不用箭头函数,完全看自己的需求, 而不是说不推荐使用箭头函数,就整个Vue项目中一个箭头函数都不用了,
要关注一下是哪里不推荐使用箭头函数.
因此:
Vue中是不是用箭头函数,完全看你自身的情况,千万不要听人说Vue不推荐使用箭头函数,就整个Vue项目中一个箭头函数都不用, 用不用,看this
5. 关于方法的事件对象
在调用方法的时候有两种情况,一种是不加括号,一种加括号
<!--不加括号 -->
<button @click="reversed">点击</button>
<!--加括号 -->
<button @click="reversed()">点击</button>
<button @click="reversed(12345)">点击</button>
那么很明显使用加括号的方式是为了传递参数给事件函数,
那么我们就来看看不同的事件绑定方式对于事件对象的影响
5.1 不加括号
不加括号的情况下,默认第一个形参就是事件对象
<div id="app">
<!-- 不加括号绑定事件 -->
<button @click="reversed">点击</button>
</div>
<script>
let vm = new Vue({
el: "#app",
data: {
msg: "Hello Vue"
},
methods: {
reversed:(ev)=> {
console.log(ev) // 事件对象
}
}
})
</script>
页面点击结果:

5.2 加括号
如果加括号无论你传不传实参,形参默认就是要接受你传递的实参
<div id="app">
<!-- 加括号未传参 -->
<button @click="reversed()">点击</button>
<!-- 加括号传参 -->
<button @click="reversed(123)">点击2</button>
</div>
<script>
let vm = new Vue({
el: "#app",
data: {
msg: "Hello Vue"
},
methods: {
reversed:(ev)=> {
console.log(ev) // 事件对象
}
}
})
</script>
点击后的结果

事件绑定加括号说明
-
通过示例发现,加括号没有传参是,事件函数的第一个形参是
undefined
因为没有接受到实参 -
如果加括号绑定事件, 事件执行传递了实参,那么事件函数的第一个形参就是传递过来的实参
那么问题来了,如果我需要传参时如何获取事件对象呢
5.3 绑定事件手动传递事件对象
如果加括号就需要手动的传递事件对象
<div id="app">
<!-- 手动传递事件对象,此时$event就是事件对象 -->
<button @click="reversed($event,123)">点击</button>
</div>
<script>
const vm = new Vue({
el:"#app",
data:{
msg:"Hello Vue"
},
methods: {
reversed(ev,num){
console.log(ev) // 事件对象
console.log(num) // 123
}
}
})
</script>
点击结果

5.4 默认事件对象的变量
同时还发现: 无论加不加括号,传不传参数,在函数里变量event
默认是事件对象, 所以不要定义同名变量将其覆盖就可以了
<div id="app">
<!-- 手动传递事件对象,此时$event就是事件对象 -->
<button @click="reversed($event,123)">点击</button>
</div>
<script>
const vm = new Vue({
el:"#app",
data:{
msg:"Hello Vue"
},
methods: {
reversed(ev,num){
console.log(event);
}
}
})
</script>
点击显示结果

总结:
- 方法写在methods属性中
- 事件函数不需要传参不加括号, 需要传参加括号
- 事件函数无括号,默认第一个参数是事件对象
- 事件函数有括号,需要手动传递事件对象
- 无论事件函数有无括号,event变量都是事件对象,前提不能有同名变量覆盖
网友评论