如果我們想要從子元件傳遞資料到母元件,我們必須使用$emit 建立一個客製化的事件,再透過這個事件,把資料投擲進到母元件。要怎麼做呢?概念其實和 props 差不多。當我們要把根元件的資料傳進子元件,需要透過 props 的方法,在子元件中建立一個接收資料的環境。
同樣的,子元件要投遞資料到母元件,也會需要先在子元件打造一組工具(客製化事件、custom event),讓 Vue 先建構一個客製化事件。最後,再透過 DOM 模板,綁定這個工具,進一步呼叫母元件的函式。
元件觸發事件的過程
先來複習一下根元件綁定事件的過程:
1 | <button @click="incrementTotal"></button> |
^
1 | var app = new Vue({ |
^
子元件呼叫根元件的 method
如果,我們今天要將 incrementTotal
綁定到元件上,是不可行的。像這樣:
<component @click="incrementTotal"></component>
(錯誤示範)
這是因為,我們無法在子元件直接使用母元件的任何東西,data、methods 都是。如果想要使用母元件的事件,我們就需要在子元件建立一個客製化事件(custom event),再透過這個事件的指令呼叫母元件的 method。
子元件中
x-template
1 | <button @click="incrementCounter" class="btn btn-outline-primary">增加 {{ counter }} 元</button> |
子元件的 template 事件呼叫建立客製化事件的函式
^
1 | Vue.component('component',{ |
可以看到,在這邊子元件中 x-template 綁定的事件 incrementCounter
呼叫的函式,做的事情只有 this.$emit('emit-event-name')
。這個 $emit 就是 Vue 提供我們建立客製化事件的方法。
所以,emit 雖然聽起來有些複雜,但我們需要做的,就只有:
- 子元件中綁定一個建立客製化事件的事件,
- 透過事件的綁定方式,把這個新的客製化事件,綁定到子元件的 DOM 模板中
1 | <component @custom-event="rootMethod"></component> |
這樣就達成子元件呼叫根元件的目的了。
那資料呢?
說了這麼多,還沒講到資料。資料的部分,也是透過 this.$emit()
這個方法傳遞的。在這個方法中,第一個參數為這個客製化事件的名稱,第二的參數就是要投擲到母元件的資料啦!如下:
子元件
1 | this.$emit('name', this.dataName) |
不過,這樣還沒結束。在跨元件的傳遞中,如果設定了一方,另一方一定也會有相對應的設定。這樣 Vue 才會知道,要在哪「兩個」元件之間做傳遞。所以,在這個範例中,子元件已經做好傳遞資料的準備,根元件當然也要有個地方接收子元件的資料。因為上述都是和事件相關的設定,想當然母元件接收資料的地方,也會是在 methods 裏頭:
母元件
1 | methods:{ |
…
記得嗎?上述我們透過客製化事件呼叫根元件的函式 <component @custom-evnet="rootMethod"></component>
,如果要接收資料,透過在這個函式建立一個參數,Vue 就會知道這個參數等於子元件傳出來的資料了。
如此一來,我們就能透過母元件做子元件資料的計算。