目錄
一、 實現所有組件看到x事件
二、 實現$on $off 以及 $emit
總結不易~ 本章節對我有很大的收獲, 希望對你也是!!!
本節素材已上傳至Gitee:yihaohhh/我愛Vue - Gitee.com
全局事件總線圖:
?本節素材已上傳至Gitee:yihaohhh/我愛Vue - Gitee.com
一、 實現所有組件看到x事件
到main.js 里面設置全局總線
import Vue from 'vue'import App from './App.vue'// 關閉Vue生產提示
Vue.config.productionTip = falseVue.prototype.x = { a: 1, b: 2 }// 創建vm
new Vue({el: '#app',render: h => h(App)
})
分別在School 和 Student組件上進行掛載輸出當前對象?
現在就是實現了第一個, 能讓所有組件看到 x
?本節素材已上傳至Gitee:yihaohhh/我愛Vue - Gitee.com
二、 實現$on $off 以及 $emit
Vue.prototype.x = { a: 1, b: 2 }
由于上面只是一個普通對象, 所以我們沒有辦法能夠訪問它的$on, $off以及$emit, 因為這些只存在組件的實例對象中, 那么我們第一件事情就是要創建組件的實例對象。
這個d組件實例對象 就是相當于一個vc 只是一個組件的實例對象~
const Demo = Vue.extend({}) // 創建一個組件
const d = new Demo() // 組件的一個實例對象// Vue.prototype.x = { a: 1, b: 2 }
Vue.prototype.x = d
在School組件內進行事件綁定:
mounted() {console.log(this.x)// $on 監聽一個名字叫 "hello" 的事件,一旦別人觸發了這個事件,我就執行后面的代碼。// $on 給x綁定了一個'hello' 事件this.x.$on('hello', (data) => {console.log('我是School組件, 收到了數據', data)})},
在Student組件內進行值的傳遞:
<button @click="sendStudenName">把學生名給School組件</button>methods: {sendStudenName() {this.x.$emit('hello', 666)}}
可以看到確實起到了全局的作用分別來進行值的輸入和接收?
但是定義那么多行的vc實在是過于臃腫,我們就可以直接在創建vm的時候來直接定義全局事件
// 創建vm
new Vue({el: '#app',render: h => h(App),beforeCreate() {// 這里的 $bus 是一個全稱Vue.prototype.$bus = this // 這個this本身就是Vue的實例對象// 安裝全局事件總線}
})
Student組件用來傳值:
<button @click="sendStudenName">把學生名給School組件</button> methods: {sendStudenName() {this.$bus.$emit('hello', this.name)}}
School用兩個生命周期鉤子進行獲取值:分別用來綁定事件?和 解綁解綁事件!
mounted() {// $on 監聽一個名字叫 "hello" 的事件,一旦別人觸發了這個事件,我就執行后面的代碼。// $on 給x綁定了一個'hello' 事件this.$bus.$on('hello', (data) => {console.log('我是School組件, 收到了數據', data)})},// 銷毀之前的鉤子// beforeDestroy已經廢棄了// 用完了 一定要把傀儡身上的事件解綁beforeUnmount() {this.$bus.$off('hello')}
TodoList全局事件總線傳值
雖然我們學習了全局事件總線,任意兩個組件之間的通信都非常方便,但是也不是所有組件之間的通信都要用上全局事件總線,就比如:父組件給子組件傳遞數據,props就極其方便~
但是在TodoList中的MyItem組件跟 App組件之間是爺孫關系 所以用全局事件總線就會比較方便~
因為List組件是沒有用到該方法的 而是轉手就又傳給了Item組件, 所以這里用全局事件總線就會非常方便!
那么我們就需要做到的是直接進行通信, 不在進行逐層傳遞~
第一步就是創建全局事件總線:
// 創建vm
new Vue({el: '#app',render: h => h(App),beforeCreate() {Vue.prototype.$bus = this}
})
第二步, 清除掉List組件和App組件 以及 Item組件通過props傳入的函數:
<MyList :todos="todos" />
第三步, 確定是Item給App傳遞數據
methods: {handleCheck(id) {console.log(id)// this.checkTodo(id)this.$bus.$emit('checkTodo', id)},handleDelete(id) {if(confirm('確定刪除嗎')) {console.log(id)// this.deleteTodo(id)this.$bus.$emit('deleteTodo', id)}}}
利用全局事件總線 進行觸發事件
分別對數據進行添加和刪除的時候, 這里都觸發的是$bus全局事件~
?本節素材已上傳至Gitee:yihaohhh/我愛Vue - Gitee.com