组件通信是什么
由于Vue组件中的数据都是相互独立的,无法直接使用和访问其他组件的数据,所以当我们想使用其他组件数据的时候便使用组件通信(组件通信解释指组件和组件之间的数据传递)。
组件关系分类
父子关系
组件A包裹了组件B和组件C,即组件A与组件B、C为父子关系,组件B和C为非父子关系。面对不同的组件关系,使用的组件通信方法也不一样。
1. 父组件通过props向子组件进行数据传递
props就相当于在组件标签身上的属性,并进行传值。
父组件代码:
<template>
<div>
<!--通过给子组件添加属性的方式传值-->
<Son :name1="Myname"></Son>
</div>
</template>
<script>
import Son from './components/Son.vue'
export default {
data(){
return {
Myname:'bro'
}
}
}
子组件代码:
<template>
<div>
使用父组件{{name1}}
</div>
</template>
<script>
export default {
//通过props进行接受数据,属性名必须与传递过来的名一样
props:['name1']
</script>
2. 父组件使用子组件数据
在父组件中,如果想要访问子组件的数据,可以通过在引用子组件时使用 ref
属性并为其命名。通过在父组件中使用 this.$refs.childData
,我们可以获取对子组件实例的引用,从而访问和操作子组件的数据。
this.$nextTick
是Vue.js提供的一个工具方法,用于在DOM更新后执行特定的代码。Vue.js是异步更新DOM的,当数据发生变化时,Vue会将DOM更新放入队列中,然后在一个事件循环周期内异步地处理这个队列。是Vue.js提供的一个工具方法,用于在DOM更新后执行特定的代码。Vue.js是异步更新DOM的,当数据发生变化时,Vue会将DOM更新放入队列中,然后在一个事件循环周期内异步地处理这个队列。
父组件代码:
<template>
<div id="app">
<SonFirst ref="childData"></SonFirst>
<div class="ab">{{ Sondata }}</div>
</div>
</template>
<script>
import SonFirst from './components/SonFirst.vue'
export default {
components: {
SonFirst
},
data () {
return {
Sondata: ''
}
},
created () {
this.$nextTick(() => {
this.getData()
})
},
methods: {
getData () {
console.log(this.$refs.childData.objData)
console.log(this.$refs.childData.myName)
this.Sondata = this.$refs.childData.myName
console.log(this.Sondata)
}
}
}
</script>
<style lang="less">
</style>
子组件代码:
<script>
export default {
data () {
return {
myName: 'hahaha',
objData: {
name: '子组件数据',
time: '2023'
}
}
}
}
</script>
3.子组件利用$emit对父组件进行数据更新
子组件中是不能直接修改父组件中的数据,只有通过$emit发送请求使父组件进行数据更新。子组件通过button按钮触发事件,通过$emit向父组件发送通知。this.$emit('事件名','修改的数据')
子组件代码:
<template>
<div>
<button @click="changeTit">修改tilte</button>
</div>
</template>
<script>
export default {
data () {
return {
}
},
methods: {
changeTit () {
this.$emit('changeTitle', '321')
}
}
}
</script>
<style>
</style>
父组件通过@’子组件的事件名‘="父组件处理函数",子组件传递的数据会在父组件处理函数中存在,之后在父组件处理函数中对父组件的数据进行修改。
父组件代码:
<template>
<div id="app">
<SonFirst @changeTitle="titlechange"></SonFirst>
<div>{{ title }}</div>
</div>
</template>
<script>
import SonFirst from './components/SonFirst.vue'
export default {
components: {
SonFirst
},
data () {
return {
title: '123'
}
},
methods: {
//newTitle为得到的子组件中的数据
titlechange (newTitle) {
this.title = newTitle
}
}
}
</script>
非父子关系
对于非父子的通信,通过使用event bus事件总线,对非父子组件之间,进行简易的消息传递。至于更加复杂的非父子通信场景,推荐使用Vuex进行数据处理。(Vuex的基础使用)
Event Bus就是创建一个组件都能访问到的事件总线。
步骤一
在utils文件夹下创建一个新的EventBus.js文件
import Vue from 'vue'
const Bus = new Vue()
export default Bus
步骤二
在组件A和B中通过调用Bus进行组件数据的通信。
组件A通过Bus.on作为监听的接收方:
<template>
<div class="A">
组件A
<p>{{ text }}</p>
</div>
</template>
<script>
import Bus from '../utils/EventBus'
export default {
data () {
return {
text: ''
}
},
created () {
// 作为接收数据的一方,监听B组件点击按钮时触发的bus事件
Bus.$on('getText', (msg) => {
this.text = msg
})
}
}
</script>
<style scoped>
.A{
width: 200px;
height: 200px;
border: 3px;
}
</style>
组件B通过事件的方式触发$emit进行数据传递:
<template>
<div class="B">
组件B
<button @click="sendText">事件触发</button>
</div>
</template>
<script>
import Bus from '../utils/EventBus'
export default {
methods: {
sendText () {
// 此处的getText需要与接受方的事件名一致
Bus.$emit('getText', '组件A接收成功')
}
}
}
</script>
<style scoped>
.B{
width: 200px;
height: 200px;
border: 3px;
}
</style>
此处B组件作为的事件发送方是面向所有通过Bus监听getText的组件。