Vue通信
什么是通信
通信是组件或模块之间的数据交互,多重通信就形成了数据流,数据流管理的优劣决定了产品能否上线,数据流(通信)越混乱,代码越难维护。
在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架构中用的最多的一种通信方案。