Vue学习(三十一)——组件间的数据交互

一、父组件向子组件传值

1、父组件发送的形式是以属性的形式绑定值到子组件身上。
    <div>
        <!--静态传值-->
        <menu-item  title="父组件中传过来的值"></menu-item>
        <!--动态传值-->
        <menu-item title="info"></menu-item>
    </div>
2、组件内部通过属性props接收传递过来的值
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="js/vue.js"></script>
</head>
<body>
<div id="app">
    <div>
        <div>{{pmsg}}</div>
        <!--1、menu-item 在 APP中嵌套着 故 menu-item 为 子组件 -->
        <!-- 给子组件传入一个静态的值 -->
        <menu-item  title="父组件中传过来的值"></menu-item>
        <!--动态传值-->
        <!--需要动态的数据的时候 需要属性绑定的形式设置 此时 info 来自父组件data 中的数据 . 传的值可以是数字、对象、数组等等-->
        <menu-item :title="info" content="hello"></menu-item>
    </div>
</div>
<script>
    Vue.component("MenuItem", {
        // 子组件用属性props接收父组件传递过来的数据
        props:["title","content"],
       data:function () {
           return {
              msg: "子組件本身的內容"
           }
       },
        template: '<div>{{msg + "---" + title + "---" + content}}</div>'
    });
    var vue = new Vue({
        el: "#app",
        data: {
            pmsg:"父組件中的內容",
            info:"动态绑定的属性"
        }
    });
</script>

</body>
</html>

动静结合传递多个属性也是支持的,效果如下:

在这里插入图片描述

3、props属性名规则
  • 字符串形式的模板中没有这个限制
  • 在props中使用驼峰形式,模板中需要使用短横线的形式
Vue.component(‘menu-item', {
// 在 JavaScript 中是驼峰式的
props: [‘menuTitle'],
template: '<div>{{ menuTitle }}</div>'
})
<!– 在html中是短横线方式的 -->
<menu-item menu-title=“nihao"></menu-item>
4、props属性值类型

props属性支持的类型有下面几种:

  • 字符串 String
  • 数值 Number
  • 布尔值 Boolean
  • 数组 Array
  • 对象 Object

注意:对于数值或者布尔值来说,如果通过v-bind绑定的话,在子组件中就可以得到对应类型的数据,如果是静态传值,那么得到的都是String类型的值。

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Document</title>
</head>
<body>
  <div id="app">
    <div>{{pmsg}}</div>
    <menu-item :pstr='pstr' :pnum='12' pboo='true' :parr='parr' :pobj='pobj'></menu-item>
  </div>
  <script type="text/javascript" src="js/vue.js"></script>
  <script type="text/javascript">
    /*
      父组件向子组件传值-props属性值类型
    */
    
    Vue.component('menu-item', {
      props: ['pstr','pnum','pboo','parr','pobj'],
      template: `
        <div>
          <div>{{pstr}}</div>
          <div>{{12 + pnum}}</div>
          <div>{{typeof pboo}}</div>
          <ul>
            <li :key='index' v-for='(item,index) in parr'>{{item}}</li>
          </ul>
            <span>{{pobj.name}}</span>
            <span>{{pobj.age}}</span>
          </div>
        </div>
      `
    });
    var vm = new Vue({
      el: '#app',
      data: {
        pmsg: '父组件中内容',
        pstr: 'hello',
        parr: ['apple','orange','banana'],
        pobj: {
          name: 'lisi',
          age: 12
        }
      }
    });
  </script>
</body>
</html>

在这里插入图片描述

二、子组件向父组件传值

1、子组件向父组件传值
  • 子组件向父组件传值是通过$emit() 触发事件的形式,这个形式是固定的;
  • $emit() 第一个参数为 自定义的事件名称,第二个参数为需要传递的数据;

语法如下:

<button v-on:click='$emit("enlarge-text", 5) '>扩大字体</button>
2、父组件监听子组件的事件
  • 父组件用v-on 监听子组件的事件;
  • 子组件传过来的参数父组件使用$event接收,这个是固定的;

