Vue学习--组件通信

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

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

    
      
    Vue.component('com',{
        template:'#com',
        props:['msg']        //变量名要用引号引起
    });

        就像函数调用过程一样,在调用组件时通过msg='父组件信息'将实参(一个字符串)传递给形参msg,在被调组件内通过props声明形参,并可以在被调组件com内使用该参数msg。

      结果如图,组件显示出来自父组件的不同信息:

        

        注意:1、html不区分大小写,因此不支持使用驼峰命名法传递属性参数,例如将msg换为myMsg将无法渲染,需要将html属性中的myMsg换为短横线分割法:my-msg,而js中可以不必修改。

                  2、prop是单向绑定,父组件值的更新会导致子组件值改变,反之则不会,因此要避免在子组件中修改、处理props中的值。

        

    
    Vue.component('com',{
        template:'#com',
        props:['myMsg']
    });     

3、可以为组件 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:

    

        在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加一。

    

一共被点击{{allCount}}

    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++;
            }
        }
    });

    结果如图:

   Vue学习--组件通信_第1张图片

子组件内的事件触发器不只是发送信息标志,还可以向父组件传递载荷数据,在父组件的事件处理函数中接收数据参数,例如:

//子组件发射载荷数据
this.$emit('message', { message: this.message });
//父组件监听message,并调用handleMessage函数接收playload参数


handleMessage: function (payload) {    //父组件通过playload接收子组件message数据
      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();
});

你可能感兴趣的:(WEB)