Vue非父子組件之間的通信方式詳解
非父子組件的通信
此篇講解的是, 在學習狀態(tài)管理之前, 非父子間通信的方案
在開發(fā)中,我們構建了組件樹之后,除了父子組件之間的通信之外,還會有非父子組件之間的通信。
這里我們主要講兩種方式:
- Provide/Inject;
- 全局事件總線;
1.Provide和Inject
1.1基本使用
Provide/Inject用于非父子組件之間共享數(shù)據(jù):
- 比如有一些深度嵌套的組件,子組件想要獲取父組件的部分內(nèi)容;
- 在這種情況下,如果我們?nèi)匀粚rops沿著組件鏈逐級傳遞下去,就會非常的麻煩;
對于這種情況下,我們可以使用 Provide 和 Inject :
- 無論層級結構有多深,父組件都可以作為其所有子組件的依賴提供者;
- 父組件有一個 provide 選項來提供數(shù)據(jù);
- 子組件有一個 inject 選項來開始使用這些數(shù)據(jù);
實際上,你可以將依賴注入看作是“long range props”,除了:
- 父組件不需要知道哪些子組件使用它 provide 的 property
- 子組件不需要知道 inject 的 property 來自哪里
我們開發(fā)一個下面這樣的結構: 讓App.vue提供一些數(shù)據(jù)給HomeContent.vue使用[外鏈圖片轉(zhuǎn)存失敗,
在祖先組件中通過provide將數(shù)據(jù)傳出, provide對應的是一個對象
export default { components: { Home }, // 通過provide將數(shù)據(jù)傳出 provide() { return { name: this.name, age: this.age, height: this.height } } }
在后代元素中, 通過inject接收祖先傳遞的數(shù)據(jù), inject對應的是一個數(shù)組
export default { inject: ["name", "age", "height"] }
1.2處理響應式數(shù)據(jù)(了解)
我們先來驗證一個結果:如果我們修改了this.names的內(nèi)容,那么使用length的子組件會不會是響應式的?
<template> <div class="app"> <home /> <h2>{{ name }}</h2> <button @click="btnClick">按鈕</button> </div> </template> <script> import Home from './Home.vue' export default { components: { Home }, data() { return { name: "chenyq", age: 18, height: 1.88, } }, // 通過provide將數(shù)據(jù)傳出 provide() { return { name: this.name, age: this.age, height: this.height } }, methods: { btnClick() { this.name = "kaisa" } }, } </script>
我們會發(fā)現(xiàn)對應的子組件中是沒有反應的:
這是因為當我們修改了names之后,之前在provide中引入的 this.name 本身并不是響應式的;
那么怎么樣可以讓我們的數(shù)據(jù)變成響應式的呢?
- 非常的簡單,我們可以使用響應式的一些API來完成這些功能,比如說computed函數(shù);
- 當然,這個computed是vue3的新特性,在后面我會專門講解,這里大家可以先直接使用一下;
import { computed } from 'vue' export default { components: { Home }, data() { return { name: "chenyq", age: 18, height: 1.88, } }, // 通過provide將數(shù)據(jù)傳出 provide() { return { name: computed(() => this.name), age: this.age, height: this.name } }, methods: { btnClick() { this.name = "kaisa" } }, }
注意:我們在使用name的時候需要獲取其中的value
這是因為computed返回的是一個ref對象,需要取出其中的value來使用;
<template> <div class="home-content"> <h2>名字: {{ name.value }}, 年齡: {{ age}}, 身高: {{ height}}</h2> </div> </template>
2.全局事件總線
Vue3從實例中移除了 o n 、 on、 on、off 和 $once 方法,所以我們?nèi)绻M^續(xù)使用全局事件總線,要通過第三方的庫:
- Vue3官方有推薦一些庫,例如 mitt 或 tiny-emitter, 這兩個庫雖然不再維護, 但還是可以使用的;
- 這里我們主要講解一下 hy-event-store 的使用, 是前端大神coderwhy封裝的他自己的庫;
首先,我們需要先安裝這個庫:npm install hy-event-store
其次,我們可以封裝一個工具eventbus.js:
import { HyEventBus } from "hy-event-store"; const eventBus = new HyEventBus() export default eventBus
在項目中導入后可以使用它們:
- 我們在App.vue中監(jiān)聽事件;
- 我們在Banner.vue中觸發(fā)事件;
Banner中觸發(fā)事件:
<template> <div class="home-content"> <button @click="btnClick">按鈕</button> </div> </template> <script> import eventBus from './utils/event-bus' export default { methods: { btnClick() { console.log("myEvent事件被監(jiān)聽") // 發(fā)送事件到事件總線上 eventBus.emit("myEvent", "chenyq", 18, 1.88) } }, } </script>
App中監(jiān)聽事件:
<script> import eventBus from './utils/event-bus' import Home from './Home.vue' export default { components: { Home }, created() { // 監(jiān)聽事件總線上的事件 eventBus.on("myEvent", (name, age, height) => { console.log(name, age, height) }) }, } </script>
總結
到此這篇關于Vue非父子組件之間的通信方式的文章就介紹到這了,更多相關Vue非父子組件通信內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
Vue.js常用指令之循環(huán)使用v-for指令教程
這篇文章主要跟大家介紹了關于Vue.js常用指令之循環(huán)使用v-for指令的相關資料,文中通過示例代碼介紹的非常詳細,對大家具有一定的參考學習價值,需要的朋友們下面來一起看看吧。2017-06-06vue2和elementUI?實現(xiàn)落日余暉登錄頁和滑塊校驗功能
這篇文章主要介紹了vue2和elementUI打造落日余暉登錄頁和滑塊校驗,本文通過實例代碼給大家介紹的非常詳細,需要的朋友可以參考下2023-06-06Vue通過for循環(huán)隨機生成不同的顏色或隨機數(shù)的實例
今天小編就為大家分享一篇Vue通過for循環(huán)隨機生成不同的顏色或隨機數(shù)的實例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2019-11-11