什麼是通訊
通訊是元件或模組之間的資料互動,多重通訊就形成了資料流,資料流管理的優劣決定了產品能否上線,資料流(通訊)越混亂,程式碼越難維護。
在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/vue@2.6.14/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架構中用的最多的一種通訊方案。