1. 程式人生 > >vue父子組件

vue父子組件

是我 bsp set send 如果 數據傳遞 pre 數組 img

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父子組件