美文网首页
[Vue]组件之间如何通信?

[Vue]组件之间如何通信?

作者: 是苏菇凉呀 | 来源:发表于2020-04-02 22:49 被阅读0次

    组件通信可以大致分为两种情况,父子组件之间的通信和非父子组件之间的通信,下面来分别介绍

    一、父子组件之间的通信

    1. props (父组件通过 props 向子组件传递数据)

    通过 props 向子组件传递 postTitle 的值

    子组件中

    Vue.component('blog-post', {
      props: ['postTitle'],
      template: '<h3>{{ postTitle }}</h3>'
    })
    

    父组件中

    <blog-post post-title="hello!"></blog-post>
    
    2. $emit (子组件向父组件传递数据)

    通过 $emit 触发父组件中的 sayHi 事件并将 message 的值 传递给父组件

    子组件中

    <template>
       <button @click="$emit('sayHi',message)">按钮</button>
    </template>
    
    <script>
      export default {
        name: 'HelloWorld',
        data() {
          return {
            message: "everyone"
          }
        }
      }
    </script>
    

    父组件中

    <template>
      <HelloWorld @sayHi="sayHi"></HelloWorld>
    </template>
    
    <script>
    import HelloWorld from './components/HelloWorld.vue'
    
    export default {
      name: 'App',
      components: {
        HelloWorld
      },
      methods: {
        sayHi(val){
          alert('hi' + val)
        }
      }
    }
    </script>
    
    3. $children (获取子组件中的数据)

    父组件中通过 $children 获取到子组件中 message 的值

    注意:$children 的值是一个数组

    子组件中

    <template>
      <div>我是子组件</div>
    </template>
    
    <script>
    export default {
      name: 'HelloWorld',
      data(){
        return {
          message: "hi,everyone"
        }
      }
    }
    </script>
    

    父组件中

    <template>
      <div id="app">
        <div>{{childrenMessage}}</div>
        <HelloWorld/>
      </div>
    </template>
    
    <script>
    import HelloWorld from './components/HelloWorld.vue'
    
    export default {
      name: 'App',
      components: {
        HelloWorld
      },
      mounted(){
        // 获取子组件中的 message 的值
        this.childrenMessage = this.$children[0].message;
      }
    }
    </script>
    
    4. $parent (获取父组件中的数据)

    将3中的例子反过来,通过 $parent 从父组件中获取 message 的值

    注意:$parent 的值是一个对象

    子组件中

    <template>
      <div>{{parentMessage}}</div>
    </template>
    
    <script>
    export default {
      name: 'HelloWorld',
      mounted(){
       this.parentMessage = this.$parent.message
      }
    }
    </script>
    

    父组件中

    <template>
      <div id="app">
        <div>我是父组件</div>
        <HelloWorld/>
      </div>
    </template>
    
    <script>
    import HelloWorld from './components/HelloWorld.vue'
    
    export default {
      name: 'App',
      components: {
        HelloWorld
      },
      data(){
        return{
          message: "hi,everyone",
        }
      }
    }
    </script>
    
    5. ref

    ref 用来给元素或者子组件注册引用信息,引用信息将会注册在父组件的 $refs 对象上,如果在普通的 DOM 元素上使用,引用指向的就是 DOM 元素,如果用在子组件上,引用就指向组件实例

    子组件中

    <template>
      <div class="hello">我是子组件</div>
    </template>
    
    <script>
    export default {
      name: 'HelloWorld',
      data(){
        return {
          message: "hi,everyone",
        }
      }
    }
    </script>
    

    父组件中

    <template>
      <div id="app">
        <div>{{childrenMessage}}</div>
        <HelloWorld ref="helloWorld"/>
      </div>
    </template>
    
    <script>
    import HelloWorld from './components/HelloWorld.vue'
    
    export default {
      name: 'App',
      components: {
        HelloWorld
      },
      mounted(){
        //通过this.$refs.helloWorld获取到子组件实例
        this.childrenMessage = this.$refs.helloWorld.message;
      },
      data(){
        return {
          childrenMessage: ''
        }
      }
    }
    </script>
    

    二、非父子组件之间的通信

    1. provide / inject

    provide / inject 要一起使用,他可以在一个祖先组件中向其所有的子孙后代组件中注入一个依赖,也就是在祖先组件中通过 provide 提供一个变量,然后在他所有的子孙后代组件中 通过 inject 来注入变量

    官网的一个示例

    // 父级组件提供 'foo'
    var Provider = {
      provide: {
        foo: 'bar'
      },
      // ...
    }
    
    // 子组件注入 'foo'
    var Child = {
      inject: ['foo'],
      created () {
        console.log(this.foo) // => "bar"
      }
      // ...
    }
    
    2. EventBus

    EventBus 又称为事件总线,在 Vue 的组件中可以将事件通过 $emit() 发送给 EventBus,然后其他组件通过 $on() 来监听这个事件,以达到组件之间的数据通信

    展示一个兄弟组件 showMessage 和 updateMessage之间通过 EventBus 传递信息的实例

    创建一个 event-bus.js

    import Vue from 'vue';
    //创建EventBus
    export const EventBus = new Vue();
    
    

    App.vue中

    <template>
      <div id="app">
        <ShowMessage></ShowMessage>
        <UpdateMessage></UpdateMessage>
      </div>
    </template>
    
    <script>
    import ShowMessage from './components/showMessage.vue'
    import UpdateMessage from './components/updateMessage.vue'
    
    export default {
      name: 'App',
      components: {
        ShowMessage,
        UpdateMessage
      }
    }
    </script>
    

    showMessage.vue中

    <template>
      <div>{{message}}</div>
    </template>
    <script>
      import { EventBus } from "../event-bus";
      export default {
        name: "showMessage",
        mounted(){
          //监听事件
          EventBus.$on("updateMessage",(value)=>{
            this.message = value;
          })
        },
        data(){
          return {
            message: 'hello'
          }
        }
      }
    </script>
    

    updateMessage.vue中

    <template>
      <button @click="updateMessage">更新消息</button>
    </template>
    <script>
      import { EventBus } from "../event-bus";
      export default {
        name: "updateMessage",
        data(){
          return {
            newMessage: "新消息"
          }
        },
        methods: {
          updateMessage(){
            //向EventBus发送事件
            EventBus.$emit("updateMessage",this.newMessage)
          }
        }
      }
    </script>
    

    相关文章

      网友评论

          本文标题:[Vue]组件之间如何通信?

          本文链接:https://www.haomeiwen.com/subject/yvhgyhtx.html