Vue-101-Day 10
26 May 2019 |使用v-on
這個 directive監聽 DOM 事件
以及執行 JavaScript code。
範例:
<div id="app-17">
<button v-on:click="counter += 1">Add 1</button>
<p>The button avoce has been clicked {{ counter }} times.</p>
</div>
var vm17 = new Vue({
el: '#app-17',
data: {
counter: 0
}
})
每當點擊 Add 1 這個 button,畫面顯示也會跟著變動
方法事件處理(Method Event Handler)
需要執行複雜的邏輯處理時,在 v-on 指令中撰寫 JavaScript 就顯得雜亂,所以 v-on 指令後面可以接 method name,將邏輯程式碼寫在 method 裡,會比較可行。
範例:
<div id="app-18">
<button v-on:click="greet">Greet</button>
</div>
var vm18 = new Vue({
el: '#app-18',
data: {
name: 'Vue'
},
methods: {
greet: function(event) {
alert(`Hello ${this.name}`)
if (event) {
alert(event.target.tagName)
}
}
}
})
透過點擊 button 觸發事件外,也可以直接引用(e.g: vm18.greet()
)
除了直接綁定 method 之外,也可以在 inline JavaScript statement 使用 method
<div id="app-19">
<button v-on:click="say('Hi', $event)">Say Hi</button>
</div>
var vm19 = new Vue({
el: '#app-19',
methods: {
say: function(message, event) {
alert(message)
}
}
})
註:有時候會需要原始的 DOM Event,Vue 提供$event
將這個特殊變數傳入方法
事件修飾符(Event Modifiers)
在 DOM 事件處理 event.preventDefault() 或 event.stopPropagation()是滿常見的,但是方法內純粹處理資料邏輯
而不用再額外處理 DOM 事件,是比較好的處理方式,Vue 提供一些事件修飾符來解決這個問題
.stop
:防止事件冒泡.prevent
:防止預設行為.capture
:事件捕獲.self
:只觸發 event.target 等於自身的 element,不是來自子元素.once
:事件只會觸發一次.passive
:
stop
防止事件冒泡,也就是 event.stopPropagation()
<div id="app-20">
<ul v-on:click="outer">
<li v-on:click="middle">
<a v-on:click="inner" target="_blank" href="http://google.com">
google.com
</a>
</li>
</ul>
</div>
var vm20 = new Vue({
el: '#app-20',
methods: {
outer: function() {
console.log('outer')
},
middle: function() {
console.log('middle')
},
inner: function() {
console.log('inner')
}
}
})
點擊 google.com 這個超連結時,除了觸發自身(inner)的 function 外,還會接觸發 middle、outer Event Handler 的事件 ,產出 LOG 如下
inner
middle
outer
冒泡事件順序為:inner -> middle -> outer
這時候加上.stop阻止冒泡事件
,如此一來就不會觸發到 middle 及 outer 事件
<div id="app-20">
<ul v-on:click="outer">
<li v-on:click="middle">
<a v-on:click.stop="inner" target="_blank" href="http://google.com">
google.com
</a>
</li>
</ul>
</div>
prevent
阻止預設行為事件
下述範例點擊完超連結後,瀏覽器會開一個新 Tab 連結到 google.com
<a target="_blank" href="http://google.com" >google.com</a>
但加上v-on:click.prevent
,就可以防止連結到 google.com,阻止預設行為發生
<div id="app-20">
<ul v-on:click="outer">
<li v-on:click="middle">
<a
v-on:click.prevent="inner"
target="_blank"
href="http://google.com"
>
google.com
</a>
</li>
</ul>
</div>
modifiers 修飾符可以串接
範例為 stop + prevent,阻止冒泡事件加上防止預設行為
<div id="app-20">
<ul v-on:click="outer">
<li v-on:click="middle">
<a
v-on:click.stop.prevent="inner"
target="_blank"
href="http://google.com"
>
google.com
</a>
</li>
</ul>
</div>
輸出結果
inner
capture
事件捕獲(Event Capture)方向是從父元素傳到子元素,以下範例來說結果為:outer -> middle -> inner
<div id="app-20">
<ul v-on:click.capture="outer">
<li v-on:click.capture="middle">
<a
v-on:click.capture="inner"
target="_blank"
href="http://google.com"
>
google.com
</a>
</li>
</ul>
</div>
var vm20 = new Vue({
el: '#app-20',
methods: {
outer: function () {
console.log('outer')
},
middle: function () {
console.log('middle')
},
inner: function () {
console.log('inner')
}
}
輸出結果
outer
middle
inner
self
觸發 event.target 等於自身的 element,而不是自子元素
範例來看:outer 及 inner 都給.self,而 middle 沒給,點擊後因為 inner 包含在 middle 裡,所以 middle 也會被觸發
<div id="app-20">
<ul v-on:click.self="outer">
<li v-on:click="middle">
<a v-on:click.self="inner" target="_blank" href="http://google.com">
google.com
</a>
</li>
</ul>
</div>
輸出結果
inner
middle
once
事件只會觸發一次
範例來說:點擊一次 counter 都會+ 1,但加上 once 後,事件只觸發一次,變數 counter 值也不會變了
<div id="app-20">
<button v-on:click="outer">Add 1</button>
<p>Counter is {{ counter }}</p>
</div>
passive
DOM Event 產生時,瀏覽器會查詢是否有 preventDefault,因為無法預先知道,所以 passive 就是告訴瀏覽器,沒有使用 preventDefault 阻止預設行為
,以利提升效能
<div v-on:scroll.passive="onScroll">...</div>
按鍵修飾符(Key modifiers)
有時候會需要監聽鍵盤事件(key board),當 key up 某個按鍵就要執行某個 method,在 Vue 可以透過 v-on
監聽鍵盤事件
範例:當在 input 欄位 按下 Enter 鍵,變數 counter 值就會+1
<div id="app-21">
<input v-on:keyup.enter="submit" />
<p>Counter is {{ counter }}</p>
</div>
var vm21 = new Vue({
el: '#app-21',
data: {
counter: 0
},
methods: {
submit: function() {
this.counter++
}
}
})
Key codes
另 Vue 提供了常用的 key code 名稱
- enter
- tab
- delete
- esc
- space
- up
- down
- left
- right
System modifiers keys
支援 Vue 2.1.0 以上
- .ctrl
- .alt
- .shift
- .meta
範例
<div id="app-21">
<input @keyup.enter="submit" @keyup.ctrl.67="clear" />
<p>Counter is now.</p>
</div>
var vm21 = new Vue({
el: '#app-21',
data: {
counter: 0
},
methods: {
submit: function() {
this.counter++
},
clear: function() {
this.counter = 0
}
}
})
exact 修飾符
支援 Vue 2.5.0 以上,控制精確的 System modifier keys
範例 1:Alt 及 Shift 按下皆會觸發
<button @click.ctrl="onClick">A</button>
範例 2:加上.exact
後,只有 Ctrl 按下才會觸發
<button @click.ctrl.exact="onCtrlClick">A</button>
Mouse button modifiers
支援 Vue 2.2.0 以上
- .left
- .right
- .middle
參考資料:
Comments