zoukankan      html  css  js  c++  java
  • 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" @click1="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                    created(){
    22                        console.log(this.$attrs);
    23                        console.log(this.$listeners);
    24                        console.log(this);
    25 
    26                    }, 
    27                     template:`<div><h1></h1><my-son v-bind="$attrs" v-on="$listeners"></my-son></div>`,
    28                     data(){
    29                             return {
    30                                 
    31                             }
    32                         },
    33                     components:{
    34                         "my-son":{
    35                             props:['msg1'],
    36                             template:`<p @click="$listeners.click1()">{{msg1}}</p>`,
    37                             inheritAttrs:true,
    38                             data(){
    39                                 return{
    40                                 }
    41                             }
    42                         }
    43                     }
    44                 }
    45             }
    46         });
    47 
    48     </script>
    49 
    50 </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>

      

  • 相关阅读:
    android应用框架搭建------BaseActivity
    Android中Application类用法
    Android App框架设计之编写基类BaseActivity
    android Application类的详细介绍
    Linux使用jstat命令查看jvm的GC情况
    cocos2dx怎样设置ios和Android横屏竖屏的几种方法
    网络请求 http get post 一
    Java多线程中wait, notify and notifyAll的使用
    一个人生活,怎样摆脱孤独提升幸福感?
    js控制文本框仅仅能输入中文、英文、数字与指定特殊符号
  • 原文地址:https://www.cnblogs.com/moon-yyl/p/11613787.html
Copyright © 2011-2022 走看看