经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » JS/JS库/框架 » Vue.js » 查看文章
Vue组件之间的通信你知道多少
来源:jb51  时间:2022/2/28 11:23:39  对本文有异议

Vue组件间通信

vue组件间通信分为以下几种:

  • 父向子传递数据,用自定义属性
  • 子向父传递数据,用自定义事件
  • 兄弟(任意)组件间传递数据,用全局事件总线或者消息订阅与发布

背吧,面试题要是说让你简述一下,就上面这段话拿过来回答呗。下面就介绍一下这几种通信方式的简单用法

1.父向子传递数据

前面已经说了,父向子传递数据用的是自定义属性,接下来就让我们看下代码是怎么写的

  1. //这是父组件,Father.vue
  2. <template>
  3. <div class="father">
  4. <!-- 父组件向子组件传递person对象 -->
  5. <Son :person="person"/>
  6. </div>
  7. </template>
  8. <script>
  9. export default {
  10. data (){
  11. return {
  12. person:{name:'张三',age:18,sex:'男'}
  13. }
  14. }
  15. }
  16. </script>
  1. //这是子组件,Son.vue
  2. <template>
  3. <div class="son">
  4. <h2>我是子组件</h2>
  5. <div>
  6. <h4>个人信息展示</h4>
  7. <ul>
  8. <li><label>姓名:</label><span>{{person.name}}</span></li>
  9. <li><label>年龄:</label><span>{{person.age}}</span></li>
  10. <li><label>性别:</label><span>{{person.sex}}</span></li>
  11. </ul>
  12. </div>
  13. </div>
  14. </template>
  15. <script>
  16. export default {
  17. //子组件通过props接收父组件传递过来的数据
  18. props:['person']
  19. }
  20. </script>

这里题外话,简单的介绍下props

1.props的大小写

当我们使用自定义属性传递数据的时候,自定属性的名称可能不会简单的是一个单词,那这个时候我们该如何书写呢?请看如下代码

  1. //父组件 父组件传递了 company-name
  2. <Son company-name = "Microsoft"></Son>
  3. //子组件 子组件接收时的写法
  4. <script>
  5. export default {
  6. props:['companyName']
  7. }
  8. </script>

2.props的两种写法

第一种是简单的写法

  1. props:['name','age','sex']

第二种是对象形式的写法

  1. props:{
  2. name:{
  3. type:String,
  4. required:true,
  5. default:''
  6. },
  7. age:{
  8. type:Number,
  9. required:true,
  10. default:0
  11. },
  12. sex:String
  13. }

这两种写法根据实际情况来决定,一般的使用第一种就可以满足需求

3.传递动态props

通过v-bind为组件传递动态数据类型

  1. <Son :categoryList="categoryList"></Son>
  2. <script>
  3. export default {
  4. data (){
  5. return {
  6. //购物车列表数据
  7. categoryList:[]
  8. }
  9. }
  10. }
  11. </script>

2.子向父传递数据

前面讲到,子向父传递数据需要用到自定义事件,但是这里通过自定义属性也可以实现,我们一起来看一下

  1. //子组件 Son.vue
  2. <template>
  3. <div class="son">
  4. <button @click="sendMsgForFather">发送信息</button>
  5. </div>
  6. </template>
  7. <script>
  8. export default {
  9. props:['getSonMessage'],
  10. methods:{
  11. sendMsgForFather(){
  12. this.getSonMessage(`我是子组件,你好啊`)
  13. }
  14. }
  15. }
  16. </script>
  1. //父组件 Father.vue
  2. <template>
  3. <div class="father">
  4. <h1>我是父组件</h1>
  5. <Son :getSonMessage="getSonMessage"/>
  6. </div>
  7. </template>
  8. <script>
  9. import Son from '@/components/Son.vue'
  10. export default {
  11. components : {
  12. Son
  13. },
  14. methods:{
  15. getSonMessage(msg){
  16. console.log(`我收到了子组件传递过来的信息:${msg}`);
  17. }
  18. }
  19. }
  20. </script>

