vue组件化(二)-有关父子组件的通信

父到子组件的通信

子组件是不能引用父组件或者vue实例的数据的。但是在开发中,往往一些数据确实需要从上层传递到下层,比如在一个页面中,我们从服务器请求到了很多的数据。其中一部分数据,并非是我们整个页面的大组件来展示的,而是需要下面的子组件进行展示。这个时候,我们并不会让子组件再次发送一个网络请求,而是直接让大组件(父组件)将数据传递给小组件(子组件)

如何进行父子组件之间的通信呢?

①通过props向子组件传递数据

②通过事件向父组件发送消息

<body>
  <div id="app">
    <!-- 在组件中需要绑定子父组件的信息 -->
          <!-- 注意这里的驼峰命名法不适用,需要改成- -->
    <cpn :cmovies="movies" :cmessage="message"></cpn>
    <cpn :cmovies="movies"></cpn>  
    <!-- 显示aaaa -->
    <cpn :cmessage="message"></cpn>
    
  </div>
</body>

<!-- //模板 -->
<template id="cpn">
      <!-- 注意这里需要根元素 -->
  <div>
    <ul>
      <li v-for="item in cmovies">{{item}}
      </li>
    </ul>
    <h2>{{cmessage}}</h2>
  </div>

</template>

<!-- 子父组件通过props传递数据 -->
<script src="../js/vue.js"></script>
<script>

  // 注册组件的信息
  const cpn = {
    template:'#cpn',  //与模板进行绑定


    //一、通过数组父向子传递数据,少用
    // props:['cmovies','cmessage'],
    
    //二、通过对象父向子传递数据
    props:{

      //1 少用
      // cmovies:Array,
      // cmessage:String,

      //2.对象形式多用
      cmovies:{
        type:Array,
        //如果类型是数组或者对象,默认值必须是一个函数,否则报错
        default(){
          return []
        },
        // required:true,
        //required 为true 组件必须v-bind传值 不然就会报错
      },

      cmessage:{
        type:String,
        default:'aaaaa',
        // required:true,
        //required 为true 组件必须v-bind传值 不然就会报错
      }
    },
    data(){
      return {}
    },
    methods:{}
  }

// 创建vue实例,将组件信息注册放入
  const app = new Vue({
    el:'#app',
    data:{
      movies:['111','222','333'],
      message:'你好'
    },
    components:{
      'cpn':cpn
    }
  })
</script>

经过演示,发现子组件中,默认无法访问到父组件中的data上的数据和 methods 中的方法

子组件中的 data 数据,并不是通过 父组件传递过来的,而是子组件自身私有的

组件中的所有 props 中的数据,都是通过父组件传递给子组件的

子到父组件的通信

props用于父组件向子组件传递数据,还有一种比较常见的子组件传递数据或事件到父组件中。

这时我们需要使用自定义事件来完成。

当子组件需要向父组件传递数据时就要用到自定义事件了。我们之前学习的v-on不仅仅可以用于监听DOM事件,也可以用于组件间的自定义事件。

流程:①在子组件中用**$emit()来触发事件 ②在父组件中,通过v-on来监听**子组件事件

<!-- 父组件模板 -->
<body>
  <div id="app">
    <!-- 监听子组件发射的事件 -->
    <!-- 监听的事件是子组件在$emit中设置的事件名称 -->
    <cpn @itemclick="cpnclick"></cpn>
  </div>
</body>

<!-- 子组件模板 -->
<template id="cpn">
  <!-- 注意这里需要根元素 -->
  <div>
    <button v-for="item in categories" @click='btnclick(item)'>{{item.name}}</button>
  </div>
</template>


<script src="../js/vue.js"></script>
<script>
  const cpn = {
    template:'#cpn',
    data(){
      return {
        categories:[
          {id:'aaa',name:'热门推荐'},
          {id:'bbb',name:'手机数码'},
          {id:'ccc',name:'家用家电'},
          {id:'ddd',name:'电脑办公'},
        ]
      }
    },
    methods:{
      btnclick(item){
        //子组件发射(包含点击事件名称和想传入的数据/对象本身)
        this.$emit('itemclick',item)
      }
    }
  }

  const app = new Vue({
    el:'#app',
    data:{
    },
    components:{
      'cpn':cpn
    },
    methods:{
      cpnclick(item){  //传入子组件给的数据
        console.log(item.name);//可以利用子组件的数据了
      }
    }
  })
</script>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值