父子组件2.0

Posted yuyujuan

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了父子组件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));

 

以上是关于父子组件2.0的主要内容,如果未能解决你的问题,请参考以下文章

React教程:父子组件传值(组件通信)

Vue中父子组件的双向数据绑定

Vue中父子组件的双向数据绑定

Vue中父子组件的双向数据绑定

vue视频学习笔记05

小程序开发 组件定义(封装)组件调用父子组件方法调用父子组件传值通讯