您的位置:首页 > 产品设计 > UI/UE

Vue学习--组件通信

2018-03-11 19:33 375 查看
        组件实例的作用域是孤立的,这意味着不能并且不应该在子组件的模板内直接引用父组件的数据。但是父子组件之间需要通信:父组件要给子组件传递数据,子组件需要将它内部发生的事情告知给父组件。在 Vue.js 中,父子组件的关系可以总结为 props down, events up :父组件通过 props 向下传递数据给子组件,子组件通过 events 给父组件发送消息。

1、子组件中通过props接收父组件的参数

  
<div id="app">
<com msg="父组件信息1"></com>
<com msg="父组件信息2"></com>
</div>
    <template id="com">
        <div>{{msg}}</div>
    </template>  
Vue.component('com',{
template:'#com',
props:['msg']//变量名要用引号引起
});
        就像函数调用过程一样,调用组件通过msg='父组件信息'将实参(一个字符串)传递给形参msg,在被调组件内通过props声明形参,并可以在被调组件内使用该参数msg。
      结果如图:组件显示出来自父组件的不同信息:
        


        注意:1、html不区分大小写,因此不支持使用驼峰命名法传递属性参数,例如将msg换为myMsg将无法渲染,需要将html属性中的myMsg换为短横线分割法:my-msg,而js中可以不必修改。
                  2、prop是单向绑定,父组件值的更新会导致子组件值改变,反之则不会,因此要避免在子组件中修改、处理props中的值。
<com my-msg="父组件信息1"></com>

<template id="com">
<div>{{myMsg}}</div>
</template>
Vue.component('com',{
template:'#com',
props:['myMsg']
});    
       可以为组件的 prop 指定验证规则。如果传入的数据不符合要求,Vue 会发出警告。此时需要用对象的形式来定义 prop。Vue.component('example', {
props: {
// 基础类型检测 (`null` 指允许任何类型)
propA: Number,
// 多种类型数组
propB: [String, Number],
// 必传且是字符串
propC: {
type: String,
required: true
},
// 数值且有默认值
propD: {
type: Number,
default: 100
},
// 数组/对象的默认值应当由一个工厂函数返回
propE: {
type: Object,
default: function () {
return { message: 'hello' };
}
},
// 自定义验证函数
propF: {
validator: function (value) {
return value > 10
}
}
}
})

2、多层组件嵌套

    在多个组件嵌套时,中间的组件不仅需要接收上层传递给自己的参数,还要接收上层传递给自己子组件的参数。类似与子类继承父类时,构造函数不仅要初始化本类的属性,还要初始化父类的属性。

    注意:1、父组件向子组件传递参数为变量时需要使用绑定。   

             2、 props[]中的变量名、父组件向下传递时标签中的属性名、子组件使用变量时的名字是一致的,例如使用c1_msg的三个地方。

    例如通过父组件parent来接收上层app组件的参数,并传给两个子组件child1与child2:
<div id="app">
<parent p_msg="父组件信息" c1_msg="child1信息" c2_msg="child2信息"></parent>
</div>

<template id="child1">
<div>{{child_msg}}</div>
</template>
<template id="child2">
<div>{{child_msg}}</div>
</template>
<template id="parentDiv">
<div>
{{p_msg}}
<!--向子组件传递参数需要绑定(:)-->
<c1 :child_msg="c1_msg"></c1>
<c2 :child_msg="c2_msg"></c2>
</div>
</template>        在vue中绑定父组件parent,设置其参数props,并在parent中绑定两个子组件,设置props:
let vue=new Vue({
el:'#app',
data:{
},
components:{
'parent':{
template:'#parentDiv',
props:['p_msg','c1_msg','c2_msg'],
components:{
'c1':{
template:'#child1',
props:['child_msg']
},
'c2':{
template:'#child2',
props:['child_msg']
}
}
}
}
});    结果父组件不仅显示了自己的信息,还将信息传递给了两个子组件显示:
    


3、子组件向父组件通信

        由于props是单向绑定,无法使用其向父组件通信。vue中使用自定义事件实现子组件向父组件的数据传递。

        父组件可以使用v-on(缩写为@)来监听子组件触发的事件,当子组件中发射出标志信息后,父组件会调用相应的方法。
    例如分别设置三个按钮组件对自己被点击的次数进行计数,然后父组件对三个子组件被点击的总次数进行计数,当子组件按钮被点击时调用countClick()函数将自己计数count++,同时通过this.$emit()函数父组件发送标志信息emittion。在父组件中用@监听emittion,并调用countAll()函数,使总次数allCount加一。
<div id="app2">
<btn @emittion="countAll()"></btn>
<btn @emittion="countAll()"></btn>
<btn @emittion="countAll()"></btn>
<p>一共被点击{{allCount}}</p>
</div>

<template id="myBtn">
<div>
<button @click="countClick()">按钮被点击{{count}}次</button>
</div>
</template>
let countAll=0;
let vue2=new Vue({
el:'#app2',
data:{
allCount:0
},
components:{
'btn':{
template:'#myBtn',
data (){
return {
count:0
};
},
methods:{
countClick(){
this.count++;
//发射信息标志通知上层事件被触发
this.$emit('emittion');
}
}
}
},
methods:{
countAll(){
this.allCount++;
}
}
});
    结果如图:
  


子组件内的事件触发器不只是发送信息标志,还可以向父组件传递载荷数据,在父组件的事件处理函数中接收数据参数,例如://子组件发射载荷数据
this.$emit('message', { message: this.message });
//父组件监听message,并调用handleMessage函数接收playload参数
<button-message v-on:message="handleMessage"></button-message>
</div>
handleMessage: function (payload) {
this.messages.push(payload.message);
}

4、非父子组件之间通信

       非父子组件之间通过一个vue类Hub实现通信,一个组件在Hub一段发送标志信息及相关数据,另一个组件侦听,一旦检测到标志,就接受数据,并用回掉函数处理:let Hub=new Vue();
Hub.$emit('emittion',data);//发送emittion及data
Hub.$on('emittion',function (data) {//检测到emittion,接收data并处理
handler();
});

    
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: