Vue组件间数据交互-父传子,子传父以及兄弟组件传值

1 父组件向子组件传值

1.1 基本用法
  • 介绍

在这里插入图片描述

  • 组件定义时,接收数据

    • 接收数据是通过props属性,在组件定义的第二个参数对象中增加props
    • props,是一个数组,数组中就是接收的传递过来的值的属性名
      • 比如[‘title’],那么title就接收使用组件时的title属性传递的值
    • 然后在template中就可以直接把title当成属性使用:{{title}}
  • 组件使用时,传递数据,传递有两种方式:

    • 第一种:title=“xxx”,值是固定的
    • 第二种::title=“title”,属性绑定,title属性绑定数据属性title,数据属性title是变化的
  • 理解:父组件向子组件传值?

    • 这里其实是,在组件使用时通过属性传递给组件定义内
    • menu-item就是父组件而menu-item的模板内容中的div是子组件
  • 代码:

<body>
  <div id="app">
    <div>{{pmsg}}</div><!--差值表达式,直接输出data属性pmsg的值-->
      <!--组件使用:传递title数据-->
    <menu-item title='来自父组件的值'></menu-item>
    <!--传递title=ptitle和content='hello'-->
    <menu-item :title='ptitle' content='hello'></menu-item>
     <!--title用了属性绑定,是因为ptitle是data的属性。
		content并没有用属性绑定,是因为hello就是一个字符串
	-->
  </div>
  <script type="text/javascript" src="js/vue.js"></script>
  <script type="text/javascript">
    /*
      父组件向子组件传值-基本使用
    */
    Vue.component('menu-item', {
      props: ['title', 'content'],//接收title属性值,content属性值
      data: function() {
        return {
          msg: '子组件本身的数据'
        }
      },
      //msg是组件自己的数据,title和content是接收的数据
      template: '<div>{{msg + "---" + title + "---" + content}}</div>'
    });
    var vm = new Vue({
      el: '#app',
      data: {
        pmsg: '父组件中内容',
        ptitle: '动态绑定属性'
      }
    });
  </script>
</body>
1.2 分析
  • 父组件向子组件传递数据分析图:
    在这里插入图片描述

2 子组件向父组件传值

2.1 基本用法
  • 介绍:
    在这里插入图片描述

  • 子组件传递信息:触发事件(第一步中的button就是子组件,是menu-item中template的内容)

    • $emit(“自定义事件名”):触发自定义事件($emit是Vue实例的方法)

    • emit:发出,发射,[iˈmɪt]

  • 父组件接收信息:绑定事件(第二步中的menu-item就是父组件)

    • v-on:自定义事件名,绑定事件
    • 只要通过v-on绑定一个自定义事件,Vue实例身上就有这个自定义事件,就可以通过$emit触发
  • 理解

    • 这里其实并没有传递数据,而是通过子组件触发事件,和父组件绑定事件来间接执行逻辑
      • 如果想传递数据,子组件触发事件时需要传递参数(看4.2.2)
    • 一句话总结:子组件向父组件传值:是通过由子组件触发父组件绑定的事件来完成的
  • 步骤:

    • 定义组件时,在子组件中通过点击事件触发父组件绑定的事件
      • 通过$emit(‘父组件事件名’)来触发
    • 使用组件时,父组件绑定事件
      • 组件绑定事件的事件处理程序,可以是vue的methods
  • 案例需求:通过子组件按钮点击之后,通知父组件,让div的文字变大

  • 案例代码:关键思路看如下注释中的1,2,3,4,5…

