监听事件
我们可以使用v-on
指令来监听DOM事件并在这些事件触发时运行一些JS代码
例如:
<div id="example-1">
<button v-on:click="counter += 1">Add 1</button>
<p>The button above has been clicked {{ counter }} times.</p>
</div>
var example1 = new Vue({
el: '#example-1',
data: {
counter: 0
}
})
方法事件处理器
上面例子中的代码很少,只是简单的对counter变量进行+1操作,实际使用时往往要比这个复杂,所以为了保持模板便于阅读,我们得把事件处理逻辑提取出来,也就是将要说到的方法,v-on
仅需调用对应方法名即可.
例如:
<div id="example-2">
<!-- `greet` is the name of a method defined below -->
<button v-on:click="greet">Greet</button>
</div>
var example2 = new Vue({
el: '#example-2',
data: {
name: 'Vue.js'
},
// define methods under the `methods` object
methods: {
greet: function (event) {
// `this` inside methods points to the Vue instance
alert('Hello ' + this.name + '!')
// `event` is the native DOM event
alert(event.target.tagName)
}
}
})
// you can invoke methods in JavaScript too
example2.greet() // -> 'Hello Vue.js!'
内联调用方法
除了像上边例子中直接绑定一个具体方法名外,我们也可以在一个内联JS语句中调用方法:
<div id="example-3">
<button v-on:click="say('hi')">Say hi</button>
<button v-on:click="say('what')">Say what</button>
</div>
new Vue({
el: '#example-3',
methods: {
say: function (message) {
alert(message)
}
}
})
有时候我们也可能需要在内联语句中访问原生DOM事件对象,并传到方法内部进行一些处理逻辑.Vue中需要使用一个特殊变量$event:
<div id="example-4">
<button v-on:click="warn('Form cannot be submitted yet.', $event)">Submit</button>
</div>
// ...
var example1 = new Vue({
el: '#example-4',
methods: {
warn: function (message, event) {
// now we have access to the native event
if (event) event.preventDefault()
alert(message)
}
}
})
事件修饰符
在事件处理器中经常需要调用 event.preventDefault()
或 event.stopPropagation()
.
尽管我们可以像上边例子中一样把$event传递给方法内部,看着似乎也不麻烦.不过Vue很务实的帮我们做了更进一步.让我们在方法中只需关心数据相关的逻辑,事件这块就不用我们再操心了🤗.
代替我们进行处理的就是事件修饰符,通过(.)号来添加具体的修饰选项:
- .stop
- .prevent
- .capture
- .self
- .once
<!-- the click event's propagation will be stopped -->
<a v-on:click.stop="doThis"></a>
<!-- the submit event will no longer reload the page -->
<form v-on:submit.prevent="onSubmit"></form>
<!-- modifiers can be chained -->
<a v-on:click.stop.prevent="doThat"></a>
<!-- just the modifier -->
<form v-on:submit.prevent></form>
<!-- use capture mode when adding the event listener -->
<div v-on:click.capture="doThis">...</div>
<!-- only trigger handler if event.target is the element itself -->
<!-- i.e. not from a child element -->
<div v-on:click.self="doThat">...</div>
其中once是2.x中新增的修饰符
<!-- the click event will be triggered at most once -->
<a v-on:click.once="doThis"></a>
.once
不像其它修饰符只能适用于原生的DOM事件,它还适用于组件中定义的事件,后面讲到组件的时候会详细说😀,现在暂时无视.
按键修饰符
在监听键盘事件时,我们经常需要检测 keyCode。Vue也帮我们处理好了,允许为 v-on 添加按键修饰符:
<!-- only call vm.submit() when the keyCode is 13 -->
<input v-on:keyup.13="submit">
🙄表示记住所有keycode不太现实,好在vue也给我们预定义好了一些使用频率最高的按键修饰符别名:
<!-- same as above -->
<input v-on:keyup.enter="submit">
<!-- also works for shorthand -->
<input @keyup.enter="submit">
下边是所有预定义的按键修饰符的别名:
- .enter
- .tab
- .delete (捕获 “删除” 和 “退格” 键)
- .esc
- .space
- .up
- .down
- .left
- .right
如果觉得不够,你也可以通过全局的配置对象,自己定义一些按键修饰符的别名:
// enable v-on:keyup.f1
Vue.config.keyCodes.f1 = 112
组合键(Modifier Keys)
v2.1.0中新增
我们可以使用以下组件键,当相应的组合键按下时才触发对应的鼠标或者键盘事件
- .ctrl
- .alt
- .shift
- .meta
meta键(表示才听说这个词),不过是个老伙计,windows键盘的话就是windows键(⊞),苹果系统的话是(⌘)...
<!-- Alt + C -->
<input @keyup.alt.67="clear">
<!-- Ctrl + Click -->
<div @click.ctrl="doSomething">Do something</div>
为什么在html中监听事件
你可能注意到这种事件监听的方式违背了传统理念 “separation of concern”(jQuery就是如此,不推荐在html中绑定事件)。不过不必担心,因为所有的 Vue.js 事件处理方法和表达式都严格绑定在当前视图的 ViewModel 上,它不会导致任何维护困难。实际上,使用 v-on 有几个好处:
扫一眼 HTML 模板便能轻松定位在 JavaScript 代码里对应的方法。
因为你无须在 JavaScript 里手动绑定事件,你的 ViewModel 代码可以是非常纯粹的逻辑,和 DOM 完全解耦,更易于测试。
当一个 ViewModel 被销毁时,所有的事件处理器都会自动被删除。你无须担心如何自己清理它们。
所以也印证了凡事无绝对,MVVM这种情景下,反而直接在模板上完成事件绑定更易于理解和维护。