24.父子组件之间的通信

在开发中,往往一些数据确实需要从上层传递到下层:

  • 比如在一个页面中,我们从服务器请求到了很多的数据;
  • 其中一部分数据,并不是使用整个页面大组件来展示,而是需要下面的子组件
  • 这个时候,并不会在让子组件再次发送一个网络请求,而是直接让大组件(父组件)将数据传递给小组件(子组件)。

如何进行父子组件间的通信呢?Vue官方提到两种方法:

  • 通过props向子组件传递数据
  • 通过事件向父组件发送消息

在下面的代码中,我直接将Vue实例当做父组件,并且其中包含子组件来简化代码。

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

 方式一:字符串数组,数组中的字符串就是传递时的名称。

 方式二:对象,对象可以设置传递时的类型,也可以i设置默认等。

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>

<!--父组件的 html 模板-->
<div id="vue">
  <!--父组件数据 绑定给 子组件的数据定义-->
  <cpn :cmovies ="movies" :cmessage="message"></cpn>
</div>

<!--子组件html模板-->
<template id="childrenHtml">
  <div>
    <ul><li v-for="item in cmovies">{{item}}</li></ul>
    <h2>{{cmessage}}</h2>
  </div>
</template>
<script src="../js/vue.js"></script>
<script>

  //特别注意:当子组件需要引入父组件时,
  //        子组件需要先定义在父组件之前

  // 父传子:props
  // props数据格式:1:字符串数组 2:对象
  const cpnChildren = {
    template: '#childrenHtml',
    props: ['cmovies',"cmessage"],
    data() {
      // 必须 return 一个实例,当然可以 return 一个空
      return{}
    },
    methods: {

    }
  }

  // 父组件
  // 通过 props 向子组件传递数据
  const app = new Vue({
    el: '#vue',
    data: {
      movies: ['java', 'c++', 'python', 'javaScript'],
      message: '你好!华为'
    },
    // 局部注册子组件
    components: {
      cpn :cpnChildren
    }
  });

</script>

</body>
</html>

props写法

    // props写法总结
    props: {

      // 基础的类型检查('null',匹配任何类型)
      propA:Number,

      // 多个可能的类型
      propB:[String,Number],

      // 必填的字符串
      propC:{
        type:Number,
        required:true
      },

      // 带有默认值的数字
      propD:{
        type:Object,

        // 对象或数组默认值必须从一个工厂函数获取
        default:function () {
          return {
            message: 'hello'
          }
        }
      },

      // 自定义验证函数
      propF:{
        validator:function (value) {
          //这个值必须是匹配下列字符串中的一个
          return['success','warning','danger'].indexOf(value) !== -1
        }
      }
    },

通过 $emit 父组件向子组件传递参数

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

<!--父组件模板-->
<div id ="vue">
    <!--其中这个v-on 不仅可以监听默认事件,还可以监听子组件事件-->
    <!--v-on 可以用来@代替-->
    <!--有的不支持驼峰:如果在script中定义了childrenCpn,在html中要用‘-’代替,不然渲染不出来-->
    <!--需要注意的是:组件通信中,@子组件=父组件 -->
    <children-cpn @itemclick="parentclick"></children-cpn>
    <p>{{message}}</p>
</div>

<!--子组件模板-->
<template id="children">
    <div>
       <button v-for="item in categories" @click="itemclick(item)">
           {{item.name}}
       </button>
    </div>
</template>

<!-- 引入vue.js 文件-->
<script src="../js/vue.js"></script>
<script>

    //子组件
    const childrenCpn = {
        template:'#children',
        data(){
            return{
                categories:[
                    {id:'aaa',name:'热门推荐'},
                    {id:'bbb',name:'手机数码'},
                    {id:'ccc',name:'家用家电'},
                    {id:'ddd',name:'电脑办公'},
                    {id:'eee',name:'市场营销'}
                ]
            }
        },
        methods:{
            itemclick(item){
                // 子组件发射:自定义事件
                this.$emit('itemclick',item)
            }
        }

    };

    // 父组件
    const vue = new Vue({
        el:'#vue',
        data:{
            message:'你好啊,华为'
        },
        components: {
            childrenCpn
        },
        methods: {
            parentclick(item){
                console.log(item)
            }
        }
    });

</script>
</body>
</html>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值