vue基础----组件通信(props,$emit,$attrs,$listeners)

Posted moon-yyl

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了vue基础----组件通信(props,$emit,$attrs,$listeners)相关的知识,希望对你有一定的参考价值。

一、父传子,子传孙

  1. props

    1>在父组件中通过子组件自定义的标签属性来传递数据。

    2>在子组件中通过props声明希望用到的数据

 1 <body>
 2     <div id="app">
 3         <my-father :msg1="msg" a="10" :b="20" @click="fn"></my-father>
 4     </div>
 5     <script src="./node_modules/vue/dist/vue.js"></script>
 6     <script>
 7         let vm = new Vue(
 8             el:"#app",
 9             data:
10                 msg:"hello yilia"
11             ,
12             methods:
13                 fn()
14                     console.log("father");
15                 
16             ,
17             components:
18                 "my-father":
19                     props:[‘msg1‘],
20                     template:`<div><h1>msg1</h1><my-son :msg2="msg1"></my-son></div>`,
21                     data()
22                         return     
23                         
24                     ,
25                     components:
26                         "my-son":
27                             props:[‘msg2‘],
28                             template:`<p>msg2</p>`,
29                             inheritAttrs:true, //为false的时候,没有用到的数据不会显示在dom结构上
30                             data()
31                                 return
32                                 
33                             
34                         
35                     
36                 
37             
38         );
39 
40     </script>
41 
42 </body>

1.1这里需要注意的props 除了上述这种写法,还可以写成对象形式,来校验数据

 1 props: 
 2 a: 
 3     type: Number,
 4     default: 10
 5 ,
 6 b: 
 7     type: String,
 8     validator(val) 
 9         return val>0; // "2">0
10     
11 ,
12 arr: 
13     type: Array,
14     //假如属性是数组或对象 默认值需要通过函数返回
15     default:()=>([1])
16 
17 ,

2.有时候my-father这块用不到数据,但需要把爷爷的数据传给孙子,可以用$attrs,在 my-son v-bind="$attrs"

this.$attrs 对没有使用的属性保留在this.$attrs (也就是props中没有申明的属性)

 1 <body>
 2     <div id="app">
 3         <my-father :msg1="msg" a="10" :b="20" @click="fn"></my-father>
 4     </div>
 5     <script src="./node_modules/vue/dist/vue.js"></script>
 6     <script>
 7         let vm = new Vue(
 8             el:"#app",
 9             data:
10                 msg:"hello Yilia"
11             ,
12             methods:
13                 fn()
14                     console.log("father");
15                 
16             ,
17             components:
18                 "my-father":
19                  //   props:[‘msg1‘],
20                     template:`<div><h1></h1><my-son v-bind="$attrs"></my-son></div>`,
21                     data()
22                         return     
23                         
24                     ,
25                     components:
26                         "my-son":
27                             props:[‘msg1‘],
28                             template:`<p>msg1</p>`,
29                             inheritAttrs:true, //为false的时候,没有用到的数据不会显示在dom结构上
30                             data()
31                                 return
32                                 
33                             
34                         
35                     
36                 
37             
38         );
39     </script>
40 </body>

二、点击子组件,调用父组件的方法 (想在父组件中绑定原生事件给组件)

1.需要添加修饰符native,不添加就被当作一个属性对待

 1 <body>
 2     <div id="app">
 3         <!--想在父组件中绑定原生事件给组件 需要加.native 不加就被当作一个属性看待-->
 4         <my-button @click.native="fn"></my-button>
 5     </div>
 6     <script src="./node_modules/vue/dist/vue.js"></script>
 7     <script>
 8         let vm = new Vue(
 9             el: "#app",
10             methods:
11                 fn() 
12                     console.log("fn() is called");
13                 
14             ,
15             components: 
16                 "MyButton": 
17                     template: `
18                     <div>
19                         点我
20                     </div>`
21                 
22             
23         );
24     </script>
25 </body>

点击 “点我” 的时候父组件的fn函数被调用。

2.$listeners 绑定所有的方法,直接调用父组件的方法

 1 <body>
 2     <div id="app">
 3         <!--想在父组件中绑定原生事件给组件 需要加.native 不加就被当作一个属性看待-->
 4         <my-button @click="fn"></my-button>
 5     </div>
 6     <script src="./node_modules/vue/dist/vue.js"></script>
 7     <script>
 8         let vm = new Vue(
 9             el: "#app",
10             methods:
11                 fn() 
12                     console.log("fn() is called");
13                 
14             ,
15             components: 
16                 "MyButton": 
17                     mounted()
18                         console.log(this.$listeners); 
19                         //click: ƒ
20                     ,               
21                     template: `<div @click="$listeners.click()">点我</div>`
22                 
23             
24         );
25     </script>
26 </body>

3.子组件想调用父组件的方法 $emit

  1> 在子组件中调用$emit()方法发布一个事件
  2> 在父组件中提供一个在子组件内部发布的事件处理函数
  3> 在父组件订阅子组件内部发布的事件
 1 <body>
 2     <div id="app">
 3         <!--想在父组件中绑定原生事件给组件 需要加.native 不加就被当作一个属性看待-->
 4         <!--<my-button @click.native="fn"></my-button>-->
 5         <my-button @click="fn" @mouseup="fn"></my-button>
 6     </div>
 7     <script src="../01-vue-basic/code/node_modules/vue/dist/vue.js"></script>
 8     <script>
 9         // 组件通信 props $emit $attrs $listeners
10         /*
11            子如何传父
12            1 在子组件中调用$emit()方法发布一个事件
13            2 在父组件中提供一个在子组件内部发布的事件处理函数
14            3 在父组件订阅子组件内部发布的事件
15         */
16         let vm = new Vue(
17             el: "#app",
18             data: 
19                 content: "点我"
20             ,
21             methods:
22                 fn(num) 
23                     console.log(num,"fn() is called");
24                 
25             ,
26             components: 
27                 "MyButton": 
28                     mounted() 
29                         console.log(this.$listeners);// 绑定所有的方法
30                     ,
31                     template: `
32                        <div>
33                          <button @click="$listeners.click(123);">点我</button>
34                          <button @click="$emit(‘click2‘,23)">点我</button>
35                          <button @click="$listeners.click(123);" @mouseup="$listeners.mouseup(123);">点我</button>
36                          <button v-on="$listeners" >点我</button>
37                        </div> 
38                     `
39                 
40             
41         );
42     </script>
43 </body>

 

 

  

以上是关于vue基础----组件通信(props,$emit,$attrs,$listeners)的主要内容,如果未能解决你的问题,请参考以下文章

Vue组件通信props$ref$emit,组件传值

vue2.0嵌套组件之间的通信($refs,props,$emit)

vue.js学习笔记— 父子组件之间通信的第一种方式 props 和 $emit

vue组件通信

vue组件通信

vue组件通信