全局注册的组件:
<body>
<div id="app">
<one></one>
<two></two>
</div>
<script type="text/javascript">
var bus = new Vue();
Vue.component('one', {
template: '<p @click="click">我是一个组件</p>',
props: {
ms: {
type: Number,
default: 0
}
},
methods: {
click() {
this.ms++;
console.log(this.ms)
bus.$emit('setmsg', this.ms)
}
}
});
Vue.component('two', {
template: '<p>我是另一个组件{{msg}}</p>',
props: {
msg: {
type: Number
}
},
created() {
var _this = this;
bus.$on('setmsg', function(ms) {
_this.msg = ms;
})
}
})
var app = new Vue({
el: "#app"
})
</script>
</body>
1、新建一个名为bus的vue实例,作为通信的媒介。
2、新建两个组件,one 和 two。
3、one组件中,添加点击事件,每次点击时,通过$emit把值发给bus,用白话来说,就是告诉bus,我这有个值this.ms先给你,如果谁需要接收这个值,需要用setmsg这个名称来接收。
4、组件two中,添加一个在组件创建时变执行的方法,关于什么时候执行方法,请了解“vue生命周期钩子”相关内容。
5、方法中,通过$on来告诉bus,我想接收刚才给你的值,$on的第二个参数function的参数ms,是任意命名的,因为无论是什么名字,他都代表刚才bus接收到的this.ms。
6、在$on之前,需要var _this = this',这么做是为了让this指向自己,如果不这么写,那么在$on中使用this.msg = ms,那么this指向的就是bus而不是接收数值的组件了。
局部注册的组件:
<body>
<div id="app1">
<one></one>
</div>
<div id="app2">
<two></two>
</div>
<script type="text/javascript">
var hub = new Vue()
var vm1 = new Vue({
el:'#app1',
components:{
one:{
template:'<p @click="click">我是一个组件</p>',
props:{
ms:{
type:Number,
default:0
}
},
methods:{
click(){
this.ms++;
console.log(this.ms)
hub.$emit('setmsg',this.ms)
}
}
}
}
})
var vm2 = new Vue({
el:'#app2',
components:{
two:{
template:'<p>我是另一个组件{{ms2}}</p>',
props:{
ms2:{
type:Number
}
},
created(){
var _this = this;
// console.log(this)
hub.$on('setmsg',function(ms){
_this.ms2 = ms;
// console.log(this)
})
}
}
}
})
</script>
</body>
实现方式几乎一样,只不过两个组件都是局部注册的,需要在不同的vue实例中显示,但是不影响互相通信。
我在本例中,没有把媒介命名为bus而是Hub,意思是媒介的命名是随意的。
点击事件触发通信
可能你还不太了解生命周期钩子,所以我修改了一下实例2中的代码,使用点击事件来触发。
代码如下:
<body>
<div id="app1">
<one></one>
</div>
<div id="app2">
<two></two>
</div>
<script type="text/javascript">
var hub = new Vue()
var vm1 = new Vue({
el:'#app1',
components:{
one:{
template:'<p @click="click">我是一个组件</p>',
props:{
ms:{
type:Number,
default:0
}
},
methods:{
click(){
this.ms++;
console.log(this.ms)
hub.$emit('setmsg',this.ms)
}
}
}
}
})
var vm2 = new Vue({
el:'#app2',
components:{
two:{
template:'<p @click="click">我是另一个组件{{ms2}}</p>',
props:{
ms2:{
type:Number
}
},
methods:{
click(){
var _this= this;
hub.$on('setmsg',function(ms){
_this.ms2 = ms;
})
}
}
}
}
})
</script>
</body>
我把数据接收放到了methods的方法中,运行后,直接点击组件1 无效果。
刷新页面,先点击组件2,再点击组件1,效果实现,因为传递数据是通过点击事件来启动的。
网友评论