<body>
  <div id="app">
    <!--5.div样式绑定fontSize(一旦fontSize改变,这里就会改变)-->
    <div :style='{fontSize: fontSize + "px"}'>{{pmsg}}</div>
    <!--6.整个过程:
		点击了子组件的按钮之后,触发enlarge-text事件,父组件监听到之后,调用handle方法
		handle方法,改变fontSize数据的值,影响到上边div的字体大小
	-->
    <!--3.父组件绑定事件,触发handle方法-->
    <menu-item :parr='parr' @enlarge-text='handle'></menu-item>
  </div>
  <script type="text/javascript" src="js/vue.js"></script>
  <script type="text/javascript">
    /*
      子组件向父组件传值-基本用法
      props传递数据原则:单向数据流
    */
    //1. 定义组件menu-item
    Vue.component('menu-item', {
      props: ['parr'],
      template: `
        <div>
          <ul>
            <li :key='index' v-for='(item,index) in parr'>{{item}}</li>
          </ul>
		 <!--子组件中,可以直接操作父组件menu-item的数据parr-->
		 <button @click='parr.push("lemon")'>点击增加</button>
	     <!--2.子组件通过触发父组件绑定的事件,来传递数据-->
          <button @click='$emit("enlarge-text")'>扩大父组件中字体大小</button>
        </div>
      `
    });
    var vm = new Vue({
      el: '#app',
      data: {
        pmsg: '父组件中内容',
        parr: ['apple','orange','banana'],
        fontSize: 10
      },
      methods: {
        //4.定义handle方法:改变fontSize大小
        handle: function(){
          // 扩大字体大小
          this.fontSize += 5;
        }
      }
    });
  </script>
</body>
  • 子组件向父组件传递数据分析
    在这里插入图片描述

3 兄弟组件之间数据交互

  • 介绍:
    在这里插入图片描述 - 兄弟组件传递数据,不再使用props和自定义事件

    • 而是通过事件中心
    • 其实类似自定义事件,都是通过触发事件和监听事件来实现
  • 上述步骤详述:

    1. 单独定义一个Vue实例,作为事件中心对象(之前的定义el,data,methods的Vue实例也需要有)

    2. 在兄弟组件A中:通过$on方法监听事件(添加事件)

    <body>
      <div id="app">
        <div>父组件</div>
        <div>
          <!--5. 单独定义一个按钮,销毁事件-->
          <button @click='handle'>销毁事件</button>
        </div>
        <test-tom></test-tom>
        <test-jerry></test-jerry>
      </div>
      <script type="text/javascript" src="js/vue.js"></script>
      <script type="text/javascript">
        /*
          兄弟组件之间数据传递
        */
        //1.提供事件中心
        var hub = new Vue();//专门用于操作事件的Vue实例
          
        //2.定义tom组件:有显示数据的div和按钮
        Vue.component('test-tom', {
          data: function(){
            return {
              num: 0//组件中有自己的数量变量
            }
          },
          template: `
            <div>
              <div>TOM:{{num}}</div>
              <div>
                <button @click='handle'>点击</button>
              </div>
            </div>
          `,
          methods: {
            handle: function(){
              hub.$emit('jerry-event', 2);//点击之后,触发jerry-event事件,并传递数据2
            }
          },
          //3. 在当前组件挂载之后,给事件中心hub添加事件tom-event
          mounted: function() {
            // 监听事件
            hub.$on('tom-event', (val) => {//事件是让num值变化
              this.num += val;
            });
          }
        });
         //jerry组件:有显示数据的div和按钮
        Vue.component('test-jerry', {
          data: function(){
            return {
              num: 0//组件中有自己的数量变量
            }
          },
          template: `
            <div>
              <div>JERRY:{{num}}</div>
              <div>
                <button @click='handle'>点击</button>
              </div>
            </div>
          `,
          methods: {
            //4. 通过jerry组件中的按钮,触发hanle,然后触发兄弟组件tom的事件,并且传递数据1
            handle: function(){
              // 触发兄弟组件的事件
              hub.$emit('tom-event', 1);
            }
          },
          mounted: function() {
            // 监听事件
            hub.$on('jerry-event', (val) => {
              this.num += val;
            });
          }
        });
        var vm = new Vue({//原来的Vue实例
          el: '#app',
          data: {
            
          },
          methods: {
            handle: function(){
              hub.$off('tom-event');//移除事件
              hub.$off('jerry-event');
            }
          }
        });
      </script>
    </body>
    
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值