vue父子组件

Posted yuyujuan

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了vue父子组件相关的知识,希望对你有一定的参考价值。

1、父子组件

在上一篇随笔中展示了vue的组件,当我们继续在组件中写组件,形成组件嵌套的时候,就是我们所说的父子组件了。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>vue</title>
    <script src="bower_components/vue/dist/vue.js"></script>
    <style>
    </style>
</head>
<body>
    <div id="box">
        <aaa></aaa>
    </div>
    <script>
        var vm=new Vue({
            el:#box,
            data:{
                a:aaa
            },
            components:{
                aaa:{
                    template:<h2>我是aaa组件</h2><bbb></bbb>,
                    components:{
                        bbb:{
                            template:<h3>我是bbb组件</h3>
                        }
                    }
                }
            }
        });

    </script>
</body>
</html>

技术分享图片

在上面的例子中,外层的组件aaa就是父组件,内层的bbb组件便是子组件了。

2、子组件获取父组件的数据

我们知道,每个组件都可以有自己的data属性,组件的数据在整个组件的内部都是可以使用的,那么在下面的例子中,组件bbb是aaa的子组件,存在于组件aaa的内部,为什么不能使用aaa的数据呢?

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>vue</title>
    <script src="bower_components/vue/dist/vue.js"></script>
</head>
<body>
    <div id="box">
        <aaa></aaa>
    </div>

    <template id="aaa">
        <h1>11111</h1>
        <bbb></bbb>
    </template>
    <script>
        var vm=new Vue({
            el:#box,
            data:{
                a:aaa
            },
            components:{
                aaa:{
                    data(){
                        return {
                            msg2:我是父组件的数据
                        }
                    },
                    template:#aaa,
                    components:{
                        bbb:{
                            template:<h3>我是bbb组件->{{msg2}}</h3>
                        }
                    }
                }
            }
        });
    </script>
</body>
</html>

技术分享图片

这是因为,在vue中,组件实例的作用域是孤立的,默认情况下,父子组件的数据是不能共享的,也就是说,子组件是不能直接访问父组件的数据的。为此,vue给我们提供了一个数据传递的选项prop,用来将父组件的数据传递给子组件。具体使用如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>vue</title>
    <script src="bower_components/vue/dist/vue.js"></script>
</head>
<body>
    <div id="box">
        <aaa></aaa>
    </div>

    <template id="aaa">
        <h1>11111</h1>
        <bbb :m="msg"></bbb>
    </template>
    <script>
        var vm=new Vue({
            el:#box,
            data:{
                a:aaa
            },
            components:{
                aaa:{
                    data(){
                        return {
                            msg:我是父组件的数据
                        }
                    },
                    template:#aaa,
                    components:{
                        bbb:{
                            props:[m],
                            template:<h3>我是bbb组件->{{m}}</h3>
                        }
                    }
                }
            }
        });
    </script>
</body>
</html>

技术分享图片

在使用prop时,我们需要在子组件中使用v-bind将父组件数据和子组件的自定义属性m进行绑定,这个自定义m就是我们在子组件的props中定义。一个组件默认可以拥有任意数量的prop,任何值都可以传递给任何的prop,所以我们在上面使用的是props来存储prop列表,这个props既可以是个数组,也可以是个对象。需要注意的是,props中的prop列表需要使用驼峰式命令法。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>vue</title>
    <script src="bower_components/vue/dist/vue.js"></script>
</head>
<body>
    <div id="box">
        <aaa></aaa>
    </div>
    <template id="aaa">
        <h1>11111</h1>
        <bbb :m="msg2" :my-msg="msg"></bbb>
    </template>
    <script>
        var vm=new Vue({
            el:#box,
            data:{
                a:aaa
            },
            components:{
                aaa:{
                    data(){
                        return {
                            msg:111,
                            msg2:我是父组件的数据
                        }
                    },
                    template:#aaa,
                    components:{
                        bbb:{
                            props:{
                                m:String,
                                myMsg:Number
                            },
                            template:<h3>我是bbb组件->{{m}} <br> {{myMsg}}</h3>
                        }
                    }
                }
            }
        });
    </script>
