什麼是通信 通信是組件或模塊之間的數據交互,多重通信就形成了數據流,數據流管理的優劣決定了產品能否上線,數據流(通信)越混亂,代碼越難維護。 在Vue中常見的通信方式 父子組件通信 父傳子使用自定義屬性(props),子傳父使用自定義事件($emit())。 狀態提示 當兄弟組件之間需要共用數據時, ...
什麼是通信
通信是組件或模塊之間的數據交互,多重通信就形成了數據流,數據流管理的優劣決定了產品能否上線,數據流(通信)越混亂,代碼越難維護。
在Vue中常見的通信方式
父子組件通信
父傳子使用自定義屬性(props),子傳父使用自定義事件($emit())。
狀態提示
當兄弟組件之間需要共用數據時,我們通常的做法是把這個數據定義它們的共同父組件中,在通過自定義屬性實現數據共用。
provide/inject
這是組件樹中,自上而下的一種數據通信方案,也就是只能父組件向後代組件傳遞。需要註意的是:當provide提供動態數據(聲明式變數)時,動態數據發生變化,後代組件不會自動更新。
ref
ref是vue中一個內置屬性,每一個html元素或組件都有這個屬性,ref作用在組件上得到組件實例。使用ref訪問組件實例,進一步可以訪問組件中的數據和方法。(說明:ref是一種快速的DOM訪問方式,當然ref可以作用在組件上得到組件實例,這些ref得到的DOM實例或組件實例,使用this.$refs來訪問)
插槽通信
藉助<slot>組件實現從子組件向父組件傳遞數據,藉助this.$slots訪問訪問父組件中的插槽實例,在自定義組件使用this.$slots訪問父組件的插槽實例;在父組件插槽中使用#default=‘scopet’訪問子組件<slot>回傳的數據
$parent/$children
藉助$parent/$children可以實現在任一組件中訪問組件樹中的其它任意組件實例,可以做到在組件中隨意穿梭。($parent表示當前組件父組件實例,$children表示當前組件的子組件)
$attrs/$listteners
藉助$attrs可以訪問父組件傳遞過來的自定義屬性(除class和style外)藉助$listenrs可以訪問父組件給的自定義事件,在某些場景下,$attrs與$listeners可以替代props/$emit()這種通信方案。
事件匯流排
藉助vue內置的事件系統($on/$emit()/$off/$once)實現“訂閱-發佈”通信,這種通信方式是一種與組件層級無關的“一對多”的通信。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script> <style> #app{ display: flex; } .box{ width: 650px; height: 400px; border: 1px solid #333; /* background-color: aqua; */ } .msgbox{ width: 649px; height: 100px; position: relative; } .msgbox>input{ width: 580px; height: 20px; } </style> </head> <body> <div id="app"> <el-user1></el-user1> <el-user2></el-user2> <!-- <div> <div class="box"></div> <div class="msgbox"> <input type="text"> <button>發送</button> </div> </div> --> </div> <script> const bus = new Vue() Vue.component('el-user1',{ template:` <div> <div class="box" v-html='content'></div> <div class="msgbox"> <input type="text" v-model='msg' @keyup.enter='send'> <button @click='send'>發送</button> </div> </div> `, data(){ return{ msg:'', content:'' } }, mounted(){ bus.$on('elme',msg=>{ this.content += `<div>miss說:${msg}</div>` }) }, methods:{ send(){ bus.$emit('el',this.msg) this.msg = '' } } }) Vue.component('el-user2',{ template:` <div> <div class="box" v-html='content'></div> <div class="msgbox"> <input type="text" v-model='msg' @keyup.enter='send'> <button @click='send'>發送</button> </div> </div> `, data(){ return{ msg:'', content:'' } }, mounted(){ bus.$on('el',msg=>{ this.content += `<div>me:${msg}</div>` }) }, methods:{ send(){ bus.$emit('elme',this.msg) this.msg = '' } } }) const app = new Vue({ el:'#app' }) </script> </body> </html>
vuex通信
是vue架構中終極通信方案,也是vue架構中用的最多的一種通信方案。