[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>