• vue 常用开发父子组件的通信


    1.父组件绑定参数,子组件props接收

    // 父组件
    <template>
        <div id="father">
            <data :msg="msg" :fn="myFunction"></data>
        </div>
    </template>
     
    <script>
    import data from "./data .vue";
    export default {
        name: father,
        components: {
            data 
        }
        data() {
            msg: "父组件定义的数据";
        },
        methods: {
            myFunction() {
                console.log("father");
            }
        },
    };
    </script>
    // 子组件
    <template>
        <div id="son">
            <p>{{msg}}</p>
            <button @click="fn">按钮</button>
        </div>
    </template>
    <script>
    export default {
        name: "data",
        props: {
    		msg: {
    			type: String,
    			defalut:''
    		},
    		fn :{
    			type: Function,
    		}
    	}
    };
    </script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45

    2.父组件自定义绑定事件,子组件$emit接收

    // 父组件
    <template>
        <div id="father">
            <data  @fn="myFunction"></data>
        </div>
    </template>
     
    <script>
    import data from "./data .vue";
    export default {
        name: father,
        components: {
            data 
        }
        data() {
        },
        methods: {
            myFunction() {
               //编写需要的方法
               console.log('0000000000000')
            }
        },
    };
    </script>
    // 子组件
    <template>
        <div id="son">
            <p>{{msg}}</p>
            <button @click="fn">按钮</button>
        </div>
    </template>
    <script>
    export default {
        name: "data",
    	},
    	data() {
        },
        methods: {
        //调用父组件
            sonHandle() {
             this.$emit('fn')
            }
        },
    };
    </script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45

    3.ref / $refs

    ref :这个属性用在子组件上,可以将子组件的数据传给父组件

    <template>
      <child ref="child"></child>
    </template>
    <script>
      import child from './child.vue'
      export default {
        components: { child },
        created() {
    		this.$refs.child.open()//调用子组件的open方法
    		//通过ref可以获取子组件的所有实例
    	}
      }
    </script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    4.this.$parent通信(子组件访问父组件)

    //父组件
    <template>
        <div id="father">
            <data ></data>
        </div>
    </template>
     
    <script>
    import data from "./data .vue";
    export default {
        name: father,
        components: {
            data 
        }
        data() {
        msg:'0000000000000000'
        },
        methods: {
            myFunction() {
               //编写需要的方法
               console.log('0000000000000')
            }
        },
    };
    </script>
    // 子组件
    <template>
        <div id="son">
            <p>{{msg}}</p>
            <button @click="fn">按钮</button>
        </div>
    </template>
    <script>
    export default {
        name: "data",
    	},
    	data() {
        },
        methods: {
        //调用父组件
            fn() {
    			 this.$nextTick(() => {//一般推荐加nextTick和保证组件有渲染不能v-if
                 this.$parent.myFunction();//访问父组件的方法
             });
    
    		}
        },
    };
    </script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49

    5.provide 和 inject通信

    //grandpa.vue
    <template>
      <div>
        <h3 style="margin-bottom: 20px">爷爷组件</h3>
        <el-button type="primary" @click="lookDetail">查看</el-button>
        <!-- 儿子组件 -->
        <son v-model:visible="openDialog"></son>
      </div>
    </template>
    
    <script>
    import Son from "./son.vue";
    export default {
      components: { Son },
      data() {
        return {
          message: "aa",
          openDialog: false,
        };
      },
      methods: {
        lookDetail() {
          this.openDialog = true;
        },
      },
    };
    </script>
    
    
    //son.vue
    <template>
      <div>
        <el-dialog  v-model="visible" title="父组件" width="50%" append-to-body @close="closeDialog">
          <el-button type="primary" @click="lookDetail">查看</el-button>
        </el-dialog>
        <!-- 孙子组件 -->
        <grandson v-model:visible="openDialog"></grandson>
      </div>
    </template>
    
    <script>
    //孙子组件
    import grandson from "./grandson.vue";
    export default {
      components: {
        grandson,
      },
      props: {
        visible: {
          type: Boolean,
          default: false,
        },
      },
      emit: ["update:visible"],
      data() {
        return {
          openDialog: false,
        };
      },
      methods: {
        closeDialog() {
          this.$emit("update:visible", false);
        },
        lookDetail() {
          this.openDialog = true;
        },
      },
    };
    </script>
    
    
    //grandson.vue
    <template>
      <div>
        <el-dialog v-model="visible" title="孙子组件"  width="30%"  @close="closeDialog">
        </el-dialog>
      </div>
    </template>
    
    <script>
    export default {
      props: {
        visible: {
          type: Boolean,
          default: false,
        },
      },
      emit: ["update:visible"],
      data() {
        return {};
      },
      methods: {
        closeDialog() {
            this.$emit("update:visible",false)
        },
      },
    };
    </script>
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99

    6、eventBus事件总线($emit / $on)

    eventBus事件总线适用于父子组件、非父子组件等之间的通信
    创建事件中心管理组件之间的通信

    // event-bus.js
    
    import Vue from 'vue'
    export const EventBus = new Vue()
    
    
    • 1
    • 2
    • 3
    • 4
    • 5

    兄弟组件firstCom和secondCom

    <template>
      <div>
        <first-com></first-com>
        <second-com></second-com>
      </div>
    </template>
    
    <script>
    import firstCom from './firstCom.vue'
    import secondCom from './secondCom.vue'
    export default {
      components: { firstCom, secondCom }
    }
    </script>
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    <template>
      <div>
        <button @click="add">加法</button>    
      </div>
    </template>
    
    <script>
    import {EventBus} from './event-bus.js' // 引入事件中心
    
    export default {
      data(){
        return{
          num:0
        }
      },
      methods:{
        add(){
          EventBus.$emit('addition', {
            num:this.num++
          })
        }
      }
    }
    </script>
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    接收事件

    <template>
      <div>求和: {{count}}</div>
    </template>
    
    <script>
    import { EventBus } from './event-bus.js'
    export default {
      data() {
        return {
          count: 0
        }
      },
      mounted() {
        EventBus.$on('addition', param => {
          this.count = this.count + param.num;
        })
      }
    }
    </script>
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    7、$attrs / $listeners

    实组件之间的跨代通信。

    $attrs:继承所有的父组件属性(除了props传递的属性、class 和 style),一般用在子组件的子元素上
    $listeners:该属性是一个对象,里面包含了作用在这个组件上的所有监听器,可以配合 v-on=" $listeners " 将所有的事件监听器指向这个组件的某个特定的子元素。(相当于子组件继承父组件的事件)

    A组件

    <template>
        <div id="app">
            //此处监听了两个事件,可以在B组件或者C组件中直接触发 
            <child1 :p-child1="child1" :p-child2="child2" @test1="onTest1" @test2="onTest2"></child1>
        </div>
    </template>
    <script>
    import Child1 from './Child1.vue';
    export default {
        components: { Child1 },
        methods: {
            onTest1() {
                console.log('test1 running');
            },
            onTest2() {
                console.log('test2 running');
            }
        }
    };
    </script>
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    B组件

    <template>
        <div class="child-1">
            <p>props: {{pChild1}}</p>
            <p>$attrs: {{$attrs}}</p>
            <child2 v-bind="$attrs" v-on="$listeners"></child2>
        </div>
    </template>
    <script>
    import Child2 from './Child2.vue';
    export default {
        props: ['pChild1'],
        components: { Child2 },
        inheritAttrs: false,
        mounted() {
            this.$emit('test1'); // 触发APP.vue中的test1方法
        }
    };
    </script>
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    C组件

    <template>
        <div class="child-2">
            <p>props: {{pChild2}}</p>
            <p>$attrs: {{$attrs}}</p>
        </div>
    </template>
    <script>
    export default {
        props: ['pChild2'],
        inheritAttrs: false,
        mounted() {
            this.$emit('test2');// 触发APP.vue中的test2方法
        }
    };
    </script>
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
  • 相关阅读:
    Python进价系列 - 16讲 多进程
    [附源码]Python计算机毕业设计Django酒店在线预约咨询小程序
    JS力扣刷题经典100题——两数相加
    L60.linux命令每日一练 -- 第九章 Linux进程管理命令 -- top和nice
    浅谈树上启发式合并(dsu on tree)
    [附源码]java毕业设计石林县石漠化信息查询分析系统
    Spring Boot 2.x源码系列【4】启动流程深入解析之启动监听器
    day42
    java爬虫使用Jsoup
    C. Zero-Sum Prefixes Codeforces Round #833 (Div. 2)(前缀和+贪心)
  • 原文地址:https://blog.csdn.net/weixin_46820017/article/details/127432804