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变量都是事件对象,前提不能有同名变量覆盖
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。