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

2020-04-02  本文已影响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>
上一篇下一篇

猜你喜欢

热点阅读