Vue-接住我的事件吧($emit)

抓住你~

簡述

Vue 的事件比較特別一些,不是透過 props,而是透過 $emit 來建立一個「custom event」,直接來看例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<template>
<div class="backdrop">
<div class="modal" :class="{ sale: isSale }">
<div class="content">
<h2>{{ user.name }}</h2>
<p>{{ user.email }}</p>
<!-- @click 執行 onClick handler -->
<button class="btn" @click="onClick">Close</button>
</div>
</div>
</div>
</template>

<script>
export default {
name: 'Modal',
props: ['user'],
methods: {
onClick() {
// 拋出 custom event
this.$emit('onClose')
}
}
}
</script>

當 child emit 出一個事件後,parent 就可以直接拿這個 event 來用:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
<template>
<div class="container">
<div class="block">
<button class="btn" @click="onOpen">Show modal</button>
</div>
</div>
<!-- @onClose = 從 Modal 傳出的 custom event -->
<Modal v-show="isModal" :user="user" @onClose="onClose" />
</template>

<script>
import Modal from './components/Modal.vue'

export default {
name: 'App',
components: {
Modal
},
data() {
return {
isModal: false,
user: {
name: 'PeaNu',
email: 'PeaNug@peanu.dev'
}
}
},
methods: {
onOpen() {
this.isModal = true
},
// @onClose 觸發時的 handler
onClose() {
this.isModal = false
}
}
}
</script>

不過這邊其實還是可以用 React 的思維來做(個人覺得 React 的作法更直覺),就是「把 function 寫好後再當作 props 傳下去」,像這樣:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
<template>
<div class="container">
<button class="btn" @click="onOpen">Show modal</button>
</div>
<!-- :onClose = 用來關掉 modal 的 handler -->
<Modal v-show="isModal" :onClose="onClose" />
</template>

<script>
import Modal from './components/Modal.vue'

export default {
name: 'App',
components: {
Modal
},
data() {
return {
isModal: false,
}
},
methods: {
onOpen() {
this.isModal = true
}
onClose() {
this.isModal = false
}
}
}
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<template>
<div class="backdrop">
<div class="modal>
<div class="content">
...
<button class="btn" @click="onClose">Close</button>
</div>
</div>
</div>
</template>

<script>
export default {
name: 'Modal',
props: ['user', 'isSale', 'onClose'] // 接收 props
}
</script>

帶上參數

emit 出去的事件的是可以帶入參數的,只要在 emit 的時候帶進去就好了:

1
2
3
4
5
6
// Popup.vue
methods: {
onClick() {
this.$emit('onClick', 'my param')
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<template>
<Popup @onClick="handle" />
</template>

<script>
export default {
name: 'App',
methods: {
handle(param) {
// my param
console.log(param)
}
}
}
</script>

如果你希望直接在 inline 中存取參數的話,可以這樣子寫:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<template>
<Popup v-if="isShowPopup" @onClick="isShowPopup = $event" />
</template>

<script>
export default {
name: 'App',
data() {
return {
isShowPopup: false
}
}
}
</script>

附註:我知道這例子有點怪,不過重點是理解可以這樣用就好。

參數會直接用 $event 來表示,所以就可以用它來取得。

Vue-我想放的是內容不是資料(Slot) Vue-傳遞資料的好夥伴(props)
Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×