Vue组件通讯

1 对于父组件向子组件传递信息, 可以使用props实现.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<!-- 子组件 -->
<template>
<div class="radius" v-bind:style="{borderRadius:radiusNumber+'px'}">
<span>子组件</span>
<left-right-text :info="{text:'子',color:'#fff',bgColor:'red'}"></left-right-text>
</div>
</template>
<script>
export default {
name: 'borderRadius',
props:{
radiusNum:{
type:Number,
default:10
}
},
computed:{
radiusNumber(){
return this.$props.radiusNum
}
}
}
</script>
1
2
3
4
5
6
7
8
// 父组件
import BorderRadius from "../components/circle.vue"
components:{
TopNav,
BorderRadius,
Trident,
leftRightText
}
1
2
3
4
5
6
// 传入变量
data () {
return {
rn:0
}
},
1
2
<!-- 使用子组件 -->
<border-radius :radius-num="rn"></border-radius>
1
2
3
4
5
6
7
8
methods:{
changeBorderRadius(){
this.rn+=10;
if(this.rn > 50){
this.rn = 0;
}
}
},

2 对于子组件向父组件传递信息, 使用this.$emit在子组件内, 触发父组件的自定义事件.

在使用子组件时, 在上面绑定一个自定义事件,事件的名称是eventInParent, 事件处理函数是changeNum.

1
2
<!-- 父组件 -->
<border-radius :radius-num="rn" @eventInParent="changeNum"></border-radius>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
changeNum(paramsFromSun, r, evt){
this.x = evt.offsetX;
this.y = evt.offsetY;
this.num = paramsFromSun;
this.draw(r);
},
draw(r){
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext("2d");
ctx.clearRect(0,0,ctx.canvas.width,ctx.canvas.height);
ctx.beginPath();
ctx.fillStyle = "red";
ctx.arc(50,50,r,0,2 * Math.PI);
ctx.closePath();
ctx.fill();
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<div class="item">
<span>用于显示子组件向父组件传递回来的参数: <b>{{num}}</b></span>
<div class="evtCls">
<div>
<span>offsetX: <b>{{x}}</b></span>
<left-right-text :info="{text:'父',color:'#fff',bgColor:'#FF00CD'}"></left-right-text>
</div>
<div>
<span>offsetY: <b>{{y}}</b></span>
<left-right-text :info="{text:'父',color:'#fff',bgColor:'#FF00CD'}"></left-right-text>
</div>
</div>
<canvas id="canvas" height="100" width="100"></canvas>
<left-right-text :info="{text:'父',color:'#fff',bgColor:'#FF00CD'}"></left-right-text>
</div>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<!-- 子组件 -->
<div class="radius b" @click="changeNumInParent($event)" :style="{backgroundColor:bgC}">
<span>点击向父组件传递信息</span>
<left-right-text :info="{text:'子',color:'#fff',bgColor:'red'}"></left-right-text>
</div>
<div class="radius evtCls">
<div>
<left-right-text :info="{text:'子',color:'#fff',bgColor:'red'}"></left-right-text>
<span>offsetX: <b>{{x}}</b></span>
</div>
<div>
<left-right-text :info="{text:'子',color:'#fff',bgColor:'red'}"></left-right-text>
<span>offsetY: <b>{{y}}</b></span>
</div>
</div>
1
2
3
4
5
6
7
8
9
10
changeNumInParent(e){
this.numInSon += 10;
this.r += 2;
if(this.r > 50) {
this.r = 2;
};
this.x = e.offsetX;
this.y = e.offsetY;
this.$emit("eventInParent", this.numInSon, this.r, e)
}

3 对于非父子组件的通讯, 可使用eventBus实现.

eventBus原理是创建一个空Vue实例, 然后在上面挂载通讯事件, 在挂载事件时, 可以认为这个Vue实例(组件), 是所有组件的父组件, 在触发事件时, 可以认为这个Vue实例, 是所有组件的子组件.

新建一个组件, 在组件元素上绑定点击事件, 用于触发其他组件内的事件.

1
2
3
4
<div class="item" @click="clickChangeOtherComponentColor">
<span>子组件</span>
<left-right-text :info="{text:'子',color:'#000',bgColor:'#F7E788'}"></left-right-text>
</div>
1
2
// 导入事件挂载和触发的载体eventBus;
import Bus from "../utils/eventBus.js";

clickChangeOtherComponentColor事件处理函数代码, 以及一个随机产生十六进制颜色值的函数.

1
2
3
4
5
6
7
8
9
10
11
12
13
sixteen() {
var base = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, "a", "b", "c", "d", "e", "f"];
var baseStr = "#";
for (var i = 0; i < 6; i++) {
var r = Math.floor(Math.random() * 16);
baseStr += base[r];
};
return baseStr;
},
clickChangeOtherComponentColor(){
this.color = this.sixteen();
Bus.$emit("changeColor", this.color);
},

Bus.$emit触发了changeColor的事件, 并传入了一个颜色值.
那么相应的在其他组件中, 应该有这个changeColor的函数, 并对传入的参数加以利用.
在第一个组价内, 导入bus, 并在生命周期的mounted阶段,
在bus上挂载一个changeColor的事件.

1
2
3
4
5
6
import Bus from "../utils/eventBus.js"
mounted(){
Bus.$on("changeColor", (color) => {
this.bgC = color;
});
},

这个事件将传递过来的颜色, 赋值到本组建的变量bgC上, 而bgC被绑定到一个元素的背景色. 这样就实现, 在trident组件内, 改变 circle组件内元素背景色的效果.

1
2
3
4
<div class="radius b" @click="changeNumInParent($event)" :style="{backgroundColor:bgC}">
<span>点击向父组件传递信息</span>
<left-right-text :info="{text:'子',color:'#fff',bgColor:'red'}"></left-right-text>
</div>

4 对于跨路由的组件通讯, 需利用路由跳转的参数传递机制.