zoukankan      html  css  js  c++  java
  • 父子组件2.0

    在前面总结过vue1.0中的组件通信,现在根据vue2.0的变化比较一下两者的不同之处。

    首先还是用一个例子回顾一下之前的父子组件通信。

    vue1.0

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>vue</title>
        <script src="vue1.0.js"></script> 
    </head>
    <body>
         <template id="child">
            <div>
                <span>我是子组件</span>
                <input type="button" value="按钮" @click="change">
                <strong>{{msg}}</strong>
            </div>
        </template>
        <div id="box">
            父级: ->{{a}}
            <br>
            <child-com :msg="a"></child-com>
        </div>
        <script>
            new Vue({
                    el:'#box',
                    data:{
                        a:'我是父组件数据'
                    },
                    components:{
                        'child-com':{
                            props:['msg'],
                            template:'#child',
                            methods:{
                                change(){
                                    this.msg='被更改了'
                                }
                            }
                        }
                    }
                });
        </script>
    </body>
    </html>

    在上面的例子中,子组件是可以更改父组件的数据的,甚至可以通过添加sync实现同步修改,但是当我们把上面的js改为vue2.0的时候,会发现程序直接报错了。

    这是因为在vue2.0中的prop中提出了一个单向下行绑定:父级 prop 的更新会向下流动到子组件中,但是反过来则不行。这样会防止从子组件意外改变父级组件的状态,从而导致你的应用的数据流向难以理解。额外的,每次父级组件发生更新时,子组件中所有的 prop 都将会刷新为最新的值。这意味着你不应该在一个子组件内部改变 prop。如果你这样做了,Vue 会在浏览器的控制台中发出警告。

    针对子组件需要更改prop传过来的值,官方文档给出了两种办法。

    本地data

    第一种方法是这个prop用来传递一个初始值,当子组件希望将这个初始值用作一个本地数据使用时,最好定义一个本地的data属性并将这个prop用作其初始值。在下面的例子中,我们希望在子组件中使用父组件的数据a,首先在父组件中通过prop将这个数据传递到子组件,然后在子组件中定义一个b,这个b的初始值就是a,然后在子组件中对b进行操作。所以,此时只能更改b,并不能同步更改a。

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>vue</title>
        <script src="vue.js"></script> 
    </head>
    <body>
         <template id="child">
            <div>
                <span>我是子组件</span>
                <input type="button" value="按钮" @click="change">
                <strong>{{b}}</strong>
            </div>
        </template>
        <div id="box">
            父级: ->{{a}}
            <br>
            <child-com :msg="a"></child-com>
        </div>
        <script>
            new Vue({
                    el:'#box',
                    data:{
                        a:'我是父组件数据'
                    },
                    components:{
                        'child-com':{
                            props:['msg'],
                            data(){
                                return {
                                    b:this.msg
                                }
                            },
                            template:'#child',
                            methods:{
                                change(){
                                    this.b='被更改了'
                                }
                            }
                        }
                    }
                });
        </script>
    </body>
    </html>

    官方中还提供了一种使用计算属性的方法。可以直接在官方查看,这里就不再演示了。

    对象引用

    除此之外,还有另外一种方法,那就是对象之间的引用,父组件不再是传递单一的基本类型数据给子组件,而是使用对象的形式进行传递,此时不仅能够实现子组件数据更改,还能同步更改父组件数据。

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>vue</title>
        <script src="vue.js"></script> 
    </head>
    <body>
         <template id="child">
            <div>
                <span>我是子组件</span>
                <input type="button" value="按钮" @click="change">
                <strong>{{msg.a}}</strong>
            </div>
        </template>
        <div id="box">
            父级: ->{{giveData.a}}
            <br>
            <child-com :msg="giveData"></child-com>
        </div>
        <script>
            new Vue({
                    el:'#box',
                    data:{
                        giveData:{
                            a:'我是父组件数据'
                        }
                    },
                    components:{
                        'child-com':{
                            props:['msg'],
                            template:'#child',
                            methods:{
                                change(){
                                    this.msg.a='被改了';
                                }
                            }
                        }
                    }
                });
        </script>
    </body>
    </html>

        

    单一事件管理组件通信。

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>vue</title>
        <script src="vue.js"></script> 
    </head>
    <body>
        <div id="box">
            <com-a></com-a>
            <com-b></com-b>
            <com-c></com-c>
        </div>
        <script>
            //准备一个空的实例对象
            var Event=new Vue();
    
            var A={
                template:`
                    <div>
                        <span>我是A组件</span> -> {{a}}
                        <input type="button" value="把A数据给C" @click="send">
                    </div>
                `,
                methods:{
                    send(){
                        Event.$emit('a-msg',this.a);
                    }
                },
                data(){
                    return {
                        a:'我是a数据'
                    }
                }
            };
            var B={
                template:`
                    <div>
                        <span>我是B组件</span> -> {{a}}
                        <input type="button" value="把B数据给C" @click="send">
                    </div>
                `,
                methods:{
                    send(){
                        Event.$emit('b-msg',this.a);
                    }
                },
                data(){
                    return {
                        a:'我是b数据'
                    }
                }
            };
            var C={
                template:`
                    <div>
                        <h3>我是C组件</h3>
                        <span>接收过来的A的数据为: {{a}}</span>
                        <br>
                        <span>接收过来的B的数据为: {{b}}</span>
                    </div>
                `,
                data(){
                    return {
                        a:'',
                        b:''
                    }
                },
                mounted(){
                    //接收A组件的数据
                    Event.$on('a-msg',function(a){
                        this.a=a;
                    }.bind(this));
    
                    //接收B组件的数据
                    Event.$on('b-msg',function(a){
                        this.b=a;
                    }.bind(this));
                }
            };
    
            new Vue({
                el:'#box',
                components:{
                    'com-a':A,
                    'com-b':B,
                    'com-c':C
                }
            });
        </script>
    </body>
    </html>

       

    主要包括三个步骤:

    • 准备一个空的实例对象   var Event=new Vue();
    • 发送数据    Event.$emit(事件名称, 数据)
    • 接收数据    Event.$on(事件名称,function(data){  }.bind(this));
  • 相关阅读:
    项目成本管理(三)
    项目成本管理(二)
    项目成本管理(一)
    男士香水
    荷兰猛兽-梅尔文训练体能
    PP学习笔记-业务基础
    SAP入行就业
    PP学习笔记02
    BZOJ 3012: [Usaco2012 Dec]First! 字典树 + tarjan
    CF319E Ping-Pong 线段树 + vector + 思维
  • 原文地址:https://www.cnblogs.com/yuyujuan/p/9823484.html
Copyright © 2011-2022 走看看