Vue公共廣播/父子元件廣播 $emit、$on的實現及原理解答
阿新 • • 發佈:2018-12-14
-
引數:
-
{string} event
-
[...args]
-
觸發當前例項上的事件。附加引數都會傳給監聽器回撥
-
-
引數:
- {string | Array<string>} event (陣列只在 2.2.0+ 中支援)
- {Function} callback
-
用法:
監聽當前例項上的自定義事件。事件可以由vm.$emit觸發。回撥函式會接收所有傳入事件觸發函式的額外引數。
-
示例:
vm.$on('test', function (msg) {
console.log(msg)
})
vm.$emit('test', 'hi')
// => "hi"
- 應用一
// index.vue <template> <div> <my-dialog @change-data="receiveDate"></my-dialog> </div> </template> <script> import myDialog from './myDialog' export default { components: { myDialog }, methods: { receiveDate (val) { console.log(val) // params } } } </script>
// myDialog.vue <template> <div> <div @click="handleClick"></div> </div> </template> <script> export default { methods: { handleClick (){ let params = "" this.$emit("change-data", params) } } } </script>
-
應用二
- eventHub 檔案裡匯出了一個 new vue 例項 ①
- 與 main.js 裡 new vue 例項 ② 是平級的
-
兩個 vue 例項上都有 $emit $on 方法,但是這個栗子裡的廣播 $emit $on 都只在 vue 例項 ① 上
-
vue 例項 ① 一直在監聽
-
當 vue 例項 ② 中在滿足某個條件需要觸發廣播時,然後用 vue 例項 ① 上的 $emit (eventHub.$emit)傳送廣播,當 vue 例項 ① 上監聽到時,就用 eventHub.$on 接收這個同名的廣播,然後執行回撥函式,至於回撥函式裡有什麼亦或做了是嗎就與它無關了,因為 vue 例項 ① 只負責監聽和接收廣播。
-
而且 vue 例項 ① 一直存在不會消失。但是 vue 例項 ② 上由於是單頁面應用,所以各種元件會經常被銷燬或者重建,如果元件被銷燬了,它裡面的廣播也就被銷燬了,所以會導致找不到相對應廣播。
// utils/eventHub.js
import Vue from 'vue'
export default new Vue() // 什麼都沒有繫結,因為它只是一個跳板,並且在實時監聽
// index.vue
<template>
<div>
<my-dialog></my-dialog>
</div>
</template>
<script>
import myDialog from './myDialog'
import eventHub from 'utils/eventHub'
export default {
components: {
myDialog
},
mounted() {
eventHub.$on("change-data", (val) => {
console.log(val) // params
})
},
beforeDestroy () { // 在例項銷燬之前,移除監聽器
eventHub.$off("change-data")
}
}
</script>
// myDialog.vue
<template>
<div>
<div @click="handleClick"></div>
</div>
</template>
<script>
import eventHub from 'utils/eventHub'
export default {
methods: {
handleClick (){
let params = ""
eventHub.$emit("change-data", params)
}
}
}
</script>
// main.js
new Vue({
el: '#app',
router,
store,
template: '<app/>',
components: { app }
})