跳至主要内容

[Vue] 元件-Emit

TL;DR

參考資料

相關連結


Emit簡介

因為元件之間的資料互相獨立,前面介紹外層元件(父元件)如果要傳遞資料給內層元件(子元件)時,需要使用props

相對的,內層元件如果要傳遞資料給外層元件時,則是使用 emit事件

在傳遞事件時,不一定需要傳送資料。也可以只有觸發事件本身。

定義Emit順序
  1. 先定義外層接收的方法

  2. 定義內層的 $emit 觸發方法

  3. 使用 v-on 的方式觸發外層方法(口訣:前內、後外)

無參數傳遞

<div id="app">
<div class="p-5">
<p>
{{` 外層num數值為: ${num}`}}
</p>
<button-counter
@parent-emit-name="addNum"
>
</button-counter>
</div>
</div>

先在methods內定義一個方法,這邊定義為childEmitName( Line:18(Vue) )。

接著在 Line:19 定義一個向外傳遞的事件名稱:this.$emit('parentEmitName')。該名稱可以自訂。

外層元件在接收時根據前內後外的口訣,將內層傳遞出來的事件綁定到外層觸發事件上 Line:7(#app) ,接著再選擇外層要執行的方法為addNum

$emit定義向外傳遞事件名稱規範

因為html在使用屬性時,必須為小寫。

所以外層元件在觸發內層傳遞出來的事件時,如果名稱有大寫,需要轉換為 - 連接(與綁定style類似)

e.g:
parentEmitName 在使用時為 :parent-emit-name="parentMethod"

有傳遞參數

<div id="app">
<div class="p-5">
內部傳來的文字:{{ text }}<br>
<button-text
@emit-text="getData"
class="mt-2"
>
</button-text>
</div>
</div>

如果有傳遞參數的需求,則需要在內層的$emit內再加上需要傳遞的參數。在外層的method內需要定義接收的參數名稱。

$emit不一定要撰寫在methods

內層元件也可以直接在 template 中撰寫$emit。這麼一來就不用另外在定義一個內層元件的method名稱。

e.g:

template:`
<button type="button"
@click="$emit('emit-text',text)"
>
</button>
`

Emit 驗證

props類似,emit同樣可以在傳出參數時先進行一個驗證(驗證定義在子元件上)

型別驗證不影響運作

props相同,emit在驗證時,就算型別與定義的不同,也可以正常執行。

只是會在開發者工具中看到Vue的warning

定義emits

<div id="app">
<div class="p-5">
<h3>Emits API</h3>
{{ num }}
<button-counter @add="addNum"></button-counter>
</div>
</div>

當定義一個$emit事件,其傳遞值由data所定義,但是又難以追蹤其變化時 (可能會隨時更改),只要定義emits屬性就可以消除這個Vue warn。

emits屬性值為一個陣列,並且在裡面使用字串方式存入向外傳遞$emit所定義的名稱,如 Line:19(Vue)

驗證傳出參數型別

<div id="app">
<div class="p-5">
<h3>驗證資料內容</h3>
{{num}}
<button-counter2 @add="addNum"></button-counter2>
</div>
</div>

其中emits改寫為物件,並且屬性名稱對應$emit所傳出的事件名稱(以此例來說即為add)。