2.4 事件绑定与监听
当模板渲染完成之后,就可以进行事件的绑定与监听了。Vue.js提供了v-on指令用来监听DOM事件,通常在模板内直接使用,而不像传统方式在js中获取DOM元素,然后绑定事件。例如:
<button v-on:click="say">Say</button>
2.4.1 方法及内联语句处理器
通过v-on可以绑定实例选项属性methods中的方法作为事件的处理器,v-on:后参数接受所有的原生事件名称。例如:
<button v-on:click="say">Say</button> var vm = new Vue({ el : '#app', data: { msg : 'Hello Vue.js' }, methods : { say : function() { alert(this.msg); } } });
单击button,即可触发say函数,弹出alert框’Hello Vue.js'。
Vue.js也提供了v-on的缩写形式,我们可以将模板中的内容改写为<button @click='say'>Say</button>,这两句语句是等价的。
除了直接绑定methods函数外,v-on也支持内联JavaScript语句,但仅限一个语句。例如:
<button v-on:click="sayFrom ('from param')">Say</button> var vm = new Vue({ el : '#app', data: { msg : 'Hello Vue.js' }, methods : { sayFrom: function(from) { alert(this.msg + '' + from); } } });
在直接绑定methods函数和内联JavaScript语句时,都有可能需要获取原生DOM事件对象,以下两种方式都可以获取:
<button v-on:click="showEvent">Event</button> <button v-on:click="showEvent($event)">showEvent</button> <button v-on:click="showEvent()">showEvent</button> // 这样写获取不到event var vm = new Vue({ el : '#app', methods : { showEvent : function(event) { console.log(event); } } }); 同一元素上也可以通过v-on绑定多个相同事件函数,执行顺序为顺序执行,例如: <div v-on:click="sayFrom('first')" v-on:click ="sayFrom('second)">
2.4.2 修饰符
Vue.js为指令v-on提供了多个修饰符,方便我们处理一些DOM事件的细节,并且修饰符可以串联使用。主要的修饰符如下。
.stop:等同于调用event. stopPropagation()。
.prevent:等同于调用event.preventDefault()。
.capture:使用capture模式添加事件监听器。
.self:只当事件是从监听元素本身触发时才触发回调。
使用方式如下:
<a v-on:click.stop='doThis'></a> <form v-on:submit.prevent="onSubmit"></form> // 阻止表单默认提交事件 <form v-on:submit.stop.prevent="onSubmit"></form> // 阻止默认提交事件且阻止冒泡 <form v-on:submit.stop.prevent></form> // 也可以只有修饰符,并不绑定事件
可以尝试运行以下这个例子,更好地理解修饰符在其中起到的作用。
var vm = new Vue({ el : '#app', methods : { saySelf(msg) { alert(msg); } } }); <div v-on:click="saySelf('click from inner')" v-on:click.self="saySelf('click from self')"> <button v-on:click="saySelf('button click')">button</button> <button v-on:click.stop="saySelf('just button click')">button</button> </div>
除了事件修饰符之外,v-on还提供了按键修饰符,方便我们监听键盘事件中的按键。例如:
<input v-on:keyup.13="submit"/> // 监听input的输入,当输入回车时触发Submit函 数(回车的keycode值为13),用于处理常见的用户输入完直接按回车键提交)
Vue.js给一些常用的按键名提供了别称,这样就省去了一些记keyCode的事件。全部按键别名为:enter、tab、delete、esc、space、up、down、left、right。例如:
<input v-on:keyup.enter="submit" />
Vue.js也允许我们自己定义按键别名,例如:
Vue.directive('on').keyCodes.f1 = 112; // 即可以使用<input v-on:keyup.f1="help" />
Vue.js 2.0中可以直接在Vue.config.keyCodes里添加自定义按键别名,无需修改v-on指令,例如:
Vue.config.keyCodes.f1 = 12。
2.4.3 与传统事件绑定的区别
如果你之前没有接触过Angularjs, ReactJS这类框架,或许会对Vue.js这种事件监听方式感到困惑。毕竟我们一开始接受的理念就是将HTML和JS隔离开编写。但其实Vue.js事件处理方法和表达式都严格绑定在当前视图的ViewModel上,所以并不会导致维护困难。
而这么写的好处在于:
① 无需手动管理事件。ViewModal被销毁时,所有的事件处理器都会自动被删除,让我们从获取DOM绑定事件然后在特定情况下再解绑这样的事情中解脱出来。
② 解耦。ViewModel代码是纯粹的逻辑代码,和DOM无关,有利于我们写自动化测试用例。
还有个与以往不同的细节是,我们在处理ul、li这种列表,尤其是下拉刷新这种需要异步加载数据的列表时,往往会把li事件代理到ul上,这样异步加载进来的新数据就不需要再次绑定事件。而Vue.js这类的框架由于不需要手动添加事件,往往直接会把事件绑定在li上,类似这样:<li v-repeat="item in items" v-on:click="clickLi"></li>,理论上每次新增li的时候都会进行同li个数的事件绑定,比用事件代理多耗了些性能。但在实际运用中并没有什么特别的性能瓶颈影响,而且我们也省去在代理中处理e.target的步骤,让事件和DOM元素关系更紧密、简单。