一边学习前端,一边通过博客的形式自己总结一些东西,当然也希望帮助一些和我一样开始学前端的小伙伴。
如果出现错误,请在评论中指出,我也好自己纠正自己的错误
author: thomaszhou
vue组件间通信
- 父子组件之间-数据通信
- 父子组件之间-方法通信
- 兄弟组件之间-通信
写Vue项目的过程中,组件之间的通信非常频繁,像父子通信的props和$emit方法是很多人都知道的,当然我这里肯定也要提一提嘛~但是兄弟间的通信方法大部分都是提倡构建evenBus
父子组件之间-数据通信
父组件向子组件传递(props)
- 父组件引用子组件的时候利用v-bind去绑定mseeage,传递给子组件(对应就是msg)
- 子组件要创建props选项,注册传递的msg值,就可以直接使用msg这个值了
父组件
<template>
<child :msg="message"></child>
</template>
<script>
import child from './child.vue';
export default {
components: {
child
},
data () {
return {
message: 'father message';
}
}
}
</script>
子组件vue
<template>
<div>{{msg}}</div>
</template>
<script>
export default {
props: {
msg: {
type: String,
required: true
}
}
}
</script>
父组件直接获取子组件的数据(this.$refs.ref的名字.变量
)
// 假设我们要获取子组件<son></son>的数据target
// 第一:子组件son要设置ref
<son ref="sonComponent"></son>
// 第二:用下面的语句去获取,修改子组件的值
console.log(this.$refs.sonComponent.target); // 取值
this.$refs.sonComponent.target = '1'; // 修改值
子组件向父组件传递数据(emit)+ 子组件调用父组件方法
子组件通过
$emit
触发父组件的方法(通过@add-parent-total="addTotal将 add-parent-total 和 addTotal联系起来)
- 子组件通过
$emit
触发add-parent-total事件 - 父组件在引入组件时设置,
@add-parent-total="addTotal"
,其中addTotal是父组件的方法
//html
<child @add-parent-total="addTotal"></child>
//根组件
var vm = new Vue({
el: "#app",
data:{
total: 0
},
components: {
Child
},
methods: {
//根组件中子组件改变根组件的方法
addTotal(args){
this.total++
console.log(args);//args就是传递值带的的参数
}
}
})
//定义子组件
var Child = {
//获取data()中的数据,并添加一个点击事件
template: `<button @click="addCounter">{{counter}}</button>`,
data(){
return {
counter: 0
}
},
methods:{
addCounter(){
this.counter++;
//自定义事件$emit传回根组件,同时调用根组件方法
this.$emit('add-parent-total',args)
}
}
}
父子组件之间-方法通信
-
父组件 --> 子组件:
- ==引用子组件 并
起名ref="demo1"
然后 通过this.$refs.demo1.getUser(elem)
调用子组件中的getUser方法并传参(elem)==
- ==引用子组件 并
-
子组件 --> 父组件:
- 方法一:子组件直接用
this.$parent.xxxx
这样直接调用父组件的方法。 - 方法二: 引用子组件并用
v-on 来做个监测的函数来检测
;子组件通过this.$emit('方法名',传递的参数)
来调用父组件的方法
- 方法一:子组件直接用
-
父组件代码
// 调用子组件
<son-demo ref="demo1" @sonname="son1"></son-demo> <!--一些要写明的属性-->
import sonDemo from '../components/sondemo.vue'
export default {
data() {
return {
sondemoVal: 'test'
};
},
mounted() {
this.$refs.demo1.getUser(this.sondemoVal); // 父 --> 子的方法
},
methods: {
son1(temp) {
console.log(`这里是父组件的方法son1:${temp}`);
}
},
}
- 子组件
<template>
<div>{{msg}}</div>
</template>
export default {
methods: {
getUser(temp) {
console.log('sondemo--->'+temp);
}
},
mounted() {
// this.$parent.son1('son'); 子 --> 父的方法一:
this.$emit('sonname','son'); // 子 --> 父的方法二:
// 'son'是传递的参数
}
}
兄弟组件之间-通信(或者非兄弟,非父子组件)
-
适用于兄弟组件的情况 和 非父子,非兄弟组件的情况
- 方法一(使用简单的情况):自己创建一个事件总线eventBus来作为通信的桥梁(也适用于非父子,非兄弟组件的情况)
- 方法二(程序比较复杂的情况):那就用Vuex(也适用于非父子,非兄弟组件的情况)
-
方法三⚠️:如果仅仅是某一个页面,或者很少的页面有兄弟组件A,B(非兄弟组件不适用)通信的问题,推荐:**将该部分逻辑写在父组件内,通过this.emit()发送到父组件进行逻辑的编写,然后通过
this.refs.子组件name
(要自己提前设置),来取到另一个子组件的值,具体如下
举例: 子组件A 要修改 子组件B 的time值??? <son1 refs="son1" @changeElem = "change"></son1> <son2 refs="son2"></son2> 思路: 子组件son1:click触发一个$emit("changeElem", val);要将son2组件的time修改为val 父组件: 通过@changeElem = "change"接收事件,编写change方法 change(elem) { this.$refs.son2.time = elem; }
这里主要讲方法一
vue2中废弃了broadcast广播和分发事件的方法。
所以在vue2.0中可以通过实例一个vue实例Bus作为媒介,要相互通信的兄弟组件之中,都引入Bus,之后通过分别调用Bus事件触发和监听来实现组件之间的通信和参数传递
- 创建一个eventBus.js作为桥梁(例子直接把js文件放在与组件同一个目录下),内容如下:
import Vue from 'vue'
export default new Vue;
- 创建两个子组件,son1.vue 和 son2.vue
// son1.vue 发送值
<template>
<div class="ex">
<button @click="sendMsg">点击我传送值</button>
</div>
</template>
<script>
import Bus from './eventBus' // 引入eventBus文件
export default {
data () {
return {
}
},
methods: {
sendMsg() {
Bus.$emit('msg', '我要传给兄弟组件们,你收到没有');//传递msg,第二个参数就是msg的值
}
}
}
</script>
// son2.vue 接受值
<template>
<div class="ex">
{{message}}
</div>
</template>
<script>
import Bus from './eventBus' // 引入eventBus文件
export default {
data () {
return {
message: '变化前'
}
},
mounted() {
let self = this;
// 利用$on来监听msg值
Bus.$on('msg', (e) => {
self.message = e;
console.log(`传来的数据是:${e}`);
});
}
}
</script>