[TOC] >[success] # v-on 绑定事件 ~~~ 1.可以用'v-on'指令监听 DOM 事件 2.'v-on'中要处理的逻辑比较复杂,因此不支持直接在'v-on'中直接写js代码,但支持 方法,内联处理,和对象的形式(2.4.0+ 支持) 2.1.着重说明不支持在'v-on'中写js代码指的是: <button v-on:click="alert('a')">v-on按钮</button> 如果这么写必须是在vue实例对象的method中有定义alter方法才行,否则不支 持js的alert使用。 3.'v-on' 的缩写是@符号 ~~~ >[info] ## v-on -- 方法处理器和内联处理器 ~~~ 1.两者区别写法上,带不带括号 2.两者区别参数上,方法处理由于没有括号不支持传参但只带event,内联由于带 括号支持传参,但必须$evnet 当参数传入才有evet事件。 ~~~ >[danger] ##### 方法处理器 ~~~ 1.使用的时候不带括号就是方法处理案例:<button v-on:click="doThis"></button> 2.下面案例是根据官方我自己延伸案例,很巧妙的配内联函数法处理,实现的效果当点button时候触发了evet事件,进入if判断中,然后执,在这就可以更加明确的 看出内联和方法的区别,自带evet事件和传参区别行,完毕后接着执行下个alert 弹出框。 ~~~ ~~~ <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <!--导入Vue cdn 的网址--> <script src="https://cdn.jsdelivr.net/npm/vue@2.5.22/dist/vue.js"></script> </head> <body> <div id="app" > <button v-on:click="doThis">v-on按钮</button> </div> <script> var vm = new Vue({ el:"#app", methods:{ // es6 语法 doThis(){ if (event) { alert(event.target.tagName) } alert('我是方法处理器') } }, }) </script> </body> </html> ~~~ >[danger] ##### 内联处理器 ~~~ 1.使用的时候带括号:'<button v-on:click="doThat('hello', $event)"></button>' 2.带括号的好处是可以传参,但不自带evet 事件,想使用event事件需要$event 参数传入 ~~~ ~~~ <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <!--导入Vue cdn 的网址--> <script src="https://cdn.jsdelivr.net/npm/vue@2.5.22/dist/vue.js"></script> </head> <body> <div id="app" > <button v-on:click="doThat('hello', $event)">v-on按钮</button> </div> <script> var vm = new Vue({ el:"#app", methods:{ // es6 语法 doThat(parameter, event){ let msg = parameter + "内联方法"; if (event) { alert(event.target.tagName) } alert(msg); } }, }) </script> </body> </html> ~~~ >[danger] ##### 参考文章 [在Vue.js中什么是内联处理器?](https://segmentfault.com/q/1010000013088053) >[info] ## v-on -- 对象处理(2.4+) ~~~ 1.根据官方api介绍,在2.4.0+版本已经开始提供可以传入对象的写法,这种写法 的好处是什么,参考下面同一个功能实现,在这之前的写法和现在的写法。 2.之前写法: <p @mouseover ="doTish" @mouseout ="doThat">对象形式</p> 3.现在写法: <p v-on="{ mouseover: doTish, mouseout: doThat }">对象形式</p> ~~~ >[danger] ##### 案例 ~~~ <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <!--导入Vue cdn 的网址--> <script src="https://cdn.jsdelivr.net/npm/vue@2.5.22/dist/vue.js"></script> </head> <body> <div id="app" > <p v-on="{ mouseover: doTish, mouseout: doThat }">对象形式</p> </div> <script> var vm = new Vue({ el:"#app", methods:{ doTish(){ event.target.style.color = "red"; }, doThat(){ event.target.style.color = "#0f0"; }, }, }) </script> </body> </html> ~~~ >[info] ## v-on:keyup -- 监听按键触发 ~~~ 1.有时候想根据键盘/鼠标上的按键触发指定的功能这时候需要keyup 2.配合keyup 有两种第一种直接使用按键别名,第二种使用定义按键序号位置 3.常见的按键别名: '.enter' '.tab' '.delete'(捕获“删除”和“退格”键) '.esc' '.space' '.up' '.down' '.left' '.right' 4.按键序号网址查询:'http://www.cnblogs.com/wuhua1/p/6686237.html' 5如果想全局配置且使用别名的方式建议这种全局书写配置: // 可以使用 `v-on:keyup.f1` Vue.config.keyCodes.f1 = 112 6.组件按键使用: <!-- Ctrl + Click --> <div @click.ctrl="doSomething">Do something</div> 7.规定组合按键顺序('exact'): <!-- 有且只有 Ctrl 被按下的时候才触发 --> <button @click.ctrl.exact="onCtrlClick">A</button> 8.当在事件不确定的时候 可以利用event这个属性去获取当前触发的事件进行判断触发逻辑 ~~~ >[danger] ##### 案例 ~~~ <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <!--导入Vue cdn 的网址--> <script src="https://cdn.jsdelivr.net/npm/vue@2.5.22/dist/vue.js"></script> </head> <body> <div id="app" > <!--鼠标点击+ctrl 才能触发--> <p @click.ctrl.exact ="doTish">对象形式</p> </div> <script> var vm = new Vue({ el:"#app", methods:{ doTish(){ event.target.style.color = "red"; }, }, }) </script> </body> </html> ~~~ >[info] ## 事件修饰符 ~~~ 1.事件修饰符可以解决到点击事件自身带的一些事件效果 '.stop' -- 阻止事件冒泡 '.prevent' -- 阻止默认事件 '.capture' -- 添加事件侦听器时使用事件捕获模式 '.self' --只当事件在该元素本身(比如不是子元素)触发时触发回调 '.once' --事件只触发一次 'native' -- 给组件绑定点击事件 'https://blog.csdn.net/cofecode/article/details/78890001' ~~~ >[danger] ##### 阻止事件冒泡 -- stop ~~~ 1.多个元素嵌套,有层次关系,这些元素都注册了相同的事件,如果里面的元素事件触 发了,外面的元素的该事件自动的触发了,注意相同事件(都是点击事件,中点击 叫做事件) 2.事件冒泡从里向外 3.阻止事件冒泡使用stop ~~~ ~~~ <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <!--导入Vue cdn 的网址--> <script src="https://cdn.jsdelivr.net/npm/vue@2.5.22/dist/vue.js"></script> <style> .inner{ width: 200px; height: 200px; background-color: darkseagreen; } </style> </head> <body> <div class="inner" id="app" @click="divClick"> <input type="button" value="点击" @click.stop="inputClick"> </div> <script> var vm = new Vue({ el:'#app', // data 负责输出理数据的 data:{ }, // methods 负责处理调用方法的 methods:{ divClick(){ console.log("最外层div") }, inputClick(){ console.log("最内层div") } } }) </script> </body> </html> ~~~ * 点击按钮效果: ~~~ 最内层div ~~~ ![](https://box.kancloud.cn/6a4b2a9f665f47bc20b1ab36d5e657d3_216x219.png) >[danger] ##### 实现捕获触发事件的机制 -- capture ~~~ 1.冒泡是从向外依次触发,使用capture,就变成了从先显示外面,在显示里面 ~~~ ~~~ <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <!--导入Vue cdn 的网址--> <script src="https://cdn.jsdelivr.net/npm/vue@2.5.22/dist/vue.js"></script> <style> .inner{ width: 200px; height: 200px; background-color: darkseagreen; } </style> </head> <body> <div class="inner" id="app" @click.capture="divClick"> <input type="button" value="点击" @click="inputClick"> </div> <script> var vm = new Vue({ el:'#app', // data 负责输出理数据的 data:{}, // methods 负责处理调用方法的 methods:{ divClick(){ console.log("最外层div") }, inputClick(){ console.log("最内层div") } } }) </script> </body> </html> ~~~ * 打印结果 ~~~ 最外层div 最内层div ~~~ >[danger] ##### 只会阻止自己身上冒泡行为 -- self ~~~ 1.只会阻止自己身上冒泡行为 ,当有多层嵌套的时候,只会阻止有self 冒泡行为 ~~~ ~~~ <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <!--导入Vue cdn 的网址--> <script src="https://cdn.jsdelivr.net/npm/vue@2.5.22/dist/vue.js"></script> <style> .inner{ width: 200px; height: 200px; background-color: darkseagreen; } </style> </head> <body> <div id="app"> <div class="outer" @click="div2Handler"> <div class="inner" @click.self="div1Handler"> <input type="button" value="戳他" @click="btnHandler"> </div> </div> </div> <script> // 创建 Vue 实例,得到 ViewModel var vm = new Vue({ el: '#app', data: {}, methods: { div1Handler() { console.log('这是触发了 inner div 的点击事件') }, btnHandler() { console.log('这是触发了 btn 按钮 的点击事件') }, div2Handler() { console.log('这是触发了 outer div 的点击事件') } } }); </script> </body> </html> ~~~ * 打印结果 ~~~ 这是触发了 btn 按钮 的点击事件 这是触发了 outer div 的点击事件 ~~~ >[danger] ##### 阻止默认事件 -- prevent ~~~ 1.例如a标签默认事件就是点击跳转页面,为了阻止a标签的默认事件触发我 们绑定的事件,可以使用prevent 2.图片的默认事件禁止拖拽,如果想给图片设置拖拽效果的话记得做阻止默 认行为 ~~~ ~~~<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <!--导入Vue cdn 的网址--> <script src="https://cdn.jsdelivr.net/npm/vue@2.5.22/dist/vue.js"></script> </head> <body> <div id="app"> <a href="www.baidu.com" @click.prevent.once="linkClick">百度</a> </div> <script> var vm = new Vue({ el:'#app', // data 负责输出理数据的 data:{}, // methods 负责处理调用方法的 methods:{ linkClick:function () { alert(1) } } }) </script> </body> </html> ~~~ * 运行的效果 ~~~ 1.a标签不会页面跳转,反而点击后会弹出弹窗显示1 ~~~ >[danger] ##### 只触发一次默认行为 ~~~ 1.只触一次规定的默认行为 2.下面的案例第二次点击就会跳转页面 ~~~ ~~~ <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <!--导入Vue cdn 的网址--> <script src="https://cdn.jsdelivr.net/npm/vue@2.5.22/dist/vue.js"></script> </head> <body> <div id="app"> <a href="www.baidu.com" @click.prevent.once="linkClick">百度</a> </div> <script> var vm = new Vue({ el:'#app', // data 负责输出理数据的 data:{}, // methods 负责处理调用方法的 methods:{ linkClick:function () { alert(1) } } }) </script> </body> </html> ~~~ >[info] ## 新增 >[danger] ##### 动态绑定key ~~~ 1.注意事项和动态的v-bind一致 ~~~ ~~~ <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <!--导入Vue cdn 的网址--> <script src="https://cdn.jsdelivr.net/npm/vue@2.6.11/dist/vue.js"></script> </head> <body> <div id="app"> <!-- 动态绑定事件 --> <p @[event]="doThis">对象形式</p> </div> <script> // 想自己配置一个按键别名 Vue.config.keyCodes.f1 = 112 const vm = new Vue({ el: '#app', data: { event: 'click' }, methods: { doThis() { console.log('我是动态的') }, }, }) </script> </body> </html> ~~~ >[info] ## 多事件处理 ~~~html <!-- 这两个 one() 和 two() 将执行按钮点击事件 --> <button @click="one($event), two($event)"> Submit </button> ~~~ * js部分 ~~~js // ... methods: { one(event) { // 第一个事件处理器逻辑... }, two(event) { // 第二个事件处理器逻辑... } } ~~~