</body>
</html>

技术分享图片

在父组件通过props向子组件传递数据时,根据需求不同,分为静态props和动态props,所谓静态props,就是子组件要显示地用props选项声明它期待获取的数据;而动态props则是动态的绑定父组件的数据到子组件的props,使用v-bind进行绑定,当父组件的数据变化时,该变化也会传递给子组件。另外需要说明的是数字的传递,在使用静态props传递数字时,它在子组件中的值是字符串,如果想传递一个实际的 number,需要使用 v-bind,从而让它的值被当作JS表达式计算 ,可以使用动态props,在data属性中设置对应的数字1。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>vue</title>
    <script src="bower_components/vue/dist/vue.js"></script>
</head>
<body>
    <div id="box">
        <aaa></aaa>
    </div>

    <template id="aaa">
        <h1>11111</h1>
        <bbb message="静态props"  c-message="ppp"  :c-mess="pmsg"  mess1="1"  :mess2="2" :mess3="num"></bbb>
    </template>
    <script>
        var vm=new Vue({
            el:#box,
            data:{
                a:aaa
            },
            components:{
                aaa:{
                    data(){
                        return {
                           pmsg:动态props,
                            num:3,
                        }
                    },
                    template:#aaa,
                    components:{
                        bbb:{
                             props:[message,cMessage,c-mess,mess1,mess2,mess3],
                            template: `
                                <div>
                                    <div>{{message}} ----  {{cMessage}}  --- {{cMess}}</div>
                                    <div>         
                                        {{mess1}}是{{ type(mess1) }}类型<br>
                                        {{mess2}}是{{ type(mess2) }}类型<br>
                                        {{mess3}}是{{ type(mess3) }}类型<br>
                                    </div>
                                <div>
                            `,
                             methods:{
                                type(text){
                                    return typeof text;
                                }
                            }
                        }
                    }
                }
            }
        });
    </script>
</body>
</html>

技术分享图片

3、父组件获取子组件的数据

和上面不一样的是,父组件想要获取子组件的数据时,需要子组件通过emit主动将自己的数据发送给父组件。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>vue</title>
    <script src="bower_components/vue/dist/vue.js"></script>
</head>
<body>
    <div id="box">
        <aaa></aaa>
    </div>
    <template id="aaa">
        <span>我是父级 -> {{msg}}</span>
        <bbb @child-msg="get"></bbb>
    </template>
    <template id="bbb">
        <h3>子组件-</h3>
        <input type="button" value="send" @click="send">
    </template>
    <script>
        var vm=new Vue({
            el:#box,
            data:{
                a:aaa
            },
            components:{
                aaa:{
                    data(){
                        return {
                            msg:111,
                            msg2:我是父组件的数据
                        }
                    },
                    template:#aaa,
                    methods:{
                        get(msg){
                            this.msg=msg;
                        }
                    },
                    components:{
                        bbb:{
                            data(){
                                return {
                                    a:我是子组件的数据
                                }
                            },
                            template:#bbb,
                            methods:{
                                send(){
                                    this.$emit(child-msg,this.a);
                                }
                            }
                        }
                    }
                }
            }
        });
    </script>
</body>
</html>

首先,我们需要在子组件中触发一个主动发送数据的事件,上面的例子中是一个点击事件send;其次,在点击事件中使用emit方法,这个emit接收两个参数:传递数据的事件和需要传递的数据,这个传递数据的事件也是自定义的;然后在父组件中引用子组件,并在引用的子组件中使用on监听上一步传递数据的事件,上面的例子中是child-msg;最后在父组件中使用这个事件,这个事件带有一个参数,就是从子组件发送过来的数据。

 


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

《Vue的父子组件传值》

vue组件之间的通信, 父子组件通信,兄弟组件通信

Vue中父子组件传值

Vue父子组件生命周期执行顺序

vue组件封装及父子组件传值,事件处理

Vue学习——父子组件的交互