Vue通信

  • Vue通信已关闭评论
  • 157 次浏览
  • A+
所属分类:Web前端
摘要

通信是组件或模块之间的数据交互,多重通信就形成了数据流,数据流管理的优劣决定了产品能否上线,数据流(通信)越混乱,代码越难维护。


什么是通信

通信是组件或模块之间的数据交互,多重通信就形成了数据流,数据流管理的优劣决定了产品能否上线,数据流(通信)越混乱,代码越难维护。

在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架构中用的最多的一种通信方案。