zoukankan      html  css  js  c++  java
  • Vue父子组件互相通信实例

    组件实例之间的作用域是独立的,意味了不应该在子组件的模板内直接引用父组件的数据,但是父子组件之间需要通信:父组件要给子组件传递数据,子组件需要将它内部发生的事情告知给父组件。

    这里写图片描述

    prop 是父组件用来传递数据的一个自定义属性。子组件需要显式地用 props 选项声明 “prop”:

    Vue.component('child', {
    
    	  // 声明 props
    
    	  props: ['message'],
    
    	  // 就像 data 一样,prop 可以用在模板内
    
    	  // 同样也可以在 vm 实例中像 “this.message” 这样使用
    
    	  template: '<span>{{ message }}</span>'
    
      })
    

    一个实例:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>多层组件通信</title>
    </head>
    <body>
        <div id="app">
            <my-parent :imgtitle='title' :imgsrc='img'></my-parent>
        </div>
    
        <template id="my_img">
            <img :src="imgsrc" width="200">
        </template>
    
        <template id="my_title">
            <h2>{{title}}</h2>
        </template>
    
        <template id="my_parent">
            <div>
                <child1 :imgsrc="imgsrc"></child1>
                <child2 :title="imgtitle"></child2>
            </div>
        </template>
    
            <script src="js/vue.min.js"></script>
            <script>
                //1.子组件的实例
                let Child1 = Vue.extend({
                    template:'#my_img',
                    props:['imgsrc']
                });
                let Child2 = Vue.extend({
                    template:'#my_title',
                    props:['title']
                });
                //注册父组件
                Vue.component('my-parent',{
                    props:['imgtitle','imgsrc'],
                    components:{
                        'child1':Child1,
                        'child2':Child2
                    },
                    template:'#my_parent'
                });
                new Vue({
                    el:'#app',
                    data:{
                        title:'我很帅',
                        img:'img/01.jpg'
                    }
                });
            </script>
    </body>
    </html>
    

    可以看到数据从父组件通过props传递给子组件,但是注意通过这种方法prop默认是单向绑定, 当父组件的属性变化时,将传导给子组件,但是反过来不会。这是为了防止子组件无意修改了父组件的状态。

    然后就是子组件传递数据给父组件,通过自定义事件。

    每个 Vue 实例都实现了事件接口(Events interface),即:

    • 使用 $on(eventName) 监听事件

    • 使用 $emit(eventName) 触发事件

    父组件可以在使用子组件的地方直接用 v-on 来监听子组件触发的事件。

    一个实例,一旦子组件的total()事件发生,通过emit触发父组件的方法。

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Vue的自定义事件</title>
    </head>
    <body>
    <div id="app">
        <my-btn @total="allcounter()"></my-btn>
        <my-btn @total="allcounter()"></my-btn>
        <my-btn @total="allcounter()"></my-btn>
        <my-btn @total="allcounter()"></my-btn>
        <my-btn @total="allcounter()"></my-btn>
        <my-btn @total="allcounter()"></my-btn>
        <p>所有按钮一共点击了{{totalCounter}}次</p>
    </div>
    
    <template id='my_btn'>
        <button @click="total()">点击了{{counter}}次</button>
    </template>
    
    <script src="js/vue.min.js"></script>
    <script>
        Vue.component('my-btn',{
            template:'#my_btn',
            data(){
                return{
                    counter:0
                }
            },
            methods:{
                total(){
                    this.counter += 1;
    
                    //子组件通知外界,我调用了这个方法
                    this.$emit('total');
                }
            }
        });
    
        new Vue({
            el: '#app',
            data: {
                totalCounter:0
            },
            methods:{
                allcounter(){
                    this.totalCounter += 1;
                }
            }
        });
    </script>
    </body>
    </html>
    

    运行结果就是子组件之间的点击互不影响,父组件总点击数增加。

  • 相关阅读:
    设计模式-状态模式
    Nginx相关
    Docker基础使用
    JavaScript定时器及回调用法
    前端交互篇
    基于ConcurrentHashMap的本地缓存
    J.U.C体系进阶(五):juc-collections 集合框架
    J.U.C体系进阶(四):juc-sync 同步器框架
    J.U.C体系进阶(三)- juc-atomic 原子类框架
    .net core https 双向验证
  • 原文地址:https://www.cnblogs.com/zhangmingzhao/p/8336502.html
Copyright © 2011-2022 走看看