下面这段代码是通过自定义事件实现的

  1. //子组件 Son.vue
  2. <template>
  3. <div class="son">
  4. <button @click="sendMsgForFather">发送信息</button>
  5. </div>
  6. </template>
  7. <script>
  8. export default {
  9. props:['getSonMessage'],
  10. methods:{
  11. //发送信息给父组件
  12. sendMsgForFather(){
  13. this.$emit('eventN',`我是子组件,hello`)
  14. }
  15. }
  16. }
  17. </script>
  1. //父组件 Father.vue
  2. <template>
  3. <div class="father">
  4. <h1>我是父组件</h1>
  5. <Son @eventN="demo"/>
  6. </div>
  7. </template>
  8. <script>
  9. import Son from '@/components/Son.vue'
  10. export default {
  11. components : {
  12. Son
  13. },
  14. methods:{
  15. demo(msg){
  16. console.log(`触发了demo函数,${msg}`);
  17. }
  18. }
  19. }
  20. </script>

其实理解起来还是很简单的,给子组件上绑定一个自定义事件,子组件上的自定义事件通过$emit触发,而$emit通过子组件上的按钮点击事件来触发,最终将数据发送给父组件,父组件通过demo函数拿到并展示数据,估计听完我说的,肯定蒙了。研究一下代码,自己敲一下就明白了

3.兄弟(任意)组件间的传值

兄弟组件间的传值方法比较多,包括我们甚至可以通过逐层使用自定义属性自定义事件来实现,但代码看起来可能不是那么舒服,甚至把自己都给绕晕了,我自己也试过,想想这种方法知道就行,效率太低了。接下来就讲讲目前主流的几种兄弟组件间传值的方法

3.1全局事件总线

  1. //main.js中安装全局事件总线
  2. new Vue({
  3. render: h => h(App),
  4. beforeCreate(){
  5. Vue.prototype.$bus = this //安装全局事件总线
  6. }
  7. }).$mount('#app')
  1. //消息发送方 SendCom.vue
  2. <template>
  3. <div class="send-container">
  4. <!-- SendCom 向组件 GetMsg 发送信息,通过$emit触发自定义事件-->
  5. <button @click="sendMsg">发送消息</button>
  6. </div>
  7. </template>
  8. <script>
  9. export default {
  10. methods:{
  11. sendMsg(){
  12. this.$bus.$emit('eventB','hello')
  13. }
  14. }
  15. }
  16. </script>
  1. //消息接收方 GetMsg.vue
  2. <template>
  3. <div class="get-msg-container">
  4. </div>
  5. </template>
  6. <script>
  7. export default {
  8. mounted() {
  9. console.log(this);
  10. this.$bus.$on('eventB', (data) => {
  11. console.log(`我是事件接受方Demo2,我收到了数据${data}`);
  12. });
  13. },
  14. beforeDestroy() {
  15. this.$bus.$off('eventB') //在使用完后将事件解绑
  16. }
  17. };
  18. </script>

3.2消息订阅与发布

消息订阅与发布在原生js下实现比较复杂,这里使用第三方库pubsub-js,通过npm i pubsub-js安装。

  1. //消息订阅者(接收方) Subscribe.vue
  2. <template>
  3. <div class="subscribe">
  4. </div>
  5. </template>
  6. <script>
  7. import pubsub from 'pubsub-js'
  8. export default {
  9. mounted(){
  10. this.pubId = pubsub.subscribe('message',(msgName,data)=>{
  11. console.log(`我收到了消息${msgName},内容是${data}`);
  12. })
  13. },
  14. beforeDestroy(){
  15. pubsub.unsubscribe(this.pubId)
  16. }
  17. }
  18. </script
  1. //消息发布者(发送方) Publish.vue
  2. <template>
  3. <div class="publish">
  4. <button @click="sendMsg">点击发送</button>
  5. </div>
  6. </template>
  7. <script>
  8. import pubsub from 'pubsub-js'
  9. export default {
  10. methods:{
  11. sendMsg(){
  12. pubsub.publish('message','这是订阅的消息')
  13. }
  14. }
  15. }
  16. </script>

总结

本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注w3xue的更多内容!

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号