关于组件之间通信的几种方法
首先先看一张关系图
根据组件之间关系讨论组件通信最为清晰有效
父子组件
– props / $emit / $parent / ref / $attrs
兄弟组件
– $parent / $root / eventbus / vuex
跨层级关系
– eventbus / vuex / provide + inject
1.props - 父组件向子组件中传递数据
父组件
<template>
<div id="app">
<HelloWorld msg="Welcome to Your Vue.js App"/>
</div>
</template>
子组件
<template>
<div>{{ msg }}</div>
</template>
<script>
export default {
props: {
msg: {
type: String,
default: ''
}
},
data() {
return {}
}
}
</script>
2.$emit - 子组件向父组件传递数据
父组件
<template>
<div id="app">
<HelloWorld @someData="getData" msg="Welcome to Your Vue.js App" @click=""/>
</div>
</template>
<script>
import HelloWorld from './components/HelloWorld.vue'
export default {
name: 'App',
components: {
HelloWorld
},
methods: {
getData(data) {
console.log(data)
}
}
}
</script>
子组件
<template>
<div @click="clickMsg">{{ msg }}</div>
</template>
<script>
export default {
props: {
msg: {
type: String,
default: ''
}
},
data() {
return {}
},
methods: {
clickMsg() {
this.$emit('someData','一些数据')
}
}
}
</script>
3. $parent 访问父实例 / $children 访问子实例(要注意边界问题 )
4. ref 获取指定的组件实例(如果是DOM元素,会直接获取DOM元素)
父组件
<template>
<div id="app">
<HelloWorld ref="HelloWorld" @someData="getData" msg="Welcome to Your Vue.js App" @click=""/>
</div>
</template>
<script>
import HelloWorld from './components/HelloWorld.vue'
export default {
name: 'App',
components: {
HelloWorld
},
methods: {
getData(data) {
console.log(data)
},
getRef() {
console.log(this.$refs.HelloWorld.list);
}
}
}
</script>
5. $attrs 继承所有的父组件属性
父组件
<template>
<div id="app">
<HelloWorld msg="Welcome to Your Vue.js App" :list="[]" :obj="{}"/>
</div>
</template>
子组件
<template>
<div >
<div>msg:{{ $attrs.msg }}</div>
<div>list:{{ $attrs.list }}</div>
<div>obj:{{ $attrs.obj }}</div>
</div>
</template>
<script>
export default {
data() {
return {
}
},
methods: {
}
}
</script>
6.$root 获取根组件的实例 ( 疑问: this和 this. $root的区别)
7.eventbus
初始化
import Vue from 'vue'
export const EventBus = new Vue()
发送事件
<template>
<div>
<button @click="sendOut">发送事件</button>
</div>
</template>
<script>
import {EventBus} from './event-bus.js'
export default {
data(){
return{
}
},
methods:{
sendOut(){
EventBus.$emit('add', '一些数据')
}
}
}
</script>
接收事件
<script>
import { EventBus } from './event-bus.js'
export default {
data() {
return {
}
},
mounted() {
EventBus.$on('add', param => {
console.log(param) // 接收到数据
})
},
destroyed() {
EventBus.$off('add', {}) // 移除监听
}
}
</script>
8.vuex
9. provide + inject 父组件向子孙组件传递数据
父组件
<template>
<div id="app">
<HelloWorld />
</div>
</template>
<script>
import HelloWorld from './components/HelloWorld.vue'
export default {
name: 'App',
provide() {
return {
msg: '注入一些数据'
}
},
components: {
HelloWorld
},
data() {
return {
}
}
}
子孙组件
<template>
<div >{{ msg }}</div>
</template>
<script>
export default {
inject: ['msg'],
data() {
return {
}
},
methods: {
}
}
</script>