语法如下:

<menu-item v-on:enlarge-text='handle($event)'></menu-item>

看下面这个例子:
我们要通过子组件传过来的一个数值来动态地修改父组件中字体的大小,代码如下:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Document</title>
</head>
<body>
  <div id="app">
    <div :style="{fontSize: fontSize + 'px'}">测试数据</div>
    <!--父组件用v-on 监听子组件的事件
    这里 enlarge-text 是从 $emit 中的第一个参数对应 handle 为对应的事件处理函数
    -->
    <menu-item @enlarge-text="handle($event)"></menu-item>
  </div>
  <script type="text/javascript" src="js/vue.js"></script>
  <script type="text/javascript">
    /*
      子组件向父组件传值
    */
    Vue.component('menu-item', {
       // 1、子组件用$emit()触发事件
      // 第一个参数为 自定义的事件名称 第二个参数为需要传递的数据
      template: `
      <button @click='$emit("enlarge-text",5)'>提交</button>
      `
    });
    var vm = new Vue({
      el: '#app',
      data: {
        fontSize: 10
      },
      methods:{
        handle:function (val) {
          // 扩大字体大小
         this.fontSize += val;
        }
      }
    });
  </script>
</body>
</html>

效果如下:
在这里插入图片描述

三、非父子组件传值

兄弟之间如何通信:

  • 兄弟之间传递数据需要借助于事件中心,通过事件中心传递数据;
  • 提供事件中心:
    var eventHub = new Vue()
  • 传递数据方,通过一个事件触发hub.$emit(方法名,传递的数据);
    eventHub.$emit(‘add-todo', id)
  • 接收数据方,通过mounted(){} 钩子中 触发hub.$on()方法名;
    eventHub.$on('add-todo', addTodo)
  • 销毁事件 : 通过hub.$off()方法名销毁之后无法进行传递数据;
    eventHub.$off('add-todo')
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Document</title>
</head>
<body>
  <div id="app">
  <div>父组件</div>
    <tom-test></tom-test>
    <jerry-test></jerry-test>
    <button @click="destroyEvent">销毁事件</button>
  </div>
  <script type="text/javascript" src="js/vue.js"></script>
  <script type="text/javascript">
    /*
      兄弟组件传值
    */
    // 定义事件中心
    var hub = new Vue();
    Vue.component('tom-test', {
      data:function(){
         return {
           num:0
         }
      },

      template: `
      <div>
          <div>Tom:{{num}}</div>
          <button @click="handle">提交</button>
      </div>
      `,
      methods:{
        handle:function () {
          // 传递数据方,通过一个事件触发hub.$emit(方法名,传递的数据) 触发兄弟组件的事件
          hub.$emit("jerry-event",2);
        }
      },
      mounted:function () {
        // 接收数据方,通过mounted(){} 钩子中 触发hub.$on(方法名
        // var为兄弟事件传过来的
        hub.$on("tom-event",(val) =>{
          this.num += val;
        })
      }
    });
    Vue.component('jerry-test', {
      data:function(){
        return {
          num:0
        }
      },

      template: `
      <div>
          <div>Jerry:{{num}}</div>
          <button @click="handle">提交</button>
      </div>
      `,
      methods:{
        handle:function () {
          // 触发兄弟组件的事件
          hub.$emit("tom-event",1);

        }
      },
      mounted:function () {
        // 监听事件
        // var为兄弟事件传过来的
        hub.$on("jerry-event",(val) =>{
          this.num += val;
        })
      }
    });
    var vm = new Vue({
      el: '#app',
      data: {
        fontSize: 10
      },
      methods:{
        handle:function (val) {
          // 扩大字体大小
         this.fontSize += val;
        },
        destroyEvent:function () {
          // 销毁事件 通过hub.$off()方法名销毁之后无法进行传递数据
         hub.$off("tom-event");
         hub.$off("jerry-event");
        }
      }
    });
  </script>
</body>
</html>

效果如下:
在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值